diff --git a/services/web/app/views/subscriptions/plans/light-redesign/_mixins.pug b/services/web/app/views/subscriptions/plans/light-redesign/_mixins.pug index 2b088f98ed..fdcc07703b 100644 --- a/services/web/app/views/subscriptions/plans/light-redesign/_mixins.pug +++ b/services/web/app/views/subscriptions/plans/light-redesign/_mixins.pug @@ -1,3 +1,7 @@ +include ./_table_ctas +include ./_table_short_feature_lists +include ./_table_column_headers_row + mixin features_premium li li @@ -26,71 +30,13 @@ mixin currency_and_payment_methods() i.fa.fa-cc-paypal.fa-2x(aria-hidden="true") span.sr-only #{translate('payment_method_accepted', { paymentMethod: 'Paypal' })} -mixin plans_cta(tableHeadKey, highlighted, eventTrackingKey, additionalEventSegmentation, period) - case tableHeadKey - when 'individual_free' - +btn_buy_individual_free() - when 'individual_collaborator' - +btn_buy_individual_collaborator(highlighted, eventTrackingKey, additionalEventSegmentation, period) - when 'individual_professional' - +btn_buy_individual_professional(highlighted, eventTrackingKey, additionalEventSegmentation, period) - when 'group_collaborator' - +btn_buy_group_collaborator(highlighted, eventTrackingKey) - +additional_link_group(eventTrackingKey, additionalEventSegmentation, 'group_collaborator') - when 'group_professional' - +btn_buy_group_professional(highlighted, eventTrackingKey) - +additional_link_group(eventTrackingKey, additionalEventSegmentation, 'group_professional') - when 'group_organization' - +btn_buy_group_organization(highlighted, eventTrackingKey) - small.plans-table-th-content-additional-link.invisible(aria-hidden="true") - when 'student_free' - +btn_buy_student_free(highlighted) - when 'student_student' - +btn_buy_student_student(highlighted, eventTrackingKey, additionalEventSegmentation, period) - mixin plans_table(period, config) - var maxColumn = config.maxColumn || 4 - var tableHeadKeys = Object.keys(config.tableHead) - var highlightedColKey = tableHeadKeys[config.highlightedColumn.index] + -var highlightedColTranslationKey = config.highlightedColumn.text[period] === 'most_popular' ? 'most_popular_uppercase' : config.highlightedColumn.text[period] === 'saving_20_percent' ? 'saving_20_percent_no_exclamation' : config.highlightedColumn.text[period] - tr(class=`plans-table-cols-${tableHeadKeys.length}`) - th - - for (var i = 0; i < maxColumn; i++) - - var tableHeadKey = tableHeadKeys[i] - - var tableHeadOptions = Object.values(config.tableHead)[i] || {} - - var highlighted = highlightedColKey === tableHeadKey - - var eventTrackingKey = config.eventTrackingKey - - var additionalEventSegmentation = config.additionalEventSegmentation || {} - - var thClass = highlighted ? 'plans-table-green-highlighted' : '' - - th( - class=thClass - scope="col" - ) - .plans-table-th - if (highlighted) - //-most_popular_uppercase - -var translationKey = config.highlightedColumn.text[period] === 'most_popular' ? 'most_popular_uppercase' : config.highlightedColumn.text[period] === 'saving_20_percent' ? 'saving_20_percent_no_exclamation' : config.highlightedColumn.text[period] - p.plans-table-green-highlighted-text #{translate(translationKey)} - .plans-table-th-content - if tableHeadKey - case tableHeadKey - when 'individual_free' - | #{translate("free")} - when 'individual_collaborator' - | #{translate("standard")} - when 'individual_professional' - | #{translate("professional")} - when 'group_collaborator' - | #{translate("group_standard")} - when 'group_professional' - | #{translate("group_professional")} - when 'group_organization' - | #{translate("organization")} - when 'student_free' - | #{translate("free")} - when 'student_student' - | #{translate("student")} + +table_column_headers_row({maxColumn, tableHeadKeys, highlightedColKey, highlightedColTranslationKey}) tr(class=`plans-table-price-row plans-table-cols-${tableHeadKeys.length}`) td @@ -101,7 +47,7 @@ mixin plans_table(period, config) - var tdClass = highlighted ? 'plans-table-green-highlighted' : '' td(class=tdClass) - .plans-table-cell + .plans-table-cell.plans-table-cell-price case tableHeadKey when 'individual_free' +table_head_price('free', period) @@ -131,7 +77,7 @@ mixin plans_table(period, config) - var tdClass = highlighted ? 'plans-table-green-highlighted' : '' td(class=tdClass) - .plans-table-cell + .plans-table-cell.plans-table-cell-cta-mobile .plans-table-btn-buy-container-mobile +plans_cta(tableHeadKey, highlighted, eventTrackingKey, additionalEventSegmentation, period) @@ -144,7 +90,7 @@ mixin plans_table(period, config) - var tdClass = highlighted ? 'plans-table-green-highlighted' : '' td(class=tdClass) - .plans-table-cell + .plans-table-cell.plans-table-cell-short-feature-list div case tableHeadKey when 'individual_free' @@ -173,7 +119,7 @@ mixin plans_table(period, config) - var tdClass = highlighted ? 'plans-table-green-highlighted' : '' td(class=tdClass) - .plans-table-cell + .plans-table-cell.plans-table-cell-cta-desktop .plans-table-btn-buy-container-desktop +plans_cta(tableHeadKey, highlighted, eventTrackingKey, additionalEventSegmentation, period) @@ -185,24 +131,26 @@ mixin plans_table(period, config) colspan=dividerColspan class=((config.highlightedColumn.index === Object.keys(config.tableHead).length - 1) ? 'plans-table-last-col-highlighted' : '') ) - div - b.plans-table-divider-label #{translate(featuresPerSection.dividerLabel)} - //- will only appear on screen width >= 768px (using CSS) - i.fa.fa-question-circle( - data-toggle="tooltip" - title=translate(featuresPerSection.dividerInfo), - data-placement="top" - ) - //- will only appear on screen width < 768px (using CSS) - span.plans-table-divider-learn-more-container - span ( - span.plans-table-divider-learn-more-text( + .plans-table-cell-divider + //- all cells need 2 layers of divs for handling border and padding. See .plans-table in CSS for more details + div + b.plans-table-divider-label #{translate(featuresPerSection.dividerLabel)} + //- will only appear on screen width >= 768px (using CSS) + i.fa.fa-question-circle( data-toggle="tooltip" title=translate(featuresPerSection.dividerInfo), data-placement="top" - ) #{translate("learn_more_lowercase")} - span ) - span.sr-only #{translate(featuresPerSection.dividerInfo)} + ) + //- will only appear on screen width < 768px (using CSS) + span.plans-table-divider-learn-more-container + span ( + span.plans-table-divider-learn-more-text( + data-toggle="tooltip" + title=translate(featuresPerSection.dividerInfo), + data-placement="top" + ) #{translate("learn_more_lowercase")} + span ) + span.sr-only #{translate(featuresPerSection.dividerInfo)} for feature, featureIndex in featuresPerSection.items tr( class=`plans-table-feature-row plans-table-cols-${tableHeadKeys.length}` @@ -216,26 +164,27 @@ mixin plans_table(period, config) class=`${featureIndex === 0 ? 'plans-table-first-feature-header' : ''}` ) .plans-table-feature-name - if feature.info - span #{translate(feature.feature)} - //- will only appear on screen width >= 768px (using CSS) - i.fa.fa-question-circle.plans-table-feature-question-icon( - data-toggle="tooltip" - title=translate(feature.info), - data-placement="right" - ) - //- will only appear on screen width < 768px (using CSS) - span.plans-table-feature-learn-more-container - span ( - span.plans-table-feature-learn-more-text( + .plans-table-feature-name-content + if feature.info + span #{translate(feature.feature)} + //- will only appear on screen width >= 768px (using CSS) + i.fa.fa-question-circle.plans-table-feature-question-icon( data-toggle="tooltip" title=translate(feature.info), - data-placement="top" - ) #{translate("learn_more_lowercase")} - span ) - span.sr-only #{translate(feature.info)} - else - | #{translate(feature.feature)} + data-placement="right" + ) + //- will only appear on screen width < 768px (using CSS) + span.plans-table-feature-learn-more-container + span ( + span.plans-table-feature-learn-more-text( + data-toggle="tooltip" + title=translate(feature.info), + data-placement="top" + ) #{translate("learn_more_lowercase")} + span ) + span.sr-only #{translate(feature.info)} + else + | #{translate(feature.feature)} for plan, planIndex in Object.keys(feature.plans) - var tableHeadOptions = Object.values(config.tableHead)[planIndex] || {} - var tdClass = planIndex === config.highlightedColumn.index ? 'plans-table-green-highlighted' : '' @@ -255,33 +204,7 @@ mixin table_student(period) table.plans-table.plans-table-student +plans_table(period, plansConfig.student) -//- free plan mixins - -mixin table_short_feature_list_free() - ul.plans-table-th-content-benefit - li #{translate("one_collaborator")} - -//- individual plan mixins - -mixin table_short_feature_list_collaborator() - ul.plans-table-th-content-benefit - li !{translate("x_collaborators_per_project", {collaboratorsCount: '10'})} - li #{translate("all_premium_features")} - -//- professional plan mixins - -mixin table_short_feature_list_professional() - ul.plans-table-th-content-benefit - li !{translate("unlimited_collabs_rt",{},["b"])} - li #{translate("all_premium_features")} - -//- group_collaborator plan mixins - -mixin table_short_feature_list_group_collaborator() - ul.plans-table-th-content-benefit - li #{translate("up_to")} !{translate("x_collaborators_per_project", {collaboratorsCount: '10'})} - li - +table_head_group_total_per_year('collaborator') +//- group mixins mixin table_price_group_collaborator() .plans-table-price-container @@ -292,14 +215,6 @@ mixin table_price_group_collaborator() p.plans-table-price-period-label | #{translate('per_user_year')} -//- group_professional plan mixins - -mixin table_short_feature_list_group_professional() - ul.plans-table-th-content-benefit - li #{translate("unlimited_collaborators_in_each_project")} - li - +table_head_group_total_per_year('professional') - mixin table_price_group_professional() .plans-table-price-container s @@ -309,8 +224,6 @@ mixin table_price_group_professional() p.plans-table-price-period-label | #{translate('per_user_year')} -//- group mixins - mixin table_head_group_total_per_year(groupPlan) - var initialLicenseSize = '2' span.plans-group-total-price(data-ol-plans-v2-group-total-price=groupPlan) #{initialLocalizedGroupPrice.price[groupPlan]} @@ -321,21 +234,6 @@ mixin table_head_group_total_per_year(groupPlan) data-ol-plans-v2-table-th-group-license-size=licenseSize ) !{translate("total_per_year_for_x_users", {licenseSize})} -mixin table_short_feature_list_group_organization(additionalEventSegmentation) - - var segmentation = JSON.stringify(Object.assign({}, {button: 'group_organization-link', location: 'table-header-list', period: 'annual'}, additionalEventSegmentation)) - ul.plans-table-th-content-benefit - li #{translate("best_choices_companies_universities_non_profits")} - li #{translate("for_groups_or_site_wide")} - li - a.inline-green-link( - target="_blank" - href="/for/contact-sales" - event-tracking="plans-page-click" - event-tracking-mb="true" - event-tracking-trigger="click" - event-segmentation=segmentation - ) #{translate("also_available_as_on_premises")} - mixin group_plans_license_picker() form.plans-license-picker-form(data-ol-plans-v2-license-picker-form) .plans-v2-license-picker-select-container @@ -387,16 +285,6 @@ mixin group_plans_license_picker() span ) span.sr-only #{translate("apply_educational_discount_info")} -//- student plan mixins - -mixin table_short_feature_list_student_student(showExtraContent) - ul.plans-table-th-content-benefit - li !{translate("x_collaborators_per_project", {collaboratorsCount: '6'})} - li #{translate("all_premium_features")} - if showExtraContent - li - b !{translate("for_students_only")} - //- all plans mixins mixin table_head_price(plan, period) @@ -433,131 +321,6 @@ mixin table_cell(feature, plan) span(aria-hidden="true") - span.sr-only #{translate("feature_not_included")} -//- CTA mixins - -mixin btn_buy_individual(highlighted, eventTrackingKey, subscriptionPlan, period) - a.btn( - data-ol-start-new-subscription=subscriptionPlan - data-ol-event-tracking-key=eventTrackingKey - data-ol-item-view=period - class=(highlighted ? 'btn-primary' : 'btn-secondary') - ) - if (period === 'monthly') - span #{translate("try_for_free")} - else - span #{translate("buy_now_no_exclamation_mark")} - -mixin btn_buy_individual_free() - if (!getSessionUser()) - a.btn( - href="/register" - class=(highlighted ? 'btn-primary' : 'btn-secondary') - ) - span #{translate("try_for_free")} - else - a.btn.invisible( - aria-hidden="true" - class=(highlighted ? 'btn-primary' : 'btn-secondary') - ) - -mixin btn_buy_individual_collaborator(highlighted, eventTrackingKey, additionalEventSegmentation, period) - +btn_buy_individual(highlighted, eventTrackingKey, 'collaborator', period) - if (period === 'monthly') - +additional_link_buy(eventTrackingKey, additionalEventSegmentation, 'collaborator', period) - -mixin btn_buy_individual_professional(highlighted, eventTrackingKey, additionalEventSegmentation, period) - +btn_buy_individual(highlighted, eventTrackingKey, 'professional', period) - if (period === 'monthly') - +additional_link_buy(eventTrackingKey, additionalEventSegmentation, 'professional', period) - -mixin btn_buy_group_collaborator(highlighted, eventTrackingKey) - a.btn( - data-ol-start-new-subscription='group_collaborator' - data-ol-event-tracking-key=eventTrackingKey - data-ol-item-view='annual' - data-ol-has-custom-href - data-ol-location='table-header' - class=(highlighted ? 'btn-primary' : 'btn-secondary') - ) - span.hidden-desktop #{translate("customize")} - span.hidden-mobile #{translate("customize_your_plan")} - -mixin btn_buy_group_professional(highlighted, eventTrackingKey) - a.btn( - data-ol-start-new-subscription='group_professional' - data-ol-event-tracking-key=eventTrackingKey - data-ol-item-view='annual' - data-ol-has-custom-href - data-ol-location='table-header' - class=(highlighted ? 'btn-primary' : 'btn-secondary') - ) - span.hidden-desktop #{translate("customize")} - span.hidden-mobile #{translate("customize_your_plan")} - -mixin btn_buy_group_organization(highlighted, eventTrackingKey) - a.btn( - data-ol-start-new-subscription='group_organization' - data-ol-event-tracking-key=eventTrackingKey - data-ol-item-view='annual' - data-ol-has-custom-href - data-ol-location='table-header' - href='/for/contact-sales' - target='_blank' - class=(highlighted ? 'btn-primary' : 'btn-secondary') - ) - span #{translate("contact_us_lowercase")} - -mixin btn_buy_student_free(highlighted) - if (!getSessionUser()) - a.btn( - href="/register" - class=(highlighted ? 'btn-primary' : 'btn-secondary') - ) - span #{translate("try_for_free")} - -mixin btn_buy_student_student(highlighted, eventTrackingKey, additionalEventSegmentation, period) - a.btn( - data-ol-start-new-subscription='student' - data-ol-event-tracking-key=eventTrackingKey - data-ol-item-view=period - data-ol-location='card' - class=(highlighted ? 'btn-primary' : 'btn-secondary') - ) - if (period === 'monthly') - span #{translate("try_for_free")} - else - span #{translate("buy_now_no_exclamation_mark")} - if (period === 'monthly') - +additional_link_buy(eventTrackingKey, additionalEventSegmentation, 'student', period) - -mixin additional_link_group(eventTrackingKey, additionalEventSegmentation, plan) - - var buttonSegmentation = plan + '-link' - - var segmentation = JSON.stringify(Object.assign({}, {button: buttonSegmentation, location: 'table-header'}, additionalEventSegmentation)) - - a.btn.btn-bg-ghost( - href="/for/contact-sales" - target="_blank" - event-tracking=eventTrackingKey - event-tracking-mb="true" - event-tracking-trigger="click" - event-segmentation=segmentation - ) #{translate("contact_us_lowercase")} - -mixin additional_link_buy(eventTrackingKey, additionalEventSegmentation, plan, period) - - var buttonSegmentation = plan + '-link' - - var segmentation = JSON.stringify(Object.assign({}, {button: buttonSegmentation, location: 'table-header', period}, additionalEventSegmentation)) - - var itmCampaign = itm_campaign ? { itm_campaign } : {itm_campaign: 'plans'} - - var itmReferrer = itm_referrer ? { itm_referrer } : {} - - var qs = new URLSearchParams({planCode: plan, currency: recommendedCurrency, itm_content: 'card', ...itmCampaign, ...itmReferrer}) - - a.btn.btn-bg-ghost( - href=`/user/subscription/new?${qs.toString()}` - event-tracking=eventTrackingKey - event-tracking-mb="true" - event-tracking-trigger="click" - event-segmentation=segmentation - ) #{translate("buy_now_no_exclamation_mark")} - //- table header and control mixins mixin plans_v2_table_sticky_header(withSwitch, config) diff --git a/services/web/app/views/subscriptions/plans/light-redesign/_table_column_headers_row.pug b/services/web/app/views/subscriptions/plans/light-redesign/_table_column_headers_row.pug new file mode 100644 index 0000000000..56baa1405a --- /dev/null +++ b/services/web/app/views/subscriptions/plans/light-redesign/_table_column_headers_row.pug @@ -0,0 +1,34 @@ +mixin table_column_headers_row({maxColumn, tableHeadKeys, highlightedColKey, highlightedColTranslationKey}) + tr(class=`plans-table-cols-${tableHeadKeys.length}`) + th + - for (var i = 0; i < maxColumn; i++) + - var tableHeadKey = tableHeadKeys[i] + - var highlighted = highlightedColKey === tableHeadKey + - var thClass = highlighted ? 'plans-table-green-highlighted' : '' + + th( + class=thClass + scope="col" + ) + .plans-table-th + if (highlighted) + p.plans-table-green-highlighted-text #{translate(highlightedColTranslationKey)} + .plans-table-th-content + if tableHeadKey + case tableHeadKey + when 'individual_free' + | #{translate("free")} + when 'individual_collaborator' + | #{translate("standard")} + when 'individual_professional' + | #{translate("professional")} + when 'group_collaborator' + | #{translate("group_standard")} + when 'group_professional' + | #{translate("group_professional")} + when 'group_organization' + | #{translate("organization")} + when 'student_free' + | #{translate("free")} + when 'student_student' + | #{translate("student")} diff --git a/services/web/app/views/subscriptions/plans/light-redesign/_table_ctas.pug b/services/web/app/views/subscriptions/plans/light-redesign/_table_ctas.pug new file mode 100644 index 0000000000..d2aaa8e211 --- /dev/null +++ b/services/web/app/views/subscriptions/plans/light-redesign/_table_ctas.pug @@ -0,0 +1,144 @@ +mixin btn_buy_individual(highlighted, eventTrackingKey, subscriptionPlan, period) + a.btn( + data-ol-start-new-subscription=subscriptionPlan + data-ol-event-tracking-key=eventTrackingKey + data-ol-item-view=period + class=(highlighted ? 'btn-primary' : 'btn-secondary') + ) + if (period === 'monthly') + span #{translate("try_for_free")} + else + span #{translate("buy_now_no_exclamation_mark")} + +mixin btn_buy_individual_free() + if (!getSessionUser()) + a.btn( + href="/register" + class=(highlighted ? 'btn-primary' : 'btn-secondary') + ) + span #{translate("try_for_free")} + else + a.btn.invisible( + aria-hidden="true" + class=(highlighted ? 'btn-primary' : 'btn-secondary') + ) + +mixin btn_buy_individual_collaborator(highlighted, eventTrackingKey, additionalEventSegmentation, period) + +btn_buy_individual(highlighted, eventTrackingKey, 'collaborator', period) + if (period === 'monthly') + +additional_link_buy(eventTrackingKey, additionalEventSegmentation, 'collaborator', period) + +mixin btn_buy_individual_professional(highlighted, eventTrackingKey, additionalEventSegmentation, period) + +btn_buy_individual(highlighted, eventTrackingKey, 'professional', period) + if (period === 'monthly') + +additional_link_buy(eventTrackingKey, additionalEventSegmentation, 'professional', period) + +mixin btn_buy_group_collaborator(highlighted, eventTrackingKey) + a.btn( + data-ol-start-new-subscription='group_collaborator' + data-ol-event-tracking-key=eventTrackingKey + data-ol-item-view='annual' + data-ol-has-custom-href + data-ol-location='table-header' + class=(highlighted ? 'btn-primary' : 'btn-secondary') + ) + span.hidden-desktop #{translate("customize")} + span.hidden-mobile #{translate("customize_your_plan")} + +mixin btn_buy_group_professional(highlighted, eventTrackingKey) + a.btn( + data-ol-start-new-subscription='group_professional' + data-ol-event-tracking-key=eventTrackingKey + data-ol-item-view='annual' + data-ol-has-custom-href + data-ol-location='table-header' + class=(highlighted ? 'btn-primary' : 'btn-secondary') + ) + span.hidden-desktop #{translate("customize")} + span.hidden-mobile #{translate("customize_your_plan")} + +mixin btn_buy_group_organization(highlighted, eventTrackingKey) + a.btn( + data-ol-start-new-subscription='group_organization' + data-ol-event-tracking-key=eventTrackingKey + data-ol-item-view='annual' + data-ol-has-custom-href + data-ol-location='table-header' + href='/for/contact-sales' + target='_blank' + class=(highlighted ? 'btn-primary' : 'btn-secondary') + ) + span #{translate("contact_us_lowercase")} + +mixin btn_buy_student_free(highlighted) + if (!getSessionUser()) + a.btn( + href="/register" + class=(highlighted ? 'btn-primary' : 'btn-secondary') + ) + span #{translate("try_for_free")} + +mixin btn_buy_student_student(highlighted, eventTrackingKey, additionalEventSegmentation, period) + a.btn( + data-ol-start-new-subscription='student' + data-ol-event-tracking-key=eventTrackingKey + data-ol-item-view=period + data-ol-location='card' + class=(highlighted ? 'btn-primary' : 'btn-secondary') + ) + if (period === 'monthly') + span #{translate("try_for_free")} + else + span #{translate("buy_now_no_exclamation_mark")} + if (period === 'monthly') + +additional_link_buy(eventTrackingKey, additionalEventSegmentation, 'student', period) + +mixin additional_link_group(eventTrackingKey, additionalEventSegmentation, plan) + - var buttonSegmentation = plan + '-link' + - var segmentation = JSON.stringify(Object.assign({}, {button: buttonSegmentation, location: 'table-header'}, additionalEventSegmentation)) + + a.btn.btn-bg-ghost( + href="/for/contact-sales" + target="_blank" + event-tracking=eventTrackingKey + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation=segmentation + ) #{translate("contact_us_lowercase")} + +mixin additional_link_buy(eventTrackingKey, additionalEventSegmentation, plan, period) + - var buttonSegmentation = plan + '-link' + - var segmentation = JSON.stringify(Object.assign({}, {button: buttonSegmentation, location: 'table-header', period}, additionalEventSegmentation)) + - var itmCampaign = itm_campaign ? { itm_campaign } : {itm_campaign: 'plans'} + - var itmReferrer = itm_referrer ? { itm_referrer } : {} + - var qs = new URLSearchParams({planCode: plan, currency: recommendedCurrency, itm_content: 'card', ...itmCampaign, ...itmReferrer}) + + a.btn.btn-bg-ghost( + href=`/user/subscription/new?${qs.toString()}` + event-tracking=eventTrackingKey + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation=segmentation + ) #{translate("buy_now_no_exclamation_mark")} + +mixin plans_cta(tableHeadKey, highlighted, eventTrackingKey, additionalEventSegmentation, period) + case tableHeadKey + when 'individual_free' + +btn_buy_individual_free() + when 'individual_collaborator' + +btn_buy_individual_collaborator(highlighted, eventTrackingKey, additionalEventSegmentation, period) + when 'individual_professional' + +btn_buy_individual_professional(highlighted, eventTrackingKey, additionalEventSegmentation, period) + when 'group_collaborator' + +btn_buy_group_collaborator(highlighted, eventTrackingKey) + +additional_link_group(eventTrackingKey, additionalEventSegmentation, 'group_collaborator') + when 'group_professional' + +btn_buy_group_professional(highlighted, eventTrackingKey) + +additional_link_group(eventTrackingKey, additionalEventSegmentation, 'group_professional') + when 'group_organization' + +btn_buy_group_organization(highlighted, eventTrackingKey) + small.plans-table-th-content-additional-link.invisible(aria-hidden="true") + when 'student_free' + +btn_buy_student_free(highlighted) + when 'student_student' + +btn_buy_student_student(highlighted, eventTrackingKey, additionalEventSegmentation, period) diff --git a/services/web/app/views/subscriptions/plans/light-redesign/_table_short_feature_lists.pug b/services/web/app/views/subscriptions/plans/light-redesign/_table_short_feature_lists.pug new file mode 100644 index 0000000000..bb8eb46843 --- /dev/null +++ b/services/web/app/views/subscriptions/plans/light-redesign/_table_short_feature_lists.pug @@ -0,0 +1,48 @@ +mixin table_short_feature_list_free() + ul + li #{translate("one_collaborator")} + +mixin table_short_feature_list_collaborator() + ul + li !{translate("x_collaborators_per_project", {collaboratorsCount: '10'})} + li #{translate("all_premium_features")} + +mixin table_short_feature_list_professional() + ul + li !{translate("unlimited_collabs_rt",{},["b"])} + li #{translate("all_premium_features")} + +mixin table_short_feature_list_group_collaborator() + ul + li #{translate("up_to")} !{translate("x_collaborators_per_project", {collaboratorsCount: '10'})} + li + +table_head_group_total_per_year('collaborator') + +mixin table_short_feature_list_group_professional() + ul + li #{translate("unlimited_collaborators_in_each_project")} + li + +table_head_group_total_per_year('professional') + +mixin table_short_feature_list_group_organization(additionalEventSegmentation) + - var segmentation = JSON.stringify(Object.assign({}, {button: 'group_organization-link', location: 'table-header-list', period: 'annual'}, additionalEventSegmentation)) + ul + li #{translate("best_choices_companies_universities_non_profits")} + li #{translate("for_groups_or_site_wide")} + li + a.inline-green-link( + target="_blank" + href="/for/contact-sales" + event-tracking="plans-page-click" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation=segmentation + ) #{translate("also_available_as_on_premises")} + +mixin table_short_feature_list_student_student(showExtraContent) + ul + li !{translate("x_collaborators_per_project", {collaboratorsCount: '6'})} + li #{translate("all_premium_features")} + if showExtraContent + li + b !{translate("for_students_only")} diff --git a/services/web/frontend/stylesheets/app/plans/plans-light-touch-redesign.less b/services/web/frontend/stylesheets/app/plans/plans-light-touch-redesign.less index 1c6dc33c69..c9a275e2c2 100644 --- a/services/web/frontend/stylesheets/app/plans/plans-light-touch-redesign.less +++ b/services/web/frontend/stylesheets/app/plans/plans-light-touch-redesign.less @@ -464,18 +464,86 @@ .plans-table-th-content, .plans-table-price, - .plans-table-comments-icon, - .plans-table-th-content-benefit { + .plans-table-comments-icon { color: var(--neutral-90); } - // cannot add border to td,th directly due to highlighted column border + .plans-table-short-feature-list ul { + color: var(--neutral-90); + font-size: var(--font-size-02); + line-height: var(--line-height-02); + hyphens: auto; + padding-left: 15px; + text-align: left; + margin-bottom: 0; + } + + // Table BORDER and PADDING + // Cannot add border to td, th directly due to highlighted column border. + // The outer div handles the border (see exception below for highlighted column). + // The inner div handles the padding. + // The 2 layers of divs make the highlighted column border appears + // as a solid vertical line across the table. + // The highlighted column's border handling is an exception. The inner div (div > div) + // of the highlighted column handles the horizontal border (gray) so that it appears as + // behind the vertical border (green). + // On mobile, there is no vertical border for the highighted column td > div, th > div { + // border border-left: @table-border; border-top: @table-border; border-right: @table-border; border-bottom: 0; + // border adjustments + &.plans-table-cell-cta-desktop, + &.plans-table-cell-cta-mobile, + &.plans-table-cell-short-feature-list, + &.plans-table-cell-price, + &.plans-table-cell-divider { + border-top: 0; + } + &.plans-table-cell-divider { + border-bottom: 0; + } + + // padding + > div { + padding: var(--spacing-05) var(--spacing-08); + @media (max-width: @screen-xs-max) { + padding: var(--spacing-05); + } + } + // padding adjustments + &.plans-table-th > div { + padding-top: var(--spacing-06); + padding-bottom: var(--spacing-06); + } + &.plans-table-cell-price > div { + padding-top: 0; + padding-bottom: var(--spacing-06); + } + &.plans-table-cell-short-feature-list > div { + padding-top: 0; + padding-bottom: 0; + + @media (max-width: @screen-xs-max) { + padding-bottom: var(--spacing-06); + } + } + &.plans-table-cell-cta-desktop > div { + padding-top: var(--spacing-08); + } + &.plans-table-cell-cta-mobile > div { + padding-top: 0; + padding-bottom: var(--spacing-06); + } + &.plans-table-feature-name > div { + padding-left: var(--spacing-05); + } + &.plans-table-cell-divider > div { + padding: var(--spacing-05) var(--spacing-08); + } @media (max-width: @screen-xs-max) { border-left: unset; @@ -483,6 +551,7 @@ } } + // border adjustments for highlighted column // remove left border for all col after highlighted column .plans-table-green-highlighted ~ td > div, .plans-table-green-highlighted ~ th > div { @@ -493,7 +562,6 @@ th:has(~ .plans-table-green-highlighted) > div { border-right: 0; } - // highlighted column border th.plans-table-green-highlighted > div, td.plans-table-green-highlighted > div { @@ -504,6 +572,10 @@ // and then apply the gray top border to the inner div, .plans-table-cell-content border-top: 0; + &.plans-table-th { + border-top: @table-border-size solid var(--green-50); + } + .plans-table-cell-content { border-top: @table-border; } @@ -511,87 +583,67 @@ @media (max-width: @screen-xs-max) { border-left: unset; border-right: unset; + .plans-table-cell-content { + border-color: transparent; + } } } - - th { - &:nth-child(2):not(.plans-table-green-highlighted) .plans-table-th { - border-top-left-radius: @plans-table-border-radius; + tr.plans-table-divider { + // highlighted divider will only show if the highlighted column is on the last visible column + .plans-table-last-col-highlighted > div { + border-right: @highlighted-border; + } + } + // add border for last row + tr:last-child { + td > div, + th > div { + border-bottom: @table-border; + } + td.plans-table-green-highlighted > div { + border-bottom: @highlighted-border; @media (max-width: @screen-xs-max) { - border-top-left-radius: 0; + // column is not highlighted on mobile, so + // match non-highlighted column border on mobile + border-top: @table-border; + border-bottom: @table-border; } } } - .plans-table-cta-desktop, - .plans-table-cta-mobile, - .plans-table-short-feature-list, - .plans-table-price-row { - td > div { + // remove borders + tr.plans-table-divider + tr { + td > div, + th > div { border-top: 0; } - } - - th[scope='col'] > div { - padding: var(--spacing-06) var(--spacing-08); - } - th[scope='row'] > div { - padding: var(--spacing-05) var(--spacing-08) var(--spacing-05) - var(--spacing-05); - } - td > div > div { - // apply spacing to inner div to not interfere with border - padding: var(--spacing-05) var(--spacing-08); - - @media (max-width: @screen-xs-max) { - padding: var(--spacing-05); + .plans-table-green-highlighted { + .plans-table-cell-content { + border-top: 0; + } } } - tr.plans-table-divider > td > div { - // td style above not applied since there is only 1 level of div within divider cells - padding: var(--spacing-05) var(--spacing-08); - } - - tr.plans-table-price-row > td > div > div { - padding-top: 0; - padding-bottom: var(--spacing-06); - } - tr.plans-table-short-feature-list > td > div > div { - padding-top: 0; - padding-bottom: 0; - - @media (max-width: @screen-xs-max) { - padding-bottom: var(--spacing-06); + tr.plans-table-cols-2 { + th:last-child { + div { + border: 0; + } } } - tr.plans-table-cta-desktop > td > div > div { - padding-top: var(--spacing-08); - } - tr.plans-table-cta-mobile > td > div > div { - padding-top: 0; - padding-bottom: var(--spacing-06); - } - // We want these `div` inside `th` and `td` to have a 100% height since - // white backgrounds are defined here: - // 1. `td > div.plans-table-cell` - // 2. `th > div.plans-table-th` - // - // To make both of them have 100% height of their respective `td` and `th`, - // we need to have the `table` has an explicit `height` rule. - // The value can be arbitrary, since it will be ignored by the browser - // - // See https://stackoverflow.com/a/56913789 for more details - height: 100%; - - th[scope='row'] { - font-weight: 500; - } + // border radius tr { - height: 100%; + th { + &:nth-child(2):not(.plans-table-green-highlighted) .plans-table-th { + border-top-left-radius: @plans-table-border-radius; + @media (max-width: @screen-xs-max) { + border-top-left-radius: 0; + } + } + } // top right border radius on desktop only &:first-of-type { th:last-child > .plans-table-th { @@ -622,28 +674,36 @@ } } } + } - td > div, - th > div { - border-bottom: @table-border; - } + // top left border radius on first feature row + .plans-table-first-feature-header > .plans-table-feature-name { + border-top-left-radius: @plans-table-border-radius; - .plans-table-green-highlighted > div { - border-bottom: @highlighted-border; - - @media (max-width: @screen-xs-max) { - // column is not highlighted on mobile, so - // match non-highlighted column border on mobile - border-top: @table-border; - border-bottom: @table-border; - .plans-table-cell-content { - border-color: transparent; - } - } + @media (max-width: @screen-xs-max) { + border-top-left-radius: 0; } } } + // We want these `div` inside `th` and `td` to have a 100% height so + // that their borders are all the full height of their row. + // + // To make both of them have 100% height of their respective `td` and `th`, + // we need to have the `table` has an explicit `height` rule. + // The value can be arbitrary, since it will be ignored by the browser + // + // See https://stackoverflow.com/a/56913789 for more details + height: 100%; + + th[scope='row'] { + font-weight: 500; + } + + tr { + height: 100%; + } + th[scope='col'], td { text-align: center; @@ -656,12 +716,6 @@ line-height: var(--line-height-04); vertical-align: top; position: relative; - - &.plans-table-green-highlighted { - .plans-table-th { - border-top: @table-border-size solid var(--green-50); - } - } } td { @@ -674,25 +728,10 @@ // keep the position here, otherwise messes up border on safari position: relative; } - - .plans-table-first-feature-header { - .plans-table-feature-name { - border-top-left-radius: @plans-table-border-radius; - - @media (max-width: @screen-xs-max) { - border-top-left-radius: 0; - } - } - } } tr.plans-table-divider { background-color: var(--neutral-10); - th > div, - td > div { - border-top: 0; - border-bottom: 0; - } // direct child selector to NOT affect the generated tooltip td > div { @@ -708,11 +747,6 @@ } } - // highlighted divider will only show if the highlighted column is on the last visible column - .plans-table-last-col-highlighted > div { - border-right: @highlighted-border; - } - @media (max-width: @screen-xs-max) { padding-top: 0; padding-right: 0; @@ -753,26 +787,6 @@ } } - tr.plans-table-divider + tr { - td > div, - th > div { - border-top: 0; - } - .plans-table-green-highlighted { - .plans-table-cell-content { - border-top: 0; - } - } - } - - tr.plans-table-cols-2 { - th:last-child { - div { - border: 0; - } - } - } - .fa-check { color: @green; } @@ -920,15 +934,6 @@ } } - ul.plans-table-th-content-benefit { - font-size: var(--font-size-02); - line-height: var(--line-height-02); - hyphens: auto; - padding-left: 15px; - text-align: left; - margin-bottom: 0; - } - // this class should only appear on the group table .plans-group-total-price { font-weight: 700; @@ -965,7 +970,7 @@ } } - .plans-table-feature-name { + .plans-table-feature-name-content { display: flex; justify-content: space-between; align-items: center;