index-style6.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  6. <title>月度排行榜</title>
  7. <link href="./css/all.min.css" rel="stylesheet">
  8. <style>
  9. :root {
  10. --toon-blue: #4FACFE;
  11. --toon-cloud: #FFFFFF;
  12. --toon-yellow: #FFD056;
  13. --toon-pink: #FF9A9E;
  14. --toon-green: #00E18F;
  15. --toon-black: #333333;
  16. --border-thick: 4px solid var(--toon-black);
  17. }
  18. * {
  19. box-sizing: border-box;
  20. margin: 0;
  21. padding: 0;
  22. /* 卡通感圆体 */
  23. font-family: 'Comic Sans MS', 'Chalkboard SE', 'YouYuan', 'Microsoft YaHei', sans-serif;
  24. -webkit-tap-highlight-color: transparent;
  25. user-select: none;
  26. }
  27. html, body {
  28. width: 100%;
  29. height: 100%;
  30. overflow: hidden;
  31. background: transparent;
  32. display: flex;
  33. justify-content: center;
  34. align-items: center;
  35. }
  36. /* 主容器 */
  37. .card-container {
  38. width: 100%;
  39. height: 100%;
  40. position: relative;
  41. background: linear-gradient(180deg, var(--toon-blue) 0%, #00F2FE 100%);
  42. border-radius: 20px;
  43. overflow: hidden;
  44. cursor: pointer;
  45. display: flex;
  46. flex-direction: column;
  47. align-items: center;
  48. /* 强制裁剪 */
  49. transform: translateZ(0);
  50. -webkit-mask-image: -webkit-radial-gradient(white, black);
  51. }
  52. /* 背景云层 */
  53. .cloud-bg {
  54. position: absolute;
  55. width: 100%; height: 100%;
  56. z-index: 0;
  57. }
  58. .cloud {
  59. position: absolute;
  60. background: rgba(255,255,255,0.4);
  61. border-radius: 50px;
  62. animation: floatCloud 20s infinite linear;
  63. }
  64. .c1 { top: 10%; left: -20%; width: 120px; height: 40px; animation-duration: 15s; }
  65. .c2 { top: 30%; right: -10%; width: 80px; height: 30px; animation-duration: 25s; animation-delay: -5s; }
  66. .c3 { bottom: 20%; left: 10%; width: 150px; height: 50px; animation-duration: 18s; animation-delay: -10s; }
  67. /* 装饰:彩虹 */
  68. .rainbow {
  69. position: absolute;
  70. top: -10%;
  71. right: -20%;
  72. width: 60vmin;
  73. height: 60vmin;
  74. border-radius: 50%;
  75. box-shadow:
  76. 0 0 0 20px var(--toon-pink),
  77. 0 0 0 40px var(--toon-yellow),
  78. 0 0 0 60px var(--toon-green);
  79. opacity: 0.6;
  80. z-index: 0;
  81. }
  82. /* 顶部年份:太阳徽章 */
  83. .year-badge {
  84. margin-top: 12%;
  85. z-index: 2;
  86. background: var(--toon-yellow);
  87. border: var(--border-thick);
  88. padding: 1vmin 4vmin;
  89. border-radius: 50px;
  90. font-size: 5vmin;
  91. font-weight: bold;
  92. color: var(--toon-black);
  93. box-shadow: 4px 4px 0 rgba(0,0,0,0.2);
  94. transform: rotate(-3deg);
  95. display: flex;
  96. align-items: center;
  97. gap: 5px;
  98. animation: floatBadge 3s infinite ease-in-out;
  99. }
  100. .sun-icon {
  101. color: var(--toon-black);
  102. font-size: 4vmin;
  103. }
  104. /* 核心视觉:云朵上的月份 */
  105. .main-visual {
  106. flex: 1;
  107. display: flex;
  108. flex-direction: column;
  109. justify-content: center;
  110. align-items: center;
  111. z-index: 2;
  112. position: relative;
  113. }
  114. .month-bg {
  115. position: absolute;
  116. width: 55vmin;
  117. height: 50vmin;
  118. background: var(--toon-cloud);
  119. border: var(--border-thick);
  120. border-radius: 50%;
  121. /* 手绘感不规则圆 */
  122. border-radius: 54% 46% 42% 58% / 60% 54% 46% 40%;
  123. box-shadow: 8px 8px 0 rgba(0,0,0,0.15);
  124. animation: blob 6s infinite ease-in-out alternate;
  125. display: flex;
  126. justify-content: center;
  127. align-items: center;
  128. }
  129. .month-num {
  130. font-size: 35vmin;
  131. color: var(--toon-pink);
  132. font-weight: 900;
  133. /* 卡通描边字 */
  134. -webkit-text-stroke: 3px var(--toon-black);
  135. text-shadow: 5px 5px 0 rgba(0,0,0,0.1);
  136. position: relative;
  137. z-index: 3;
  138. }
  139. .month-tag {
  140. position: absolute;
  141. bottom: -10%;
  142. background: var(--toon-green);
  143. border: var(--border-thick);
  144. color: #fff;
  145. padding: 1vmin 3vmin;
  146. border-radius: 15px;
  147. font-size: 5vmin;
  148. font-weight: bold;
  149. transform: rotate(3deg);
  150. box-shadow: 3px 3px 0 rgba(0,0,0,0.2);
  151. z-index: 4;
  152. -webkit-text-stroke: 1px var(--toon-black);
  153. }
  154. /* 底部按钮:巨大的游戏按钮 */
  155. .action-container {
  156. margin-bottom: 12%;
  157. z-index: 2;
  158. width: 100%;
  159. display: flex;
  160. justify-content: center;
  161. }
  162. .toon-btn {
  163. background: #FF6B6B;
  164. border: var(--border-thick);
  165. border-radius: 20px;
  166. padding: 3vmin 8vmin;
  167. color: #fff;
  168. font-size: 5vmin;
  169. font-weight: bold;
  170. display: flex;
  171. align-items: center;
  172. gap: 2vmin;
  173. box-shadow:
  174. inset 0 5px 0 rgba(255,255,255,0.3),
  175. 0 6px 0 var(--toon-black); /* 立体厚度 */
  176. transition: all 0.1s;
  177. position: relative;
  178. top: 0;
  179. }
  180. .toon-btn i {
  181. -webkit-text-stroke: 1px var(--toon-black);
  182. }
  183. /* 交互:按下扁平化 */
  184. .card-container:active .toon-btn {
  185. top: 6px;
  186. box-shadow:
  187. inset 0 5px 0 rgba(255,255,255,0.3),
  188. 0 0 0 var(--toon-black);
  189. }
  190. .card-container:active .month-bg {
  191. transform: scale(0.95) rotate(5deg);
  192. }
  193. /* 动画 */
  194. @keyframes floatCloud {
  195. from { transform: translateX(-150%); }
  196. to { transform: translateX(350%); }
  197. }
  198. @keyframes blob {
  199. 0% { border-radius: 54% 46% 42% 58% / 60% 54% 46% 40%; transform: rotate(0deg); }
  200. 100% { border-radius: 45% 55% 55% 45% / 50% 40% 60% 50%; transform: rotate(2deg); }
  201. }
  202. @keyframes floatBadge {
  203. 0%, 100% { transform: rotate(-3deg) translateY(0); }
  204. 50% { transform: rotate(-3deg) translateY(-5px); }
  205. }
  206. </style>
  207. </head>
  208. <body>
  209. <div class="card-container" onclick="redirectToDetail()">
  210. <div class="rainbow"></div>
  211. <div class="cloud-bg">
  212. <div class="cloud c1"></div>
  213. <div class="cloud c2"></div>
  214. <div class="cloud c3"></div>
  215. </div>
  216. <!-- 太阳年份徽章 -->
  217. <div class="year-badge">
  218. <i class="fa-solid fa-sun sun-icon"></i>
  219. <span class="year-text">2025年</span>
  220. </div>
  221. <!-- 中央视觉 -->
  222. <div class="main-visual">
  223. <div class="month-bg">
  224. <div class="month-num">12</div>
  225. <div class="month-tag">月挑战赛</div>
  226. </div>
  227. </div>
  228. <!-- 游戏感按钮 -->
  229. <div class="action-container">
  230. <div class="toon-btn">
  231. <i class="fa-solid fa-play"></i>
  232. <span>GO! 排行榜</span>
  233. </div>
  234. </div>
  235. </div>
  236. <script src="./bridge.js"></script>
  237. <script src="./js/target_logic.js"></script>
  238. <script>
  239. // Auto-Update Date
  240. (function() {
  241. const now = new Date();
  242. const year = now.getFullYear();
  243. const month = now.getMonth() + 1;
  244. const yearEl = document.querySelector('.year-text');
  245. const monthEl = document.querySelector('.month-num');
  246. if (yearEl) yearEl.innerText = year + '年';
  247. if (monthEl) monthEl.innerText = month;
  248. })();
  249. // Logger Utility
  250. const Logger = {
  251. _isDev: false,
  252. init: function(isDev) {
  253. this._isDev = isDev;
  254. },
  255. log: function() {
  256. if (this._isDev) {
  257. console.log.apply(console, arguments);
  258. }
  259. },
  260. warn: function() {
  261. if (this._isDev) {
  262. console.warn.apply(console, arguments);
  263. }
  264. },
  265. error: function() {
  266. console.error.apply(console, arguments);
  267. }
  268. };
  269. function getQueryParam(name) {
  270. const params = new URLSearchParams(window.location.search);
  271. return params.get(name);
  272. }
  273. // Initialize Logger
  274. const env = (getQueryParam('env') || '').toLowerCase();
  275. Logger.init(env === 'mock'); // Only log if env=mock
  276. function redirectToDetail() {
  277. const token = getQueryParam('token');
  278. const id = getQueryParam('id');
  279. // Use centralized logic
  280. let detailUrl = getTargetDetail();
  281. const queryParams = [];
  282. if (token) {
  283. queryParams.push(`token=${encodeURIComponent(token)}`);
  284. }
  285. if (id) {
  286. queryParams.push(`id=${encodeURIComponent(id)}`);
  287. }
  288. if (queryParams.length > 0) {
  289. detailUrl += `?${queryParams.join('&')}`;
  290. }
  291. detailUrl += (detailUrl.includes('?') ? '&' : '?') + 'full=true';
  292. Logger.log("Navigating to:", detailUrl);
  293. if (window.Bridge && window.Bridge.appAction) {
  294. Bridge.appAction(detailUrl);
  295. } else {
  296. window.location.href = detailUrl;
  297. }
  298. }
  299. </script>
  300. </body>
  301. </html>