Edit in JSFiddle

// Global scope
let pane;
let presentTransition = {
  duration: 600,
  opacity: 0,
  translateY: 280,
  prespective: 250,
  rotateX: 65,
  scale: 0.3
};
let destroyTransition = {
  duration: 600,
  opacity: 0,
  translateY: 280,
  prespective: 250,
  rotateX: 65,
  scale: 0.3
};


// DOM ready
window.onload = async function () {
  await document.querySelector('ion-app').componentOnReady();
  drawGraphCanvas();
  window.addEventListener('resize', drawGraphCanvas);

  // Calculator
  let price = '23,165.82';
  let amount = document.querySelector('#amount');
  let submitButton = document.querySelector('#submitButton');
  let estPrice = document.querySelector('#estPrice');
  let estBtc = document.querySelector('#estBtc');
  let swipeCancel = document.querySelector('#swipeCancel');
  let sendingOrder = document.querySelector('#sendingOrder');

  // Cupertino-Pane is magic panes for PWA interfaces
  // npm i cupertino-pane
  pane = new CupertinoPane('cupertino-pane', {
    fitHeight: true,
    inverse: true,
    bottomClose: true,
    showDraggable: false,
    bottomOffset: 120,
    upperThanTop: true,
    dragBy: ['.backdrop', '.cupertino-pane-wrapper .pane'],
    backdrop: true,
    backdropOpacity: 0,
    events: {
      onWillPresent: () => {
        amount.value = '$1';
        estPrice.value = `$${price}`;
        estBtc.value = '0.0000431670 BTC';
        submitButton.removeAttribute('disabled');
      },
      onWillDismiss: () => {
        document.body.classList.remove('pane-visible');
      },
      onDidDismiss: () => {
        sendingOrder.classList.add('hidden');
        swipeCancel.classList.remove('hidden');
      }
    }
  });
	
  // Rewrite and customize some transitions to make 
  // pane moved by touchmove events with 
  // custom perspective transitions
  pane.transitions.setPaneElTransform = (params) => setPaneElTransform(params);

  // Set caret
  amount.addEventListener('ionFocus', () => {
    let val = amount.value;
    amount.value = '$1 ';
    setTimeout(() => amount.value = val);
  });
  // calculate value
  amount.addEventListener('ionChange', (val) => {
    val = val.detail.value;
    val = val.replace(/\D/g,'');
    amount.value = `$${val}`;

    if (!val) {
      submitButton.setAttribute('disabled', '');
      estBtc.value = '-';
    } else {
      submitButton.removeAttribute('disabled');
      estBtc.value = `${(val / parseInt(price.replace(',', ''))).toFixed(10)} BTC`;
    }
  });
};

// rewrite basic transition function 
function setPaneElTransform(params) {
  let customY = destroyTransition.translateY;
  let customAngle = destroyTransition.rotateX;
  let customPerspective = destroyTransition.prespective;
  let customOpacity = destroyTransition.opacity;
  let customScale = destroyTransition.scale;
  let path = pane.breakpoints.topper - customY;
  let factor = -1 * (100 - (params.translateY - (customY - path)) * 100 / path);
  factor = factor / 100;

  if (params.type === 'move') {
    if (params.translateY < customY) {
      return;
    }
    pane.paneEl.style.setProperty(
      'transform', `translateY(${params.translateY}px) translateZ(1000px) perspective(${customPerspective + ((1000 - customPerspective) * factor)}px) rotateX(${customAngle - (customAngle * factor)}deg) scale(${customScale + ((1 - customScale) * factor)})`
    );
    pane.paneEl.style.setProperty('opacity', `${customOpacity + ((1 - customOpacity) * factor)}`);
    return;
  }

  if (params.type === 'destroy') {
    pane.paneEl.style.setProperty(
      'transform', `translateY(${customY}px) translateZ(1000px) perspective(${customPerspective}px) rotateX(${customAngle}deg) scale(${customScale})`
    );
    pane.paneEl.style.setProperty('opacity', `${customOpacity}`);
    return;
  }

  if (params.type === 'end') {
    pane.paneEl.style.setProperty('opacity', '1');
  }

  pane.paneEl.style.transform = `translateY(${params.translateY}px) translateZ(1000px)`;
}

async function toggleTheme() {
  document.body.classList.toggle('primary');
  document.body.classList.toggle('secondary');

  drawGraphCanvas();
}

async function showDialog(buy) {
  document.body.classList.add('pane-visible');
  await pane.present({
    animate: true,
    transition: {
      duration: presentTransition.duration,
      from: {
        opacity: presentTransition.opacity,
        transform: `translateY(${presentTransition.translateY}px) translateZ(1000px) perspective(${presentTransition.prespective}px) rotateX(${presentTransition.rotateX}deg) scale(${presentTransition.scale})`
      },
      to: {
        opacity: 1
      }
    }
  });
}

async function submit() {
  submitButton.setAttribute('disabled', '');
  swipeCancel.classList.add('hidden');
  sendingOrder.classList.remove('hidden');
  await new Promise(resolve => setTimeout(resolve, 2000));
  await pane.destroy({
    animate: true,
    transition: {
      duration: destroyTransition.duration,
      to: {
        opacity: destroyTransition.opacity,
        transform: `translateY(${destroyTransition.translateY}px) translateZ(1000px) perspective(${destroyTransition.prespective}px) rotateX(${destroyTransition.rotateX}deg) scale(${destroyTransition.scale})`
      }
    }
  });
}

async function drawGraphCanvas() {
  let height = (window.innerHeight * 0.76) - 160;
  // let height = 480;
  let color = getComputedStyle(document.body).getPropertyValue('--ion-color-secondary');
  let canvas = document.querySelector('canvas');
  canvas.width = window.innerWidth;
  canvas.height = height;
  let context = canvas.getContext('2d');
  document.querySelector('.graph-container').appendChild(canvas);

  // declare graph start and end  
  let GRAPH_TOP = 0;  
  let GRAPH_BOTTOM = height;
  let GRAPH_LEFT = 0;  
  let GRAPH_RIGHT = 275;
  let GRAPH_HEIGHT = height;   
  let GRAPH_WIDTH = window.innerWidth > 390 ? 390 : window.innerWidth;  

  context.clearRect( 0, 0, GRAPH_WIDTH + 50, GRAPH_HEIGHT + 50 );

  // Bitcoin two weeks raw data
  let dataArr = [ 
    23.8584, 23.3082, 23.3444, 23.1198,
    23.3082, 22.6133, 23.4476, 22.5935,
    22.6121, 22.8222, 23.2145, 22.4387,
    22.8208, 22.9887, 23.6237, 22.6986,
    23.6342, 23.7742, 24.6053, 23.5218,
    23.7743, 23.8502, 24.3400, 23.4514,
    23.8500, 22.9577, 24.1905, 22.6116,
    22.9583, 21.2480, 23.0278, 21.0475,
    21.2487, 21.3016, 21.3223, 20.7373,
    21.3019, 22.5823, 22.6533, 21.2754,
    22.5821, 22.4498, 22.9879, 22.2813,
    22.4604, 22.6836, 22.9910, 21.9717,
    22.6752, 23.1500, 23.7414, 22.5242,
    23.1530, 23.2199, 23.4038, 22.3602,
    23.2152, 23.4120, 24.2580, 22.9444,
    23.4102, 22.5293, 23.7573, 21.5818,
    22.5258, 20.7856, 22.7149, 20.7706,
    20.7856, 21.2098, 21.6544, 20.7552,
    21.2099, 20.8252, 21.5613, 20.4844,
    20.8251, 20.5861, 21.1781, 20.3934,
    20.5860, 20.2500, 20.8622, 19.6649,
    20.2500, 19.3316, 20.2508, 18.9422,
    19.3309, 19.9632, 20.0517, 19.2796,
    19.9632, 20.8472, 20.8550, 19.8970,
  ].reverse();

  let smallest =  Math.min(...dataArr);
  dataArr = dataArr.map(item => item - smallest);
  let largest =  Math.max(...dataArr);
  let arrayLen = dataArr.length;

  context.beginPath();
  context.lineJoin = "round";
  context.strokeStyle = color;
  context.lineWidth = 2;

  context.shadowColor = color;
  context.shadowBlur = 10;
  context.shadowOffsetX = 2;
  context.shadowOffsetY = 2;

  // add first point in the graph  
  context.moveTo( GRAPH_LEFT, ( GRAPH_HEIGHT - dataArr[ 0 ] / largest * GRAPH_HEIGHT ) + GRAPH_TOP );

  // loop over data and add points
  for(let i = 1; i < arrayLen; i++ ){  
      context.lineTo( GRAPH_RIGHT / arrayLen * i + GRAPH_LEFT, ( GRAPH_HEIGHT - dataArr[ i ] / largest * GRAPH_HEIGHT ) + GRAPH_TOP );  
  }
  context.stroke();
}
<html mode="ios">
<head>
 <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
</head>
  <body class="dark primary">
   <ion-app>
    <ion-content scroll-y="false">
      <!-- Texts -->
      <div class="top-content hide-on-present">
        <div class="titles">
          <h1>$23,165.82</h1>
          <h2 class="result">+$49.56 (0.32%)</h2>
          <h2 class="name">Bitcoin</h2>
        </div>

        <!-- Thanks GUI CHALLENGE for button idea -->
        <button class="theme-toggle" onclick="toggleTheme();" id="theme-toggle" title="Toggles light & dark" aria-label="auto" aria-live="polite">
          <svg class="sun-and-moon" aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">
            <mask class="moon" id="moon-mask">
              <rect x="0" y="0" width="100%" height="100%" fill="white" />
              <circle cx="24" cy="10" r="6" fill="black" />
            </mask>
            <circle class="sun" cx="12" cy="12" r="6" mask="url(#moon-mask)" fill="currentColor" />
            <g class="sun-beams" stroke="currentColor">
              <line x1="12" y1="1" x2="12" y2="3" />
              <line x1="12" y1="21" x2="12" y2="23" />
              <line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
              <line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
              <line x1="1" y1="12" x2="3" y2="12" />
              <line x1="21" y1="12" x2="23" y2="12" />
              <line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
              <line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
             </g>
          </svg>
        </button>
      </div>

      <!-- Synthwave -->
      <section class="synthwave">
        <div class="fade-overlay"></div>
        <div class="synth-wrapper">
          <div class="background"></div>
          <div class="grid"></div>
        </div>
      </section>

      <!-- Bottom texts -->
      <div class="bottom-content show-on-present">
        <div class="titles">
          <h1 id="swipeCancel">Swipe up to cancel</h1>
          <h1 id="sendingOrder" class="sending-order hidden">Sending order...</h1>
        </div>
      </div>

      <!-- Pane -->
      <cupertino-pane>
        <ion-list>
          <ion-item class="amount">
            <ion-label>Amount in USD</ion-label>
            <ion-input id="amount" class="ion-text-right" type="text"></ion-input>
          </ion-item>
          <ion-item>
            <ion-label>Est Price</ion-label>
            <ion-input class="ion-text-right" id="estPrice" readonly type="text"></ion-input>
          </ion-item>
          <ion-item>
            <ion-label>Est Btc</ion-label>
            <ion-input class="ion-text-right" id="estBtc" readonly type="text"></ion-input>
          </ion-item>
        </ion-list>
        <div class="description">
          <ion-text>Order Summary</ion-text>
          <small>You are placing an order to buy Bitcoin. Amount purchased may vary due to market volatility. Cryptocurrencies are not securities and are not FOIC or SIPC insured.</small>
        </div>
        <ion-button id="submitButton" color="primary" expand="full" onclick="submit();">Submit</ion-button>
      </cupertino-pane>
    </ion-content>

    <!-- Graph -->
    <div class="graph-container hide-on-present">
      <canvas></canvas>
      <div class="signal"></div>
    </div>

    <!-- Footer -->
    <ion-footer translucent class="hide-on-present">
      <ion-toolbar>
        <div class="buttons">
          <ion-button color="primary" onclick="showDialog(true);" expand="full">Buy</ion-button>
          <ion-button color="secondary" onclick="showDialog(false);" expand="full">Sell</ion-button>
        </div>
      </ion-toolbar>
    </ion-footer>
  </ion-app>
  </body>
</html>
body.dark {
    --ion-background-color: #080317;
    --ion-background-color-rgb: rgb(8 3 23);
    --ion-toolbar-background: #1f1f1f;
    --hide-delay: 400ms;
}

  body.primary {
    --ion-color-primary: #ff69b4;
    --ion-color-primary-rgb: 255, 107, 181;
    --ion-color-primary-contrast: #333333;
    --ion-color-primary-contrast-rgb: 51, 51, 51;
    --ion-color-primary-shade: #f3499e;
    --ion-color-primary-tint: #fa71b5;

    --ion-color-secondary: #add65c;
    --ion-color-secondary-rgb: 173, 214, 92;
    --ion-color-secondary-contrast: #333333;
    --ion-color-secondary-contrast-rgb: 51, 51, 51;
    --ion-color-secondary-shade: #a4d63e;
    --ion-color-secondary-tint: #b5da6b;
  }

  body.secondary {
    --ion-color-primary: #add65c;
    --ion-color-primary-rgb: 173, 214, 92;
    --ion-color-primary-contrast: #333333;
    --ion-color-primary-contrast-rgb: 51, 51, 51;
    --ion-color-primary-shade: #a4d63e;
    --ion-color-primary-tint: #b5da6b;

    --ion-color-secondary: #ff69b4;
    --ion-color-secondary-rgb: 255, 107, 181;
    --ion-color-secondary-contrast: #333333;
    --ion-color-secondary-contrast-rgb: 51, 51, 51;
    --ion-color-secondary-shade: #f3499e;
    --ion-color-secondary-tint: #fa71b5;
  }

  .hide-on-present {
    opacity: 1;
    transition: opacity var(--hide-delay) ease;
  }

  .show-on-present {
    opacity: 0;
    transition: opacity var(--hide-delay) ease;
  }

  body.pane-visible .hide-on-present {
    opacity: 0; 
  }

  body.pane-visible .show-on-present {
    opacity: 1;
  }

  /* Synthwave styles */
  .fade-overlay {
    position: absolute;
    bottom: 183px;
    width: 100vw;
    height: 100px;
    z-index: 1;
    background: linear-gradient(180deg, rgba(8,3,23,1) 0%, rgba(8,3,23,0.8) 37%, rgba(8,3,23,0) 100%); 
  }

  section.synthwave {
    position: absolute;
    bottom: 0px;
    height: 270px;
    overflow: visible;
    z-index: 1;
  }

  section.synthwave div.synth-wrapper {
    height: 100vh;
    width: 140vw;
    margin-left: -20vw;
    perspective: 470px;
    filter: saturate(0.9);
    opacity: 0.9;
  }

  section.synthwave .background {
    width: 100%;
    height: 292px;
    position: absolute;
    background: rgba(var(--ion-color-primary-rgb), 0.23);
  }

  section.synthwave .grid {
    background-size: 40px 50px;
    background-image: linear-gradient(to right, var(--ion-color-primary) 2px, transparent 1px), 
                      linear-gradient(to bottom, var(--ion-color-primary) 2px, transparent 1px);
    height: inherit;
    transform: rotateX(35deg) scale(0.8);
    transform-origin: top center;
    animation: 1.8s linear infinite wave;
    background-position-y: 0px;
  }

  @keyframes wave {
    to {
      background-position-y: -50px;
    }
  }

  /* Bottom toolbar */
  ion-footer {
    position: absolute;
    bottom: 0;
  }

  ion-toolbar {
    --padding-top: 20px;
    --padding-bottom: 30px;
    --padding-start: 10px;
    --padding-end: 10px;
  }

  ion-toolbar .buttons {
    display: flex;
    max-width: 390px;
    gap: 10px;
    margin: auto;
  }

  ion-toolbar ion-button {
    width: 100%;
    height: 44px;
    font-weight: 700;
    margin: auto;
  }

  ion-toolbar ion-button::part(native) {
    border-radius: 30px;
  }

  /* Prices texts */
  .top-content {
    position: absolute;
    top: 20px;
    width: calc(100% - 40px);
    max-width: 390px;
    left: 0;
    right: 0;
    margin-left: auto;
    margin-right: auto;
    height: 190px;
    justify-content: space-between;
    display: flex;
    flex-direction: column;
    z-index: 1;
  }

  .titles h1 {
    font-size: 35px;
    color: #f4f5f6;
    text-shadow: 1px 1px #1a1b20;
    margin-bottom: 10px;
  }

  .titles h2 {
    font-size: 17px;
    font-weight: 500;
    color: #f4f5f6;
    margin-top: 0;
  }

  .titles h2.result {
    color: var(--ion-color-secondary);
  }

  .titles h2.name {
    font-size: 20px;
  }

  /* Bottom text */
  .bottom-content {
    position: absolute;
    bottom: calc(100vh * 0.255 - 70px);
    width: calc(100% - 40px);
    max-width: 390px;
    left: 0;
    right: 0;
    text-align: center;
    margin-left: auto;
    margin-right: auto;
    justify-content: space-between;
    flex-direction: column;
    z-index: 1;
  }

  .bottom-content h1 {
    font-size: 25px;
    opacity: 1;
    transition: opacity var(--hide-delay) ease;
    position: absolute;
    left: 0;
    right: 0;
  }

  .bottom-content h1.hidden {
    opacity: 0;
  }

  /* Graph */
  .graph-container {
    position: absolute;
    z-index: 10;
    width: 100%;
    max-width: 390px;
    left: 0;
    right: 0;
    margin-left: auto;
    margin-right: auto;
    transform: translateZ(1px);
    bottom: calc(100vh * 0.22);
  }

  .graph-container .signal {
    position: absolute;
    top: 12%;
    left: 268px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ion-color-secondary);
  }

  .graph-container .signal::before {
    content: "";
    width: 8px;
    height: 8px;
    position: absolute;
    border-radius: 50%;
    z-index: -1;
    opacity: 1;
    transform: scale(1);
    background-color: rgba(var(--ion-color-secondary-rgb), 1);
    animation: 1.8s linear infinite signal;
  }

  @keyframes signal {
    to {
      transform: scale(5);
      opacity: 0;
    }
  }

  /* Cupertino Pane */
  .cupertino-pane-wrapper .pane {
    border-radius: 10px !important;
    background: var(--ion-background-color);
    box-shadow: 0px 0px 40px 0px rgba(var(--ion-color-primary-rgb), 0.3);
  }

  cupertino-pane {
    display: none;
  }

  cupertino-pane ion-list ion-item {
    --border-color: rgba(var(--ion-color-primary-rgb), 0.2);
    --padding-end: 20px;
    --padding-start: 20px;
    --inner-border-width: 0 0 2px 0;
  }

  cupertino-pane ion-list ion-item ion-label {
    font-size: 14px !important;
    font-weight: 600 !important;
    color: #ffffff !important;
    margin-bottom: 22px;
    margin-top: 22px;
  }

  cupertino-pane ion-list ion-item ion-input {
    --color: #ffffff !important;
    font-size: 14px !important;
    font-weight: 600 !important;
    --padding-end: 0 !important;
  }

  cupertino-pane ion-list ion-item.amount ion-input {
    font-size: 20px !important;
  }

  cupertino-pane ion-list ion-item.amount ion-label {
    color: var(--ion-color-primary) !important;
    font-size: 15px !important;
  }

  cupertino-pane ion-button {
    margin-left: 20px !important;
    margin-top: 30px !important;
    margin-right: 20px !important;
    margin-bottom: 30px !important;
    height: 50px;
    font-weight: 700;
    margin: auto;
  }

  cupertino-pane ion-button::part(native) {
    border-radius: 30px;
  }

  cupertino-pane .description {
    margin-top: 30px;
    margin-left: 20px;
    margin-right: 20px;
  }

  cupertino-pane .description ion-text {
    display: block;
    color: #9e9e9e;
    font-size: 14px;
  }

  cupertino-pane .description small {
    color: #9e9e9e;
    display: block;
    font-size: 12px;
    margin-top: 8px;
    line-height: 18px;
  }

  /* Theme switcher */
  @import"https://unpkg.com/open-props/easings.min.css";
  .sun-and-moon>:is(.moon, .sun, .sun-beams) {
      transform-origin: center center
  }

  .sun-and-moon>:is(.moon, .sun) {
      fill: var(--icon-fill)
  }

  .sun-and-moon>.sun-beams {
      stroke: var(--icon-fill);
      stroke-width: 2px
  }

  body.primary .sun-and-moon>.sun {
      transform: scale(1.75)
  }

  body.primary .sun-and-moon>.sun-beams {
      opacity: 0
  }

  body.primary .sun-and-moon>.moon>circle {
      transform: translate(-7px)
  }

  @supports (cx: 1) {
      body.primary .sun-and-moon>.moon>circle {
          transform: translate(0);
          cx: 17
      }
  }

  @media (prefers-reduced-motion: no-preference) {
      .sun-and-moon>.sun {
          transition: transform .5s var(--ease-elastic-3)
      }
      .sun-and-moon>.sun-beams {
          transition: transform .5s var(--ease-elastic-4), opacity .5s var(--ease-3)
      }
      .sun-and-moon .moon>circle {
          transition: transform .25s var(--ease-out-5)
      }
      @supports (cx: 1) {
          .sun-and-moon .moon>circle {
              transition: cx .25s var(--ease-out-5)
          }
      }
      body.primary .sun-and-moon>.sun {
          transform: scale(1.75);
          transition-timing-function: var(--ease-3);
          transition-duration: .25s
      }
      body.primary .sun-and-moon>.sun-beams {
          transform: rotate(-25deg);
          transition-duration: .15s
      }
      body.primary .sun-and-moon>.moon>circle {
          transition-delay: .25s;
          transition-duration: .5s
      }
  }

  .theme-toggle {
      --size: 26px;
      --icon-fill: rgba(var(--ion-color-secondary-rgb), 0.7);
      background: none;
      border: none;
      padding: 0;
      inline-size: var(--size);
      block-size: var(--size);
      aspect-ratio: 1;
      border-radius: 50%;
      cursor: pointer;
      touch-action: manipulation;
      -webkit-tap-highlight-color: transparent;
      outline-offset: 5px;
      position: absolute;
      right: 0px;
      top: 30px;
  }

  .theme-toggle>svg {
      inline-size: 100%;
      block-size: 100%;
      stroke-linecap: round
  }