textBasedModules.html
<header class="siteHeader">
  <div class="container">
    <div class="siteHeader__content">
    <a class="siteHeader__logo" href="">
      <svg viewBox="0 0 300 133" fill="none" xmlns="http://www.w3.org/2000/svg">
        <rect width="300" height="133" fill="currentColor"/>
      </svg>
    </a>
    <nav class="siteHeader__utilityNav navigation">
      <ul class="navigation__list">
        <li class="navigation__item">
          <p-openable class="navigation__button" label="Utility Dropdown" :close-on-blur="false">
            <template #default>
              <div class="navigation__dropdown dropdown">
                <ul class="dropdown__list">
                  <li class="dropdown__item">
                    <a class="dropdown__link" href=""><span>Elit?</span></a>
                  </li>
                  <li class="dropdown__item">
                    <a class="dropdown__link" href=""><span>Dolor.</span></a>
                  </li>
                  <li class="dropdown__item">
                    <a class="dropdown__link" href=""><span>Adipisicing!</span></a>
                  </li>
                  <li class="dropdown__item">
                    <a class="dropdown__link" href=""><span>Amet</span></a>
                  </li>
                  <li class="dropdown__item">
                    <a class="dropdown__link" href=""><span>Adipisicing</span></a>
                  </li>
                </ul>
              </div>
            </template>
          </p-openable>
        </li>
        <li class="navigation__item">
          <a class="navigation__link" href="#">Contact</a>
        </li>
      </ul>
    </nav>
    <div class="siteHeader__search search">
      <svg class="search__icon" xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M232.49,215.51,185,168a92.12,92.12,0,1,0-17,17l47.53,47.54a12,12,0,0,0,17-17ZM44,112a68,68,0,1,1,68,68A68.07,68.07,0,0,1,44,112Z"></path></svg>
      <input class="search__input input" type="search" placeholder="Search">
    </div>
    <nav class="siteHeader__mobileNav mobileNavigation">
      <p-openable class="mobileNavigation__menu button -circle -ghost" label="menu">
        <template #toggle>
            <svg class="button__icon icon"><use href="/main-icons-sprite.svg#bars" /></svg>
        </template>
        <template v-slot="{ click }">
          <div class="mobileNavigation__pane" v-scrolllock>
            <div class="mobileNavigation__title">
              Menu
            </div>
            <ul class="mobileNavigation__list" v-directionals>
              <li class="dropdown__item">
                <p-openable class="mobileNavigation__button" name="submenu">
                  <template #toggle>
                    Submenu
                    <svg class="icon"><use href="/main-icons-sprite.svg#chevron-right" /></svg>
                  </template>
                  <template v-slot="{ click }">
                    <div class="mobileNavigation__pane">
                      <div class="mobileNavigation__title">
                        <div class="mobileNavigation__actions">
                          <button class="button -circle -ghost" @click.stopPropagation="click" tabindex="-1">
                            <svg class="icon"><use href="/main-icons-sprite.svg#chevron-left" /></svg>
                          </button>
                        </div>
                        Menu
                      </div>
                      <ul class="mobileNavigation__list" v-directionals>
                        <li class="mobileNavigation__item"><a href="" class="mobileNavigation__link">Consectetur asperiores</a></li>
                        <li class="mobileNavigation__item"><a href="" class="mobileNavigation__link">Consectetur asperiores</a></li>
                        <li class="mobileNavigation__item"><a href="" class="mobileNavigation__link">Amet porro.</a></li>
                        <li class="mobileNavigation__item"><a href="" class="mobileNavigation__link">Ipsum dolorem</a></li>
                      </ul>
                    </div>
                  </template>
                </p-openable>
              </li>
              <li class="dropdown__item">
                <p-openable class="mobileNavigation__button" name="submenu">
                  <template #toggle>
                    STUFF
                    <svg class="icon"><use href="/main-icons-sprite.svg#chevron-right" /></svg>
                  </template>
                  <template v-slot="{ click }">
                    <div class="mobileNavigation__pane">
                      <div class="mobileNavigation__title">
                        <div class="mobileNavigation__actions">
                          <button class="button -circle -ghost" @click.stopPropagation="click" tabindex="-1">
                            <svg class="icon"><use href="/main-icons-sprite.svg#chevron-left" /></svg>
                          </button>
                        </div>
                        Menu
                      </div>
                      <ul class="mobileNavigation__list" v-directionals>
                        <li class="mobileNavigation__item"><a href="" class="mobileNavigation__link">Consectetur asperiores</a></li>
                        <li class="mobileNavigation__item"><a href="" class="mobileNavigation__link">Consectetur asperiores</a></li>
                        <li class="mobileNavigation__item"><a href="" class="mobileNavigation__link">Amet porro.</a></li>
                        <li class="mobileNavigation__item"><a href="" class="mobileNavigation__link">Ipsum dolorem</a></li>
                      </ul>
                    </div>
                  </template>
                </p-openable>
              </li>
              <li class="mobileNavigation__item"><a href="" class="mobileNavigation__link">Consectetur asperiores</a></li>
              <li class="mobileNavigation__item"><a href="" class="mobileNavigation__link">Amet porro.</a></li>
              <li class="mobileNavigation__item"><a href="" class="mobileNavigation__link">Ipsum dolorem</a></li>
              <li class="mobileNavigation__item">
                <a class="mobileNavigation__link" href="">Amet impedit cumque</a>
              </li>
              <li class="mobileNavigation__item">
                <a class="mobileNavigation__link" href="">Consectetur vitae temporibus!</a>
              </li>
              <li class="mobileNavigation__item">
                <a class="mobileNavigation__link" href="">Consectetur doloremque reiciendis</a>
              </li>
              <li class="mobileNavigation__item">
                <a class="mobileNavigation__link" href="">Dolor pariatur rerum.</a>
              </li>
              <li class="mobileNavigation__item">
                <a class="mobileNavigation__link" href="">Ipsum a officiis.</a>
              </li>
              <li class="mobileNavigation__item">
                <a class="mobileNavigation__link" href="">Dolor unde debitis.</a>
              </li>
              <li class="mobileNavigation__item">
                <a class="mobileNavigation__link" href="">Adipisicing delectus velit</a>
              </li>
              <li class="mobileNavigation__item">
                <a class="mobileNavigation__link" href="">Amet aliquam voluptates</a>
              </li>
            </ul>
          </div>
          <div class="mobileNavigation__closeButton">
            <button class="button -circle -ghost" @click="click">
              <svg class="icon"><use href="/main-icons-sprite.svg#close" /></svg>
            </button>
          </div>
        </template>
      </p-openable>
    </nav>

    <nav class="siteHeader__primaryNav navigation" v-directionals>
      <ul class="navigation__list">
        <li class="navigation__item" v-directionals>
          <p-openable class="navigation__button" label="Default Dropdown" :close-on-blur="false">
            <template #default>
              <div class="navigation__dropdown dropdown">
                <ul class="dropdown__list">
                  <li class="dropdown__item"><a class="dropdown__link" href=""><span>Consectetur asperiores</span></a></li>
                  <li class="dropdown__item"><a class="dropdown__link" href=""><span>Consectetur asperiores</span></a></li>
                  <li class="dropdown__item"><a class="dropdown__link" href=""><span>Amet porro.</span></a></li>
                  <li class="dropdown__item"><a class="dropdown__link" href=""><span>Ipsum dolorem</span></a></li>
                </ul>
              </div>
            </template>
          </p-openable>
        </li>
        <li class="navigation__item" v-directionals>
          <p-openable class="navigation__button" label="Centered Dropdown" :close-on-blur="false">
            <template #default>
              <div class="navigation__dropdown dropdown -center">
                <ul class="dropdown__list">
                  <li class="dropdown__item"><a class="dropdown__link" href=""><span>Consectetur asperiores</span></a></li>
                  <li class="dropdown__item"><a class="dropdown__link" href=""><span>Consectetur asperiores</span></a></li>
                  <li class="dropdown__item"><a class="dropdown__link" href=""><span>Amet porro.</span></a></li>
                  <li class="dropdown__item"><a class="dropdown__link" href=""><span>Ipsum dolorem</span></a></li>
                </ul>
              </div>
            </template>
          </p-openable>
        </li>
        <li class="navigation__item -wide" v-directionals>
          <p-openable class="navigation__button" label="Full-width Dropdown" :close-on-blur="false">
            <template #default>
              <div class="navigation__dropdown dropdown grid -columns-3">
                <div class="cell">
                  <h3>Heading</h3>
                  <p>
                    Adipisicing obcaecati tempora qui ullam voluptates beatae? Assumenda soluta quae
                  </p>
                  <ul class="dropdown__list">
                    <li class="dropdown__item"><a class="dropdown__link" href=""><span>Consectetur asperiores</span></a></li>
                    <li class="dropdown__item"><a class="dropdown__link" href=""><span>Consectetur asperiores</span></a></li>
                    <li class="dropdown__item"><a class="dropdown__link" href=""><span>Amet porro.</span></a></li>
                    <li class="dropdown__item"><a class="dropdown__link" href=""><span>Ipsum dolorem</span></a></li>
                  </ul>
                </div>
                <div class="cell">
                  <h3>Heading</h3>
                  <p>
                    Adipisicing obcaecati tempora qui ullam voluptates beatae? Assumenda soluta quae
                  </p>
                  <ul class="dropdown__list">
                    <li class="dropdown__item"><a class="dropdown__link" href=""><span>Consectetur asperiores</span></a></li>
                    <li class="dropdown__item"><a class="dropdown__link" href=""><span>Consectetur asperiores</span></a></li>
                    <li class="dropdown__item"><a class="dropdown__link" href=""><span>Amet porro.</span></a></li>
                    <li class="dropdown__item"><a class="dropdown__link" href=""><span>Ipsum dolorem</span></a></li>
                  </ul>
                </div>
                <div class="cell">
                  <h3>Heading</h3>
                  <p>
                    Adipisicing obcaecati tempora qui ullam voluptates beatae? Assumenda soluta quae
                  </p>
                  <ul class="dropdown__list">
                    <li class="dropdown__item"><a class="dropdown__link" href=""><span>Consectetur asperiores</span></a></li>
                    <li class="dropdown__item"><a class="dropdown__link" href=""><span>Consectetur asperiores</span></a></li>
                    <li class="dropdown__item"><a class="dropdown__link" href=""><span>Amet porro.</span></a></li>
                    <li class="dropdown__item"><a class="dropdown__link" href=""><span>Ipsum dolorem</span></a></li>
                  </ul>
                </div>
              </div>
            </template>
          </p-openable>
        </li>
        <li class="navigation__item" v-directionals>
          <p-openable class="navigation__button" label="Right Aligned Dropdown" :close-on-blur="false">
            <template #default>
              <div class="navigation__dropdown dropdown -rightAligned">
                <ul class="dropdown__list">
                  <li class="dropdown__item"><a class="dropdown__link" href=""><span>Consectetur asperiores</span></a></li>
                  <li class="dropdown__item"><a class="dropdown__link" href=""><span>Consectetur asperiores</span></a></li>
                  <li class="dropdown__item"><a class="dropdown__link" href=""><span>Amet porro.</span></a></li>
                  <li class="dropdown__item"><a class="dropdown__link" href=""><span>Ipsum dolorem</span></a></li>
                </ul>
              </div>
            </template>
          </p-openable>
        </li>
      </ul>
    </nav>
    </div>
  </div>
</header>

<section class="section">
  <div class="container">
    <h1 class="h1">Text based modules</h1>
    <p>
      Reference layouts for text-heavy modules: combine <code>.container</code> with Pronto’s <code>.grid</code> / <code>.cell</code>, and use the <code>editorialSplit</code> section variants where noted. Full markup for each variant lives under <code>organisms/textBased/</code>.
    </p>
  </div>
</section>

<section class="section">
  <div class="container">
    <header class="section__header">
      <h2 class="h2">Equal two columns</h2>
      <p>Simple two-column body copy using <code>.grid.-columns-2</code> and <code>.cell</code>.</p>
    </header>
    <div class="grid -columns-2">
      <div class="cell">
        <p>
          Nullam efficitur libero elit, consectetur commodo nulla rutrum ac. Suspendisse semper eleifend fringilla. Donec pharetra mauris feugiat mi malesuada, nec fringilla quam fermentum.
        </p>
        <p>
          Etiam ac tristique arcu, eget vestibulum metus. Aenean feugiat, lorem sit amet varius condimentum, mauris velit fermentum ante.
        </p>
      </div>
      <div class="cell">
        <p>
          Praesent quis est dapibus, pretium mi at, cursus tellus. In eleifend, quam efficitur dapibus fermentum, odio eros scelerisque felis, sit amet posuere lectus ante vitae mauris.
        </p>
        <p>
          Nam ullamcorper lobortis libero et laoreet. Duis nec varius ex, in convallis ante. Donec mollis sollicitudin ligula quis placerat.
        </p>
      </div>
    </div>
  </div>
</section>

<section class="section editorialSplit -introBody">
  <div class="container">
    <header class="section__header">
      <h2 class="h2">Asymmetric intro and body</h2>
      <p>Narrow intro column beside wider body copy. Uses <code>editorialSplit</code> with <code>-introBody</code></p>
    </header>
    <div class="editorialSplit__grid grid -columns-12">
      <div class="editorialSplit__aside -stickyAside">
        <p class="editorialSplit__introText">
          Elementum libero nulla mollis lectus, proin consequat dui nec commodo.
        </p>
      </div>
      <div class="editorialSplit__main">
        <div class="editorialSplit__body">
          <p>
            Praesent quis est dapibus, pretium mi at, cursus tellus. In eleifend, quam efficitur dapibus fermentum, odio eros scelerisque felis, sit amet posuere lectus ante vitae mauris. Nam ullamcorper lobortis libero et laoreet. Duis nec varius ex, in convallis ante. Donec mollis sollicitudin ligula quis placerat. Vestibulum luctus lacus in justo ultrices, sed egestas orci ornare.
          </p>
          <p>
            Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent quis est dapibus, pretium mi at, cursus tellus.
          </p>
        </div>
      </div>
    </div>
  </div>
</section>

<section class="section editorialSplit -headline">
  <div class="container">
    <header class="section__header">
      <h2 class="h2">Aside and display headline</h2>
      <p>Supporting lede beside a large display headline. Section uses <code>-headline</code>; spacer column is hidden on small screens.</p>
    </header>
    <div class="editorialSplit__grid grid -columns-12">
      <div class="editorialSplit__aside -stickyAside">
        <p class="editorialSplit__lede">
          Nunc lorem erat, molestie vel turpis eget, vehicula cursus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum dignissim urna quam, eu sollicitudin.
        </p>
      </div>
      <div class="editorialSplit__spacer" aria-hidden="true"></div>
      <div class="editorialSplit__main">
        <h2 class="h2 editorialSplit__headline">
          Duis nec varius ex, in convallis ante. Donec mollis sollicitudin ligula quis placerat, vestibulum luctus lacus in justo ultrices; dolorem ipsum.
        </h2>
      </div>
    </div>
  </div>
</section>

<section class="section stackedSplitsSection">
  <div class="stackedSplitsSection__container container">
    <div class="stackedSplitsSection__split -lead -alignEnd">
      <h2 class="h2 stackedSplitsSection__headline">
        Duis tellus ex, rutrum non tortor in, dolor vulputate iaculis est.
      </h2>
      <p class="stackedSplitsSection__intro">
        Quis elementum libero nulla mollis lectus, proin consequat dui nec commodo iaculis magna:
      </p>
    </div>
    <div class="stackedSplitsSection__split">
      <div class="stackedSplitsSection__primary">
        <p>
          Proin consequat dui nec cursus commodo. Proin non magna quam. Duis tellus ex, rutrum non tortor in, vulputate iaculis est. Integer pulvinar rhoncus lectus, sed sodales neque.
        </p>
        <div class="actions">
          <a class="button accent-primary" href="#">Default Button</a>
          <a class="link" href="#">
            Standalone Text Link
            <svg viewBox="0 0 18 12"><use href="/main-icons-sprite.svg#arrow-right" /></svg>
          </a>
        </div>
      </div>
      <div class="stackedSplitsSection__features">
        <div class="stackedSplitsSection__feature">
          <h4 class="h4 stackedSplitsSection__featureTitle">Integer pulvinar rhoncus neque</h4>
          <p class="stackedSplitsSection__featureText">
            Proin consequat dui nec cursus commodo. Proin non magna quam. Duis tellus ex, rutrum non tortor in, vulputate iaculis est. Integer pulvinar rhoncus lectus, sed sodales neque.
          </p>
        </div>
        <div class="stackedSplitsSection__feature">
          <h4 class="h4 twoColumnNested__featureTitle">Pulvinar rhoncus nec ipsum sit adiscipit</h4>
          <p class="stackedSplitsSection__featureText">
            Duis tellus ex, rutrum non tortor in, vulputate iaculis est. Integer pulvinar rhoncus lectus, sed sodales neque. Proin consequat dui nec cursus commodo. Proin non magna quam.
          </p>
        </div>
        <div class="stackedSplitsSection__feature">
          <h4 class="h4 twoColumnNested__featureTitle">Pulvinar rhoncus nec ipsum sit adiscipit</h4>
          <p class="stackedSplitsSection__featureText">
            Duis tellus ex, rutrum non tortor in, vulputate iaculis est. Integer pulvinar rhoncus lectus, sed sodales neque. Proin consequat dui nec cursus commodo. Proin non magna quam.
          </p>
        </div>
        <div class="stackedSplitsSection__feature">
          <h4 class="h4 stackedSplitsSection__featureTitle">Integer pulvinar rhoncus neque</h4>
          <p class="stackedSplitsSection__featureText">
            Proin consequat dui nec cursus commodo. Proin non magna quam. Duis tellus ex, rutrum non tortor in, vulputate iaculis est. Integer pulvinar rhoncus lectus, sed sodales neque.
          </p>
        </div>
      </div>
    </div>
  </div>
</section>

<section class="section offsetSection">
  <div class="container">
    <h3 class="h3 offsetSection__title">
      Sed sed porttitor ante. Vivamus auctor mi nec laoreet vestibulum. Cras accumsan tempus tincidunt, aenean scelerisque at purus non varius.
    </h3>
    <div class="offsetSection__columns">
      <div class="offsetSection__column">
        <p>
          Donec pharetra mauris feugiat mi malesuada, nec fringilla quam fermentum. Pellentesque in odio quis turpis porttitor aliquet. Vivamus commodo efficitur turpis. Aliquam
        </p>
      </div>
      <div class="offsetSection__column">
        <p>
          Pellentesque in odio quis turpis porttitor aliquet. Vivamus commodo efficitur turpis. Aliquam pharetra tellus in turpis commodo, non dapibus urna ultrices. Cras commodo vulputate
        </p>
      </div>
      <div class="offsetSection__column">
        <p>
          Aliquam pharetra tellus in turpis commodo, non dapibus urna ultrices. Cras commodo vulputate ipsum sed iaculis. Etiam ac tristique arcu, eget vestibulum metus. Aenean feugiat.
        </p>
      </div>
    </div>
  </div>
</section>

<section class="section detailsSection">
  <div class="container">
    <header class="detailsSection__header">
      <h2 class="h2 detailsSection__title">
        Centered headline and four detail columns
      </h2>
      <p class="detailsSection__intro">
        Centered title and intro, then a responsive step grid: one column on phones, two from <code>md</code>, four from <code>lg</code>.
      </p>
    </header>
    <div class="grid detailsSection__grid">
      <div class="cell detailsSection__item">
        <h3 class="detailsSection__itemTitle">1. Lorem Ipsum</h3>
        <p class="detailsSection__itemText">
          Donec pharetra mauris feugiat mi malesuada, nec fringilla quam fermentum. Pellentesque in odio quis turpis porttitor aliquet. Vivamus commodo efficitur turpis.
        </p>
      </div>
      <div class="cell detailsSection__item">
        <h3 class="detailsSection__itemTitle">2. Dapibus Urna in Turpis</h3>
        <p class="detailsSection__itemText">
          Pellentesque in odio quis turpis porttitor aliquet. Vivamus commodo efficitur turpis. Aliquam pharetra tellus in turpis commodo, non dapibus urna ultrices.
        </p>
      </div>
      <div class="cell detailsSection__item">
        <h3 class="detailsSection__itemTitle">3. Portitor Turpius Adisciput</h3>
        <p class="detailsSection__itemText">
          Aliquam pharetra tellus in turpis commodo, non dapibus urna ultrices. Cras commodo vulputate ipsum sed iaculis. Etiam ac tristique arcu, eget vestibulum metus.
        </p>
      </div>
      <div class="cell detailsSection__item">
        <h3 class="detailsSection__itemTitle">4. Malesuada Mauris</h3>
        <p class="detailsSection__itemText">
          Nam ullamcorper lobortis libero et laoreet. Duis nec varius ex, in convallis ante. Donec mollis sollicitudin ligula quis placerat.
        </p>
      </div>
    </div>
  </div>
</section>

<section class="section editorialSplit -withCards">
  <div class="container">
    <header class="section__header">
      <h2 class="h2">Intro column and horizontal cards</h2>
      <p>Muted band with intro column and horizontal cards stacked in <code>.cardList</code> (<code>molecules/cardList/</code>). Section uses <code>-withCards</code> on <code>editorialSplit</code>.</p>
    </header>
    <div class="editorialSplit__grid grid -columns-12">
      <div class="editorialSplit__aside">
        <div>
          <h3 class="h3">Adisciput Nostra, per inceptos.</h3>
          <p class="editorialSplit__lede">
            Turpis eget, vehicula cursus leo ad litora torquent per conubia nostra, per inceptos himenaeos.
          </p>
        </div>
        <a class="button accent-primary" href="#">Default Button</a>
      </div>
      <div class="editorialSplit__main">
        <div class="cardList">
          <article class="card -horizontal">
            <h4 class="h4 card__title">Convallis ante</h4>
            <div class="card__body">
              <div>
                <p>
                  Nunc lorem erat, molestie vel turpis eget, vehicula cursus leo ad litora torquent per conubia nostra, per inceptos himenaeos.
                </p>
                <p class="card__intro">
                  Nunc lorem erat, molestie vel turpis eget, vehicula cursus leo.
                </p>
              </div>
              <a class="card__link" href="#">
                Standalone Text Link
                <svg viewBox="0 0 18 12"><use href="/main-icons-sprite.svg#arrow-right" /></svg>
              </a>
            </div>
          </article>
          <article class="card -horizontal">
            <h4 class="h4 card__title">Convallis ante</h4>
            <div class="card__body">
              <div>
                <p>
                  Nunc lorem erat, molestie vel turpis eget, vehicula cursus leo ad litora torquent per conubia nostra, per inceptos himenaeos.
                </p>
                <p class="card__intro">
                  Nunc lorem erat, molestie vel turpis eget, vehicula cursus leo.
                </p>
              </div>
              <a class="card__link" href="#">
                Standalone Text Link
                <svg viewBox="0 0 18 12"><use href="/main-icons-sprite.svg#arrow-right" /></svg>
              </a>
            </div>
          </article>
        </div>
      </div>
    </div>
  </div>
</section>

editorialSplit -withCards with sticky aside
<section class="section editorialSplit -withCards">
  <div class="container">
    <header class="section__header">
      <h2 class="h2">Intro column and horizontal cards</h2>
      <p>Muted band with intro column and horizontal cards stacked in <code>.cardList</code> (<code>molecules/cardList/</code>). Section uses <code>-withCards</code> on <code>editorialSplit</code>.</p>
    </header>
    <div class="editorialSplit__grid grid -columns-12">
      <div class="editorialSplit__aside -stickyAside">
        <div>
          <h3 class="h3">Adisciput Nostra, per inceptos.</h3>
          <p class="editorialSplit__lede">
            Turpis eget, vehicula cursus leo ad litora torquent per conubia nostra, per inceptos himenaeos.
          </p>
        </div>
        <a class="button accent-primary" href="#">Default Button</a>
      </div>
      <div class="editorialSplit__main">
        <div class="cardList">
          <article class="card -horizontal">
            <h4 class="h4 card__title">Convallis ante</h4>
            <div class="card__body">
              <div>
                <p>
                  Nunc lorem erat, molestie vel turpis eget, vehicula cursus leo ad litora torquent per conubia nostra, per inceptos himenaeos.
                </p>
                <p class="card__intro">
                  Nunc lorem erat, molestie vel turpis eget, vehicula cursus leo.
                </p>
              </div>
              <a class="card__link" href="#">
                Standalone Text Link
                <svg viewBox="0 0 18 12"><use href="/main-icons-sprite.svg#arrow-right" /></svg>
              </a>
            </div>
          </article>
          <article class="card -horizontal">
            <h4 class="h4 card__title">Sed do eiusmod tempor incididunt.</h4>
            <div class="card__body">
              <div>
                <p>
                  Nunc lorem erat, molestie vel turpis eget, vehicula cursus leo ad litora torquent per conubia nostra, per inceptos himenaeos.
                </p>
                <p class="card__intro">
                  Nunc lorem erat, molestie vel turpis eget, vehicula cursus leo.
                </p>
              </div>
              <a class="card__link" href="#">
                Standalone Text Link
                <svg viewBox="0 0 18 12"><use href="/main-icons-sprite.svg#arrow-right" /></svg>
              </a>
            </div>
          </article>
          <article class="card -horizontal">
            <h4 class="h4 card__title">Consectetur adipiscing elit.</h4>
            <div class="card__body">
              <div>
                <p>
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
                </p>
                <p class="card__intro">
                  Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
                </p>
              </div>
              <a class="card__link" href="#">
                Standalone Text Link
                <svg viewBox="0 0 18 12"><use href="/main-icons-sprite.svg#arrow-right" /></svg>
              </a>
            </div>
          </article>
          <article class="card -horizontal">
            <h4 class="h4 card__title">Consectetur adipiscing elit.</h4>
            <div class="card__body">
              <div>
                <p>
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
                </p>
                <p class="card__intro">
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
                </p>
              </div>
              <a class="card__link" href="#">
                Standalone Text Link
                <svg viewBox="0 0 18 12"><use href="/main-icons-sprite.svg#arrow-right" /></svg>
              </a>
            </div>
            </div>
          </article>
        </div>
      </div>
    </div>
  </div>
</section>

<footer class="siteFooter">
  <div class="container">
    <div class="siteFooter__content">
      <aside class="siteFooter__info">
        <a class="siteFooter__logo" href="">
          <svg viewBox="0 0 300 133" fill="none" xmlns="http://www.w3.org/2000/svg">
            <rect width="300" height="133" fill="currentColor"/>
          </svg>
        </a>
        <div class="siteFooter__address">
          <div class="h5">Address</div>
          <address>
            123 West Main Street<br>
            Second Floor<br>
            Townsville, MA 01234
          </address>
          <a href="">Get Directions</a>
        </div>
        <div class="siteFooter__contact">
          <a href="tel:1234567890">(123) 546 - 7890</a><br>
          <a href="mailto:contact@companycorp.com">contact@companycorp.com</a>
        </div>
      </aside>
      <div class="siteFooter__navigation sitemap">
        <ul class="sitemap__list">
          <li class="sitemap__item">
            <div class="sitemap__heading">Link Heading</div>
            <ul class="sitemap__sublist">
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
            </ul>
          </li>
          <li class="sitemap__item">
            <div class="sitemap__heading">Link Heading</div>
            <ul class="sitemap__sublist">
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
            </ul>
          </li>
          <li class="sitemap__item">
            <div class="sitemap__heading">Link Heading</div>
            <ul class="sitemap__sublist">
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
            </ul>
          </li>
          <li class="sitemap__item">
            <div class="sitemap__heading">Link Heading</div>
            <ul class="sitemap__sublist">
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
              <li><a href="">Plain Text Link</a></li>
            </ul>
          </li>
        </ul>
      </div>
      <nav class="siteFooter__social actions">
        <a class="button -square -ghost" href="#">
            <span class="srOnly">On Facebook</span>
            <svg class="button__icon -large"><use href="/main-icons-sprite.svg#facebook" /></svg>
        </a>
        <a class="button -square -ghost" href="#">
            <span class="srOnly">On Instagram</span>
            <svg class="button__icon -large"><use href="/main-icons-sprite.svg#instagram" /></svg>
        </a>
        <a class="button -square -ghost" href="#">
            <span class="srOnly">On LinkedIn</span>
            <svg class="button__icon -large"><use href="/main-icons-sprite.svg#linkedin" /></svg>
        </a>
        <a class="button -square -ghost" href="#">
            <span class="srOnly">On YouTube</span>
            <svg class="button__icon -large"><use href="/main-icons-sprite.svg#youtube" /></svg>
        </a>
      </nav>
      <nav class="siteFooter__utility">
        <span class="siteFooter__copyright">© 2025 CompanyCorp LLC</span>
        <a href="">Privacy Policy</a>
        <a href="">Terms of Service</a>
        <a href="">Cookie Policy</a>
      </nav>
    </div>
  </div>
</footer>
POpenable.vue
<script>
const openableGroups = {}
</script>

<script setup>
import { ref, nextTick, useTemplateRef } from 'vue'

import focusableElements from '../composables/FocusableElements.js'

const { closeOnBlur, refocus, label, name, openOnHover, hoverOrClick } = defineProps({
  closeOnBlur: { type: Boolean, default: true },
  refocus: { type: Boolean, default: true },
  label: { type: String, default: '' },
  name: { type: String, default: 'global' },
  openOnHover: { type: Boolean, default: false },
  hoverOrClick: { type: Boolean, default: false },
})
const emit = defineEmits(['open', 'close'])
const button = useTemplateRef('button')
const openable = useTemplateRef('openable')
const open = ref(false)

const targetOutside = evt => {
  if (openable.value && !openable.value.contains(evt.target)) {
    toggle()
  }
}

const pressEscape = evt => {
  if (evt.key === 'Escape') {
    evt.stopPropagation()
    toggle()
  }
}

const updateGroup = open => {
  if (!name) {
    return
  }

  if (!(name in openableGroups)) {
    openableGroups[name] = new Set()
  }

  if (open) {
    openableGroups[name].forEach(t => t())
    openableGroups[name].add(toggle)
  } else {
    openableGroups[name].delete(toggle)
  }
}

const toggle = (evt, { noFocus = false } = {}) => {
  evt?.stopPropagation()
  emit(open.value ? 'close' : 'open')
  open.value = !open.value
  updateGroup(open.value)
  nextTick(() => {
    if (open.value) {
      if (refocus && !noFocus) {
        focusableElements(openable)?.[0].focus()
      }

      document.documentElement.addEventListener('click', targetOutside)
      openable.value.addEventListener('keydown', pressEscape)

      if (closeOnBlur) {
        document.documentElement.addEventListener('focusin', targetOutside)
      }
    } else {
      document.documentElement.removeEventListener('click', targetOutside)
      openable.value.removeEventListener('keydown', pressEscape)

      if (closeOnBlur) {
        document.documentElement.removeEventListener('focusin', targetOutside)
      }

      if (refocus && !noFocus) {
        focusableElements(button)?.[0].focus()
      }
    }
  })
}

let timeout = null

const mouseover = () => {
  if (timeout) {
    clearTimeout(timeout)
  }

  timeout = setTimeout(() => {
    if (!open.value) {
      toggle(undefined, { noFocus: true })
    }
  }, 450)
}

const mouseout = () => {
  if (timeout) {
    clearTimeout(timeout)
  }

  timeout = setTimeout(() => {
    if (open.value) {
      toggle(undefined, { noFocus: true })
    }
  }, 450)
}

const keypress = evt => {
  if (evt.key == ' ' || evt.key == 'Enter') {
    toggle()
  }
}

let bindings = { click: toggle }
if (openOnHover) {
  bindings = { mouseover, mouseout, keypress }
}
if (hoverOrClick) {
  bindings = { click: toggle, mouseover, mouseout }
}
</script>

<template>
  <button v-bind="$attrs" ref="button" v-on="bindings">
    <slot name="toggle" v-bind="bindings">
      {{ label }}
    </slot>
  </button>
  <div ref="openable" v-on="openOnHover || hoverOrClick ? { mouseover, mouseout } : {}">
    <slot v-if="open" v-bind="bindings" />
  </div>
</template>
vDirectionals.js
import focusableElements from '../composables/FocusableElements.js'

/**
 * Default key filters. These should be functions that 'filter out' what
 * elements should be considered when a key is hit.
 */
const KEY_BINDINGS = {
  ArrowRight: elements => elements.filter(({ x, top, bottom }) => x > 0 && top < 0 && bottom > 0),
  ArrowLeft: elements => elements.filter(({ x, top, bottom }) => x < 0 && top < 0 && bottom > 0),
  ArrowDown: elements => elements.filter(({ y, left, right }) => y > 0 && left < 0 && right > 0),
  ArrowUp: elements => elements.filter(({ y, left, right }) => y < 0 && left < 0 && right > 0),
  Home: elements => elements.length && elements.slice(0, 1),
  End: elements => elements.length && elements.slice(-1),
}

/**
 * Retrieves where the element is drawn on screen (client rects).
 * Adds in x and y for the center of the element.
 */
const getElementRects = el => {
  if (!el) {
    console.error('Unable to determine location of element', el)
    return null
  }

  const rects = el.getClientRects()[0]

  if (!rects) {
    return getElementRects(el.parentElement)
  }

  return {
    bottom: rects.bottom,
    height: rects.height,
    left: rects.left,
    right: rects.right,
    top: rects.top,
    width: rects.width,
    x: rects.left + rects.width / 2,
    y: rects.top + rects.height / 2,
  }
}

/**
 * Calls getElementRects for every element in nodeList, and adjust the
 * values to be relative to origin for simpler follow up math. Also
 * calculates the distance between the two elements' centers.
 */
const augmentElementRects = (nodeList, origin) => {
  const elements = []
  origin = getElementRects(origin)

  nodeList.forEach(el => {
    const rects = getElementRects(el)
    if (rects === null) {
      return
    }

    rects.bottom -= origin.y
    rects.left -= origin.x
    rects.right -= origin.x
    rects.top -= origin.y
    rects.x -= origin.x
    rects.y -= origin.y

    const distance = Math.sqrt(rects.x * rects.x + rects.y * rects.y)

    elements.push({ el, ...rects, distance })
  })

  return elements
}

const findTarget = (el, key, root) => {
  const elements = augmentElementRects(focusableElements(root), el)
  if (key in KEY_BINDINGS) {
    const { el } = KEY_BINDINGS[key](elements).reduce(
      (closest, el) => {
        return el.distance < closest.distance ? el : closest
      },
      { distance: Infinity },
    )

    return el
  }
  return null
}

export default {
  mounted(element) {
    const handler = evt => {
      const target = findTarget(evt.target, evt.key, element)

      if (target) {
        evt.preventDefault()
        evt.stopPropagation()
        target.focus()
      }
    }
    element.addEventListener('keydown', handler)
  },
}
vScrolllock.js
export default {
  mounted() {
    document.documentElement.style.overflow = 'hidden'
  },
  unmounted() {
    document.documentElement.style.overflow = ''
  },
}