393393 flex-wrap : wrap;
394394 }
395395
396+ .serving-time-container {
397+ margin-top : 16px ;
398+ }
399+
400+ .serving-time-btn {
401+ background : transparent;
402+ border : 2px solid rgba (255 , 255 , 255 , 0.5 );
403+ color : # fff ;
404+ padding : 10px 24px ;
405+ border-radius : 25px ;
406+ cursor : pointer;
407+ font-size : 0.9rem ;
408+ transition : border-color 0.2s , background 0.2s ;
409+ }
410+
411+ .serving-time-btn : hover {
412+ border-color : # fff ;
413+ background : rgba (255 , 255 , 255 , 0.1 );
414+ }
415+
416+ .serving-time-input-wrapper {
417+ display : flex;
418+ align-items : center;
419+ justify-content : center;
420+ gap : 12px ;
421+ background : rgba (0 , 0 , 0 , 0.2 );
422+ padding : 12px 16px ;
423+ border-radius : 12px ;
424+ }
425+
426+ .serving-time-input-wrapper label {
427+ font-size : 0.9rem ;
428+ opacity : 0.9 ;
429+ }
430+
431+ .serving-time-input-wrapper input [type = "time" ] {
432+ padding : 8px 12px ;
433+ border : 2px solid rgba (255 , 255 , 255 , 0.3 );
434+ border-radius : 8px ;
435+ background : rgba (255 , 255 , 255 , 0.1 );
436+ color : # fff ;
437+ font-size : 1.1rem ;
438+ font-weight : 600 ;
439+ }
440+
441+ .serving-time-input-wrapper input [type = "time" ]: focus {
442+ outline : none;
443+ border-color : # fff ;
444+ }
445+
446+ .serving-time-set {
447+ background : linear-gradient (135deg , # 00b894 0% , # 00cec9 100% );
448+ border : none;
449+ color : # fff ;
450+ padding : 8px 16px ;
451+ border-radius : 6px ;
452+ cursor : pointer;
453+ font-size : 0.9rem ;
454+ font-weight : 600 ;
455+ transition : transform 0.2s , box-shadow 0.2s ;
456+ }
457+
458+ .serving-time-set : hover {
459+ transform : scale (1.05 );
460+ box-shadow : 0 2px 10px rgba (0 , 184 , 148 , 0.3 );
461+ }
462+
463+ .serving-time-cancel {
464+ background : transparent;
465+ border : none;
466+ color : # fff ;
467+ font-size : 1.4rem ;
468+ cursor : pointer;
469+ opacity : 0.6 ;
470+ padding : 4px 8px ;
471+ }
472+
473+ .serving-time-cancel : hover {
474+ opacity : 1 ;
475+ }
476+
477+ .elapsed-label .countdown {
478+ color : # f39c12 ;
479+ }
480+
396481 .current-step {
397482 background : linear-gradient (135deg , # 00b894 0% , # 00cec9 100% );
398483 border-radius : 16px ;
@@ -680,9 +765,18 @@ <h1 id="recipeName">Cooking Timer</h1>
680765
681766 < div class ="start-section " id ="startSection ">
682767 < button class ="start-btn " id ="startBtn " onclick ="startCooking() "> START COOKING</ button >
768+ < div class ="serving-time-container " id ="servingTimeContainer ">
769+ < button class ="serving-time-btn " id ="servingTimeBtn " onclick ="showServingTimeInput() "> Set Serving Time</ button >
770+ < div class ="serving-time-input-wrapper hidden " id ="servingTimeInputWrapper ">
771+ < label for ="servingTimeInput "> Serve at:</ label >
772+ < input type ="time " id ="servingTimeInput ">
773+ < button class ="serving-time-set " onclick ="onServingTimeSelected() "> Set</ button >
774+ < button class ="serving-time-cancel " onclick ="hideServingTimeInput() "> ×</ button >
775+ </ div >
776+ </ div >
683777 < div class ="hidden " id ="timerDisplay ">
684778 < div class ="elapsed-time " id ="elapsedTime "> 00:00</ div >
685- < div class ="elapsed-label "> Elapsed Time</ div >
779+ < div class ="elapsed-label " id =" elapsedLabel " > Elapsed Time</ div >
686780 < div class ="timer-controls ">
687781 < button class ="reset-btn " onclick ="resetTimer() "> Reset Timer</ button >
688782 </ div >
@@ -1301,6 +1395,9 @@ <h2>Full Timeline</h2>
13011395
13021396 // Reset timer display
13031397 document . getElementById ( 'startBtn' ) . classList . remove ( 'hidden' ) ;
1398+ document . getElementById ( 'servingTimeContainer' ) . classList . remove ( 'hidden' ) ;
1399+ document . getElementById ( 'servingTimeBtn' ) . classList . remove ( 'hidden' ) ;
1400+ document . getElementById ( 'servingTimeInputWrapper' ) . classList . add ( 'hidden' ) ;
13041401 document . getElementById ( 'timerDisplay' ) . classList . add ( 'hidden' ) ;
13051402 document . getElementById ( 'startSection' ) . classList . remove ( 'running' ) ;
13061403 document . getElementById ( 'currentStepSection' ) . classList . add ( 'hidden' ) ;
@@ -1331,8 +1428,58 @@ <h2>Full Timeline</h2>
13311428 startTimer ( ) ;
13321429 }
13331430
1431+ function showServingTimeInput ( ) {
1432+ document . getElementById ( 'servingTimeBtn' ) . classList . add ( 'hidden' ) ;
1433+ document . getElementById ( 'servingTimeInputWrapper' ) . classList . remove ( 'hidden' ) ;
1434+
1435+ // Set default value to a reasonable time (1 hour from now, rounded to nearest 5 min)
1436+ const now = new Date ( ) ;
1437+ const steps = isMultiRecipeMode ? mergedSteps : currentRecipe . steps ;
1438+ const lastStepTime = steps [ steps . length - 1 ] . time ;
1439+ const suggestedServing = new Date ( now . getTime ( ) + lastStepTime * 1000 + 5 * 60 * 1000 ) ;
1440+
1441+ // Round to nearest 5 minutes
1442+ suggestedServing . setMinutes ( Math . ceil ( suggestedServing . getMinutes ( ) / 5 ) * 5 ) ;
1443+ suggestedServing . setSeconds ( 0 ) ;
1444+
1445+ const hours = suggestedServing . getHours ( ) . toString ( ) . padStart ( 2 , '0' ) ;
1446+ const mins = suggestedServing . getMinutes ( ) . toString ( ) . padStart ( 2 , '0' ) ;
1447+ document . getElementById ( 'servingTimeInput' ) . value = `${ hours } :${ mins } ` ;
1448+ }
1449+
1450+ function hideServingTimeInput ( ) {
1451+ document . getElementById ( 'servingTimeBtn' ) . classList . remove ( 'hidden' ) ;
1452+ document . getElementById ( 'servingTimeInputWrapper' ) . classList . add ( 'hidden' ) ;
1453+ }
1454+
1455+ function onServingTimeSelected ( ) {
1456+ const timeInput = document . getElementById ( 'servingTimeInput' ) . value ;
1457+ if ( ! timeInput ) return ;
1458+
1459+ const [ hours , minutes ] = timeInput . split ( ':' ) . map ( Number ) ;
1460+ const steps = isMultiRecipeMode ? mergedSteps : currentRecipe . steps ;
1461+ const lastStepTime = steps [ steps . length - 1 ] . time ;
1462+
1463+ // Create the serving time for today
1464+ const now = new Date ( ) ;
1465+ let servingTime = new Date ( now ) ;
1466+ servingTime . setHours ( hours , minutes , 0 , 0 ) ;
1467+
1468+ // If the serving time is in the past, assume it's for tomorrow
1469+ if ( servingTime . getTime ( ) < now . getTime ( ) ) {
1470+ servingTime . setDate ( servingTime . getDate ( ) + 1 ) ;
1471+ }
1472+
1473+ // Calculate the start time by subtracting the total cooking time
1474+ startTime = servingTime . getTime ( ) - ( lastStepTime * 1000 ) ;
1475+
1476+ saveTimerState ( ) ;
1477+ startTimer ( ) ;
1478+ }
1479+
13341480 function startTimer ( ) {
13351481 document . getElementById ( 'startBtn' ) . classList . add ( 'hidden' ) ;
1482+ document . getElementById ( 'servingTimeContainer' ) . classList . add ( 'hidden' ) ;
13361483 document . getElementById ( 'timerDisplay' ) . classList . remove ( 'hidden' ) ;
13371484 document . getElementById ( 'startSection' ) . classList . add ( 'running' ) ;
13381485 document . getElementById ( 'notStartedMsg' ) . classList . add ( 'hidden' ) ;
@@ -1348,6 +1495,9 @@ <h2>Full Timeline</h2>
13481495 saveTimerState ( ) ;
13491496
13501497 document . getElementById ( 'startBtn' ) . classList . remove ( 'hidden' ) ;
1498+ document . getElementById ( 'servingTimeContainer' ) . classList . remove ( 'hidden' ) ;
1499+ document . getElementById ( 'servingTimeBtn' ) . classList . remove ( 'hidden' ) ;
1500+ document . getElementById ( 'servingTimeInputWrapper' ) . classList . add ( 'hidden' ) ;
13511501 document . getElementById ( 'timerDisplay' ) . classList . add ( 'hidden' ) ;
13521502 document . getElementById ( 'startSection' ) . classList . remove ( 'running' ) ;
13531503 document . getElementById ( 'currentStepSection' ) . classList . add ( 'hidden' ) ;
@@ -1382,7 +1532,18 @@ <h2>Full Timeline</h2>
13821532 function updateDisplay ( ) {
13831533 const steps = isMultiRecipeMode ? mergedSteps : currentRecipe . steps ;
13841534 const elapsed = Math . floor ( ( Date . now ( ) - startTime ) / 1000 ) ;
1385- document . getElementById ( 'elapsedTime' ) . textContent = formatTimeWithHours ( elapsed ) ;
1535+ const elapsedLabel = document . getElementById ( 'elapsedLabel' ) ;
1536+
1537+ // Handle negative elapsed time (waiting to start based on serving time)
1538+ if ( elapsed < 0 ) {
1539+ document . getElementById ( 'elapsedTime' ) . textContent = formatTimeWithHours ( Math . abs ( elapsed ) ) ;
1540+ elapsedLabel . textContent = 'Starts in' ;
1541+ elapsedLabel . classList . add ( 'countdown' ) ;
1542+ } else {
1543+ document . getElementById ( 'elapsedTime' ) . textContent = formatTimeWithHours ( elapsed ) ;
1544+ elapsedLabel . textContent = 'Elapsed Time' ;
1545+ elapsedLabel . classList . remove ( 'countdown' ) ;
1546+ }
13861547
13871548 // Find current and upcoming steps
13881549 let currentStep = null ;
@@ -1403,7 +1564,7 @@ <h2>Full Timeline</h2>
14031564 }
14041565
14051566 // If no "just started" step, find the most recent active step
1406- if ( ! currentStep ) {
1567+ if ( ! currentStep && elapsed >= 0 ) {
14071568 for ( let i = steps . length - 1 ; i >= 0 ; i -- ) {
14081569 if ( steps [ i ] . time <= elapsed ) {
14091570 currentStep = steps [ i ] ;
@@ -1439,6 +1600,9 @@ <h2>Full Timeline</h2>
14391600 categoryEl . style . display = currentStep . category ? 'inline-block' : 'none' ;
14401601 categoryEl . style . background = 'rgba(0,0,0,0.2)' ;
14411602 }
1603+ } else {
1604+ // Hide current step section when waiting to start or between steps
1605+ document . getElementById ( 'currentStepSection' ) . classList . add ( 'hidden' ) ;
14421606 }
14431607
14441608 // Update upcoming steps
0 commit comments