Wikipedia para siempre
ShareCode
Permalink: http://www.treeweb.es/u/974/ 01/02/2011

ShareCode

1 <!DOCTYPE html>2 <html lang="es">3 <head>4 <meta charset="UTF-8">5 <meta name="viewport" content="width=device-width, initial-scale=1.0">6 <title>Contador · +2 / −3</title>7 <link rel="preconnect" href="https://fonts.googleapis.com">8 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>9 <link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=Unbounded:wght@500;700;800&display=swap" rel="stylesheet">10 <style>11  *{box-sizing:border-box;margin:0;padding:0}12  :root{13  --bg:#0c1210;14  --panel:#131b17;15  --panel-2:#0f1713;16  --line:rgba(190,255,220,.09);17  --text:#eaf4ee;18  --muted:#7f968c;19  --green:#2fd66b;20  --green-soft:rgba(47,214,107,.14);21  --red:#ff5d5d;22  --red-soft:rgba(255,93,93,.14);23  }24  html,body{min-height:100%}25  body{26  background:var(--bg);27  color:var(--text);28  font-family:'Space Mono',monospace;29  overflow-x:hidden;30  }31  ::selection{background:var(--green);color:#04150b}32 33  /* ── fondo por capas ─────────────────────────── */34  .bg{35  position:fixed;inset:0;z-index:-2;36  background:37  radial-gradient(55% 45% at 18% 12%, rgba(47,214,107,.10), transparent 60%),38  radial-gradient(45% 40% at 85% 88%, rgba(255,93,93,.09), transparent 60%),39  linear-gradient(180deg,#0d1411,#0a0f0d);40  }41  .bg::before{42  content:"";position:absolute;inset:0;43  background:44  linear-gradient(rgba(200,255,225,.035) 1px, transparent 1px),45  linear-gradient(90deg, rgba(200,255,225,.035) 1px, transparent 1px);46  background-size:44px 44px;47  -webkit-mask-image:radial-gradient(80% 70% at 50% 40%, #000 30%, transparent 100%);48  mask-image:radial-gradient(80% 70% at 50% 40%, #000 30%, transparent 100%);49  }50  .bg::after{51  content:"";position:absolute;inset:0;opacity:.05;52  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.6'/></svg>");53  }54  .orb{position:fixed;z-index:-1;border-radius:50%;filter:blur(90px);pointer-events:none}55  .orb.g{width:420px;height:420px;background:rgba(47,214,107,.13);top:-140px;left:-120px;animation:drift 16s ease-in-out infinite alternate}56  .orb.r{width:380px;height:380px;background:rgba(255,93,93,.11);bottom:-140px;right:-100px;animation:drift 21s ease-in-out infinite alternate-reverse}57  @keyframes drift{to{transform:translate(60px,40px) scale(1.08)}}58 59  /* ── estructura ──────────────────────────────── */60  .wrap{max-width:1120px;margin:0 auto;padding:28px 22px 40px;min-height:100vh;display:flex;flex-direction:column;gap:26px}61 62  header{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap}63  .brand{display:flex;align-items:center;gap:14px}64  .mark{65  width:44px;height:44px;border-radius:12px;display:grid;place-items:center;66  font:800 1.5rem 'Unbounded';color:#0b1210;67  background:linear-gradient(135deg,var(--green) 0%,var(--green) 50%,var(--red) 50%,var(--red) 100%);68  box-shadow:0 5px 0 rgba(0,0,0,.35),0 10px 24px rgba(0,0,0,.3);69  text-shadow:0 1px 0 rgba(255,255,255,.25);70  }71  .brand h1{font:800 1.05rem 'Unbounded';letter-spacing:.08em}72  .brand small{display:block;margin-top:6px;color:var(--muted);font-size:.62rem;letter-spacing:.22em}73  .hud{display:flex;align-items:center;gap:14px}74  .led{width:11px;height:11px;border-radius:50%;background:#33453c;transition:background .12s,box-shadow .12s}75  .led.add{background:var(--green);box-shadow:0 0 14px var(--green)}76  .led.sub{background:var(--red);box-shadow:0 0 14px var(--red)}77 78  .ghost{79  background:transparent;border:1px solid var(--line);color:var(--muted);80  font:400 .68rem 'Space Mono',monospace;letter-spacing:.14em;81  padding:9px 14px;border-radius:9px;cursor:pointer;transition:all .18s;82  display:inline-flex;align-items:center;gap:8px;83  }84  .ghost:hover{color:var(--text);border-color:rgba(190,255,220,.3);background:rgba(190,255,220,.05)}85  kbd{86  font:700 .62rem 'Space Mono',monospace;color:var(--text);87  background:rgba(190,255,220,.07);border:1px solid var(--line);border-bottom-width:2px;88  border-radius:5px;padding:2px 6px;89  }90 91  main{display:grid;grid-template-columns:1fr 330px;gap:24px;align-items:stretch;flex:1}92 93  /* ── panel principal ─────────────────────────── */94  .stage{95  background:linear-gradient(180deg,var(--panel),var(--panel-2));96  border:1px solid var(--line);border-radius:20px;97  padding:34px 26px 38px;position:relative;overflow:hidden;98  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:26px;99  min-height:440px;100  box-shadow:inset 0 1px 0 rgba(255,255,255,.04),0 24px 60px rgba(0,0,0,.35);101  }102  .topline{position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,var(--green),var(--red));opacity:.5}103  .readout-label{display:flex;align-items:center;gap:12px;color:var(--muted);font-size:.68rem;letter-spacing:.3em}104  .readout-label::before,.readout-label::after{content:"";width:34px;height:1px;background:var(--line)}105 106  .counter-box{position:relative;display:grid;place-items:center;padding:12px 0 6px}107  .counter{108  position:relative;z-index:1;109  font:700 clamp(4.2rem,15vw,9.5rem)/1 'Space Mono',monospace;110  letter-spacing:-.03em;font-variant-numeric:tabular-nums;user-select:none;111  }112  .counter.add{animation:roll-up .3s cubic-bezier(.18,.85,.3,1.12),glow-add .8s ease-out}113  .counter.sub{animation:roll-down .3s cubic-bezier(.18,.85,.3,1.12),glow-sub .8s ease-out}114  .counter.zero{animation:pop .35s ease-out}115  @keyframes roll-up{from{transform:translateY(.32em);opacity:0;filter:blur(5px)}to{transform:none;opacity:1;filter:none}}116  @keyframes roll-down{from{transform:translateY(-.32em);opacity:0;filter:blur(5px)}to{transform:none;opacity:1;filter:none}}117  @keyframes glow-add{30%{text-shadow:0 0 14px rgba(47,214,107,.6),0 0 55px rgba(47,214,107,.4)}100%{text-shadow:0 0 0 rgba(47,214,107,0)}}118  @keyframes glow-sub{30%{text-shadow:0 0 14px rgba(255,93,93,.6),0 0 55px rgba(255,93,93,.4)}100%{text-shadow:0 0 0 rgba(255,93,93,0)}}119  @keyframes pop{from{transform:scale(1.12)}to{transform:scale(1)}}120 121  .pulse{122  position:absolute;left:50%;top:50%;width:min(52vw,320px);aspect-ratio:1/1;123  margin:calc(min(52vw,320px)/-2) 0 0 calc(min(52vw,320px)/-2);124  border-radius:50%;border:2px solid transparent;opacity:0;pointer-events:none;125  }126  .pulse.add{border-color:var(--green)}127  .pulse.sub{border-color:var(--red)}128  .pulse.go{animation:pulse .7s ease-out}129  @keyframes pulse{0%{opacity:.85;transform:scale(.5)}100%{opacity:0;transform:scale(1.6)}}130 131  .chip{132  position:absolute;left:50%;top:-6px;z-index:2;transform:translateX(-50%);133  font:700 1.15rem 'Space Mono',monospace;padding:.28em .7em;border-radius:999px;134  pointer-events:none;animation:chip .95s ease-out forwards;135  }136  .chip.add{color:var(--green);background:var(--green-soft);border:1px solid rgba(47,214,107,.45)}137  .chip.sub{color:var(--red);background:var(--red-soft);border:1px solid rgba(255,93,93,.45)}138  @keyframes chip{139  0%{opacity:0;transform:translate(-50%,14px) scale(.8)}140  25%{opacity:1}141  100%{opacity:0;transform:translate(-50%,-64px) scale(1.05)}142  }143 144  .stats{display:flex;gap:10px;flex-wrap:wrap;justify-content:center}145  .stat{146  border:1px solid var(--line);border-radius:10px;padding:8px 14px;147  font-size:.68rem;letter-spacing:.12em;color:var(--muted);148  display:flex;gap:8px;align-items:center;149  }150  .stat b{color:var(--text);font-size:.95rem}151  .stat.g b{color:var(--green)}152  .stat.r b{color:var(--red)}153 154  /* ── botones ─────────────────────────────────── */155  .controls{display:flex;gap:18px;width:100%;max-width:540px;justify-content:center;flex-wrap:wrap}156  .btn{157  flex:1 1 190px;max-width:250px;158  display:flex;flex-direction:column;align-items:center;gap:3px;159  padding:16px 18px 14px;border-radius:16px;border:1px solid rgba(0,0,0,.4);160  cursor:pointer;font-family:'Space Mono',monospace;161  transition:transform .09s ease,box-shadow .09s ease,filter .18s ease;162  }163  .btn .op{font-size:2rem;font-weight:700;line-height:1}164  .btn .lbl{font-size:.62rem;letter-spacing:.3em;opacity:.7}165  .btn:focus-visible{outline:2px solid var(--text);outline-offset:3px}166  .btn.green{167  background:linear-gradient(180deg,#43e986,#1fb463);color:#04150b;168  box-shadow:0 7px 0 #0d5a32,0 16px 34px rgba(47,214,107,.22);169  }170  .btn.green:hover{filter:brightness(1.08);transform:translateY(-2px);box-shadow:0 9px 0 #0d5a32,0 20px 40px rgba(47,214,107,.3)}171  .btn.green:active{transform:translateY(5px);box-shadow:0 2px 0 #0d5a32,0 8px 18px rgba(47,214,107,.2)}172  .btn.red{173  background:linear-gradient(180deg,#ff8080,#ee4a4a);color:#210404;174  box-shadow:0 7px 0 #6d1a1a,0 16px 34px rgba(255,93,93,.2);175  }176  .btn.red:hover{filter:brightness(1.08);transform:translateY(-2px);box-shadow:0 9px 0 #6d1a1a,0 20px 40px rgba(255,93,93,.3)}177  .btn.red:active{transform:translateY(5px);box-shadow:0 2px 0 #6d1a1a,0 8px 18px rgba(255,93,93,.2)}178 179  .hint{display:flex;gap:16px;flex-wrap:wrap;justify-content:center;color:var(--muted);font-size:.68rem;letter-spacing:.08em}180  .hint span{display:flex;align-items:center;gap:6px}181 182  /* ── registro ────────────────────────────────── */183  .log{184  background:linear-gradient(180deg,var(--panel),var(--panel-2));185  border:1px solid var(--line);border-radius:20px;padding:20px;186  display:flex;flex-direction:column;gap:14px;187  box-shadow:inset 0 1px 0 rgba(255,255,255,.04),0 24px 60px rgba(0,0,0,.35);188  }189  .log-head{display:flex;justify-content:space-between;align-items:baseline}190  .log-head h2{font:700 .78rem 'Unbounded';letter-spacing:.16em}191  .log-head span{font-size:.62rem;color:var(--muted);letter-spacing:.12em}192  #logList{list-style:none;display:flex;flex-direction:column;gap:8px;overflow-y:auto;max-height:360px;flex:1}193  #logList::-webkit-scrollbar{width:6px}194  #logList::-webkit-scrollbar-thumb{background:rgba(190,255,220,.15);border-radius:3px}195  #logList li{196  display:grid;grid-template-columns:auto auto 1fr;align-items:center;gap:10px;197  font-size:.8rem;padding:9px 12px;border:1px solid var(--line);border-radius:10px;198  background:rgba(190,255,220,.02);animation:slidein .25s ease-out;199  }200  #logList .t{color:var(--muted);font-size:.68rem}201  #logList .d{font-weight:700}202  #logList .d.add{color:var(--green)}203  #logList .d.sub{color:var(--red)}204  #logList .v{justify-self:end;font-weight:700}205  #logList li.empty{206  display:block;text-align:center;border:1px dashed var(--line);background:transparent;207  color:var(--muted);font-size:.72rem;line-height:1.7;letter-spacing:.06em;padding:26px 10px;208  }209  @keyframes slidein{from{opacity:0;transform:translateX(10px)}to{opacity:1;transform:none}}210 211  footer{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;color:var(--muted);font-size:.66rem;letter-spacing:.12em}212 213  @media(max-width:900px){214  main{grid-template-columns:1fr}215  .stage{min-height:400px}216  #logList{max-height:220px}217  }218  @media(max-width:480px){219  .controls{flex-direction:column}220  .btn{max-width:none}221  }222 </style>223 </head>224 <body>225 226 <div class="bg" aria-hidden="true"></div>227 <div class="orb g" aria-hidden="true"></div>228 <div class="orb r" aria-hidden="true"></div>229 230 <div class="wrap">231 232  <header>233  <div class="brand">234  <div class="mark" aria-hidden="true">±</div>235  <div>236  <h1>CONTADOR</h1>237  <small>PANEL M+2 / R−3</small>238  </div>239  </div>240  <div class="hud">241  <span class="led" id="led" aria-hidden="true"></span>242  <button class="ghost" id="soundBtn" aria-pressed="true">SONIDO: ON</button>243  </div>244  </header>245 246  <main>247  <section class="stage">248  <div class="topline" aria-hidden="true"></div>249  <div class="readout-label">VALOR ACTUAL</div>250 251  <div class="counter-box" id="counterBox">252  <div class="pulse" id="pulse" aria-hidden="true"></div>253  <div class="counter" id="counter" role="status" aria-live="polite">0</div>254  </div>255 256  <div class="stats">257  <span class="stat g">SUMAS <b id="adds">0</b></span>258  <span class="stat r">RESTAS <b id="subs">0</b></span>259  <span class="stat">ÚLTIMA <b id="last">—</b></span>260  </div>261 262  <div class="controls">263  <button class="btn green" id="btnAdd">264  <span class="op">+2</span><span class="lbl">SUMAR</span>265  </button>266  <button class="btn red" id="btnSub">267  <span class="op">−3</span><span class="lbl">RESTAR</span>268  </button>269  </div>270 271  <div class="hint">272  <span><kbd>↑</kbd> o <kbd>W</kbd> suma</span>273  <span><kbd>↓</kbd> o <kbd>S</kbd> resta</span>274  </div>275  </section>276 277  <aside class="log">278  <div class="log-head">279  <h2>REGISTRO</h2>280  <span>ÚLTIMAS 12</span>281  </div>282  <ul id="logList">283  <li class="empty">Aún no hay operaciones.<br>Pulsa un botón para empezar.</li>284  </ul>285  </aside>286  </main>287 288  <footer>289  <span>HTML + JS · SIN DEPENDENCIAS</span>290  <button class="ghost" id="resetBtn">↺ REINICIAR <kbd>R</kbd></button>291  </footer>292 293 </div>294 295 <script>296  const $ = id => document.getElementById(id);297  const counterEl = $('counter'), boxEl = $('counterBox'), pulseEl = $('pulse'),298  led = $('led'), addsEl = $('adds'), subsEl = $('subs'), lastEl = $('last'),299  list = $('logList'), soundBtn = $('soundBtn');300 301  let count = 0, adds = 0, subs = 0, soundOn = true, ledTimer = null, actx = null;302 303  const fmt = n => n < 0 ? '−' + Math.abs(n) : String(n);304  const stamp = () => new Date().toLocaleTimeString('es-ES', {hour12:false});305 306  function beep(freq){307  if(!soundOn) return;308  try{309  actx = actx || new (window.AudioContext || window.webkitAudioContext)();310  if(actx.state === 'suspended') actx.resume();311  const o = actx.createOscillator(), g = actx.createGain(), t = actx.currentTime;312  o.type = 'square'; o.frequency.value = freq;313  g.gain.setValueAtTime(.05, t);314  g.gain.exponentialRampToValueAtTime(.0001, t + .15);315  o.connect(g); g.connect(actx.destination);316  o.start(t); o.stop(t + .16);317  }catch(e){}318  }319 320  function retrigger(el, ...cls){321  el.classList.remove('add','sub','zero','go');322  void el.offsetWidth; /* fuerza reflujo para reiniciar la animación */323  cls.forEach(c => el.classList.add(c));324  }325 326  function flashLed(dir){327  led.className = 'led ' + dir;328  clearTimeout(ledTimer);329  ledTimer = setTimeout(() => led.className = 'led', 380);330  }331 332  function spawnChip(text, dir){333  const c = document.createElement('span');334  c.className = 'chip ' + dir;335  c.textContent = text;336  c.style.top = (-4 + Math.random() * 14) + 'px';337  boxEl.appendChild(c);338  c.addEventListener('animationend', () => c.remove());339  }340 341  function addLog(dir, value){342  const empty = list.querySelector('.empty');343  if(empty) empty.remove();344  const label = dir === 'add' ? '+2' : dir === 'sub' ? '−3' : '↺';345  const li = document.createElement('li');346  li.innerHTML = `<span class="t">${stamp()}</span><span class="d ${dir}">${label}</span><span class="v">${fmt(value)}</span>`;347  list.prepend(li);348  while(list.children.length > 12) list.lastElementChild.remove();349  }350 351  function apply(dir, delta){352  count += delta;353  dir === 'add' ? adds++ : subs++;354  counterEl.textContent = fmt(count);355  retrigger(counterEl, dir);356  retrigger(pulseEl, dir, 'go');357  spawnChip(dir === 'add' ? '+2' : '−3', dir);358  flashLed(dir);359  beep(dir === 'add' ? 760 : 230);360  addsEl.textContent = adds;361  subsEl.textContent = subs;362  lastEl.textContent = dir === 'add' ? '+2' : '−3';363  addLog(dir, count);364  }365 366  function reset(){367  count = 0; adds = 0; subs = 0;368  counterEl.textContent = '0';369  retrigger(counterEl, 'zero');370  addsEl.textContent = '0';371  subsEl.textContent = '0';372  lastEl.textContent = '—';373  list.innerHTML = '<li class="empty">Aún no hay operaciones.<br>Pulsa un botón para empezar.</li>';374  beep(150);375  }376 377  $('btnAdd').addEventListener('click', () => apply('add', 2));378  $('btnSub').addEventListener('click', () => apply('sub', -3));379  $('resetBtn').addEventListener('click', reset);380 381  soundBtn.addEventListener('click', () => {382  soundOn = !soundOn;383  soundBtn.textContent = soundOn ? 'SONIDO: ON' : 'SONIDO: OFF';384  soundBtn.setAttribute('aria-pressed', soundOn);385  if(soundOn) beep(620);386  });387 388  addEventListener('keydown', e => {389  const k = e.key.toLowerCase();390  if(k === 'arrowup' || k === 'w'){ e.preventDefault(); apply('add', 2); }391  else if(k === 'arrowdown' || k === 's'){ e.preventDefault(); apply('sub', -3); }392  else if(k === 'r'){ reset(); }393  });394 </script>395 </body>396 </html>397 
Enlace
El enlace para compartir es: