/ src / components / pages / ArticlePage.svelte
ArticlePage.svelte
  1  <script lang="ts" context="module">
  2      import type { ArticlePage } from '@jet-app/app-store/api/models';
  3  
  4      import type { DefaultPageRequirements } from './DefaultPage.svelte';
  5  
  6      /**
  7       * Just the `Page` props that we actually need to render this component
  8       */
  9      export type ArticlePageRequirements = DefaultPageRequirements & {
 10          card: ArticlePage['card'];
 11          footerLockup: ArticlePage['footerLockup'];
 12      };
 13  </script>
 14  
 15  <script lang="ts">
 16      import TodayCard from '~/components/jet/today-card/TodayCard.svelte';
 17      import ShelfComponent from '~/components/jet/shelf/Shelf.svelte';
 18      import FooterLockupItem from '~/components/jet/item/FooterLockupItem.svelte';
 19      export let page: ArticlePageRequirements;
 20  
 21      $: ({ card } = page);
 22  </script>
 23  
 24  <div class="article-page-container" data-testid="article-page-container">
 25      <div class="article-layout">
 26          {#if card}
 27              <div class="card-container">
 28                  <TodayCard {card} suppressClickAction />
 29              </div>
 30          {/if}
 31  
 32          <div class="story-container">
 33              {#each page.shelves as shelf}
 34                  {#if !shelf.isHidden}
 35                      <ShelfComponent {shelf} />
 36                  {/if}
 37              {/each}
 38  
 39              {#if page.footerLockup}
 40                  <div class="footer-lockup-container">
 41                      <FooterLockupItem item={page.footerLockup} />
 42                  </div>
 43              {/if}
 44          </div>
 45      </div>
 46  </div>
 47  
 48  <style lang="scss">
 49      @use 'ac-sasskit/modules/viewportcontent/core' as *;
 50      @use 'amp/stylekit/core/viewports' as *;
 51  
 52      .article-page-container {
 53          flex-grow: 1;
 54          width: 100%;
 55          margin: 0 auto;
 56      }
 57  
 58      .article-layout {
 59          --article-page-padding: 20px;
 60          display: flex;
 61          flex-direction: column;
 62          align-items: center;
 63          justify-content: center;
 64          gap: var(--article-page-padding);
 65          max-width: 1600px;
 66          margin: 0 auto;
 67  
 68          @media (--range-small-up) {
 69              padding: 2em var(--bodyGutter);
 70          }
 71  
 72          @media (--range-small-only) {
 73              --article-page-padding: 40px;
 74          }
 75  
 76          @media (--range-medium-up) {
 77              align-items: flex-start;
 78              flex-direction: row;
 79          }
 80  
 81          @media (--range-medium-only) {
 82              --article-page-padding: 20px;
 83          }
 84  
 85          @media (--range-large-up) {
 86              --article-page-padding: 40px;
 87          }
 88      }
 89  
 90      .card-container {
 91          flex-shrink: 0;
 92          aspect-ratio: 3/4;
 93          width: 100%;
 94  
 95          @media (--range-xsmall-only) {
 96              --border-radius: 0;
 97          }
 98  
 99          @media (--range-small-only) {
100              aspect-ratio: 16/9;
101          }
102  
103          @media (--range-small-up) {
104              width: 100%;
105          }
106  
107          @media (--range-medium-up) {
108              position: sticky;
109              top: 2em;
110              aspect-ratio: 3 / 4;
111              height: min(calc(100vh - 80px), calc(33vw * 4 / 3));
112              min-height: 420px;
113              max-height: 700px;
114              width: auto;
115          }
116      }
117  
118      .story-container {
119          width: 100%;
120          margin-top: 20px;
121          padding-bottom: var(--bodyGutter);
122  
123          @media (--range-small-up) {
124              width: calc(100%);
125              margin-top: 0;
126          }
127  
128          @media (--range-medium-up) {
129              min-width: calc(50% - calc(var(--article-page-padding)));
130          }
131      }
132  
133      .story-container :global(.shelf:first-of-type) {
134          padding-top: 0;
135          padding-bottom: 13px;
136      }
137  
138      .footer-lockup-container {
139          margin: var(--bodyGutter);
140      }
141  </style>