JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<!-- template for the modal component -->
<script type="text/x-template" id="modal-template">
  <transition name="modal">
    <div class="modal-mask">
      <div class="modal-wrapper">
        <div class="modal-container">

          <div class="modal-header">
            <slot name="header">
              default header
            </slot>
          </div>

          <div class="modal-body">
            <slot name="body">
              default body
            </slot>
          </div>

          <div class="modal-footer">
            <slot name="footer">
              default footer
              <button class="modal-default-button" @click="$emit('close')">
                Dismiss
              </button>
            </slot>
          </div>
        </div>
      </div>
    </div>
  </transition>
</script>

<!-- app -->
<div id="app">
  <div class="page-header">
    <button id="show-modal" @click="openModal">Show Modal</button>
  </div>
  <div class="page-content" v-html="pageContent"></div>
  <!-- use the modal component, pass in the prop -->
  <modal v-if="showModal" @close="closeModal">
    <!--
      you can use custom content here to overwrite
      default content
    -->
    <h3 slot="header">custom header</h3>
  </modal>
</div>

CSS

body.modal-open {
  overflow: hidden;
}
.page-header {
  position: fixed;
  top: 0;
  left: 0;
  background-color: white;
  width: 100vw;
  padding: 20px;
  box-shadow: 0 0 5px black;
}
.page-content {
  margin: 70px 20px;
}
.modal-mask {
  position: fixed;
  z-index: 9998;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: table;
  transition: opacity 0.3s ease;
}

.modal-wrapper {
  display: table-cell;
  vertical-align: middle;
}

.modal-container {
  width: 300px;
  margin: 0px auto;
  padding: 20px 30px;
  background-color: #fff;
  border-radius: 2px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .33);
  transition: all .3s ease;
  font-family: Helvetica, Arial, sans-serif;
}

.modal-header h3 {
  margin-top: 0;
  color: #42b983;
}

.modal-body {
  margin: 20px 0;
}

.modal-default-button {
  float: right;
}

/*
 * The following styles are auto-applied to elements with
 * transition="modal" when their visibility is toggled
 * by Vue.js.
 *
 * You can easily play with the modal transition by editing
 * these styles.
 */

.modal-enter {
  opacity: 0;
}

.modal-leave-active {
  opacity: 0;
}

.modal-enter .modal-container,
.modal-leave-active .modal-container {
  -webkit-transform: scale(1.1);
  transform: scale(1.1);
}

JavaScript

const sentences = [
	'Nam tristique eros nisl, ac dapibus justo rhoncus sit amet',
	'Donec et urna pretium, pharetra ante vel, mollis odio',
	'Duis elit turpis, accumsan in sollicitudin vitae, fringilla non nulla',
	'Quisque condimentum leo eu erat ultricies ornare',
	'Vestibulum in sem vel nisl fermentum dapibus eget ac lorem',
	'Curabitur vitae massa ut ante ultricies pharetra sit amet bibendum neque',
	'Aliquam libero nisi, sagittis eget varius eget, faucibus nec ligula',
	'Aliquam orci nulla, convallis nec leo ac, tempor eleifend purus',
	'Integer semper, mi eget luctus fermentum, dui tellus volutpat nibh, eu vestibulum tortor diam vitae enim',
	'Nullam sed nisl nec purus tristique maximus',
	'Vestibulum nec rhoncus tortor',
	'Donec malesuada tortor quis justo venenatis, a aliquet sem ultricies',
	'Phasellus sagittis, mauris quis efficitur lobortis, arcu nulla bibendum enim, ut semper eros augue vitae lorem',
	'Sed vitae elit vel odio semper consequat',
	'Sed euismod, risus ut pharetra blandit, enim dui pulvinar diam, nec sagittis diam lectus at libero'
];

// register modal component
Vue.component('modal', {
  template: '#modal-template'
})

// start app
new Vue({
  el: '#app',
  data: {
    showModal: false,
    pageContent: ''
  },
  methods: {
    openModal() {
      this.showModal = true;
      document.body.classList.add('modal-open');
    },
    closeModal() {
      this.showModal = false;
      document.body.classList.remove('modal-open');
    },
    getTitle(seed) {
      const shuffled = this.shuffleArray(sentences, seed);
      
      const sentence = shuffled[seed];
      
      return sentence.split(' ').map((word) => { return _.capitalize(word.replace(',', '')); }).slice(0, 3).join(' ');
    },
    getParagraph(seed) {
    	// Shuffle array
      const shuffled = this.shuffleArray(sentences, seed);

      // Get a number between 3 and 7, so that paragraphs have 3 to 7 sentences
      const n = Math.floor((Math.random() * 5) + 3);
      
      //...