Give the content pages the landing's look
Moving from the landing to a page read as changing sites: a narrow centred column on a flat background, light headings, no cards. The page now opens like the landing's hero — the same two lights, the same left edge as the logo, a bold title with the excerpt as its lead — and the body's headings are bold like every section title on the landing. The lights move into a shared mixin (ui/_lights.scss) so the hero and the pages cannot drift apart. On a page they sit on the whole <main> with `overflow: clip`, so they fade out on their own instead of ending in a hard edge right where the text starts, and `clip` rather than `hidden` keeps the sticky side column working. A side column keeps a page from being a dead end: "keep reading" cards for the other pages, its own category first, and a card to get in touch, both on the landing's card surface. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
@use './lights';
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
@@ -16,55 +18,86 @@
|
||||
}
|
||||
}
|
||||
|
||||
// The lights sit on the whole page rather than on its top: on the hero alone
|
||||
// they end in a hard edge where it does, and here the text starts right there.
|
||||
// A page is tall enough for them to fade out on their own.
|
||||
.content-page {
|
||||
padding-block: 4rem 5rem;
|
||||
@include lights.glow($overflow: clip);
|
||||
}
|
||||
|
||||
// The top of the page is the landing's hero, minus the stats and buttons: the
|
||||
// same left edge as the logo, the same heading weight.
|
||||
.content-hero {
|
||||
padding-block: 5rem 2.5rem;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
padding-block: 6rem 7rem;
|
||||
padding-block: 7rem 3.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
// A reading column, not the landing's full width: prose past ~70 characters a
|
||||
// line is hard to follow.
|
||||
.content-page__inner {
|
||||
max-width: 48rem;
|
||||
}
|
||||
|
||||
.content-page__title {
|
||||
.content-hero__title {
|
||||
margin: 0;
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
line-height: 1.1;
|
||||
max-width: 22ch;
|
||||
font-size: clamp(2.25rem, 5.5vw, 3.5rem);
|
||||
line-height: 1.08;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.content-page__lead {
|
||||
margin: 1.25rem 0 0;
|
||||
line-height: 1.6;
|
||||
.content-hero__lead {
|
||||
max-width: 46ch;
|
||||
margin: 1.5rem 0 0;
|
||||
}
|
||||
|
||||
// Reading column and a side column, on the landing's own grid width. The
|
||||
// column keeps prose to a readable measure; the side keeps the page from
|
||||
// ending in a dead end.
|
||||
.content-page__layout {
|
||||
display: grid;
|
||||
gap: 3rem;
|
||||
padding-bottom: 5rem;
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
grid-template-columns: minmax(0, 46rem) minmax(16rem, 20rem);
|
||||
justify-content: space-between;
|
||||
gap: 4rem;
|
||||
padding-bottom: 7rem;
|
||||
}
|
||||
}
|
||||
|
||||
.content-page__media {
|
||||
margin: 2.5rem 0 0;
|
||||
margin: 0 0 2.5rem;
|
||||
overflow: hidden;
|
||||
border-radius: var(--pi-theme-card-radius, 1.5rem);
|
||||
}
|
||||
|
||||
// The `<img>` belongs to `app-api-image`, so a scoped rule cannot reach it.
|
||||
.content-page__media ::ng-deep img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.content-page__body {
|
||||
margin-top: 2.5rem;
|
||||
font-size: 1.0625rem;
|
||||
line-height: 1.75;
|
||||
|
||||
// The body is HTML from the panel's editor, not this component's template,
|
||||
// so it carries none of the scoping attributes: only `::ng-deep` reaches it.
|
||||
// Confined to this container, it styles nothing else on the page.
|
||||
::ng-deep {
|
||||
// Bold, like every heading on the landing — a light heading here was the
|
||||
// one thing that made the page read as another site.
|
||||
h2 {
|
||||
margin: 2.5rem 0 0.75rem;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.25;
|
||||
margin: 3rem 0 1rem;
|
||||
font-size: clamp(1.5rem, 3vw, 1.875rem);
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
letter-spacing: -0.015em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 2rem 0 0.5rem;
|
||||
font-size: 1.2rem;
|
||||
margin: 2rem 0 0.75rem;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
// One rhythm for both: left alone, the library's sheet sets paragraphs
|
||||
@@ -80,12 +113,20 @@
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin: 0 0 1.25rem;
|
||||
margin: 0 0 1.5rem;
|
||||
padding-left: 1.25rem;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
&::marker {
|
||||
color: var(--pi-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
a {
|
||||
@@ -98,20 +139,77 @@
|
||||
}
|
||||
}
|
||||
|
||||
.content-page__back {
|
||||
display: inline-block;
|
||||
margin-top: 3rem;
|
||||
color: var(--pi-color-grey-600, #5b5b6b);
|
||||
text-decoration: none;
|
||||
.content-page__aside {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
|
||||
&:hover {
|
||||
color: inherit;
|
||||
// Stays in view beside a long page, under the sticky header.
|
||||
@media (min-width: 1024px) {
|
||||
position: sticky;
|
||||
top: 6rem;
|
||||
align-self: start;
|
||||
}
|
||||
}
|
||||
|
||||
// The `<img>` belongs to `app-api-image`, so a scoped rule cannot reach it.
|
||||
.content-page__media ::ng-deep img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
.content-page__related {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
// `landing-card` is the landing's card surface and hover, drawn on a link
|
||||
// rather than on `pi-card`, which brings no padding or radius of its own here.
|
||||
.content-page__card,
|
||||
.content-page__cta {
|
||||
display: block;
|
||||
padding: 1.25rem 1.5rem;
|
||||
border-radius: var(--pi-theme-card-radius, 1.5rem);
|
||||
box-shadow: var(--pi-theme-card-shadow, none);
|
||||
}
|
||||
|
||||
.content-page__card {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.content-page__card-title {
|
||||
display: block;
|
||||
font-size: 1.0625rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.content-page__card-text {
|
||||
display: -webkit-box;
|
||||
margin-top: 0.375rem;
|
||||
overflow: hidden;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5;
|
||||
// Relative to the card's own text colour, so it holds up in dark mode too,
|
||||
// where the grey token is nearly the background.
|
||||
color: color-mix(in srgb, currentColor 68%, transparent);
|
||||
}
|
||||
|
||||
.content-page__cta {
|
||||
padding: 1.5rem;
|
||||
|
||||
// The call to action is not a link as a whole, so it does not lift.
|
||||
&:hover {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0.5rem 0 1.25rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
|
||||
.content-page__cta-title {
|
||||
margin: 0;
|
||||
font-size: 1.375rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user