src/app/(proper_react)/(redesign)/(public)/PlansTable.module.scss (332 lines of code) (raw):

@use "../../../tokens"; .plansTable { border-spacing: tokens.$spacing-xl 0; table-layout: fixed; width: 100%; // Set column widths: thead th { width: calc(30% - tokens.$spacing-xl); } // Styles for the column headings thead { th.featureHeadingCell { text-align: start; vertical-align: bottom; padding-block: tokens.$spacing-lg; } .freeHeadingCell, .plusHeadingCell { padding-block: tokens.$spacing-2xl; position: relative; } h3 { font: tokens.$text-title-xs; font-weight: 600; b { color: tokens.$color-purple-70; } } } // Styles for the non-heading parts of the columns: tbody { // Ideally, the top border would span the entire row, but then it won't show // up because we haven't set `border-collapse: collapse` today. So as a // compromise, we only show it on individual cells, rather than on the `tr`: tr td, tr th { border-top: 1px solid tokens.$color-grey-20; font-weight: 400; } .featureBodyCell { text-align: start; } // This rule is less specific than the `tr td, tr th` above, but since // that line ideally would have been just `tr`, I'm leaving it up there: /* stylelint-disable no-descending-specificity */ th, td { padding-block: tokens.$spacing-md; .cellWrapper { display: flex; align-items: center; } svg.checkIcon { display: inline-block; color: tokens.$color-blue-50; } } /* stylelint-enable no-descending-specificity */ .priceCell { display: flex; flex-direction: column; align-items: stretch; gap: tokens.$spacing-lg; text-align: center; padding-block-end: tokens.$spacing-md; padding-inline: tokens.$spacing-md; width: 100%; .billingPeriod { display: flex; align-items: center; justify-content: center; min-height: tokens.$layout-md; font-weight: 500; color: tokens.$color-blue-50; } .price { font: tokens.$text-title-sm; } .total { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: tokens.$layout-xl; font: tokens.$text-body-lg; .discount { color: tokens.$color-purple-70; font-weight: 700; font-style: normal; } .sum { color: tokens.$color-grey-40; font-weight: 500; } } button { font-weight: 700; } .reassurance { font: tokens.$text-body-sm; font-weight: 400; } } } // Draw purple border around the Plus plan column: .freeCell, .plusCell { background-color: tokens.$color-white; vertical-align: middle; color: tokens.$color-grey-50; .cellWrapper { justify-content: center; } } .plusCell { font-weight: 700; border-inline: 4px solid tokens.$color-purple-70; } .badge { position: absolute; top: 0; background-color: tokens.$color-purple-70; color: tokens.$color-white; transform: translateX(-50%) translateY(-50%); border-radius: tokens.$border-radius-md; font: tokens.$text-body-sm; font-weight: 600; padding: tokens.$spacing-sm tokens.$spacing-md; @include tokens.uppercase-only-english; } th.plusHeadingCell { border-top: 4px solid tokens.$color-purple-70; border-top-right-radius: tokens.$border-radius-md; border-top-left-radius: tokens.$border-radius-md; &::before { content: "+"; position: absolute; display: flex; align-items: center; justify-content: center; background-color: tokens.$color-purple-70; color: tokens.$color-white; width: tokens.$spacing-2xl; height: tokens.$spacing-2xl; border-radius: tokens.$border-radius-xl; font: tokens.$text-title-sm; inset-block-start: 0; inset-inline-start: 0; transform: translateX(-50%) translateY(-50%); } } tbody tr:last-child .plusBodyCell { border-bottom: 4px solid tokens.$color-purple-70; border-bottom-right-radius: tokens.$border-radius-md; border-bottom-left-radius: tokens.$border-radius-md; } // Draw a light-grey line around the Free plan column: .freeCell { border-inline: 1px solid tokens.$color-grey-20; } th.freeHeadingCell { border-top: 1px solid tokens.$color-grey-20; border-top-right-radius: tokens.$border-radius-md; border-top-left-radius: tokens.$border-radius-md; } tbody tr:last-child td:nth-child(2) { border-bottom: 1px solid tokens.$color-grey-20; border-bottom-right-radius: tokens.$border-radius-md; border-bottom-left-radius: tokens.$border-radius-md; } } .plansCards { display: flex; flex-direction: row-reverse; flex-wrap: wrap; gap: tokens.$spacing-xl; padding: tokens.$spacing-md; [role="group"] { flex: 1 1 tokens.$content-sm; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: tokens.$spacing-lg; background-color: tokens.$color-white; border-radius: tokens.$border-radius-md; padding: tokens.$spacing-2xl tokens.$spacing-md; hr { border-style: none; border-top: 1px solid tokens.$color-grey-20; width: 100%; } .head { display: flex; flex-direction: column; align-items: center; gap: tokens.$spacing-sm; h3 { font: tokens.$text-title-xs; font-weight: 600; b { color: tokens.$color-purple-70; } } } .priceSection { display: flex; flex-direction: column; align-items: center; gap: tokens.$spacing-lg; .cost { display: flex; flex-direction: column; align-items: center; gap: tokens.$spacing-md; .price { font: tokens.$text-title-sm; } .total { display: block; color: tokens.$color-grey-40; em { font-weight: 700; font-style: normal; } } } .cta { font-weight: 700; } .reassurance { font: tokens.$text-body-sm; font-weight: 400; } } .featuresSection { display: flex; flex-direction: column; gap: tokens.$spacing-md; padding-inline: tokens.$spacing-sm; h4 { font: tokens.$text-title-3xs; } .featureList { list-style-type: none; display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: tokens.$spacing-lg; margin: 0; padding: 0; li { display: flex; align-items: flex-start; gap: tokens.$spacing-xs; .inclusionIcon { margin: tokens.$spacing-xs; flex: 1 0 auto; } &.included .inclusionIcon { color: tokens.$color-green-90; } &.notIncluded .inclusionIcon { color: tokens.$color-red-60; } button { flex: 1 0 auto; } } } } &.plusCard { position: relative; border: 4px solid tokens.$color-purple-70; } &.freeCard { position: relative; border: 2px solid tokens.$color-grey-20; } .badge { position: absolute; top: 0; left: 50%; transform: translateY(-50%) translateX(-50%); background-color: tokens.$color-purple-70; color: tokens.$color-white; border-radius: tokens.$border-radius-md; font: tokens.$text-body-sm; font-weight: 600; padding: tokens.$spacing-sm tokens.$spacing-md; @include tokens.uppercase-only-english; } } } .popoverTrigger { background-color: transparent; border-style: none; cursor: pointer; border-radius: tokens.$border-radius-md; padding: 0; svg { width: tokens.$layout-2xs; height: tokens.$layout-2xs; } } .popoverUnderlay { position: fixed; inset: 0; } .popover { box-shadow: tokens.$box-shadow-sm; background-color: tokens.$color-white; border: 1px solid tokens.$color-grey-20; border-radius: tokens.$border-radius-md; padding: tokens.$spacing-md; max-width: tokens.$content-sm; } .popoverArrow { position: absolute; width: 12px; height: 12px; fill: tokens.$color-white; stroke: tokens.$color-grey-20; stroke-width: 1px; &[data-placement="top"] { top: 100%; transform: translateX(-50%); } &[data-placement="bottom"] { bottom: 100%; transform: translateX(-50%) rotate(180deg); } } @media (max-width: tokens.$screen-lg) { .plansTable { display: none; } } @media (min-width: calc(tokens.$screen-lg + 1px)) { .plansCards { display: none; } }