list.html 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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>Targets - List</title>
  7. <link rel="stylesheet" href="../list.css">
  8. <style>
  9. /* Targets-specific card previews (to match anime.js docs vibe) */
  10. .card {
  11. min-height: 120px;
  12. padding: 18px 18px 16px 18px;
  13. }
  14. .card-preview {
  15. height: 62px;
  16. border-radius: 10px;
  17. background: rgba(255,255,255,0.02);
  18. border: 1px solid rgba(255,255,255,0.04);
  19. position: relative;
  20. overflow: hidden;
  21. display: flex;
  22. align-items: center;
  23. justify-content: center;
  24. margin-bottom: 14px;
  25. }
  26. .preview-grid {
  27. width: 100%;
  28. padding: 0 14px;
  29. display: flex;
  30. align-items: center;
  31. justify-content: space-between;
  32. }
  33. .preview-stack {
  34. display: flex;
  35. flex-direction: column;
  36. gap: 6px;
  37. }
  38. .preview-sq {
  39. width: 12px;
  40. height: 12px;
  41. border-radius: 3px;
  42. background: #3a3a3a;
  43. transition: transform 0.35s ease, background 0.2s ease;
  44. }
  45. .preview-sq.orange { background: #ff9f43; }
  46. .preview-sq.red { background: #ff4b4b; }
  47. /* Hover gives a subtle “replay” feel like anime.js cards */
  48. .card:hover .preview-stack.left .preview-sq {
  49. transform: translateX(10px);
  50. }
  51. .card:hover .preview-stack.right .preview-sq {
  52. transform: translateX(-10px);
  53. }
  54. .preview-pill {
  55. font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  56. color: #9a9a9a;
  57. background: rgba(255,255,255,0.04);
  58. border: 1px solid rgba(255,255,255,0.06);
  59. padding: 10px 14px;
  60. border-radius: 10px;
  61. font-size: 13px;
  62. letter-spacing: 0.2px;
  63. }
  64. </style>
  65. </head>
  66. <body>
  67. <div class="search-header">
  68. <div class="search-title">Targets</div>
  69. <div class="search-input-container">
  70. <div class="search-icon"></div>
  71. <input type="text" class="search-input" placeholder="Filter targets...">
  72. </div>
  73. </div>
  74. <div class="grid-section">
  75. <!-- Header Card (Overview) -->
  76. <div class="header-card active" onclick="selectItem('overview.html', this)">
  77. <div class="header-dots"></div>
  78. <div class="header-title">Targets</div>
  79. </div>
  80. <div class="card-grid" style="margin-top: 40px;">
  81. <!-- CSS Selector -->
  82. <div class="card" data-content="targets/test_css_selector.html" onclick="selectItem('test_css_selector.html', this)">
  83. <div class="card-preview">
  84. <div class="preview-grid">
  85. <div class="preview-stack left" aria-hidden="true">
  86. <div class="preview-sq"></div>
  87. <div class="preview-sq"></div>
  88. <div class="preview-sq"></div>
  89. </div>
  90. <div class="preview-stack right" aria-hidden="true">
  91. <div class="preview-sq orange"></div>
  92. <div class="preview-sq orange"></div>
  93. <div class="preview-sq orange"></div>
  94. </div>
  95. </div>
  96. </div>
  97. <div class="card-footer">CSS Selector</div>
  98. </div>
  99. <!-- DOM Elements -->
  100. <div class="card" data-content="targets/test_dom_elements.html" onclick="selectItem('test_dom_elements.html', this)">
  101. <div class="card-preview">
  102. <div class="preview-grid">
  103. <div class="preview-stack left" aria-hidden="true">
  104. <div class="preview-sq"></div>
  105. <div class="preview-sq"></div>
  106. <div class="preview-sq"></div>
  107. </div>
  108. <div class="preview-stack right" aria-hidden="true">
  109. <div class="preview-sq red"></div>
  110. <div class="preview-sq"></div>
  111. <div class="preview-sq"></div>
  112. </div>
  113. </div>
  114. </div>
  115. <div class="card-footer">DOM Elements</div>
  116. </div>
  117. <!-- JS Objects -->
  118. <div class="card" data-content="targets/test_js_objects.html" onclick="selectItem('test_js_objects.html', this)">
  119. <div class="card-preview">
  120. <div class="preview-pill">{ "x": 0, "y": 0 }</div>
  121. </div>
  122. <div class="card-footer">JavaScript Objects <span class="tag">JS</span></div>
  123. </div>
  124. <!-- Arrays -->
  125. <div class="card" data-content="targets/test_array_targets.html" onclick="selectItem('test_array_targets.html', this)">
  126. <div class="card-preview">
  127. <div class="preview-pill">{ "x": "0" }</div>
  128. </div>
  129. <div class="card-footer">Array of targets</div>
  130. </div>
  131. </div>
  132. </div>
  133. <script>
  134. function selectItem(url, el) {
  135. // Manage active state for standard cards
  136. document.querySelectorAll('.card').forEach(c => c.classList.remove('active'));
  137. document.querySelectorAll('.header-card').forEach(c => c.classList.remove('active'));
  138. if (el.classList.contains('header-card')) {
  139. el.classList.add('active');
  140. } else {
  141. el.classList.add('active');
  142. }
  143. if (window.parent && window.parent.loadContent) {
  144. window.parent.loadContent('targets/' + url);
  145. }
  146. }
  147. // Called from parent to keep active selection in sync with the right iframe
  148. function setActiveByContentUrl(contentUrl) {
  149. const normalized = String(contentUrl || '').replace(/^\.\//, '');
  150. const header = document.querySelector('.header-card');
  151. const cards = Array.from(document.querySelectorAll('.card[data-content]'));
  152. document.querySelectorAll('.card').forEach(c => c.classList.remove('active'));
  153. document.querySelectorAll('.header-card').forEach(c => c.classList.remove('active'));
  154. if (!normalized) return;
  155. if (normalized.includes('targets/overview.html')) {
  156. header?.classList.add('active');
  157. return;
  158. }
  159. const match = cards.find(c => normalized.endsWith(c.dataset.content) || normalized.includes(c.dataset.content));
  160. if (match) match.classList.add('active');
  161. }
  162. // expose for parent iframe access
  163. window.setActiveByContentUrl = setActiveByContentUrl;
  164. </script>
  165. </body>
  166. </html>