XTaylorSpenceX

Archive Alchemy

Oct 1st, 2025
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 46.94 KB | None | 0 0
  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.0">
  6. <title>Archive Alchemy</title>
  7. <style>
  8. * {
  9. margin: 0;
  10. padding: 0;
  11. box-sizing: border-box;
  12. }
  13.  
  14. body {
  15. font-family: 'Courier New', monospace;
  16. background: linear-gradient(135deg, #0a0e27 0%, #1a0b2e 50%, #2d1b69 100%);
  17. color: #e0e0ff;
  18. min-height: 100vh;
  19. overflow-x: hidden;
  20. position: relative;
  21. }
  22.  
  23. /* Animated Background */
  24. body::before {
  25. content: '';
  26. position: fixed;
  27. top: 0;
  28. left: 0;
  29. width: 100%;
  30. height: 100%;
  31. background:
  32. radial-gradient(circle at 20% 50%, rgba(138, 43, 226, 0.1) 0%, transparent 50%),
  33. radial-gradient(circle at 80% 50%, rgba(75, 0, 130, 0.1) 0%, transparent 50%),
  34. radial-gradient(circle at 50% 50%, rgba(147, 112, 219, 0.05) 0%, transparent 70%);
  35. animation: breathe 10s ease-in-out infinite;
  36. pointer-events: none;
  37. }
  38.  
  39. @keyframes breathe {
  40. 0%, 100% { opacity: 0.5; }
  41. 50% { opacity: 1; }
  42. }
  43.  
  44. .header {
  45. text-align: center;
  46. padding: 2rem;
  47. position: relative;
  48. z-index: 10;
  49. }
  50.  
  51. h1 {
  52. font-size: 3rem;
  53. background: linear-gradient(45deg, #ff00ff, #00ffff, #ffff00, #ff00ff);
  54. background-size: 300% 300%;
  55. -webkit-background-clip: text;
  56. background-clip: text;
  57. color: transparent;
  58. animation: gradient 5s ease infinite;
  59. text-shadow: 0 0 30px rgba(138, 43, 226, 0.5);
  60. margin-bottom: 0.5rem;
  61. }
  62.  
  63. @keyframes gradient {
  64. 0%, 100% { background-position: 0% 50%; }
  65. 50% { background-position: 100% 50%; }
  66. }
  67.  
  68. .subtitle {
  69. color: #9d7cff;
  70. font-size: 1.2rem;
  71. opacity: 0.9;
  72. }
  73.  
  74. /* Points Display */
  75. .points-display {
  76. position: absolute;
  77. top: 2rem;
  78. right: 2rem;
  79. background: linear-gradient(135deg, #ffd700, #ff6347);
  80. padding: 1rem 2rem;
  81. border-radius: 50px;
  82. font-size: 1.5rem;
  83. font-weight: bold;
  84. color: #000;
  85. box-shadow: 0 0 30px rgba(255, 215, 0, 0.5);
  86. animation: pulse 2s ease-in-out infinite;
  87. }
  88.  
  89. @keyframes pulse {
  90. 0%, 100% { transform: scale(1); }
  91. 50% { transform: scale(1.05); }
  92. }
  93.  
  94. .main-container {
  95. display: grid;
  96. grid-template-columns: 1fr 2fr 1fr;
  97. gap: 2rem;
  98. padding: 2rem;
  99. max-width: 1400px;
  100. margin: 0 auto;
  101. position: relative;
  102. z-index: 5;
  103. }
  104.  
  105. /* Document Library */
  106. .document-library {
  107. background: rgba(30, 20, 60, 0.8);
  108. border: 2px solid rgba(138, 43, 226, 0.5);
  109. border-radius: 15px;
  110. padding: 1.5rem;
  111. backdrop-filter: blur(10px);
  112. box-shadow: 0 0 30px rgba(138, 43, 226, 0.3);
  113. }
  114.  
  115. .section-title {
  116. color: #ff00ff;
  117. font-size: 1.3rem;
  118. margin-bottom: 1rem;
  119. text-align: center;
  120. text-shadow: 0 0 10px currentColor;
  121. }
  122.  
  123. .document-item {
  124. background: rgba(75, 0, 130, 0.3);
  125. border: 1px solid rgba(138, 43, 226, 0.4);
  126. border-radius: 10px;
  127. padding: 1rem;
  128. margin: 0.5rem 0;
  129. cursor: grab;
  130. transition: all 0.3s;
  131. position: relative;
  132. overflow: hidden;
  133. }
  134.  
  135. .document-item.used {
  136. opacity: 0.3;
  137. cursor: not-allowed;
  138. background: rgba(50, 50, 50, 0.3);
  139. }
  140.  
  141. .document-item::before {
  142. content: '';
  143. position: absolute;
  144. top: -2px;
  145. left: -2px;
  146. right: -2px;
  147. bottom: -2px;
  148. background: linear-gradient(45deg, #ff00ff, #00ffff, #ffff00);
  149. border-radius: 10px;
  150. opacity: 0;
  151. z-index: -1;
  152. transition: opacity 0.3s;
  153. }
  154.  
  155. .document-item:not(.used):hover::before {
  156. opacity: 0.5;
  157. animation: rotate 2s linear infinite;
  158. }
  159.  
  160. @keyframes rotate {
  161. 0% { transform: rotate(0deg); }
  162. 100% { transform: rotate(360deg); }
  163. }
  164.  
  165. .document-item:not(.used):hover {
  166. transform: translateY(-2px) scale(1.05);
  167. box-shadow: 0 5px 20px rgba(138, 43, 226, 0.5);
  168. }
  169.  
  170. .document-item.dragging {
  171. opacity: 0.5;
  172. cursor: grabbing;
  173. }
  174.  
  175. .doc-type {
  176. font-size: 0.8rem;
  177. color: #00ffff;
  178. margin-bottom: 0.3rem;
  179. }
  180.  
  181. .doc-name {
  182. font-size: 1rem;
  183. color: #ffffff;
  184. margin-bottom: 0.5rem;
  185. }
  186.  
  187. .doc-keywords {
  188. font-size: 0.7rem;
  189. color: #9d7cff;
  190. font-style: italic;
  191. }
  192.  
  193. .doc-power {
  194. color: #ffd700;
  195. font-size: 0.8rem;
  196. margin-top: 0.3rem;
  197. text-align: right;
  198. }
  199.  
  200. .document-stats {
  201. background: rgba(75, 0, 130, 0.3);
  202. border-radius: 10px;
  203. padding: 0.8rem;
  204. margin: 1rem 0;
  205. text-align: center;
  206. }
  207.  
  208. .stat-row {
  209. display: flex;
  210. justify-content: space-around;
  211. margin: 0.3rem 0;
  212. }
  213.  
  214. .stat-badge {
  215. background: rgba(138, 43, 226, 0.3);
  216. border: 1px solid rgba(138, 43, 226, 0.5);
  217. border-radius: 15px;
  218. padding: 0.3rem 0.8rem;
  219. font-size: 0.8rem;
  220. }
  221.  
  222. .rarity-common { color: #9d7cff; }
  223. .rarity-uncommon { color: #00ffff; }
  224. .rarity-rare { color: #ff00ff; }
  225. .rarity-legendary { color: #ffd700; }
  226.  
  227. /* Cauldron Area */
  228. .cauldron-section {
  229. display: flex;
  230. flex-direction: column;
  231. align-items: center;
  232. }
  233.  
  234. .cauldron-container {
  235. width: 300px;
  236. height: 300px;
  237. position: relative;
  238. margin: 2rem auto;
  239. }
  240.  
  241. .cauldron {
  242. width: 250px;
  243. height: 200px;
  244. background: radial-gradient(ellipse at center, #2d1b69 0%, #1a0b2e 70%);
  245. border: 3px solid #8a2be2;
  246. border-radius: 0 0 100px 100px;
  247. position: absolute;
  248. bottom: 20px;
  249. left: 50%;
  250. transform: translateX(-50%);
  251. box-shadow:
  252. 0 0 50px rgba(138, 43, 226, 0.5),
  253. inset 0 0 30px rgba(75, 0, 130, 0.5);
  254. overflow: hidden;
  255. }
  256.  
  257. .cauldron::before {
  258. content: '';
  259. position: absolute;
  260. top: 0;
  261. left: 0;
  262. right: 0;
  263. height: 50%;
  264. background: linear-gradient(to bottom, transparent, rgba(0, 255, 255, 0.1));
  265. animation: bubble 3s ease-in-out infinite;
  266. }
  267.  
  268. @keyframes bubble {
  269. 0%, 100% { transform: translateY(0); }
  270. 50% { transform: translateY(10px); }
  271. }
  272.  
  273. .cauldron.active {
  274. animation: brew 1s ease-in-out infinite;
  275. }
  276.  
  277. @keyframes brew {
  278. 0%, 100% { transform: translateX(-50%) rotate(0deg); }
  279. 25% { transform: translateX(-50%) rotate(-2deg); }
  280. 75% { transform: translateX(-50%) rotate(2deg); }
  281. }
  282.  
  283. .slot {
  284. width: 80px;
  285. height: 80px;
  286. background: rgba(30, 20, 60, 0.8);
  287. border: 2px dashed rgba(138, 43, 226, 0.5);
  288. border-radius: 10px;
  289. position: absolute;
  290. display: flex;
  291. align-items: center;
  292. justify-content: center;
  293. transition: all 0.3s;
  294. z-index: 10;
  295. }
  296.  
  297. .slot.dragover {
  298. background: rgba(138, 43, 226, 0.3);
  299. border-color: #ff00ff;
  300. box-shadow: 0 0 20px rgba(255, 0, 255, 0.5);
  301. }
  302.  
  303. .slot.filled {
  304. border-style: solid;
  305. background: rgba(75, 0, 130, 0.5);
  306. }
  307.  
  308. .slot1 { top: 50px; left: 20px; }
  309. .slot2 { top: 50px; right: 20px; }
  310.  
  311. .transmute-btn {
  312. background: linear-gradient(45deg, #8a2be2, #4b0082);
  313. color: white;
  314. border: 2px solid #ff00ff;
  315. border-radius: 50px;
  316. padding: 1rem 2rem;
  317. font-size: 1.2rem;
  318. cursor: pointer;
  319. transition: all 0.3s;
  320. margin-top: 2rem;
  321. position: relative;
  322. overflow: hidden;
  323. text-transform: uppercase;
  324. letter-spacing: 2px;
  325. }
  326.  
  327. .transmute-btn::before {
  328. content: '';
  329. position: absolute;
  330. top: 50%;
  331. left: 50%;
  332. width: 0;
  333. height: 0;
  334. background: radial-gradient(circle, rgba(255, 255, 255, 0.3), transparent);
  335. transition: width 0.6s, height 0.6s;
  336. transform: translate(-50%, -50%);
  337. }
  338.  
  339. .transmute-btn:hover:not(:disabled)::before {
  340. width: 300px;
  341. height: 300px;
  342. }
  343.  
  344. .transmute-btn:hover:not(:disabled) {
  345. transform: scale(1.1);
  346. box-shadow: 0 0 30px rgba(255, 0, 255, 0.8);
  347. }
  348.  
  349. .transmute-btn:disabled {
  350. opacity: 0.5;
  351. cursor: not-allowed;
  352. }
  353.  
  354. .transmute-btn.processing {
  355. animation: processingPulse 0.5s ease-in-out infinite;
  356. pointer-events: none;
  357. }
  358.  
  359. @keyframes processingPulse {
  360. 0%, 100% { opacity: 0.5; }
  361. 50% { opacity: 1; }
  362. }
  363.  
  364. /* Results Panel */
  365. .results-panel {
  366. background: rgba(30, 20, 60, 0.8);
  367. border: 2px solid rgba(138, 43, 226, 0.5);
  368. border-radius: 15px;
  369. padding: 1.5rem;
  370. backdrop-filter: blur(10px);
  371. box-shadow: 0 0 30px rgba(138, 43, 226, 0.3);
  372. }
  373.  
  374. .artifact-item {
  375. background: linear-gradient(135deg, rgba(255, 0, 255, 0.1), rgba(0, 255, 255, 0.1));
  376. border: 1px solid rgba(255, 215, 0, 0.5);
  377. border-radius: 10px;
  378. padding: 1rem;
  379. margin: 0.5rem 0;
  380. position: relative;
  381. animation: glow 2s ease-in-out infinite;
  382. }
  383.  
  384. .artifact-item.corrupted {
  385. background: linear-gradient(135deg, rgba(255, 0, 0, 0.2), rgba(100, 0, 0, 0.2));
  386. border-color: rgba(255, 0, 0, 0.5);
  387. }
  388.  
  389. .artifact-item.legendary {
  390. background: linear-gradient(135deg, rgba(255, 215, 0, 0.3), rgba(255, 140, 0, 0.3));
  391. border-color: rgba(255, 215, 0, 0.8);
  392. animation: legendaryGlow 1s ease-in-out infinite;
  393. }
  394.  
  395. @keyframes legendaryGlow {
  396. 0%, 100% { box-shadow: 0 0 20px rgba(255, 215, 0, 0.6); }
  397. 50% { box-shadow: 0 0 40px rgba(255, 215, 0, 1); }
  398. }
  399.  
  400. @keyframes glow {
  401. 0%, 100% { box-shadow: 0 0 10px rgba(255, 215, 0, 0.3); }
  402. 50% { box-shadow: 0 0 20px rgba(255, 215, 0, 0.6); }
  403. }
  404.  
  405. .artifact-name {
  406. color: #ffd700;
  407. font-size: 1.1rem;
  408. margin-bottom: 0.3rem;
  409. text-shadow: 0 0 5px currentColor;
  410. }
  411.  
  412. .artifact-desc {
  413. color: #e0e0ff;
  414. font-size: 0.9rem;
  415. margin-bottom: 0.5rem;
  416. }
  417.  
  418. .artifact-power {
  419. position: absolute;
  420. top: 10px;
  421. right: 10px;
  422. font-size: 1.2rem;
  423. font-weight: bold;
  424. }
  425.  
  426. .artifact-actions {
  427. display: flex;
  428. gap: 0.5rem;
  429. margin-top: 0.5rem;
  430. }
  431.  
  432. .action-btn {
  433. flex: 1;
  434. padding: 0.3rem 0.5rem;
  435. border: 1px solid;
  436. border-radius: 5px;
  437. cursor: pointer;
  438. font-size: 0.8rem;
  439. transition: all 0.3s;
  440. text-align: center;
  441. }
  442.  
  443. .inspect-btn {
  444. background: rgba(0, 255, 255, 0.2);
  445. border-color: #00ffff;
  446. color: #00ffff;
  447. }
  448.  
  449. .inspect-btn:hover {
  450. background: rgba(0, 255, 255, 0.4);
  451. box-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
  452. }
  453.  
  454. .consume-btn {
  455. background: rgba(0, 255, 0, 0.2);
  456. border-color: #00ff00;
  457. color: #00ff00;
  458. }
  459.  
  460. .consume-btn:hover {
  461. background: rgba(0, 255, 0, 0.4);
  462. box-shadow: 0 0 10px rgba(0, 255, 0, 0.5);
  463. }
  464.  
  465. .consume-btn:disabled {
  466. opacity: 0.3;
  467. cursor: not-allowed;
  468. }
  469.  
  470. .destroy-btn {
  471. background: rgba(255, 0, 0, 0.2);
  472. border-color: #ff6666;
  473. color: #ff6666;
  474. }
  475.  
  476. .destroy-btn:hover {
  477. background: rgba(255, 0, 0, 0.4);
  478. box-shadow: 0 0 10px rgba(255, 0, 0, 0.5);
  479. }
  480.  
  481. /* Particles */
  482. .particle {
  483. position: absolute;
  484. width: 4px;
  485. height: 4px;
  486. background: radial-gradient(circle, rgba(255, 255, 255, 0.9), transparent);
  487. pointer-events: none;
  488. animation: float 3s ease-in-out infinite;
  489. }
  490.  
  491. @keyframes float {
  492. 0% { transform: translateY(0) translateX(0); opacity: 0; }
  493. 10% { opacity: 1; }
  494. 90% { opacity: 1; }
  495. 100% { transform: translateY(-100px) translateX(var(--random-x, 0px)); opacity: 0; }
  496. }
  497.  
  498. .find-btn {
  499. background: linear-gradient(135deg, #00ffff, #4b0082);
  500. border: 2px solid #00ffff;
  501. border-radius: 25px;
  502. color: white;
  503. padding: 0.7rem 1.5rem;
  504. font-size: 1rem;
  505. cursor: pointer;
  506. margin: 1rem auto;
  507. display: block;
  508. transition: all 0.3s;
  509. text-shadow: 0 0 5px rgba(0, 255, 255, 0.5);
  510. animation: findPulse 2s ease-in-out infinite;
  511. }
  512.  
  513. @keyframes findPulse {
  514. 0%, 100% { box-shadow: 0 0 10px rgba(0, 255, 255, 0.3); }
  515. 50% { box-shadow: 0 0 20px rgba(0, 255, 255, 0.6); }
  516. }
  517.  
  518. .find-btn:hover {
  519. transform: scale(1.1);
  520. background: linear-gradient(135deg, #4b0082, #00ffff);
  521. box-shadow: 0 0 30px rgba(0, 255, 255, 0.8);
  522. }
  523.  
  524. .find-btn:active {
  525. transform: scale(0.95);
  526. }
  527.  
  528. .find-btn.drawing {
  529. animation: drawAnimation 1s ease-in-out;
  530. pointer-events: none;
  531. }
  532.  
  533. @keyframes drawAnimation {
  534. 0% { transform: rotate(0deg) scale(1); }
  535. 25% { transform: rotate(-5deg) scale(1.1); }
  536. 50% { transform: rotate(5deg) scale(1.1); }
  537. 75% { transform: rotate(-5deg) scale(1.1); }
  538. 100% { transform: rotate(0deg) scale(1); }
  539. }
  540.  
  541. .document-item.drawing-in {
  542. animation: slideIn 0.5s ease-out;
  543. }
  544.  
  545. @keyframes slideIn {
  546. from {
  547. opacity: 0;
  548. transform: translateX(-100px) rotate(-10deg);
  549. }
  550. to {
  551. opacity: 1;
  552. transform: translateX(0) rotate(0deg);
  553. }
  554. }
  555.  
  556. /* Recipe Book */
  557. .recipe-hint {
  558. background: rgba(255, 215, 0, 0.1);
  559. border: 1px solid rgba(255, 215, 0, 0.3);
  560. border-radius: 10px;
  561. padding: 1rem;
  562. margin-top: 1rem;
  563. text-align: center;
  564. font-style: italic;
  565. color: #ffd700;
  566. }
  567.  
  568. /* Notification */
  569. .notification {
  570. position: fixed;
  571. top: 50%;
  572. left: 50%;
  573. transform: translate(-50%, -50%) scale(0);
  574. background: linear-gradient(135deg, #2d1b69, #4b0082);
  575. border: 3px solid #ffd700;
  576. border-radius: 20px;
  577. padding: 2rem;
  578. text-align: center;
  579. z-index: 100;
  580. animation: popIn 0.5s forwards;
  581. box-shadow: 0 0 50px rgba(255, 215, 0, 0.5);
  582. }
  583.  
  584. @keyframes popIn {
  585. to { transform: translate(-50%, -50%) scale(1); }
  586. }
  587.  
  588. .notification h2 {
  589. color: #ffd700;
  590. margin-bottom: 1rem;
  591. text-shadow: 0 0 10px currentColor;
  592. }
  593.  
  594. .close-notification {
  595. background: #8a2be2;
  596. color: white;
  597. border: none;
  598. border-radius: 20px;
  599. padding: 0.5rem 1.5rem;
  600. cursor: pointer;
  601. margin-top: 1rem;
  602. }
  603.  
  604. /* Stats */
  605. .stats {
  606. background: rgba(75, 0, 130, 0.3);
  607. border-radius: 10px;
  608. padding: 1rem;
  609. margin-top: 1rem;
  610. text-align: center;
  611. }
  612.  
  613. .stat-item {
  614. display: flex;
  615. justify-content: space-between;
  616. margin: 0.5rem 0;
  617. }
  618.  
  619. .stat-label {
  620. color: #9d7cff;
  621. }
  622.  
  623. .stat-value {
  624. color: #00ffff;
  625. font-weight: bold;
  626. }
  627.  
  628. .inventory-count {
  629. text-align: center;
  630. color: #ff00ff;
  631. margin-top: 0.5rem;
  632. font-size: 0.9rem;
  633. }
  634.  
  635. .point-change {
  636. position: fixed;
  637. font-size: 2rem;
  638. font-weight: bold;
  639. pointer-events: none;
  640. z-index: 200;
  641. animation: floatUp 2s ease-out forwards;
  642. }
  643.  
  644. @keyframes floatUp {
  645. 0% {
  646. opacity: 1;
  647. transform: translateY(0);
  648. }
  649. 100% {
  650. opacity: 0;
  651. transform: translateY(-100px);
  652. }
  653. }
  654.  
  655. .point-change.positive {
  656. color: #00ff00;
  657. text-shadow: 0 0 10px currentColor;
  658. }
  659.  
  660. .point-change.negative {
  661. color: #ff0000;
  662. text-shadow: 0 0 10px currentColor;
  663. }
  664.  
  665. /* Search Animation */
  666. @keyframes searchPulse {
  667. 0% {
  668. width: 0px;
  669. height: 0px;
  670. opacity: 1;
  671. }
  672. 100% {
  673. width: 300px;
  674. height: 300px;
  675. opacity: 0;
  676. }
  677. }
  678. </style>
  679. </head>
  680. <body>
  681. <div class="points-display" id="pointsDisplay">
  682. ⭐ 0 Points
  683. </div>
  684.  
  685. <div class="header">
  686. <h1>Archive Alchemy</h1>
  687. <div class="subtitle">Transform Digital Documents into Mystical Artifacts</div>
  688. </div>
  689.  
  690. <div class="main-container">
  691. <div class="document-library">
  692. <h2 class="section-title">📚 Document Library</h2>
  693. <button class="find-btn" id="findBtn">
  694. 🔍 Find Documents
  695. </button>
  696. <div id="documentList"></div>
  697. <div id="documentStats"></div>
  698. <div class="recipe-hint" id="recipeHint">
  699. 💡 Hint: Click "Find Documents" to draw from the archive!
  700. </div>
  701. </div>
  702.  
  703. <div class="cauldron-section">
  704. <h2 class="section-title">⚗️ Alchemical Cauldron</h2>
  705. <div class="cauldron-container">
  706. <div class="slot slot1" data-slot="1">
  707. <span style="color: #9d7cff;">Slot 1</span>
  708. </div>
  709. <div class="slot slot2" data-slot="2">
  710. <span style="color: #9d7cff;">Slot 2</span>
  711. </div>
  712. <div class="cauldron" id="cauldron"></div>
  713. </div>
  714. <button class="transmute-btn" id="transmuteBtn" disabled>
  715. Transmute
  716. </button>
  717. <div class="stats">
  718. <div class="stat-item">
  719. <span class="stat-label">Transmutations:</span>
  720. <span class="stat-value" id="transmutationCount">0</span>
  721. </div>
  722. <div class="stat-item">
  723. <span class="stat-label">Success Rate:</span>
  724. <span class="stat-value" id="successRate">0%</span>
  725. </div>
  726. <div class="stat-item">
  727. <span class="stat-label">Level:</span>
  728. <span class="stat-value" id="alchemyLevel">1</span>
  729. </div>
  730. <div class="stat-item">
  731. <span class="stat-label">Risk Level:</span>
  732. <span class="stat-value" id="riskLevel">Low</span>
  733. </div>
  734. </div>
  735. </div>
  736.  
  737. <div class="results-panel">
  738. <h2 class="section-title">✨ Artifacts Created</h2>
  739. <div class="inventory-count" id="inventoryCount">0/10 Artifacts</div>
  740. <div id="artifactsList"></div>
  741. </div>
  742. </div>
  743.  
  744. <script>
  745. // Document Templates
  746. const documentTemplates = [
  747. { name: "Ancient Codex", type: "PDF", keywords: ["wisdom", "mystery", "ancient"], power: 3 },
  748. { name: "Data Crystal", type: "JSON", keywords: ["data", "structure", "logic"], power: 2 },
  749. { name: "Mystic Scroll", type: "TXT", keywords: ["magic", "spells", "ancient"], power: 3 },
  750. { name: "Algorithm Tome", type: "JS", keywords: ["logic", "code", "patterns"], power: 4 },
  751. { name: "Dream Journal", type: "MD", keywords: ["dreams", "consciousness", "mystery"], power: 2 },
  752. { name: "Quantum Notes", type: "XML", keywords: ["quantum", "science", "data"], power: 3 },
  753. { name: "Poetry Archive", type: "DOC", keywords: ["emotion", "words", "beauty"], power: 2 },
  754. { name: "Binary Grimoire", type: "BIN", keywords: ["binary", "code", "mystery"], power: 4 },
  755. { name: "Star Chart", type: "SVG", keywords: ["cosmos", "patterns", "navigation"], power: 3 },
  756. { name: "Memory Bank", type: "SQL", keywords: ["memory", "data", "structure"], power: 3 },
  757. { name: "Chaos Manifest", type: "RAW", keywords: ["chaos", "entropy", "unknown"], power: 5 },
  758. { name: "Time Crystal", type: "LOG", keywords: ["time", "sequence", "history"], power: 3 },
  759. { name: "Neural Map", type: "AI", keywords: ["mind", "neural", "patterns"], power: 4 },
  760. { name: "Void Fragment", type: "NULL", keywords: ["void", "empty", "unknown"], power: 1 },
  761. { name: "Ethereal Notes", type: "AURA", keywords: ["spirit", "ethereal", "energy"], power: 3 },
  762. { name: "Cipher Key", type: "KEY", keywords: ["cipher", "security", "hidden"], power: 4 },
  763. { name: "Reality Script", type: "SIM", keywords: ["reality", "simulation", "code"], power: 5 },
  764. { name: "Emotion Core", type: "FEEL", keywords: ["emotion", "heart", "soul"], power: 2 },
  765. { name: "Fractal Blueprint", type: "FRAC", keywords: ["fractal", "infinite", "patterns"], power: 4 },
  766. { name: "Shadow Archive", type: "DARK", keywords: ["shadow", "hidden", "secret"], power: 3 }
  767. ];
  768.  
  769. // Active documents
  770. let documents = [];
  771. let draggedDoc = null;
  772.  
  773. // Alchemy Recipes
  774. const recipes = {
  775. "ancient,mystery": { name: "Tome of Lost Knowledge", desc: "Reveals hidden truths", power: 5, hidden: false },
  776. "data,structure": { name: "Crystal Matrix", desc: "Perfect data alignment", power: 4, hidden: false },
  777. "magic,ancient": { name: "Primordial Spell", desc: "Ancient magical power", power: 6, hidden: true },
  778. "logic,code": { name: "Divine Algorithm", desc: "Solves impossible problems", power: 5, hidden: false },
  779. "dreams,mystery": { name: "Oneiric Portal", desc: "Gateway to dream realms", power: 4, hidden: true },
  780. "quantum,data": { name: "Quantum Codex", desc: "Manipulates probability", power: 5, hidden: false },
  781. "emotion,beauty": { name: "Heart's Resonance", desc: "Empathic connection", power: 3, hidden: false },
  782. "binary,code": { name: "Digital Philosopher's Stone", desc: "Transforms all data", power: 7, hidden: true },
  783. "cosmos,patterns": { name: "Celestial Navigator", desc: "Maps impossible paths", power: 5, hidden: false },
  784. "memory,data": { name: "Eternal Archive", desc: "Never forgets", power: 4, hidden: false },
  785. "chaos,unknown": { name: "Pandora's Cache", desc: "Dangerous but powerful", power: 8, hidden: true, risk: true },
  786. "void,empty": { name: "Null Singularity", desc: "Consumes everything", power: 1, corrupted: true },
  787. "reality,simulation": { name: "Reality Compiler", desc: "Rewrites existence", power: 9, hidden: true }
  788. };
  789.  
  790. // Game State
  791. let gameState = {
  792. slots: { 1: null, 2: null },
  793. artifacts: [],
  794. transmutations: 0,
  795. successes: 0,
  796. level: 1,
  797. points: 0,
  798. isTransmuting: false,
  799. inspectedArtifacts: new Set(),
  800. consumedWithoutInspection: 0,
  801. totalDocumentsUsed: 0,
  802. documentsFound: false
  803. };
  804.  
  805. // Enhanced Find Documents feature
  806. function findDocuments() {
  807.     const btn = document.getElementById('findBtn');
  808.     btn.classList.add('drawing');
  809.    
  810.     // Disable button during drawing animation
  811.     btn.disabled = true;
  812.    
  813.     // Clear existing documents if needed
  814.     if (!gameState.documentsFound || documents.filter(d => !d.used).length === 0) {
  815.         generateDocumentLibrary();
  816.         gameState.documentsFound = true;
  817.     }
  818.    
  819.     // Animate drawing documents with enhanced effects
  820.     const container = document.getElementById('documentList');
  821.     container.innerHTML = '';
  822.    
  823.     // Create search animation effect
  824.     createSearchAnimation();
  825.    
  826.     // Show documents with staggered animation
  827.     documents.forEach((doc, index) => {
  828.         setTimeout(() => {
  829.             const elem = document.createElement('div');
  830.             elem.className = doc.used ? 'document-item used drawing-in' : 'document-item drawing-in';
  831.             elem.draggable = !doc.used;
  832.             elem.dataset.docId = doc.id;
  833.             elem.innerHTML = `
  834.                 <div class="doc-type">[${doc.type}]</div>
  835.                 <div class="doc-name">${doc.name}</div>
  836.                 <div class="doc-keywords">${doc.keywords.join(', ')}</div>
  837.                 <div class="doc-power">${'⭐'.repeat(Math.min(doc.power, 3))}</div>
  838.             `;
  839.             container.appendChild(elem);
  840.            
  841.             // Enhanced particle effect for each document
  842.             createEnhancedDocumentParticle(elem, doc.power);
  843.            
  844.             // Add hover info for document power
  845.             elem.title = `Power Level: ${doc.power}/5`;
  846.            
  847.         }, index * 150);
  848.     });
  849.    
  850.     // Update document stats
  851.     updateDocumentStats();
  852.    
  853.     // Re-enable button and setup interactions
  854.     setTimeout(() => {
  855.         btn.classList.remove('drawing');
  856.         btn.disabled = false;
  857.         setupDragAndDrop();
  858.         updateHints();
  859.        
  860.         // Show found notification
  861.         showDocumentFoundNotification(documents.length);
  862.        
  863.     }, documents.length * 150 + 500);
  864. }
  865.  
  866. // Enhanced particle effects for document discovery
  867. function createEnhancedDocumentParticle(element, power) {
  868.     const rect = element.getBoundingClientRect();
  869.     const particleCount = 3 + power;
  870.    
  871.     for (let i = 0; i < particleCount; i++) {
  872.        setTimeout(() => {
  873.             const particle = document.createElement('div');
  874.             particle.className = 'particle';
  875.            
  876.             let color;
  877.             if (power >= 4) color = 'rgba(255, 215, 0, 0.9)';
  878.             else if (power >= 3) color = 'rgba(0, 255, 255, 0.9)';
  879.             else color = 'rgba(138, 43, 226, 0.9)';
  880.  
  881.             particle.style.background = `radial-gradient(circle, ${color}, transparent)`;
  882.             particle.style.width = (3 + power) + 'px';
  883.             particle.style.height = (3 + power) + 'px';
  884.             particle.style.left = rect.left + Math.random() * rect.width + 'px';
  885.             particle.style.top = rect.top + rect.height / 2 + 'px';
  886.             particle.style.setProperty('--random-x', (Math.random() * 100 - 50) + 'px');
  887.             document.body.appendChild(particle);
  888.             setTimeout(() => particle.remove(), 1000);
  889.         }, i * 100);
  890.     }
  891. }
  892.  
  893. // Create search animation around the find button
  894. function createSearchAnimation() {
  895.     const btn = document.getElementById('findBtn');
  896.     const rect = btn.getBoundingClientRect();
  897.    
  898.     for (let i = 0; i < 3; i++) {
  899.        setTimeout(() => {
  900.             const circle = document.createElement('div');
  901.             circle.style.position = 'fixed';
  902.             circle.style.left = rect.left + rect.width / 2 + 'px';
  903.             circle.style.top = rect.top + rect.height / 2 + 'px';
  904.             circle.style.width = '0px';
  905.             circle.style.height = '0px';
  906.             circle.style.border = '2px solid rgba(0, 255, 255, 0.5)';
  907.             circle.style.borderRadius = '50%';
  908.             circle.style.transform = 'translate(-50%, -50%)';
  909.             circle.style.animation = `searchPulse 1.5s ease-out ${i * 0.2}s forwards`;
  910.             circle.style.zIndex = '99';
  911.            
  912.             document.body.appendChild(circle);
  913.             setTimeout(() => circle.remove(), 1500);
  914.         }, i * 200);
  915.     }
  916. }
  917.  
  918. // Show notification when documents are found
  919. function showDocumentFoundNotification(count) {
  920.     const rareDocs = documents.filter(doc => doc.power >= 4).length;
  921.     const notification = document.createElement('div');
  922.     notification.className = 'notification';
  923.     notification.style.zIndex = '1000';
  924.    
  925.     let message = `Found ${count} documents!`;
  926.     if (rareDocs > 0) {
  927.         message += ` Including ${rareDocs} rare document${rareDocs > 1 ? 's' : ''}!`;
  928.     }
  929.    
  930.     notification.innerHTML = `
  931.         <h2>📚 Documents Found!</h2>
  932.         <div style="color: #00ffff; font-size: 1.2rem; margin: 1rem 0;">${message}</div>
  933.         <div style="color: #9d7cff; font-size: 0.9rem;">
  934.             Drag documents to the cauldron slots to begin transmutation
  935.         </div>
  936.         <button class="close-notification" onclick="this.parentElement.remove()">Start Alchemy</button>
  937.     `;
  938.    
  939.     document.body.appendChild(notification);
  940.    
  941.     setTimeout(() => {
  942.         if (notification.parentElement) {
  943.             notification.remove();
  944.         }
  945.     }, 3000);
  946. }
  947.  
  948. // Update document statistics display
  949. function updateDocumentStats() {
  950.     let statsContainer = document.getElementById('documentStats');
  951.     if (!statsContainer) {
  952.         statsContainer = document.createElement('div');
  953.         statsContainer.id = 'documentStats';
  954.         statsContainer.className = 'document-stats';
  955.         document.getElementById('documentList').parentNode.insertBefore(statsContainer, document.getElementById('recipeHint'));
  956.     }
  957.    
  958.     const totalDocs = documents.length;
  959.     const availableDocs = documents.filter(d => !d.used).length;
  960.     const averagePower = documents.reduce((sum, doc) => sum + doc.power, 0) / totalDocs;
  961.     const rareCount = documents.filter(doc => doc.power >= 4).length;
  962.    
  963.     statsContainer.innerHTML = `
  964.         <div class="stat-row">
  965.             <span class="stat-badge">Available: ${availableDocs}/${totalDocs}</span>
  966.             <span class="stat-badge">Avg Power: ${averagePower.toFixed(1)}</span>
  967.         </div>
  968.         <div class="stat-row">
  969.             <span class="stat-badge rarity-rare">Rare: ${rareCount}</span>
  970.             <span class="stat-badge">Ready: ${availableDocs >= 2 ? '✅' : '❌'}</span>
  971.         </div>
  972.     `;
  973. }
  974.  
  975. // Enhanced document generation with rarity system
  976. function generateDocumentLibrary() {
  977.     documents = [];
  978.    
  979.     const totalDocs = 12;
  980.    
  981.     for (let i = 0; i < totalDocs; i++) {
  982.        let powerLevel;
  983.        const roll = Math.random();
  984.        
  985.        if (roll < 0.6) {
  986.            powerLevel = 1 + Math.floor(Math.random() * 2);
  987.        } else if (roll < 0.85) {
  988.            powerLevel = 2 + Math.floor(Math.random() * 2);
  989.        } else if (roll < 0.95) {
  990.            powerLevel = 3 + Math.floor(Math.random() * 2);
  991.        } else {
  992.            powerLevel = 4 + Math.floor(Math.random() * 2);
  993.        }
  994.        
  995.        const suitableTemplates = documentTemplates.filter(t =>
  996.             Math.abs(t.power - powerLevel) <= 1
  997.        );
  998.        
  999.        const template = suitableTemplates.length > 0
  1000.             ? suitableTemplates[Math.floor(Math.random() * suitableTemplates.length)]
  1001.             : documentTemplates[Math.floor(Math.random() * documentTemplates.length)];
  1002.        
  1003.         documents.push({
  1004.             id: Date.now() + i + Math.random(),
  1005.             ...template,
  1006.             power: powerLevel,
  1007.             used: false,
  1008.             rarity: getRarityFromPower(powerLevel)
  1009.         });
  1010.     }
  1011.    
  1012.     documents.sort((a, b) => b.power - a.power);
  1013. }
  1014.  
  1015. // Helper function to determine rarity from power
  1016. function getRarityFromPower(power) {
  1017.     if (power >= 4) return 'legendary';
  1018.     if (power >= 3) return 'rare';
  1019.     if (power >= 2) return 'uncommon';
  1020.     return 'common';
  1021. }
  1022.  
  1023. // Enhanced document rendering with rarity colors
  1024. function renderDocuments() {
  1025.     const container = document.getElementById('documentList');
  1026.     container.innerHTML = '';
  1027.  
  1028.     documents.forEach(doc => {
  1029.         const elem = document.createElement('div');
  1030.         elem.className = doc.used ? 'document-item used' : 'document-item';
  1031.         elem.draggable = !doc.used;
  1032.         elem.dataset.docId = doc.id;
  1033.         elem.classList.add(`rarity-${doc.rarity}`);
  1034.        
  1035.         elem.innerHTML = `
  1036.             <div class="doc-type">[${doc.type}]</div>
  1037.             <div class="doc-name">${doc.name}</div>
  1038.             <div class="doc-keywords">${doc.keywords.join(', ')}</div>
  1039.             <div class="doc-power">${'⭐'.repeat(Math.min(doc.power, 5))} ${doc.rarity.toUpperCase()}</div>
  1040.         `;
  1041.        
  1042.         if (doc.power >= 4) {
  1043.             elem.style.boxShadow = '0 0 15px rgba(255, 215, 0, 0.5)';
  1044.         }
  1045.        
  1046.         container.appendChild(elem);
  1047.     });
  1048.  
  1049.     setupDragAndDrop();
  1050.     updateDocumentStats();
  1051. }
  1052.  
  1053. // Initialize the game
  1054. function init() {
  1055.     document.getElementById('findBtn').addEventListener('click', findDocuments);
  1056.    
  1057.     generateDocumentLibrary();
  1058.     gameState.documentsFound = false;
  1059.    
  1060.     document.getElementById('recipeHint').innerHTML = `
  1061.         💡 <strong>Click "Find Documents" to draw from the archive!</strong><br>
  1062.         <small>Discover rare documents with higher power levels for better artifacts!</small>
  1063.     `;
  1064.  
  1065.     setupTransmuteButton();
  1066.     createFloatingParticles();
  1067.     updateStats();
  1068.     updateArtifacts();
  1069.     updateHints();
  1070. }
  1071.  
  1072. // Setup drag and drop functionality
  1073. function setupDragAndDrop() {
  1074.     document.querySelectorAll('.document-item:not(.used)').forEach(item => {
  1075.         item.addEventListener('dragstart', (e) => {
  1076.             draggedDoc = documents.find(d => d.id == e.target.dataset.docId);
  1077.             e.target.classList.add('dragging');
  1078.         });
  1079.  
  1080.         item.addEventListener('dragend', (e) => {
  1081.             e.target.classList.remove('dragging');
  1082.         });
  1083.     });
  1084.  
  1085.     document.querySelectorAll('.slot').forEach(slot => {
  1086.         slot.addEventListener('dragover', (e) => {
  1087.             e.preventDefault();
  1088.             slot.classList.add('dragover');
  1089.         });
  1090.  
  1091.         slot.addEventListener('dragleave', (e) => {
  1092.             slot.classList.remove('dragover');
  1093.         });
  1094.  
  1095.         slot.addEventListener('drop', (e) => {
  1096.             e.preventDefault();
  1097.             slot.classList.remove('dragover');
  1098.  
  1099.             if (!draggedDoc || draggedDoc.used) return;
  1100.  
  1101.             const slotNum = slot.dataset.slot;
  1102.  
  1103.             if (gameState.slots[slotNum]) {
  1104.                 const oldDoc = documents.find(d => d.id === gameState.slots[slotNum].id);
  1105.                 if (oldDoc) oldDoc.used = false;
  1106.             }
  1107.  
  1108.             gameState.slots[slotNum] = draggedDoc;
  1109.             draggedDoc.used = true;
  1110.  
  1111.             slot.classList.add('filled');
  1112.             slot.innerHTML = `
  1113.                 <div style="text-align: center; font-size: 0.8rem;">
  1114.                     <div style="color: ${getRarityColor(draggedDoc.rarity)};">${draggedDoc.type}</div>
  1115.                     <div style="color: #fff; font-size: 0.7rem;">${draggedDoc.name.substring(0, 8)}...</div>
  1116.                     <div style="color: #ffd700; font-size: 0.6rem;">${'⭐'.repeat(draggedDoc.power)}</div>
  1117.                 </div>
  1118.             `;
  1119.  
  1120.             renderDocuments();
  1121.             checkTransmuteReady();
  1122.             createSlotParticles(slot, draggedDoc);
  1123.         });
  1124.     });
  1125. }
  1126.  
  1127. // Helper function for rarity colors
  1128. function getRarityColor(rarity) {
  1129.     switch(rarity) {
  1130.         case 'legendary': return '#ffd700';
  1131.         case 'rare': return '#ff00ff';
  1132.         case 'uncommon': return '#00ffff';
  1133.         default: return '#9d7cff';
  1134.     }
  1135. }
  1136.  
  1137. // Enhanced slot particles with rarity colors
  1138. function createSlotParticles(slot, doc) {
  1139.     let color;
  1140.     switch(doc.rarity) {
  1141.         case 'legendary': color = 'rgba(255, 215, 0, 0.9)'; break;
  1142.         case 'rare': color = 'rgba(255, 0, 255, 0.9)'; break;
  1143.         case 'uncommon': color = 'rgba(0, 255, 255, 0.9)'; break;
  1144.         default: color = 'rgba(138, 43, 226, 0.9)';
  1145.     }
  1146.    
  1147.     for (let i = 0; i < 15; i++) {
  1148.        const particle = document.createElement('div');
  1149.        particle.className = 'particle';
  1150.        const rect = slot.getBoundingClientRect();
  1151.        particle.style.left = rect.left + rect.width / 2 + 'px';
  1152.        particle.style.top = rect.top + rect.height / 2 + 'px';
  1153.        particle.style.background = `radial-gradient(circle, ${color}, transparent)`;
  1154.        particle.style.width = '6px';
  1155.        particle.style.height = '6px';
  1156.        document.body.appendChild(particle);
  1157.  
  1158.        setTimeout(() => particle.remove(), 1000);
  1159.     }
  1160. }
  1161.  
  1162. // Check if ready to transmute
  1163. function checkTransmuteReady() {
  1164.     const btn = document.getElementById('transmuteBtn');
  1165.     if (gameState.slots[1] && gameState.slots[2] && !gameState.isTransmuting) {
  1166.        btn.disabled = false;
  1167.         btn.classList.remove('processing');
  1168.     } else {
  1169.         btn.disabled = true;
  1170.     }
  1171. }
  1172.  
  1173. // Setup transmute button
  1174. function setupTransmuteButton() {
  1175.     document.getElementById('transmuteBtn').addEventListener('click', performTransmutation);
  1176. }
  1177.  
  1178. // Perform transmutation
  1179. function performTransmutation() {
  1180.     if (gameState.isTransmuting) return;
  1181.     if (gameState.artifacts.length >= 10) {
  1182.         showNotification({
  1183.             name: "Inventory Full!",
  1184.             desc: "Destroy or consume artifacts to make space",
  1185.             power: 0
  1186.         }, false, true);
  1187.         return;
  1188.     }
  1189.  
  1190.     const doc1 = gameState.slots[1];
  1191.     const doc2 = gameState.slots[2];
  1192.  
  1193.     if (!doc1 || !doc2) return;
  1194.  
  1195.     gameState.isTransmuting = true;
  1196.     const btn = document.getElementById('transmuteBtn');
  1197.     btn.classList.add('processing');
  1198.     btn.disabled = true;
  1199.  
  1200.     const cauldron = document.getElementById('cauldron');
  1201.     cauldron.classList.add('active');
  1202.     createTransmuteParticles();
  1203.  
  1204.     setTimeout(() => {
  1205.         const keywords1 = doc1.keywords;
  1206.         const keywords2 = doc2.keywords;
  1207.         let artifact = null;
  1208.         let success = false;
  1209.  
  1210.         const commonKeywords = keywords1.filter(k => keywords2.includes(k));
  1211.  
  1212.         if (commonKeywords.length > 0) {
  1213.             const recipeKey = commonKeywords.sort().join(',');
  1214.             if (recipes[recipeKey]) {
  1215.                 artifact = {
  1216.                     ...recipes[recipeKey],
  1217.                     id: Date.now(),
  1218.                     inspected: false,
  1219.                     trueNature: null
  1220.                 };
  1221.                 success = true;
  1222.             } else {
  1223.                 const basePower = Math.ceil((doc1.power + doc2.power) / 2) + commonKeywords.length;
  1224.                 artifact = {
  1225.                     id: Date.now(),
  1226.                     name: `${doc1.name.split(' ')[0]} ${doc2.name.split(' ')[1]} Fusion`,
  1227.                     desc: `Combined essence of ${doc1.type} and ${doc2.type}`,
  1228.                     power: basePower,
  1229.                     hidden: Math.random() > 0.7,
  1230.                     inspected: false,
  1231.                     trueNature: null
  1232.                 };
  1233.                 success = basePower > 2;
  1234.             }
  1235.         } else if (Math.random() > 0.8) {
  1236.             success = true;
  1237.             artifact = {
  1238.                 id: Date.now(),
  1239.                 name: "Chaotic Artifact",
  1240.                 desc: "Unpredictable properties",
  1241.                 power: Math.floor(Math.random() * 4) + 1,
  1242.                 hidden: true,
  1243.                 inspected: false,
  1244.                 trueNature: null,
  1245.                 chaotic: true
  1246.             };
  1247.         } else {
  1248.             artifact = {
  1249.                 id: Date.now(),
  1250.                 name: "Corrupted Data",
  1251.                 desc: "Incompatible combination",
  1252.                 power: 0,
  1253.                 corrupted: true,
  1254.                 inspected: false,
  1255.                 trueNature: null
  1256.             };
  1257.         }
  1258.  
  1259.         if (artifact.hidden) {
  1260.             const roll = Math.random();
  1261.             if (roll < 0.3) {
  1262.                artifact.trueNature = 'corrupted';
  1263.            } else if (roll > 0.8) {
  1264.                 artifact.trueNature = 'legendary';
  1265.             } else {
  1266.                 artifact.trueNature = 'enhanced';
  1267.             }
  1268.         }
  1269.  
  1270.         gameState.transmutations++;
  1271.         gameState.totalDocumentsUsed += 2;
  1272.  
  1273.         if (success) {
  1274.             gameState.successes++;
  1275.             gameState.artifacts.push(artifact);
  1276.  
  1277.             let pointsGained = artifact.power * 10;
  1278.             if (artifact.corrupted) pointsGained = -20;
  1279.             else if (artifact.power <= 2) pointsGained = -10;
  1280.  
  1281.            updatePoints(pointsGained);
  1282.  
  1283.            if (gameState.successes % 5 === 0) {
  1284.                gameState.level++;
  1285.                updatePoints(50);
  1286.            }
  1287.        } else {
  1288.            gameState.artifacts.push(artifact);
  1289.            updatePoints(-10);
  1290.        }
  1291.  
  1292.        showNotification(artifact, success, false);
  1293.        updateStats();
  1294.        updateArtifacts();
  1295.  
  1296.        clearSlots();
  1297.        cauldron.classList.remove('active');
  1298.        refreshUsedDocuments();
  1299.        gameState.isTransmuting = false;
  1300.        checkTransmuteReady();
  1301.        updateHints();
  1302.  
  1303.    }, 2000);
  1304. }
  1305.  
  1306. // Refresh used documents
  1307. function refreshUsedDocuments() {
  1308.    for (let i = 0; i < documents.length; i++) {
  1309.        if (documents[i].used) {
  1310.            const template = documentTemplates[Math.floor(Math.random() * documentTemplates.length)];
  1311.            documents[i] = {
  1312.                id: Date.now() + Math.random(),
  1313.                ...template,
  1314.                used: false,
  1315.                rarity: getRarityFromPower(template.power)
  1316.            };
  1317.        }
  1318.    }
  1319.    documents.sort((a, b) => b.power - a.power);
  1320.     renderDocuments();
  1321. }
  1322.  
  1323. // Clear slots
  1324. function clearSlots() {
  1325.     gameState.slots = { 1: null, 2: null };
  1326.     document.querySelectorAll('.slot').forEach(slot => {
  1327.         slot.classList.remove('filled');
  1328.         slot.innerHTML = `<span style="color: #9d7cff;">Slot ${slot.dataset.slot}</span>`;
  1329.     });
  1330.     checkTransmuteReady();
  1331. }
  1332.  
  1333. // Update points
  1334. function updatePoints(change) {
  1335.     if (change === 0) return;
  1336.  
  1337.     const oldPoints = gameState.points;
  1338.     gameState.points = Math.max(0, gameState.points + change);
  1339.  
  1340.     const display = document.getElementById('pointsDisplay');
  1341.     display.textContent = `⭐ ${gameState.points} Points`;
  1342.  
  1343.     const floater = document.createElement('div');
  1344.     floater.className = change > 0 ? 'point-change positive' : 'point-change negative';
  1345.     floater.textContent = `${change > 0 ? '+' : ''}${change}`;
  1346.     floater.style.left = display.getBoundingClientRect().left + 'px';
  1347.     floater.style.top = display.getBoundingClientRect().bottom + 'px';
  1348.     document.body.appendChild(floater);
  1349.  
  1350.     setTimeout(() => floater.remove(), 2000);
  1351. }
  1352.  
  1353. // Update stats
  1354. function updateStats() {
  1355.     document.getElementById('transmutationCount').textContent = gameState.transmutations;
  1356.     const rate = gameState.transmutations > 0
  1357.         ? Math.round((gameState.successes / gameState.transmutations) * 100)
  1358.         : 0;
  1359.     document.getElementById('successRate').textContent = rate + '%';
  1360.     document.getElementById('alchemyLevel').textContent = gameState.level;
  1361.     updateRiskLevel();
  1362. }
  1363.  
  1364. // Update risk level
  1365. function updateRiskLevel() {
  1366.     const ratio = gameState.consumedWithoutInspection / Math.max(gameState.transmutations, 1);
  1367.     let risk = "Low";
  1368.     if (ratio > 0.5) risk = "Critical";
  1369.     else if (ratio > 0.3) risk = "High";
  1370.     else if (ratio > 0.1) risk = "Medium";
  1371.  
  1372.     document.getElementById('riskLevel').textContent = risk;
  1373.     document.getElementById('riskLevel').style.color =
  1374.         risk === "Critical" ? "#ff0000" :
  1375.         risk === "High" ? "#ff6600" :
  1376.         risk === "Medium" ? "#ffaa00" : "#00ff00";
  1377. }
  1378.  
  1379. // Update artifacts list
  1380. function updateArtifacts() {
  1381.     const container = document.getElementById('artifactsList');
  1382.     const countDisplay = document.getElementById('inventoryCount');
  1383.  
  1384.     countDisplay.textContent = `${gameState.artifacts.length}/10 Artifacts`;
  1385.     countDisplay.style.color = gameState.artifacts.length >= 10 ? '#ff0000' : '#ff00ff';
  1386.  
  1387.     container.innerHTML = '';
  1388.  
  1389.     if (gameState.artifacts.length === 0) {
  1390.         container.innerHTML = '<div style="text-align: center; color: #9d7cff;">No artifacts created yet...</div>';
  1391.         return;
  1392.     }
  1393.  
  1394.     gameState.artifacts.slice().reverse().forEach(artifact => {
  1395.         const elem = document.createElement('div');
  1396.         elem.className = 'artifact-item';
  1397.  
  1398.         if (artifact.inspected) {
  1399.             if (artifact.corrupted) elem.classList.add('corrupted');
  1400.             else if (artifact.power >= 7) elem.classList.add('legendary');
  1401.         }
  1402.  
  1403.         const stars = '⭐'.repeat(Math.min(Math.max(Math.floor(artifact.power / 2), 0), 5));
  1404.         const powerColor = artifact.corrupted ? '#ff0000' :
  1405.             artifact.power >= 7 ? '#ffd700' :
  1406.             artifact.power <= 2 ? '#ff6666' : '#00ffff';
  1407.  
  1408.        elem.innerHTML = `
  1409.            <div class="artifact-name">${artifact.name}</div>
  1410.             <div class="artifact-desc">${artifact.desc}</div>
  1411.             <div class="artifact-power" style="color: ${powerColor};">${stars || '💀'}</div>
  1412.             <div class="artifact-actions">
  1413.                 <button class="action-btn inspect-btn" onclick="inspectArtifact(${artifact.id})" ${artifact.inspected ? 'disabled' : ''}>
  1414.                     ${artifact.inspected ? 'Inspected' : 'Inspect'}
  1415.                 </button>
  1416.                 <button class="action-btn consume-btn" onclick="consumeArtifact(${artifact.id})">
  1417.                     Consume
  1418.                 </button>
  1419.                 <button class="action-btn destroy-btn" onclick="destroyArtifact(${artifact.id})">
  1420.                     Destroy
  1421.                 </button>
  1422.             </div>
  1423.         `;
  1424.         container.appendChild(elem);
  1425.     });
  1426. }
  1427.  
  1428. // Artifact actions
  1429. function inspectArtifact(artifactId) {
  1430.     const artifact = gameState.artifacts.find(a => a.id === artifactId);
  1431.     if (!artifact) return;
  1432.  
  1433.     if (artifact.inspected) {
  1434.         showNotification({
  1435.             name: "Already Inspected",
  1436.             desc: "This artifact's properties are known",
  1437.             power: 0
  1438.         }, false, true);
  1439.         return;
  1440.     }
  1441.  
  1442.     artifact.inspected = true;
  1443.     gameState.inspectedArtifacts.add(artifactId);
  1444.  
  1445.     let pointChange = 0;
  1446.     let message = "";
  1447.  
  1448.     if (artifact.hidden && artifact.trueNature) {
  1449.        if (artifact.trueNature === 'corrupted') {
  1450.            artifact.corrupted = true;
  1451.             artifact.power = 0;
  1452.             pointChange = -30;
  1453.             message = "Revealed as corrupted! Artifact destroyed!";
  1454.             gameState.artifacts = gameState.artifacts.filter(a => a.id !== artifactId);
  1455.         } else if (artifact.trueNature === 'legendary') {
  1456.             artifact.power = Math.min(artifact.power * 2, 10);
  1457.             pointChange = artifact.power * 20;
  1458.             message = "Legendary artifact discovered!";
  1459.         } else {
  1460.             artifact.power += 2;
  1461.             pointChange = 30;
  1462.             message = "Hidden power revealed!";
  1463.         }
  1464.     } else if (artifact.corrupted) {
  1465.         pointChange = -20;
  1466.         message = "Corruption confirmed!";
  1467.         gameState.artifacts = gameState.artifacts.filter(a => a.id !== artifactId);
  1468.     } else {
  1469.         pointChange = Math.floor(artifact.power * 5);
  1470.         message = "Properties analyzed!";
  1471.     }
  1472.  
  1473.     updatePoints(pointChange);
  1474.     showNotification({
  1475.         name: message,
  1476.         desc: `${pointChange > 0 ? '+' : ''}${pointChange} points`,
  1477.         power: artifact.power
  1478.     }, pointChange > 0, true);
  1479.  
  1480.     updateArtifacts();
  1481. }
  1482.  
  1483. function consumeArtifact(artifactId) {
  1484.     const artifact = gameState.artifacts.find(a => a.id === artifactId);
  1485.     if (!artifact) return;
  1486.  
  1487.     let pointChange = 0;
  1488.     let message = "";
  1489.  
  1490.     if (!artifact.inspected) {
  1491.         gameState.consumedWithoutInspection++;
  1492.  
  1493.         if (artifact.corrupted || artifact.power <= 2) {
  1494.            pointChange = -50;
  1495.            message = "Consumed corrupted essence!";
  1496.        } else if (artifact.hidden && Math.random() > 0.5) {
  1497.             pointChange = -30;
  1498.             message = "Unknown artifact backfired!";
  1499.         } else {
  1500.             pointChange = artifact.power * 15;
  1501.             message = "Risky consumption paid off!";
  1502.         }
  1503.     } else {
  1504.         if (artifact.corrupted) {
  1505.             pointChange = -10;
  1506.             message = "Why would you consume this?";
  1507.         } else {
  1508.             pointChange = artifact.power * 20;
  1509.             message = "Artifact power absorbed!";
  1510.         }
  1511.     }
  1512.  
  1513.     gameState.artifacts = gameState.artifacts.filter(a => a.id !== artifactId);
  1514.  
  1515.     updatePoints(pointChange);
  1516.     showNotification({
  1517.         name: message,
  1518.         desc: `${pointChange > 0 ? '+' : ''}${pointChange} points`,
  1519.         power: 0
  1520.     }, pointChange > 0, true);
  1521.  
  1522.     updateArtifacts();
  1523.     updateRiskLevel();
  1524. }
  1525.  
  1526. function destroyArtifact(artifactId) {
  1527.     const artifact = gameState.artifacts.find(a => a.id === artifactId);
  1528.     if (!artifact) return;
  1529.  
  1530.     gameState.artifacts = gameState.artifacts.filter(a => a.id !== artifactId);
  1531.  
  1532.     showNotification({
  1533.         name: "Artifact Destroyed",
  1534.         desc: "Safely disposed of",
  1535.         power: 0
  1536.     }, false, true);
  1537.  
  1538.     updateArtifacts();
  1539. }
  1540.  
  1541. // Show notification
  1542. function showNotification(artifact, success, isQuick) {
  1543.     const notification = document.createElement('div');
  1544.     notification.className = 'notification';
  1545.     notification.innerHTML = `
  1546.         <h2>${success ? '✨ Success!' : '❌ Alert'}</h2>
  1547.         <div style="color: ${success ? '#ffd700' : '#ff6666'}; font-size: 1.3rem; margin-bottom: 0.5rem;">
  1548.             ${artifact.name}
  1549.         </div>
  1550.         <div style="color: #e0e0ff;">
  1551.             ${artifact.desc}
  1552.         </div>
  1553.         ${artifact.power > 0 ? `<div style="color: #ff00ff; font-size: 1.1rem; margin-top: 0.5rem;">
  1554.             Power: ${'⚡'.repeat(Math.min(artifact.power, 5))}
  1555.         </div>` : ''}
  1556.         <button class="close-notification" onclick="this.parentElement.remove()">Continue</button>
  1557.     `;
  1558.     document.body.appendChild(notification);
  1559.  
  1560.     if (isQuick) {
  1561.         setTimeout(() => notification.remove(), 2000);
  1562.     }
  1563. }
  1564.  
  1565. // Create floating particles
  1566. function createFloatingParticles() {
  1567.     setInterval(() => {
  1568.         if (Math.random() > 0.7) {
  1569.             const particle = document.createElement('div');
  1570.             particle.className = 'particle';
  1571.             particle.style.left = Math.random() * window.innerWidth + 'px';
  1572.             particle.style.bottom = '0px';
  1573.             particle.style.animationDelay = Math.random() * 2 + 's';
  1574.             document.body.appendChild(particle);
  1575.  
  1576.             setTimeout(() => particle.remove(), 3000);
  1577.         }
  1578.     }, 500);
  1579. }
  1580.  
  1581. // Create transmute particles
  1582. function createTransmuteParticles() {
  1583.     const cauldron = document.getElementById('cauldron');
  1584.     const rect = cauldron.getBoundingClientRect();
  1585.  
  1586.     for (let i = 0; i < 20; i++) {
  1587.        const particle = document.createElement('div');
  1588.        particle.className = 'particle';
  1589.        particle.style.left = rect.left + rect.width / 2 + (Math.random() - 0.5) * 100 + 'px';
  1590.        particle.style.top = rect.top + 'px';
  1591.        particle.style.background = 'radial-gradient(circle, rgba(255, 215, 0, 0.9), transparent)';
  1592.        particle.style.width = '6px';
  1593.        particle.style.height = '6px';
  1594.        document.body.appendChild(particle);
  1595.  
  1596.        setTimeout(() => particle.remove(), 2000);
  1597.     }
  1598. }
  1599.  
  1600. // Update hints
  1601. function updateHints() {
  1602.     const hints = [
  1603.         "💡 Inspect artifacts to reveal hidden properties!",
  1604.         "⚠️ Consuming without inspection is risky!",
  1605.         "🌟 Legendary artifacts hide among the corrupted!",
  1606.         "🎯 Match keywords for powerful combinations!",
  1607.         "📊 2-star artifacts and below lose points!",
  1608.         "🔄 Documents refresh after each transmutation!",
  1609.         "💰 Inspection bonuses increase with power!",
  1610.         "🎲 Chaos combinations have unpredictable results!",
  1611.         "📦 Maximum 10 artifacts - manage wisely!",
  1612.         "⚡ Level up every 5 successful transmutations!"
  1613.     ];
  1614.  
  1615.     const hint = hints[Math.floor(Math.random() * hints.length)];
  1616.     document.getElementById('recipeHint').textContent = hint;
  1617. }
  1618.  
  1619. // Start the game
  1620. window.addEventListener('DOMContentLoaded', function() {
  1621.     init();
  1622. });
  1623. </script>
  1624. </body>
  1625. </html>
  1626.  
Add Comment
Please, Sign In to add comment