Web-based Winamp controller for CarPC � Go backend, mobile-first UI
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

424 satır
10KB

  1. :root {
  2. --bg: #1a1a2e;
  3. --surface: #16213e;
  4. --accent: #e94560;
  5. --accent2: #0f3460;
  6. --text: #eaeaea;
  7. --text-dim: #888;
  8. --radius: 12px;
  9. --btn-h: 64px;
  10. }
  11. * { box-sizing: border-box; margin: 0; padding: 0; }
  12. html, body {
  13. height: 100%;
  14. background: var(--bg);
  15. color: var(--text);
  16. font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  17. -webkit-tap-highlight-color: transparent;
  18. -webkit-user-select: none;
  19. user-select: none;
  20. }
  21. #app {
  22. max-width: 600px;
  23. margin: 0 auto;
  24. padding: 16px;
  25. display: -webkit-flex;
  26. display: flex;
  27. -webkit-flex-direction: column;
  28. flex-direction: column;
  29. min-height: 100vh;
  30. }
  31. /* gap fallback: margin between every direct child */
  32. #app > * + * { margin-top: 16px; }
  33. /* Status bar */
  34. #status-bar {
  35. display: -webkit-flex;
  36. display: flex;
  37. -webkit-align-items: center;
  38. align-items: center;
  39. font-size: 12px;
  40. color: var(--text-dim);
  41. }
  42. #status-bar > * + * { margin-left: 8px; }
  43. #winamp-status { font-size: 16px; }
  44. #winamp-status.ok { color: #4caf50; }
  45. #winamp-status.err { color: var(--accent); }
  46. /* Track info */
  47. #track-info {
  48. background: var(--surface);
  49. border-radius: var(--radius);
  50. padding: 20px;
  51. text-align: center;
  52. }
  53. #track-title {
  54. font-size: 18px;
  55. font-weight: 600;
  56. white-space: nowrap;
  57. overflow: hidden;
  58. text-overflow: ellipsis;
  59. }
  60. #star-rating {
  61. font-size: 32px;
  62. margin-top: 10px;
  63. letter-spacing: 4px;
  64. cursor: pointer;
  65. -webkit-tap-highlight-color: transparent;
  66. -webkit-user-select: none;
  67. user-select: none;
  68. }
  69. .star {
  70. color: #333;
  71. -webkit-transition: color 0.12s, -webkit-transform 0.1s;
  72. transition: color 0.12s, transform 0.1s;
  73. display: inline-block;
  74. }
  75. .star.lit { color: #f5a623; }
  76. .star:active { -webkit-transform: scale(1.25); transform: scale(1.25); }
  77. #playlist-pos {
  78. font-size: 12px;
  79. color: var(--text-dim);
  80. margin-top: 6px;
  81. }
  82. /* Visualisation canvas */
  83. #viz {
  84. width: 100%;
  85. height: 80px;
  86. border-radius: var(--radius);
  87. background: #000;
  88. display: block;
  89. cursor: pointer;
  90. }
  91. /* Progress */
  92. #progress-wrap {
  93. display: -webkit-flex;
  94. display: flex;
  95. -webkit-flex-direction: column;
  96. flex-direction: column;
  97. }
  98. #progress-wrap > * + * { margin-top: 4px; }
  99. #progress-bar {
  100. height: 8px;
  101. background: var(--accent2);
  102. border-radius: 4px;
  103. overflow: hidden;
  104. cursor: pointer;
  105. }
  106. #progress-fill {
  107. height: 100%;
  108. background: var(--accent);
  109. width: 0%;
  110. -webkit-transition: width 0.5s linear;
  111. transition: width 0.5s linear;
  112. border-radius: 4px;
  113. }
  114. #time-display {
  115. display: -webkit-flex;
  116. display: flex;
  117. -webkit-justify-content: space-between;
  118. justify-content: space-between;
  119. font-size: 12px;
  120. color: var(--text-dim);
  121. }
  122. /* Buttons base */
  123. /* No flexbox here: on iOS 9 a <button> with display:flex ignores
  124. justify-content, leaving text left-aligned. Classic text-align (horizontal)
  125. + line-height (vertical) centering is single-line only but works on every
  126. browser. line-height is set per variant to match each button's height. */
  127. .btn {
  128. background: var(--surface);
  129. color: var(--text);
  130. border: none;
  131. border-radius: var(--radius);
  132. font-size: 22px;
  133. cursor: pointer;
  134. -webkit-transition: background 0.15s, -webkit-transform 0.08s;
  135. transition: background 0.15s, transform 0.08s;
  136. text-align: center;
  137. white-space: nowrap;
  138. padding: 0;
  139. touch-action: manipulation;
  140. }
  141. .btn:active { -webkit-transform: scale(0.93); transform: scale(0.93); background: var(--accent2); }
  142. /* ── Seek row ────────────────────────────────────────────────────────────── */
  143. /* Base: flexbox (iOS 9 and up) */
  144. #seek-row {
  145. display: -webkit-flex;
  146. display: flex;
  147. }
  148. #seek-row > .btn-seek {
  149. -webkit-flex: 1;
  150. flex: 1;
  151. }
  152. #seek-row > .btn-seek + .btn-seek { margin-left: 8px; }
  153. /* Enhancement: CSS Grid (iOS 10.3+, all modern browsers) */
  154. @supports (display: grid) {
  155. #seek-row {
  156. display: grid;
  157. grid-template-columns: repeat(4, 1fr);
  158. gap: 8px;
  159. }
  160. #seek-row > .btn-seek { -webkit-flex: none; flex: none; }
  161. #seek-row > .btn-seek + .btn-seek { margin-left: 0; }
  162. }
  163. .btn-seek {
  164. height: 52px;
  165. line-height: 52px;
  166. font-size: 19px;
  167. font-weight: 600;
  168. }
  169. /* ── Controls row ───────────────────────────────────────────────────────── */
  170. /* Base: flexbox */
  171. #controls-row {
  172. display: -webkit-flex;
  173. display: flex;
  174. }
  175. #controls-row > .btn-ctrl {
  176. -webkit-flex: 1;
  177. flex: 1;
  178. }
  179. #controls-row > .btn-ctrl + .btn-ctrl { margin-left: 8px; }
  180. /* Enhancement: CSS Grid */
  181. @supports (display: grid) {
  182. #controls-row {
  183. display: grid;
  184. grid-template-columns: repeat(4, 1fr);
  185. gap: 8px;
  186. }
  187. #controls-row > .btn-ctrl { -webkit-flex: none; flex: none; }
  188. #controls-row > .btn-ctrl + .btn-ctrl { margin-left: 0; }
  189. }
  190. .btn-ctrl { height: var(--btn-h); line-height: var(--btn-h); font-size: 28px; }
  191. .btn-play {
  192. background: var(--accent);
  193. font-size: 32px;
  194. }
  195. .btn-play:active { background: #c73652; }
  196. /* Volume row */
  197. #volume-row {
  198. display: -webkit-flex;
  199. display: flex;
  200. -webkit-align-items: center;
  201. align-items: center;
  202. }
  203. #volume-row > * + * { margin-left: 10px; }
  204. .btn-vol { width: 48px; height: 48px; line-height: 48px; -webkit-flex-shrink: 0; flex-shrink: 0; font-size: 18px; }
  205. #btn-mute { font-size: 22px; }
  206. #btn-mute.muted { color: var(--accent); }
  207. #volume-bar-wrap {
  208. -webkit-flex: 1;
  209. flex: 1;
  210. display: -webkit-flex;
  211. display: flex;
  212. -webkit-flex-direction: column;
  213. flex-direction: column;
  214. }
  215. #volume-bar-wrap > * + * { margin-top: 4px; }
  216. #volume-bar {
  217. height: 8px;
  218. background: var(--accent2);
  219. border-radius: 4px;
  220. overflow: hidden;
  221. cursor: pointer;
  222. }
  223. #volume-fill {
  224. height: 100%;
  225. background: #4caf50;
  226. width: 70%;
  227. -webkit-transition: width 0.2s;
  228. transition: width 0.2s;
  229. border-radius: 4px;
  230. }
  231. #volume-pct {
  232. font-size: 11px;
  233. color: var(--text-dim);
  234. text-align: center;
  235. }
  236. #volume-fill.muted { background: var(--accent); }
  237. /* Killist */
  238. #killist-row {
  239. display: -webkit-flex;
  240. display: flex;
  241. }
  242. #killist-row > * + * { margin-left: 8px; }
  243. .btn-kill { -webkit-flex: 1; flex: 1; height: 52px; line-height: 52px; font-size: 16px; background: #3a1a1a; }
  244. .btn-kill:active { background: var(--accent); }
  245. .btn-kill-list { width: 64px; height: 52px; line-height: 52px; font-size: 14px; }
  246. .btn-action { width: 52px; height: 52px; line-height: 52px; font-size: 20px; }
  247. #killist-panel {
  248. background: var(--surface);
  249. border-radius: var(--radius);
  250. padding: 16px;
  251. }
  252. #killist-panel h3 { margin-bottom: 12px; }
  253. #killist-items {
  254. list-style: none;
  255. display: -webkit-flex;
  256. display: flex;
  257. -webkit-flex-direction: column;
  258. flex-direction: column;
  259. }
  260. #killist-items li + li { margin-top: 8px; }
  261. #killist-items li {
  262. display: -webkit-flex;
  263. display: flex;
  264. -webkit-justify-content: space-between;
  265. justify-content: space-between;
  266. -webkit-align-items: center;
  267. align-items: center;
  268. background: var(--bg);
  269. border-radius: 8px;
  270. padding: 8px 12px;
  271. font-size: 14px;
  272. }
  273. #killist-items li button {
  274. background: var(--accent);
  275. color: white;
  276. border: none;
  277. border-radius: 6px;
  278. padding: 4px 10px;
  279. cursor: pointer;
  280. }
  281. #btn-close-killist { margin-top: 12px; width: 100%; height: 44px; line-height: 44px; font-size: 15px; }
  282. /* ── Playlist overlay ────────────────────────────────────────────────────── */
  283. #playlist-overlay {
  284. position: fixed;
  285. /* inset: 0 fallback for browsers without inset support (iOS < 14.5) */
  286. top: 0;
  287. right: 0;
  288. bottom: 0;
  289. left: 0;
  290. z-index: 200;
  291. background: var(--bg);
  292. display: -webkit-flex;
  293. display: flex;
  294. -webkit-flex-direction: column;
  295. flex-direction: column;
  296. }
  297. #playlist-header {
  298. display: -webkit-flex;
  299. display: flex;
  300. -webkit-align-items: center;
  301. align-items: center;
  302. -webkit-justify-content: space-between;
  303. justify-content: space-between;
  304. padding: 16px 20px;
  305. background: var(--surface);
  306. border-bottom: 1px solid #ffffff12;
  307. -webkit-flex-shrink: 0;
  308. flex-shrink: 0;
  309. }
  310. #playlist-title-label {
  311. font-size: 16px;
  312. font-weight: 600;
  313. }
  314. #btn-close-playlist {
  315. background: none;
  316. border: none;
  317. color: var(--text-dim);
  318. font-size: 22px;
  319. cursor: pointer;
  320. padding: 4px 8px;
  321. border-radius: 8px;
  322. line-height: 1;
  323. touch-action: manipulation;
  324. }
  325. #btn-close-playlist:active { background: var(--accent2); color: var(--text); }
  326. #playlist-list {
  327. list-style: none;
  328. overflow-y: auto;
  329. -webkit-flex: 1;
  330. flex: 1;
  331. padding: 8px 0;
  332. -webkit-overflow-scrolling: touch;
  333. }
  334. #playlist-list li {
  335. display: -webkit-flex;
  336. display: flex;
  337. -webkit-align-items: center;
  338. align-items: center;
  339. padding: 12px 20px;
  340. cursor: pointer;
  341. border-radius: 0;
  342. -webkit-transition: background 0.1s;
  343. transition: background 0.1s;
  344. -webkit-tap-highlight-color: transparent;
  345. }
  346. #playlist-list li > * + * { margin-left: 12px; }
  347. #playlist-list li:active { background: var(--accent2); }
  348. #playlist-list li.current {
  349. background: #e9456018;
  350. border-left: 3px solid var(--accent);
  351. padding-left: 17px;
  352. }
  353. .pl-idx {
  354. font-size: 12px;
  355. color: var(--text-dim);
  356. min-width: 32px;
  357. text-align: right;
  358. -webkit-flex-shrink: 0;
  359. flex-shrink: 0;
  360. }
  361. .pl-title {
  362. font-size: 15px;
  363. white-space: nowrap;
  364. overflow: hidden;
  365. text-overflow: ellipsis;
  366. }
  367. li.current .pl-title { color: var(--accent); font-weight: 600; }
  368. #playlist-loading {
  369. text-align: center;
  370. color: var(--text-dim);
  371. padding: 40px;
  372. font-size: 14px;
  373. }
  374. /* ── gap enhancement for all flex containers (iOS 14.5+ / modern browsers) */
  375. @supports (gap: 1px) {
  376. #app { gap: 16px; }
  377. #app > * + * { margin-top: 0; }
  378. #status-bar { gap: 8px; }
  379. #status-bar > * + * { margin-left: 0; }
  380. #progress-wrap { gap: 4px; }
  381. #progress-wrap > * + * { margin-top: 0; }
  382. #volume-row { gap: 10px; }
  383. #volume-row > * + * { margin-left: 0; }
  384. #volume-bar-wrap { gap: 4px; }
  385. #volume-bar-wrap > * + * { margin-top: 0; }
  386. #killist-row { gap: 8px; }
  387. #killist-row > * + * { margin-left: 0; }
  388. #killist-items { gap: 8px; }
  389. #killist-items li + li { margin-top: 0; }
  390. #playlist-list li { gap: 12px; }
  391. #playlist-list li > * + * { margin-left: 0; }
  392. }
  393. .hidden { display: none !important; }