fix: match footer to design documents with typography and colors

This commit is contained in:
Christian Andolf
2025-05-27 13:12:01 +02:00
parent 32cc0cbe88
commit ade0279c8d
7 changed files with 100 additions and 138 deletions

View File

@@ -1,15 +1,15 @@
.details { .details {
background: var(--Base-Text-High-contrast); background: var(--Primary-Dark-Surface-Normal);
color: var(--Primary-Dark-On-Surface-Text); color: var(--Primary-Dark-On-Surface-Text);
padding: var(--Spacing-x3) 0 var(--Spacing-x6); padding: var(--Space-x3) 0 var(--Space-x6);
} }
.topContainer { .topContainer {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding-bottom: var(--Spacing-x2); padding-bottom: var(--Space-x2);
max-width: var(--max-width-page); max-width: var(--max-width-page);
margin: 0 auto var(--Spacing-x2); margin: 0 auto var(--Space-x2);
} }
.bottomContainer { .bottomContainer {
@@ -22,26 +22,26 @@
.socialNav { .socialNav {
display: flex; display: flex;
gap: var(--Spacing-x2); gap: var(--Space-x2);
} }
.navigationContainer { .navigationContainer {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin-bottom: var(--Spacing-x2); margin-bottom: var(--Space-x2);
padding-bottom: var(--Spacing-x2); padding-bottom: var(--Space-x2);
border-bottom: 1px solid var(--Base-Text-Medium-contrast); border-bottom: 1px solid var(--Primary-Dim-On-Surface-Accent);
} }
.navigation { .navigation {
display: flex; display: flex;
gap: var(--Spacing-x1); gap: var(--Space-x1);
} }
.link { .link {
&::after { &::after {
content: "·"; content: "·";
margin-left: var(--Spacing-x1); margin-left: var(--Space-x1);
} }
&:last-child { &:last-child {
@@ -51,19 +51,14 @@
} }
} }
.copyrightContainer {
display: flex;
gap: var(--Spacing-x1);
}
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {
.details { .details {
padding: var(--Spacing-x6) 0 var(--Spacing-x4); padding: var(--Space-x6) 0 var(--Space-x4);
} }
.bottomContainer { .bottomContainer {
border-top: 1px solid var(--Base-Text-Medium-contrast); border-top: 1px solid var(--Primary-Dark-On-Surface-Divider);
padding-top: var(--Spacing-x2); padding-top: var(--Space-x2);
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
} }
@@ -72,7 +67,7 @@
border-bottom: 0; border-bottom: 0;
padding-bottom: 0; padding-bottom: 0;
margin-bottom: 0; margin-bottom: 0;
gap: var(--Spacing-x4); gap: var(--Space-x4);
align-items: center; align-items: center;
} }
} }

View File

@@ -1,10 +1,11 @@
import { Typography } from "@scandic-hotels/design-system/Typography"
import { getFooter } from "@/lib/trpc/memoizedRequests" import { getFooter } from "@/lib/trpc/memoizedRequests"
import Image from "@/components/Image" import Image from "@/components/Image"
import LanguageSwitcher from "@/components/LanguageSwitcher" import LanguageSwitcher from "@/components/LanguageSwitcher"
import SkeletonShimmer from "@/components/SkeletonShimmer" import SkeletonShimmer from "@/components/SkeletonShimmer"
import Link from "@/components/TempDesignSystem/Link" import Link from "@/components/TempDesignSystem/Link"
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
@@ -20,7 +21,7 @@ export default async function FooterDetails() {
const currentYear = new Date().getFullYear() const currentYear = new Date().getFullYear()
return ( return (
<section className={styles.details}> <div className={styles.details}>
<div className={styles.topContainer}> <div className={styles.topContainer}>
<Link href={`/${lang}`}> <Link href={`/${lang}`}>
<Image <Image
@@ -37,8 +38,8 @@ export default async function FooterDetails() {
</nav> </nav>
</div> </div>
<div className={styles.bottomContainer}> <div className={styles.bottomContainer}>
<div className={styles.copyrightContainer}> <Typography variant="Tag/sm">
<Footnote type="label" textTransform="uppercase"> <p>
{intl.formatMessage( {intl.formatMessage(
{ {
defaultMessage: defaultMessage:
@@ -46,35 +47,27 @@ export default async function FooterDetails() {
}, },
{ currentYear } { currentYear }
)} )}
</Footnote> </p>
</div> </Typography>
<div className={styles.navigationContainer}> <div className={styles.navigationContainer}>
<nav className={styles.navigation}> <nav className={styles.navigation}>
{footer?.tertiaryLinks.map( {footer?.tertiaryLinks.map((link) => (
(link) => <Typography key={link.title} variant="Tag/sm">
link.url && ( <Link
<Footnote className={styles.link}
asChild color="peach50"
type="label" href={link.url}
textTransform="uppercase" target="_blank"
key={link.title} >
> {link.title}
<Link </Link>
className={styles.link} </Typography>
color="peach50" ))}
href={link.url}
target="_blank"
>
{link.title}
</Link>
</Footnote>
)
)}
</nav> </nav>
<LanguageSwitcher type="footer" /> <LanguageSwitcher type="footer" />
</div> </div>
</div> </div>
</section> </div>
) )
} }
@@ -99,8 +92,8 @@ export async function FooterDetailsSkeleton() {
</nav> </nav>
</div> </div>
<div className={styles.bottomContainer}> <div className={styles.bottomContainer}>
<div className={styles.copyrightContainer}> <Typography variant="Tag/sm">
<Footnote type="label" textTransform="uppercase"> <p>
{intl.formatMessage( {intl.formatMessage(
{ {
defaultMessage: defaultMessage:
@@ -108,8 +101,8 @@ export async function FooterDetailsSkeleton() {
}, },
{ currentYear } { currentYear }
)} )}
</Footnote> </p>
</div> </Typography>
<div className={styles.navigationContainer}> <div className={styles.navigationContainer}>
<nav className={styles.navigation}> <nav className={styles.navigation}>
<SkeletonShimmer width="40ch" height="20px" contrast="dark" /> <SkeletonShimmer width="40ch" height="20px" contrast="dark" />

View File

@@ -7,16 +7,12 @@
} }
.mainNavigationItem { .mainNavigationItem {
padding: var(--Spacing-x3) 0; padding: var(--Space-x3) 0;
border-bottom: 1px solid var(--Base-Border-Normal); border-bottom: 1px solid var(--Base-Border-Normal);
&:first-child { &:first-child {
padding-top: 0; padding-top: 0;
} }
&:last-child {
border-bottom: 0;
}
} }
.mainNavigationLink { .mainNavigationLink {

View File

@@ -1,9 +1,10 @@
"use client" "use client"
import { Typography } from "@scandic-hotels/design-system/Typography"
import Image from "@/components/Image" import Image from "@/components/Image"
import SkeletonShimmer from "@/components/SkeletonShimmer" import SkeletonShimmer from "@/components/SkeletonShimmer"
import Link from "@/components/TempDesignSystem/Link" import Link from "@/components/TempDesignSystem/Link"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import useLang from "@/hooks/useLang" import useLang from "@/hooks/useLang"
import { trackFooterClick, trackSocialMediaClick } from "@/utils/tracking" import { trackFooterClick, trackSocialMediaClick } from "@/utils/tracking"
@@ -20,58 +21,49 @@ export default function FooterSecondaryNav({
return ( return (
<div className={styles.secondaryNavigation}> <div className={styles.secondaryNavigation}>
{appDownloads && ( <nav className={styles.secondaryNavigationGroup}>
<nav className={styles.secondaryNavigationGroup}> <Typography variant="Title/Overline/sm">
<Caption <h3>{appDownloads.title}</h3>
color="textMediumContrast" </Typography>
textTransform="uppercase" {appDownloads.links.length ? (
type="label" <ul className={styles.secondaryNavigationList}>
> {appDownloads.links.map(
{appDownloads.title} ({ href, type }) =>
</Caption> href && (
{appDownloads.links.length ? ( <li key={type}>
<ul className={styles.secondaryNavigationList}> <a
{appDownloads.links.map( href={href.href}
({ href, type }) => target="_blank"
href && ( aria-label={href.title}
<li key={type} className={styles.appDownloadItem}> onClick={() => trackSocialMediaClick(href.title)}
<a >
href={href.href} <Image
target="_blank" src={
aria-label={href.title} AppDownLoadLinks[
onClick={() => trackSocialMediaClick(href.title)} `${type}_${lang}` as keyof typeof AppDownLoadLinks
> ]
<Image }
src={ alt={href.title}
AppDownLoadLinks[ width={125}
`${type}_${lang}` as keyof typeof AppDownLoadLinks height={40}
] />
} </a>
alt="" </li>
width={125} )
height={40} )}
/> </ul>
</a> ) : null}
</li> </nav>
)
)}
</ul>
) : null}
</nav>
)}
{secondaryLinks.map((group) => ( {secondaryLinks.map((group) => (
<nav className={styles.secondaryNavigationGroup} key={group.title}> <nav className={styles.secondaryNavigationGroup} key={group.title}>
<Caption <Typography variant="Title/Overline/sm">
color="textMediumContrast" <h3>{group.title}</h3>
textTransform="uppercase" </Typography>
type="label" {group.links.length ? (
>
{group.title}
</Caption>
{group?.links.length ? (
<ul className={styles.secondaryNavigationList}> <ul className={styles.secondaryNavigationList}>
{group.links.map((link) => ( {group.links.map((link) => (
<li key={link.title} className={styles.secondaryNavigationItem}> <li key={link.title}>
<Link <Link
href={link.url} href={link.url}
target={link.openInNewTab ? "_blank" : undefined} target={link.openInNewTab ? "_blank" : undefined}
@@ -96,10 +88,10 @@ export function FooterSecondaryNavSkeleton() {
<nav className={styles.secondaryNavigationGroup}> <nav className={styles.secondaryNavigationGroup}>
<SkeletonShimmer width="10ch" /> <SkeletonShimmer width="10ch" />
<ul className={styles.secondaryNavigationList}> <ul className={styles.secondaryNavigationList}>
<li className={styles.appDownloadItem}> <li>
<SkeletonShimmer width="16ch" /> <SkeletonShimmer width="16ch" />
</li> </li>
<li className={styles.appDownloadItem}> <li>
<SkeletonShimmer width="16ch" /> <SkeletonShimmer width="16ch" />
</li> </li>
</ul> </ul>
@@ -107,7 +99,7 @@ export function FooterSecondaryNavSkeleton() {
<nav className={styles.secondaryNavigationGroup}> <nav className={styles.secondaryNavigationGroup}>
<SkeletonShimmer width="20ch" /> <SkeletonShimmer width="20ch" />
<ul className={styles.secondaryNavigationList}> <ul className={styles.secondaryNavigationList}>
<li className={styles.secondaryNavigationItem}> <li>
<SkeletonShimmer width="25ch" /> <SkeletonShimmer width="25ch" />
</li> </li>
</ul> </ul>
@@ -115,16 +107,16 @@ export function FooterSecondaryNavSkeleton() {
<nav className={styles.secondaryNavigationGroup}> <nav className={styles.secondaryNavigationGroup}>
<SkeletonShimmer width="15ch" /> <SkeletonShimmer width="15ch" />
<ul className={styles.secondaryNavigationList}> <ul className={styles.secondaryNavigationList}>
<li className={styles.secondaryNavigationItem}> <li>
<SkeletonShimmer width="30ch" /> <SkeletonShimmer width="30ch" />
</li> </li>
<li className={styles.secondaryNavigationItem}> <li>
<SkeletonShimmer width="36ch" /> <SkeletonShimmer width="36ch" />
</li> </li>
<li className={styles.secondaryNavigationItem}> <li>
<SkeletonShimmer width="12ch" /> <SkeletonShimmer width="12ch" />
</li> </li>
<li className={styles.secondaryNavigationItem}> <li>
<SkeletonShimmer width="20ch" /> <SkeletonShimmer width="20ch" />
</li> </li>
</ul> </ul>

View File

@@ -1,35 +1,21 @@
.secondaryNavigation { .secondaryNavigation {
display: flex; display: flex;
flex-direction: column-reverse; flex-direction: column-reverse;
gap: var(--Spacing-x6); gap: var(--Space-x6);
} }
.secondaryNavigationList { .secondaryNavigationList {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
list-style: none; list-style: none;
gap: var(--Spacing-x3); gap: var(--Space-x2);
} }
.secondaryNavigationGroup { .secondaryNavigationGroup {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--Spacing-x3); gap: var(--Space-x3);
} color: var(--Primary-Dim-On-Surface-Accent);
.secondaryNavigationGroupTitle {
color: var(--Base-Text-Medium-contrast);
font-weight: var(--typography-Body-Bold-fontWeight);
font-family: var(--typography-Body-Bold-fontFamily);
margin: 0;
}
.secondaryNavigationLink {
color: var(--Base-Text-High-contrast);
font-weight: var(--typography-Body-Bold-fontWeight);
font-family: var(--typography-Body-Bold-fontFamily);
margin: 0;
text-decoration: none;
} }
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {

View File

@@ -12,7 +12,7 @@ export default async function FooterNavigation() {
} }
return ( return (
<section className={styles.section}> <div className={styles.section}>
<div className={styles.maxWidth}> <div className={styles.maxWidth}>
<FooterMainNav mainLinks={footer.mainLinks} /> <FooterMainNav mainLinks={footer.mainLinks} />
<FooterSecondaryNav <FooterSecondaryNav
@@ -20,17 +20,17 @@ export default async function FooterNavigation() {
appDownloads={footer.appDownloads} appDownloads={footer.appDownloads}
/> />
</div> </div>
</section> </div>
) )
} }
export function FooterNavigationSkeleton() { export function FooterNavigationSkeleton() {
return ( return (
<section className={styles.section}> <div className={styles.section}>
<div className={styles.maxWidth}> <div className={styles.maxWidth}>
<FooterMainNavSkeleton /> <FooterMainNavSkeleton />
<FooterSecondaryNavSkeleton /> <FooterSecondaryNavSkeleton />
</div> </div>
</section> </div>
) )
} }

View File

@@ -1,28 +1,28 @@
.section { .section {
background: var(--Base-Surface-Subtle-Normal); background: var(--Base-Surface-Subtle-Normal);
padding: var(--Spacing-x7) 0; padding: var(--Space-x7) 0;
} }
.maxWidth { .maxWidth {
display: grid; display: grid;
gap: var(--Spacing-x6); gap: var(--Space-x6);
margin: 0 auto; margin: 0 auto;
max-width: var(--max-width-page); max-width: var(--max-width-page);
} }
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {
.section { .section {
padding: var(--Spacing-x9) 0; padding: var(--Space-x8) 0;
} }
.maxWidth { .maxWidth {
gap: var(--Spacing-x4); gap: var(--Space-x4);
} }
} }
@media screen and (min-width: 1367px) { @media screen and (min-width: 1367px) {
.maxWidth { .maxWidth {
gap: var(--Spacing-x2); gap: var(--Space-x2);
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
} }
} }