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;
}
}