style.css 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472
  1. :root {
  2. --bg-color: #0d1117;
  3. --panel-bg: rgba(22, 27, 34, 0.7);
  4. --border-color: rgba(48, 54, 61, 0.8);
  5. --text-main: #c9d1d9;
  6. --text-muted: #8b949e;
  7. --primary-gradient: linear-gradient(135deg, #2ea043 0%, #238636 100%);
  8. --primary-color: #2ea043;
  9. --user-msg-bg: linear-gradient(135deg, #1f6feb 0%, #164e63 100%);
  10. --bot-msg-bg: rgba(33, 38, 45, 0.8);
  11. --glass-blur: blur(16px);
  12. }
  13. * {
  14. box-sizing: border-box;
  15. margin: 0;
  16. padding: 0;
  17. }
  18. body {
  19. font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  20. background-color: var(--bg-color);
  21. background-image: radial-gradient(circle at top right, rgba(46, 160, 67, 0.15), transparent 400px),
  22. radial-gradient(circle at bottom left, rgba(31, 111, 235, 0.1), transparent 400px);
  23. color: var(--text-main);
  24. display: flex;
  25. justify-content: center;
  26. align-items: center;
  27. height: 100vh;
  28. padding: 20px;
  29. overflow: hidden;
  30. }
  31. .app-container {
  32. width: 100%;
  33. max-width: 900px;
  34. height: 90vh;
  35. background: var(--panel-bg);
  36. backdrop-filter: var(--glass-blur);
  37. -webkit-backdrop-filter: var(--glass-blur);
  38. border: 1px solid var(--border-color);
  39. border-radius: 20px;
  40. display: flex;
  41. flex-direction: column;
  42. box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
  43. overflow: hidden;
  44. }
  45. .chat-header {
  46. padding: 16px 24px;
  47. border-bottom: 1px solid var(--border-color);
  48. display: flex;
  49. justify-content: space-between;
  50. align-items: center;
  51. background: rgba(13, 17, 23, 0.6);
  52. }
  53. .brand {
  54. display: flex;
  55. align-items: center;
  56. gap: 12px;
  57. }
  58. .logo {
  59. font-size: 28px;
  60. background: var(--primary-gradient);
  61. -webkit-background-clip: text;
  62. background-clip: text;
  63. }
  64. h1 {
  65. font-size: 1.1rem;
  66. font-weight: 600;
  67. color: #f0f6fc;
  68. }
  69. .status-indicator {
  70. display: inline-block;
  71. width: 8px;
  72. height: 8px;
  73. background-color: #2ea043;
  74. border-radius: 50%;
  75. margin-right: 6px;
  76. box-shadow: 0 0 10px #2ea043;
  77. }
  78. .status-text {
  79. font-size: 0.75rem;
  80. color: var(--text-muted);
  81. }
  82. #clear-chat {
  83. background: none;
  84. border: none;
  85. color: var(--text-muted);
  86. cursor: pointer;
  87. transition: color 0.2s ease;
  88. padding: 8px;
  89. border-radius: 8px;
  90. }
  91. #clear-chat:hover {
  92. color: #f85149;
  93. background: rgba(248, 81, 73, 0.1);
  94. }
  95. .chat-container {
  96. flex: 1;
  97. padding: 24px;
  98. overflow-y: auto;
  99. display: flex;
  100. flex-direction: column;
  101. gap: 20px;
  102. scroll-behavior: smooth;
  103. }
  104. .chat-container::-webkit-scrollbar {
  105. width: 6px;
  106. }
  107. .chat-container::-webkit-scrollbar-thumb {
  108. background: var(--border-color);
  109. border-radius: 10px;
  110. }
  111. .message {
  112. display: flex;
  113. gap: 16px;
  114. max-width: 85%;
  115. animation: fadeIn 0.3s ease forwards;
  116. opacity: 0;
  117. transform: translateY(10px);
  118. }
  119. @keyframes fadeIn {
  120. to {
  121. opacity: 1;
  122. transform: translateY(0);
  123. }
  124. }
  125. .message.user {
  126. align-self: flex-end;
  127. flex-direction: row-reverse;
  128. }
  129. .avatar {
  130. width: 36px;
  131. height: 36px;
  132. border-radius: 10px;
  133. display: flex;
  134. justify-content: center;
  135. align-items: center;
  136. font-size: 20px;
  137. flex-shrink: 0;
  138. background: rgba(255, 255, 255, 0.1);
  139. }
  140. .message.user .avatar {
  141. background: var(--user-msg-bg);
  142. }
  143. .message.system .avatar {
  144. background: var(--bot-msg-bg);
  145. border: 1px solid var(--border-color);
  146. }
  147. .message-content {
  148. padding: 14px 18px;
  149. border-radius: 18px;
  150. line-height: 1.6;
  151. font-size: 0.95rem;
  152. white-space: pre-wrap;
  153. word-break: break-word;
  154. }
  155. .message.user .message-content {
  156. background: var(--user-msg-bg);
  157. color: #fff;
  158. border-top-right-radius: 4px;
  159. }
  160. .message.system .message-content {
  161. background: var(--bot-msg-bg);
  162. border: 1px solid var(--border-color);
  163. border-top-left-radius: 4px;
  164. box-shadow: 0 4px 12px rgba(0,0,0,0.1);
  165. }
  166. .chat-input-area {
  167. padding: 20px 24px;
  168. background: rgba(13, 17, 23, 0.8);
  169. border-top: 1px solid var(--border-color);
  170. }
  171. .input-form {
  172. display: flex;
  173. gap: 12px;
  174. align-items: flex-end;
  175. background: var(--bg-color);
  176. border: 1px solid var(--border-color);
  177. border-radius: 16px;
  178. padding: 8px 16px;
  179. transition: border-color 0.2s, box-shadow 0.2s;
  180. }
  181. .input-form:focus-within {
  182. border-color: rgba(46, 160, 67, 0.5);
  183. box-shadow: 0 0 0 2px rgba(46, 160, 67, 0.1);
  184. }
  185. textarea {
  186. flex: 1;
  187. background: none;
  188. border: none;
  189. color: var(--text-main);
  190. font-family: inherit;
  191. font-size: 1rem;
  192. resize: none;
  193. max-height: 150px;
  194. padding: 10px 0;
  195. outline: none;
  196. }
  197. textarea::placeholder {
  198. color: var(--text-muted);
  199. }
  200. .send-btn {
  201. background: var(--primary-color);
  202. border: none;
  203. border-radius: 12px;
  204. width: 40px;
  205. height: 40px;
  206. display: flex;
  207. justify-content: center;
  208. align-items: center;
  209. color: #fff;
  210. cursor: pointer;
  211. transition: transform 0.2s, background 0.2s;
  212. flex-shrink: 0;
  213. margin-bottom: 2px;
  214. }
  215. .send-btn:hover {
  216. background: #3fb950;
  217. transform: scale(1.05);
  218. }
  219. .send-btn:active {
  220. transform: scale(0.95);
  221. }
  222. .send-btn:disabled {
  223. background: var(--border-color);
  224. color: var(--text-muted);
  225. cursor: not-allowed;
  226. transform: none;
  227. }
  228. .footer-note {
  229. text-align: center;
  230. font-size: 0.7rem;
  231. color: var(--text-muted);
  232. margin-top: 12px;
  233. }
  234. .typing-indicator {
  235. display: flex;
  236. gap: 4px;
  237. padding: 4px 8px;
  238. align-items: center;
  239. }
  240. .typing-dot {
  241. width: 6px;
  242. height: 6px;
  243. background: var(--text-muted);
  244. border-radius: 50%;
  245. animation: typing 1.4s infinite ease-in-out both;
  246. }
  247. .typing-dot:nth-child(1) { animation-delay: -0.32s; }
  248. .typing-dot:nth-child(2) { animation-delay: -0.16s; }
  249. .typing-dot:nth-child(3) { animation-delay: 0s; }
  250. @keyframes typing {
  251. 0%, 80%, 100% { transform: scale(0); }
  252. 40% { transform: scale(1); }
  253. }
  254. /* Modal Styles */
  255. .nav-btn {
  256. background: rgba(255, 255, 255, 0.1);
  257. border: 1px solid var(--border-color);
  258. color: var(--text-main);
  259. padding: 6px 12px;
  260. border-radius: 8px;
  261. cursor: pointer;
  262. margin-right: 10px;
  263. font-size: 0.85rem;
  264. transition: background 0.2s;
  265. }
  266. .nav-btn:hover {
  267. background: rgba(255, 255, 255, 0.2);
  268. }
  269. .modal-overlay {
  270. position: fixed;
  271. top: 0; left: 0; right: 0; bottom: 0;
  272. background: rgba(0, 0, 0, 0.6);
  273. backdrop-filter: blur(8px);
  274. -webkit-backdrop-filter: blur(8px);
  275. display: flex;
  276. justify-content: center;
  277. align-items: center;
  278. z-index: 1000;
  279. opacity: 1;
  280. transition: opacity 0.3s ease;
  281. }
  282. .modal-overlay.hidden {
  283. opacity: 0;
  284. pointer-events: none;
  285. }
  286. .modal-content {
  287. background: var(--panel-bg);
  288. border: 1px solid var(--border-color);
  289. border-radius: 16px;
  290. padding: 30px;
  291. width: 350px;
  292. position: relative;
  293. box-shadow: 0 10px 30px rgba(0,0,0,0.5);
  294. transform: translateY(0);
  295. transition: transform 0.3s ease;
  296. }
  297. .modal-overlay.hidden .modal-content {
  298. transform: translateY(-20px);
  299. }
  300. .close-modal {
  301. position: absolute;
  302. top: 15px;
  303. right: 20px;
  304. background: none;
  305. border: none;
  306. color: var(--text-muted);
  307. font-size: 1.5rem;
  308. cursor: pointer;
  309. }
  310. .close-modal:hover {
  311. color: var(--text-main);
  312. }
  313. .modal-content h2 {
  314. margin-top: 0;
  315. margin-bottom: 20px;
  316. font-size: 1.3rem;
  317. text-align: center;
  318. }
  319. .input-group {
  320. margin-bottom: 15px;
  321. }
  322. .input-group label {
  323. display: block;
  324. margin-bottom: 5px;
  325. font-size: 0.85rem;
  326. color: var(--text-muted);
  327. }
  328. .input-group input {
  329. width: 100%;
  330. padding: 10px;
  331. background: rgba(0, 0, 0, 0.2);
  332. border: 1px solid var(--border-color);
  333. border-radius: 8px;
  334. color: var(--text-main);
  335. font-size: 0.95rem;
  336. outline: none;
  337. transition: border-color 0.2s;
  338. }
  339. .input-group input:focus {
  340. border-color: var(--primary-color);
  341. }
  342. .error-text {
  343. color: #f85149;
  344. font-size: 0.85rem;
  345. margin-bottom: 10px;
  346. text-align: center;
  347. min-height: 18px;
  348. }
  349. .success-text {
  350. color: #3fb950;
  351. font-size: 0.85rem;
  352. margin-bottom: 10px;
  353. text-align: center;
  354. min-height: 18px;
  355. }
  356. .primary-btn {
  357. width: 100%;
  358. padding: 10px;
  359. background: var(--primary-gradient);
  360. border: none;
  361. border-radius: 8px;
  362. color: #fff;
  363. font-size: 1rem;
  364. cursor: pointer;
  365. transition: opacity 0.2s;
  366. }
  367. .primary-btn:hover {
  368. opacity: 0.9;
  369. }
  370. /* Authentication Screen Gateway specific styles */
  371. .auth-container {
  372. width: 100%;
  373. max-width: 400px;
  374. background: var(--panel-bg);
  375. backdrop-filter: var(--glass-blur);
  376. -webkit-backdrop-filter: var(--glass-blur);
  377. border: 1px solid var(--border-color);
  378. border-radius: 20px;
  379. padding: 40px;
  380. box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
  381. transition: opacity 0.5s ease, transform 0.5s ease;
  382. }
  383. .auth-header {
  384. text-align: center;
  385. margin-bottom: 30px;
  386. }
  387. .auth-header h2 {
  388. font-size: 1.5rem;
  389. color: #f0f6fc;
  390. margin-bottom: 8px;
  391. }
  392. .auth-header p {
  393. font-size: 0.9rem;
  394. color: var(--text-muted);
  395. }
  396. .auth-toggle {
  397. text-align: center;
  398. font-size: 0.85rem;
  399. color: var(--text-muted);
  400. margin-top: 20px;
  401. }
  402. .auth-toggle a {
  403. color: var(--primary-color);
  404. text-decoration: none;
  405. font-weight: 500;
  406. transition: color 0.2s;
  407. }
  408. .auth-toggle a:hover {
  409. color: #3fb950;
  410. text-decoration: underline;
  411. }
  412. /* Animations for transitioning out the auth screen */
  413. .fade-out {
  414. opacity: 0;
  415. transform: scale(0.95);
  416. pointer-events: none;
  417. }
  418. .fade-in {
  419. opacity: 1;
  420. transform: scale(1);
  421. }
  422. /* --------------------------------- */
  423. /* Food Search Component Styles */
  424. /* --------------------------------- */
  425. .search-module {
  426. padding: 10px 24px;
  427. background: rgba(22, 27, 34, 0.4);
  428. border-bottom: 1px solid var(--border-color);
  429. position: relative;
  430. z-index: 10;
  431. }
  432. .search-input-wrapper {
  433. position: relative;
  434. display: flex;
  435. align-items: center;
  436. background: rgba(13, 17, 23, 0.8);
  437. border: 1px solid var(--border-color);
  438. border-radius: 12px;
  439. padding: 8px 16px;
  440. transition: all 0.3s ease;
  441. box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
  442. }
  443. .search-input-wrapper:focus-within {
  444. border-color: rgba(46, 160, 67, 0.6);
  445. box-shadow: 0 0 0 3px rgba(46, 160, 67, 0.15), inset 0 2px 4px rgba(0,0,0,0.1);
  446. }
  447. .search-icon {
  448. color: var(--text-muted);
  449. margin-right: 12px;
  450. }
  451. #food-search-input {
  452. flex: 1;
  453. background: transparent;
  454. border: none;
  455. color: var(--text-main);
  456. font-size: 0.95rem;
  457. outline: none;
  458. font-family: inherit;
  459. width: 100%;
  460. }
  461. #clear-search-btn {
  462. background: transparent;
  463. border: none;
  464. color: var(--text-muted);
  465. cursor: pointer;
  466. border-radius: 50%;
  467. padding: 4px;
  468. display: flex;
  469. align-items: center;
  470. justify-content: center;
  471. transition: all 0.2s;
  472. }
  473. #clear-search-btn:hover {
  474. background: rgba(255, 255, 255, 0.1);
  475. color: #f85149;
  476. }
  477. .search-results-dropdown {
  478. position: absolute;
  479. top: 100%;
  480. left: 24px;
  481. right: 24px;
  482. margin-top: 8px;
  483. background: rgba(22, 27, 34, 0.85);
  484. backdrop-filter: blur(20px);
  485. -webkit-backdrop-filter: blur(20px);
  486. border: 1px solid var(--border-color);
  487. border-radius: 12px;
  488. box-shadow: 0 15px 35px rgba(0,0,0,0.4);
  489. max-height: 350px;
  490. overflow-y: auto;
  491. z-index: 100;
  492. opacity: 0;
  493. transform: translateY(-10px);
  494. animation: dropdownFadeIn 0.2s forwards;
  495. }
  496. @keyframes dropdownFadeIn {
  497. to { opacity: 1; transform: translateY(0); }
  498. }
  499. .search-results-dropdown::-webkit-scrollbar {
  500. width: 6px;
  501. }
  502. .search-results-dropdown::-webkit-scrollbar-thumb {
  503. background: rgba(255,255,255,0.2);
  504. border-radius: 10px;
  505. }
  506. .food-item {
  507. padding: 14px 18px;
  508. border-bottom: 1px solid rgba(255,255,255,0.05);
  509. cursor: pointer;
  510. transition: background 0.2s, padding-left 0.2s;
  511. }
  512. .food-item:last-child {
  513. border-bottom: none;
  514. }
  515. .food-item:hover {
  516. background: rgba(255,255,255,0.05);
  517. padding-left: 22px;
  518. }
  519. .food-item-header {
  520. display: flex;
  521. justify-content: space-between;
  522. align-items: center;
  523. margin-bottom: 8px;
  524. }
  525. .food-name {
  526. font-weight: 600;
  527. color: #e6edf3;
  528. font-size: 1rem;
  529. }
  530. .food-badge {
  531. background: rgba(46, 160, 67, 0.15);
  532. color: #3fb950;
  533. border: 1px solid rgba(46, 160, 67, 0.3);
  534. padding: 2px 8px;
  535. border-radius: 12px;
  536. font-size: 0.7rem;
  537. font-weight: 600;
  538. text-transform: uppercase;
  539. letter-spacing: 0.5px;
  540. }
  541. .food-macros {
  542. display: flex;
  543. gap: 15px;
  544. font-size: 0.8rem;
  545. color: var(--text-muted);
  546. }
  547. .macro-tag span {
  548. color: #c9d1d9;
  549. font-weight: 500;
  550. }
  551. /* --- Expandable Details (Task #40) --- */
  552. .food-item-footer {
  553. display: flex;
  554. justify-content: space-between;
  555. align-items: center;
  556. margin-top: 10px;
  557. }
  558. .details-btn {
  559. background: none;
  560. border: 1px solid var(--border);
  561. border-radius: 4px;
  562. color: var(--primary);
  563. font-size: 0.75rem;
  564. padding: 2px 8px;
  565. cursor: pointer;
  566. transition: all 0.2s;
  567. }
  568. .details-btn:hover {
  569. background: rgba(255, 255, 255, 0.05);
  570. border-color: var(--primary);
  571. }
  572. .details-panel {
  573. max-height: 0;
  574. overflow: hidden;
  575. transition: max-height 0.3s ease-out, margin-top 0.3s;
  576. }
  577. .details-panel.expanded {
  578. max-height: 500px; /* Large enough for content */
  579. margin-top: 12px;
  580. border-top: 1px solid rgba(255, 255, 255, 0.05);
  581. padding-top: 12px;
  582. }
  583. .nutrient-section {
  584. margin-bottom: 12px;
  585. }
  586. .nutrient-section-title {
  587. font-size: 0.7rem;
  588. text-transform: uppercase;
  589. letter-spacing: 0.05em;
  590. color: var(--text-muted);
  591. margin-bottom: 6px;
  592. font-weight: 700;
  593. }
  594. .nutrient-grid {
  595. display: grid;
  596. grid-template-columns: repeat(2, 1fr);
  597. gap: 8px;
  598. }
  599. .nutrient-item {
  600. display: flex;
  601. justify-content: space-between;
  602. font-size: 0.8rem;
  603. padding: 4px 0;
  604. }
  605. .nutrient-label {
  606. color: var(--text-muted);
  607. }
  608. .nutrient-value {
  609. font-weight: 500;
  610. color: var(--text);
  611. }
  612. .search-loading, .search-empty {
  613. padding: 20px;
  614. text-align: center;
  615. color: var(--text-muted);
  616. font-size: 0.9rem;
  617. background: transparent;
  618. }
  619. /* Mobile Responsiveness */
  620. @media (max-width: 600px) {
  621. body {
  622. padding: 0;
  623. }
  624. .app-container {
  625. height: 100vh;
  626. border-radius: 0;
  627. border: none;
  628. }
  629. .chat-header {
  630. flex-direction: column;
  631. align-items: flex-start;
  632. gap: 10px;
  633. }
  634. .actions {
  635. width: 100%;
  636. justify-content: space-between;
  637. }
  638. .search-module {
  639. padding: 10px 12px;
  640. }
  641. .search-results-dropdown {
  642. left: 12px;
  643. right: 12px;
  644. }
  645. .message {
  646. max-width: 95%;
  647. }
  648. }
  649. /* =============================================
  650. Macro Dashboard (US-07 Task #38)
  651. ============================================= */
  652. .macro-dashboard {
  653. display: flex;
  654. gap: 12px;
  655. padding: 12px 20px;
  656. background: rgba(255, 255, 255, 0.02);
  657. border-bottom: 1px solid var(--border);
  658. flex-wrap: wrap;
  659. animation: fadeIn 0.4s ease;
  660. }
  661. .macro-card {
  662. flex: 1;
  663. min-width: 100px;
  664. background: rgba(255, 255, 255, 0.05);
  665. border: 1px solid var(--border);
  666. border-radius: 12px;
  667. padding: 12px 16px;
  668. text-align: center;
  669. backdrop-filter: blur(6px);
  670. -webkit-backdrop-filter: blur(6px);
  671. transition: transform 0.2s ease, border-color 0.2s ease;
  672. }
  673. .macro-card:hover {
  674. transform: translateY(-2px);
  675. border-color: rgba(255, 255, 255, 0.25);
  676. }
  677. .macro-label {
  678. font-size: 0.75rem;
  679. color: var(--text-muted);
  680. text-transform: uppercase;
  681. letter-spacing: 1.2px;
  682. margin-bottom: 6px;
  683. font-weight: 600;
  684. }
  685. .macro-value {
  686. font-size: 1.4rem;
  687. font-weight: 700;
  688. transition: opacity 0.3s ease;
  689. }
  690. /* Color-coded per macro type */
  691. #macro-calories .macro-value, #macro-calories { --macro-color: #facc15; }
  692. #macro-protein .macro-value, #macro-protein { --macro-color: #ef4444; }
  693. #macro-carbs .macro-value, #macro-carbs { --macro-color: #3b82f6; }
  694. #macro-fat .macro-value, #macro-fat { --macro-color: #22c55e; }
  695. #macro-calories .macro-value { color: #facc15; }
  696. #macro-protein .macro-value { color: #ef4444; }
  697. #macro-carbs .macro-value { color: #3b82f6; }
  698. #macro-fat .macro-value { color: #22c55e; }
  699. #macro-calories { border-color: rgba(250, 204, 21, 0.2); }
  700. #macro-protein { border-color: rgba(239, 68, 68, 0.2); }
  701. #macro-carbs { border-color: rgba(59, 130, 246, 0.2); }
  702. #macro-fat { border-color: rgba(34, 197, 94, 0.2); }
  703. @media (max-width: 768px) {
  704. .macro-dashboard {
  705. gap: 8px;
  706. padding: 10px 12px;
  707. }
  708. .macro-card {
  709. min-width: 70px;
  710. padding: 10px 10px;
  711. }
  712. .macro-value {
  713. font-size: 1.1rem;
  714. }
  715. }
  716. /* =============================================
  717. Meal Builder (US-10 Task #46)
  718. ============================================= */
  719. .meal-builder-tray {
  720. margin: 0 20px;
  721. background: rgba(255, 255, 255, 0.03);
  722. border: 1px solid var(--border);
  723. border-radius: 12px;
  724. overflow: hidden;
  725. backdrop-filter: blur(10px);
  726. -webkit-backdrop-filter: blur(10px);
  727. transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  728. margin-bottom: 12px;
  729. }
  730. .meal-builder-header {
  731. display: flex;
  732. justify-content: space-between;
  733. align-items: center;
  734. padding: 10px 16px;
  735. background: rgba(255, 255, 255, 0.05);
  736. cursor: pointer;
  737. }
  738. .tray-title {
  739. display: flex;
  740. align-items: center;
  741. gap: 10px;
  742. }
  743. .tray-title h3 {
  744. font-size: 0.95rem;
  745. font-weight: 600;
  746. margin: 0;
  747. }
  748. .tray-title .item-count {
  749. font-size: 0.75rem;
  750. color: var(--text-muted);
  751. background: rgba(255, 255, 255, 0.1);
  752. padding: 2px 8px;
  753. border-radius: 10px;
  754. }
  755. .meal-content {
  756. max-height: 500px;
  757. overflow: hidden;
  758. transition: max-height 0.3s ease-out, opacity 0.3s ease;
  759. opacity: 1;
  760. }
  761. .meal-content.collapsed {
  762. max-height: 0;
  763. opacity: 0;
  764. }
  765. .meal-items-list {
  766. padding: 12px;
  767. max-height: 250px;
  768. overflow-y: auto;
  769. display: flex;
  770. flex-direction: column;
  771. gap: 8px;
  772. }
  773. /* Custom Scrollbar for Meal List */
  774. .meal-items-list::-webkit-scrollbar {
  775. width: 4px;
  776. }
  777. .meal-items-list::-webkit-scrollbar-thumb {
  778. background: rgba(255, 255, 255, 0.1);
  779. border-radius: 4px;
  780. }
  781. .meal-item-row {
  782. display: flex;
  783. align-items: center;
  784. gap: 12px;
  785. padding: 8px 12px;
  786. background: rgba(255, 255, 255, 0.05);
  787. border: 1px solid rgba(255, 255, 255, 0.05);
  788. border-radius: 8px;
  789. animation: slideInLeft 0.3s ease-out;
  790. }
  791. .meal-item-name {
  792. flex: 1;
  793. font-size: 0.9rem;
  794. white-space: nowrap;
  795. overflow: hidden;
  796. text-overflow: ellipsis;
  797. }
  798. .meal-item-controls {
  799. display: flex;
  800. align-items: center;
  801. gap: 8px;
  802. }
  803. .weight-input-wrapper {
  804. display: flex;
  805. align-items: center;
  806. background: rgba(0, 0, 0, 0.25);
  807. border-radius: 8px;
  808. padding: 4px 10px;
  809. border: 1px solid var(--border);
  810. transition: border-color 0.2s, box-shadow 0.2s;
  811. }
  812. .weight-input-wrapper:focus-within {
  813. border-color: var(--primary);
  814. box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
  815. }
  816. .weight-input-wrapper input {
  817. background: transparent;
  818. border: none;
  819. color: var(--text);
  820. width: 65px;
  821. font-size: 0.95rem;
  822. text-align: right;
  823. padding: 2px;
  824. outline: none;
  825. font-weight: 500;
  826. }
  827. /* Hide Spinners (Arrows) for cleaner look */
  828. .weight-input-wrapper input::-webkit-outer-spin-button,
  829. .weight-input-wrapper input::-webkit-inner-spin-button {
  830. -webkit-appearance: none;
  831. margin: 0;
  832. }
  833. .weight-input-wrapper input[type=number] {
  834. -moz-appearance: textfield;
  835. }
  836. .weight-unit {
  837. font-size: 0.75rem;
  838. color: var(--text-muted);
  839. margin-left: 2px;
  840. }
  841. .remove-item-btn {
  842. background: transparent;
  843. border: none;
  844. color: #ef4444;
  845. cursor: pointer;
  846. padding: 4px;
  847. border-radius: 4px;
  848. display: flex;
  849. align-items: center;
  850. justify-content: center;
  851. opacity: 0.7;
  852. transition: opacity 0.2s, background 0.2s;
  853. }
  854. .remove-item-btn:hover {
  855. opacity: 1;
  856. background: rgba(239, 68, 68, 0.1);
  857. }
  858. .empty-meal-msg {
  859. text-align: center;
  860. padding: 20px;
  861. font-size: 0.85rem;
  862. color: var(--text-muted);
  863. font-style: italic;
  864. }
  865. #toggle-meal-btn {
  866. transition: transform 0.3s ease;
  867. }
  868. .meal-content:not(.collapsed) + .meal-builder-header #toggle-meal-btn {
  869. transform: rotate(180deg);
  870. }
  871. /* Add-to-meal button in search results */
  872. .add-meal-btn {
  873. background: var(--primary);
  874. color: white;
  875. border: none;
  876. border-radius: 6px;
  877. padding: 4px 10px;
  878. font-size: 0.8rem;
  879. cursor: pointer;
  880. transition: background 0.2s, transform 0.1s;
  881. font-weight: 600;
  882. }
  883. .add-meal-btn:hover {
  884. background: var(--primary-hover);
  885. transform: scale(1.05);
  886. }
  887. .add-meal-btn:active {
  888. transform: scale(0.95);
  889. }
  890. .food-item-footer {
  891. display: flex;
  892. gap: 8px;
  893. margin-top: 10px;
  894. }
  895. @keyframes slideInLeft {
  896. from { opacity: 0; transform: translateX(-10px); }
  897. to { opacity: 1; transform: translateX(0); }
  898. }
  899. @media (max-width: 600px) {
  900. .meal-builder-tray {
  901. margin: 0 12px 10px 12px;
  902. }
  903. .meal-item-name {
  904. font-size: 0.8rem;
  905. }
  906. }
  907. .meal-builder-footer {
  908. padding: 12px;
  909. border-top: 1px solid rgba(255, 255, 255, 0.05);
  910. display: flex;
  911. justify-content: center;
  912. background: rgba(255, 255, 255, 0.02);
  913. }
  914. .primary-btn-sm {
  915. background: var(--primary);
  916. color: white;
  917. border: none;
  918. border-radius: 8px;
  919. padding: 8px 16px;
  920. font-size: 0.85rem;
  921. font-weight: 600;
  922. cursor: pointer;
  923. transition: all 0.2s ease;
  924. width: 100%;
  925. }
  926. .primary-btn-sm:hover {
  927. background: var(--primary-hover);
  928. transform: translateY(-1px);
  929. box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
  930. }
  931. .primary-btn-sm:active {
  932. transform: translateY(0);
  933. }
  934. /* --- Meal Totals Banner --- */
  935. .meal-totals-banner {
  936. width: 100%;
  937. margin-bottom: 12px;
  938. background: rgba(15, 23, 42, 0.4);
  939. border: 1px solid rgba(255, 255, 255, 0.1);
  940. border-radius: 10px;
  941. padding: 12px;
  942. }
  943. .totals-header {
  944. display: flex;
  945. justify-content: space-between;
  946. align-items: center;
  947. margin-bottom: 10px;
  948. padding-bottom: 6px;
  949. border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  950. }
  951. .totals-title {
  952. font-size: 0.85rem;
  953. font-weight: 600;
  954. color: var(--text-muted);
  955. text-transform: uppercase;
  956. letter-spacing: 0.5px;
  957. }
  958. .totals-weight {
  959. font-size: 0.85rem;
  960. font-weight: 500;
  961. color: var(--text-muted);
  962. }
  963. .totals-grid {
  964. display: grid;
  965. grid-template-columns: repeat(4, 1fr);
  966. gap: 8px;
  967. }
  968. .total-card {
  969. display: flex;
  970. flex-direction: column;
  971. align-items: center;
  972. justify-content: center;
  973. background: rgba(255, 255, 255, 0.03);
  974. border-radius: 6px;
  975. padding: 8px 4px;
  976. transition: background 0.3s;
  977. }
  978. .total-val {
  979. font-size: 1.05rem;
  980. font-weight: 700;
  981. color: var(--text-light);
  982. }
  983. .total-lbl {
  984. font-size: 0.7rem;
  985. color: var(--text-muted);
  986. margin-top: 2px;
  987. }
  988. .protein-highlight .total-val {
  989. color: var(--primary);
  990. }
  991. .protein-highlight {
  992. background: rgba(59, 130, 246, 0.05);
  993. border: 1px solid rgba(59, 130, 246, 0.1);
  994. }
  995. .meal-totals-banner.has-error {
  996. border-color: rgba(239, 68, 68, 0.5);
  997. background: rgba(127, 29, 29, 0.2);
  998. animation: errorPulse 2s infinite;
  999. }
  1000. @keyframes errorPulse {
  1001. 0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }
  1002. 70% { box-shadow: 0 0 0 10px rgba(239, 68, 68, 0); }
  1003. 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
  1004. }
  1005. /* =============================================
  1006. Sprint 8: Saved Meals & Dashboard UI
  1007. ============================================= */
  1008. .secondary-btn-sm {
  1009. background: rgba(255, 255, 255, 0.05);
  1010. color: var(--text-main);
  1011. border: 1px solid var(--border-color);
  1012. border-radius: 8px;
  1013. padding: 8px 12px;
  1014. font-size: 0.85rem;
  1015. font-weight: 500;
  1016. cursor: pointer;
  1017. transition: all 0.2s ease;
  1018. display: flex;
  1019. align-items: center;
  1020. gap: 6px;
  1021. white-space: nowrap;
  1022. }
  1023. .secondary-btn-sm:hover {
  1024. background: rgba(255, 255, 255, 0.1);
  1025. border-color: var(--text-muted);
  1026. }
  1027. .modal {
  1028. position: fixed;
  1029. top: 0; left: 0; width: 100%; height: 100%;
  1030. background: rgba(0, 0, 0, 0.75);
  1031. backdrop-filter: blur(10px);
  1032. -webkit-backdrop-filter: blur(10px);
  1033. display: flex;
  1034. justify-content: center;
  1035. align-items: center;
  1036. z-index: 2000;
  1037. }
  1038. .modal-content {
  1039. background: #161b22;
  1040. border: 1px solid var(--border-color);
  1041. border-radius: 20px;
  1042. width: 90%;
  1043. max-width: 420px;
  1044. box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.6);
  1045. animation: modalSlideUp 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  1046. overflow: hidden;
  1047. }
  1048. @keyframes modalSlideUp {
  1049. from { transform: translateY(30px); opacity: 0; }
  1050. to { transform: translateY(0); opacity: 1; }
  1051. }
  1052. .modal-header {
  1053. padding: 20px 24px;
  1054. border-bottom: 1px solid var(--border-color);
  1055. display: flex;
  1056. justify-content: space-between;
  1057. align-items: center;
  1058. background: rgba(255, 255, 255, 0.02);
  1059. }
  1060. .modal-header h3 {
  1061. font-size: 1.15rem;
  1062. font-weight: 600;
  1063. margin: 0;
  1064. color: #f0f6fc;
  1065. }
  1066. .close-btn {
  1067. background: none;
  1068. border: none;
  1069. color: var(--text-muted);
  1070. font-size: 1.8rem;
  1071. cursor: pointer;
  1072. line-height: 1;
  1073. padding: 0;
  1074. transition: color 0.2s;
  1075. }
  1076. .close-btn:hover {
  1077. color: #ef4444;
  1078. }
  1079. .modal-body {
  1080. padding: 24px;
  1081. }
  1082. .modal-body p {
  1083. font-size: 0.95rem;
  1084. color: var(--text-muted);
  1085. line-height: 1.5;
  1086. margin-bottom: 16px;
  1087. }
  1088. .modal-footer {
  1089. padding: 20px 24px;
  1090. border-top: 1px solid var(--border-color);
  1091. display: flex;
  1092. gap: 12px;
  1093. justify-content: flex-end;
  1094. background: rgba(255, 255, 255, 0.02);
  1095. }
  1096. .secondary-btn {
  1097. background: transparent;
  1098. border: 1px solid var(--border-color);
  1099. color: var(--text-main);
  1100. padding: 10px 20px;
  1101. border-radius: 10px;
  1102. font-size: 0.95rem;
  1103. font-weight: 500;
  1104. cursor: pointer;
  1105. transition: all 0.2s;
  1106. }
  1107. .secondary-btn:hover {
  1108. background: rgba(255, 255, 255, 0.05);
  1109. border-color: var(--text-muted);
  1110. }
  1111. /* --- Dashboard Overlay --- */
  1112. .dashboard-overlay {
  1113. position: absolute;
  1114. top: 0; left: 0; right: 0; bottom: 0;
  1115. background: rgba(13, 17, 23, 0.95);
  1116. backdrop-filter: blur(20px);
  1117. -webkit-backdrop-filter: blur(20px);
  1118. z-index: 50;
  1119. display: flex;
  1120. flex-direction: column;
  1121. animation: fadeIn 0.3s ease;
  1122. }
  1123. .dashboard-content {
  1124. height: 100%;
  1125. display: flex;
  1126. flex-direction: column;
  1127. }
  1128. .dashboard-header {
  1129. padding: 24px;
  1130. border-bottom: 1px solid var(--border-color);
  1131. display: flex;
  1132. justify-content: space-between;
  1133. align-items: center;
  1134. }
  1135. .dashboard-title-group {
  1136. display: flex;
  1137. align-items: center;
  1138. gap: 12px;
  1139. }
  1140. .dashboard-title-group h2 {
  1141. font-size: 1.25rem;
  1142. color: #f0f6fc;
  1143. }
  1144. .dashboard-body {
  1145. flex: 1;
  1146. overflow-y: auto;
  1147. padding: 24px;
  1148. }
  1149. .dashboard-grid {
  1150. display: grid;
  1151. grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  1152. gap: 20px;
  1153. }
  1154. .empty-meal-msg {
  1155. grid-column: 1 / -1;
  1156. text-align: center;
  1157. padding: 60px 20px;
  1158. color: var(--text-muted);
  1159. font-size: 1.1rem;
  1160. border: 2px dashed var(--border-color);
  1161. border-radius: 20px;
  1162. }
  1163. /* --- Meal Cards (#59) --- */
  1164. @keyframes cardSlideIn {
  1165. from { opacity: 0; transform: translateY(20px); }
  1166. to { opacity: 1; transform: translateY(0); }
  1167. }
  1168. .meal-card {
  1169. background: rgba(22, 27, 34, 0.6);
  1170. border: 1px solid rgba(48, 54, 61, 0.8);
  1171. border-radius: 18px;
  1172. padding: 20px;
  1173. display: flex;
  1174. flex-direction: column;
  1175. gap: 16px;
  1176. backdrop-filter: blur(12px);
  1177. -webkit-backdrop-filter: blur(12px);
  1178. transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
  1179. border-color 0.3s ease,
  1180. box-shadow 0.3s ease;
  1181. animation: cardSlideIn 0.4s ease both;
  1182. cursor: default;
  1183. }
  1184. .meal-card:hover {
  1185. transform: translateY(-6px);
  1186. border-color: rgba(88, 166, 255, 0.4);
  1187. box-shadow: 0 20px 40px -12px rgba(0, 0, 0, 0.5),
  1188. 0 0 0 1px rgba(88, 166, 255, 0.1);
  1189. }
  1190. .meal-card-header {
  1191. display: flex;
  1192. justify-content: space-between;
  1193. align-items: flex-start;
  1194. gap: 10px;
  1195. }
  1196. .meal-card-name {
  1197. font-size: 1.05rem;
  1198. font-weight: 700;
  1199. color: #f0f6fc;
  1200. line-height: 1.3;
  1201. flex: 1;
  1202. }
  1203. .meal-card-date {
  1204. font-size: 0.72rem;
  1205. color: var(--text-muted);
  1206. white-space: nowrap;
  1207. padding-top: 3px;
  1208. }
  1209. .meal-card-macros {
  1210. display: grid;
  1211. grid-template-columns: repeat(2, 1fr);
  1212. gap: 8px;
  1213. }
  1214. .card-macro {
  1215. display: flex;
  1216. flex-direction: column;
  1217. align-items: center;
  1218. justify-content: center;
  1219. padding: 10px 8px;
  1220. border-radius: 12px;
  1221. border: 1px solid transparent;
  1222. gap: 2px;
  1223. }
  1224. .card-macro-val {
  1225. font-size: 1.1rem;
  1226. font-weight: 700;
  1227. line-height: 1;
  1228. }
  1229. .card-macro-lbl {
  1230. font-size: 0.65rem;
  1231. font-weight: 500;
  1232. text-transform: uppercase;
  1233. letter-spacing: 0.05em;
  1234. opacity: 0.8;
  1235. }
  1236. /* Color-coded macro badges */
  1237. .card-macro.kcal {
  1238. background: rgba(251, 146, 60, 0.12);
  1239. border-color: rgba(251, 146, 60, 0.25);
  1240. color: #fb923c;
  1241. }
  1242. .card-macro.protein {
  1243. background: rgba(59, 130, 246, 0.12);
  1244. border-color: rgba(59, 130, 246, 0.25);
  1245. color: #60a5fa;
  1246. }
  1247. .card-macro.carbs {
  1248. background: rgba(34, 197, 94, 0.12);
  1249. border-color: rgba(34, 197, 94, 0.25);
  1250. color: #4ade80;
  1251. }
  1252. .card-macro.fat {
  1253. background: rgba(168, 85, 247, 0.12);
  1254. border-color: rgba(168, 85, 247, 0.25);
  1255. color: #c084fc;
  1256. }
  1257. /* --- Meal Card Actions (#61) --- */
  1258. .meal-card-actions {
  1259. display: flex;
  1260. justify-content: flex-end;
  1261. gap: 10px;
  1262. margin-top: auto;
  1263. padding-top: 10px;
  1264. border-top: 1px solid rgba(255, 255, 255, 0.05);
  1265. }
  1266. .edit-meal-btn, .delete-meal-btn {
  1267. background: rgba(255, 255, 255, 0.05);
  1268. border: 1px solid rgba(255, 255, 255, 0.1);
  1269. color: var(--text-muted);
  1270. width: 32px;
  1271. height: 32px;
  1272. border-radius: 8px;
  1273. display: flex;
  1274. align-items: center;
  1275. justify-content: center;
  1276. cursor: pointer;
  1277. transition: all 0.2s;
  1278. }
  1279. .edit-meal-btn:hover {
  1280. background: rgba(59, 130, 246, 0.15);
  1281. border-color: rgba(59, 130, 246, 0.3);
  1282. color: #60a5fa;
  1283. }
  1284. .delete-meal-btn:hover {
  1285. background: rgba(239, 68, 68, 0.15);
  1286. border-color: rgba(239, 68, 68, 0.3);
  1287. color: #f87171;
  1288. }