mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-17 08:36:25 +03:00
477 lines
26 KiB
CSS
477 lines
26 KiB
CSS
/* ============================================================
|
|
Screen 07: layout structure.
|
|
|
|
Every other structural screen changes something you can see on its own: a
|
|
divider is there or it is not, a corner is round or it is square. This one
|
|
changes proportion, and a proportion is invisible without a ruler. Four
|
|
pages with the columns nudged a few points apart are four identical pages.
|
|
|
|
So the ruler is drawn. The measure below is a real twelve-column grid, and
|
|
the three disciplined answers place every block on an exact column count:
|
|
what changes between them is which spans the page spends its columns on.
|
|
Freeform is then the one answer that crosses the lines, and it reads as a
|
|
decision because the thing it is breaking is on screen next to it.
|
|
|
|
Two selectors per option, the shape screen 03 established. The first is the
|
|
hover preview and belongs to this screen alone. The second is the committed
|
|
answer and reaches every artboard marked data-carry, which is this screen
|
|
plus boundaries, corners, and depth, so each later question is asked about
|
|
the page as it has been chosen so far. The measure itself does not travel:
|
|
it is an instrument for this question, drawn only where it is asked.
|
|
============================================================ */
|
|
|
|
/* ── The measure ─────────────────────────────────────────────
|
|
Twelve columns and eleven gutters inside the page margins, so a column is
|
|
(100% - 11 x 1.6%) / 12. The span variables are the width of n columns
|
|
including the gutters they swallow, which is what a grid track needs and
|
|
what makes an answer legible: --pvs-w7 against --pvs-w5 is a seven-five
|
|
hero, and it is written that way rather than as 57.6667%.
|
|
|
|
Percentages resolve against the box they are used in. Every section's
|
|
content box is the page width, so spans hold there; the gallery sits inside
|
|
one editorial track, so its gutter is scaled by that track's share. The
|
|
ladder runs to ten because the widest gallery track is a ten-column one,
|
|
and each answer's gallery gutter is derived from the number here. */
|
|
[data-carry] {
|
|
--pvs-gut: 1.6%;
|
|
--pvs-w1: 6.8667%;
|
|
--pvs-w2: 15.3333%;
|
|
--pvs-w3: 23.8%;
|
|
--pvs-w4: 32.2667%;
|
|
--pvs-w5: 40.7333%;
|
|
--pvs-w6: 49.2%;
|
|
--pvs-w7: 57.6667%;
|
|
--pvs-w8: 66.1333%;
|
|
--pvs-w9: 74.6%;
|
|
--pvs-w10: 83.0667%;
|
|
}
|
|
|
|
/* The page's own margins are asymmetric under two of the answers, and a
|
|
drawn grid makes it obvious when only some rows honor them. Chrome and the
|
|
editorial band are brought onto the same measure as the hero and the proof
|
|
band. Scoped to the structural artboards: screens 03 and 04 are judging
|
|
color and glyphs, and their page is not under a ruler. */
|
|
[data-carry]:not(.picker-preview-layout) :is(.ps-nav, .ps-editorial, .ps-footer) {
|
|
padding-right: var(--pvs-gutter-end);
|
|
}
|
|
|
|
/* The proof band divides in four, which on a twelve-column page means each
|
|
claim takes three columns and each divider sits in a gutter. It was four
|
|
equal shares of whatever was left after a fixed 25px gap, which lands a few
|
|
pixels off every column line: close enough to pass unnoticed on a bare
|
|
page, and the one row that looks wrong once the lines are drawn. */
|
|
[data-carry]:not(.picker-preview-layout) .ps-desktop > .ps-proof {
|
|
grid-template-columns:
|
|
var(--pvs-w3) auto
|
|
var(--pvs-w3) auto
|
|
var(--pvs-w3) auto
|
|
minmax(0, 1fr);
|
|
column-gap: calc(var(--pvs-gut) / 2);
|
|
}
|
|
|
|
/* Eleven hairlines, one down the middle of each gutter, rather than the
|
|
filled columns a grid tool draws. Filled columns cover four fifths of the
|
|
page and turn it into wallpaper at any tint dark enough to see, and the
|
|
gutter is ten pixels wide at this size, so painting it whole gives a stripe
|
|
rather than a line. The centre line carries the same information and
|
|
carries it better: where two blocks are on the grid, the mark lands dead
|
|
centre in the gap between them, and where one is not, it does not.
|
|
|
|
Mixed from the artboard's own ink so the field survives a drenched ground,
|
|
and kept under the page so nothing is read through it. */
|
|
|
|
/* The field is nailed to six and six and carries its own twelve columns
|
|
rather than reading the answer's margins and the ladder above. A measure
|
|
that re-fits itself to whatever page is on it is not a measure: the origin
|
|
and the column width would both follow the answer, and four pages each
|
|
checked against a ruler cut to fit would be four pages checked against
|
|
nothing. The instrument is the same one under all four. What moves is the
|
|
page standing on it, which is the whole of what this screen is asking. */
|
|
.picker-preview-layout .ps-desktop {
|
|
position: relative;
|
|
isolation: isolate;
|
|
}
|
|
|
|
.picker-preview-layout .ps-desktop::before {
|
|
--pvs-field-col: 6.8667%;
|
|
--pvs-field-gut: 1.6%;
|
|
--pvs-mark: calc(var(--pvs-field-col) + var(--pvs-field-gut) / 2);
|
|
|
|
content: "";
|
|
position: absolute;
|
|
z-index: -1;
|
|
inset: 0 6%;
|
|
background-image: repeating-linear-gradient(
|
|
to right,
|
|
transparent 0 calc(var(--pvs-mark) - 0.5px),
|
|
color-mix(in oklab, var(--pvs-ink) 5%, transparent)
|
|
calc(var(--pvs-mark) - 0.5px) calc(var(--pvs-mark) + 0.5px),
|
|
transparent calc(var(--pvs-mark) + 0.5px)
|
|
calc(var(--pvs-field-col) + var(--pvs-field-gut))
|
|
);
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* The handset has one column, so twelve bands would say nothing there. What
|
|
the answer changes on a phone is the measure itself and whether anything
|
|
is allowed to cross it, so the two content edges are the whole ruler. */
|
|
.picker-preview-layout .ps-phone-body {
|
|
position: relative;
|
|
isolation: isolate;
|
|
}
|
|
|
|
.picker-preview-layout .ps-phone-body::before {
|
|
content: "";
|
|
position: absolute;
|
|
z-index: -1;
|
|
top: 0;
|
|
bottom: 0;
|
|
left: var(--pvs-phone-gutter, 6%);
|
|
right: var(--pvs-phone-gutter, 6%);
|
|
border-inline: 1px solid color-mix(in oklab, var(--pvs-ink) 5%, transparent);
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* ── Simple grid ─────────────────────────────────────────────
|
|
Six and six, four cards of two, equal margins, bands of near-equal weight.
|
|
Everything starts and stops on a line, and the thing to notice is that
|
|
there is nothing to notice. */
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) [data-carry]:not(.picker-preview-layout) {
|
|
--pvs-gutter: 6%;
|
|
--pvs-gutter-end: 6%;
|
|
--pvs-hero-cols: var(--pvs-w6) minmax(0, 1fr);
|
|
--pvs-hero-gap: var(--pvs-gut);
|
|
--pvs-editorial-cols: var(--pvs-w4) minmax(0, 1fr);
|
|
--pvs-editorial-gap: var(--pvs-gut);
|
|
/* Four equal cards of two columns need no ratio. The gap is the page
|
|
gutter restated as a share of the eight-column track it sits inside. */
|
|
--pvs-gallery-cols: repeat(4, minmax(0, 1fr));
|
|
--pvs-gallery-gap: calc(var(--pvs-gut) * 100 / 66.1333);
|
|
--pvs-section-align: start;
|
|
--pvs-rows: 9.4% 45.5% 9% 27.8% 8.3%;
|
|
--pvs-phone-gutter: 7%;
|
|
--pvs-phone-gallery-cols: 1fr 1fr;
|
|
}
|
|
|
|
/* ── Balanced ────────────────────────────────────────────────
|
|
The same grid, spent unevenly. The hero leans five-seven and the lead card
|
|
takes three columns where its neighbours take two. Both breaks land on the
|
|
lines: the emphasis is chosen, the discipline is not loosened. */
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="balanced"]:checked) [data-carry]:not(.picker-preview-layout) {
|
|
--pvs-gutter: 6%;
|
|
--pvs-gutter-end: 6%;
|
|
--pvs-hero-cols: var(--pvs-w5) minmax(0, 1fr);
|
|
--pvs-hero-gap: var(--pvs-gut);
|
|
--pvs-editorial-cols: var(--pvs-w3) minmax(0, 1fr);
|
|
--pvs-editorial-gap: var(--pvs-gut);
|
|
/* Three columns then three of two. The tracks are fr in the same
|
|
proportion as the spans, because fr cannot take a percentage variable,
|
|
and the gap is the page gutter inside a nine-column track. */
|
|
--pvs-gallery-cols: 23.8fr 15.3333fr 15.3333fr 15.3333fr;
|
|
--pvs-gallery-gap: calc(var(--pvs-gut) * 100 / 74.6);
|
|
--pvs-section-align: center;
|
|
--pvs-rows: 9.4% 50.6% 9% 22.7% 8.3%;
|
|
--pvs-phone-gutter: 6%;
|
|
--pvs-phone-gallery-cols: 1.35fr 0.85fr;
|
|
}
|
|
|
|
/* Balanced needs no block of its own on this screen. The shared artboard is
|
|
already an asymmetrically balanced page: margins of 5.5 and 3.2, a hero that
|
|
splits 35.8 against the rest across a wide gap, and a lead card carrying more
|
|
than the three beside it. Unequal parts that settle on a centered axis is
|
|
what balance means, so the default is the answer and Simple grid is the one
|
|
that has to be talked out of it, below. */
|
|
|
|
/* Simple grid, on this screen's own preview. The regular one: equal margins,
|
|
whole-column spans, four identical cards, and a single gutter used as every
|
|
gap down the page, so one rhythm runs from the nav to the footer. Every block
|
|
hangs from the top of its band rather than floating in the middle of it.
|
|
Nothing added, only proportions evened out. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) .picker-preview-layout,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) .picker-preview-layout {
|
|
--pvs-gutter: 6%;
|
|
--pvs-gutter-end: 6%;
|
|
/* Equal halves. Any split with a dominant mass is asymmetrical balance,
|
|
which is the other answer. The copy's own bars are capped below so the
|
|
half does not read as a half-page smear of text. */
|
|
--pvs-hero-cols: var(--pvs-w6) minmax(0, 1fr);
|
|
--pvs-hero-gap: var(--pvs-gut);
|
|
/* The section copy is removed below, so the card row takes the whole band:
|
|
four cards of exactly three columns, sitting directly under the proof
|
|
band's four three-column claims. Two rows of the same four cells is what
|
|
a simple grid looks like. */
|
|
--pvs-editorial-cols: minmax(0, 1fr);
|
|
--pvs-editorial-gap: 0%;
|
|
--pvs-gallery-cols: repeat(4, minmax(0, 1fr));
|
|
--pvs-gallery-gap: var(--pvs-gut);
|
|
--pvs-section-align: start;
|
|
--pvs-rows: 9.4% 45.5% 9% 27.8% 8.3%;
|
|
--pvs-phone-gutter: 6%;
|
|
--pvs-phone-gallery-cols: 1fr 1fr;
|
|
}
|
|
|
|
/* The one block that leaves: the section copy beside the cards. A text column
|
|
against a card row is a two-weight composition, and this answer is the one
|
|
without a second weight. Desktop only; the handset stack is sized in pixels
|
|
and closes the gap itself. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) .picker-preview-layout .ps-desktop .ps-editorial-copy,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) .picker-preview-layout .ps-desktop .ps-editorial-copy {
|
|
display: none;
|
|
}
|
|
|
|
/* The handset, on the same terms. The section copy goes for the same reason it
|
|
went on the desktop, and its row goes with it so the two cards keep the
|
|
flexible row at the bottom of the stack. The card gap comes down to the
|
|
page's own gutter and the proof band's uneven inset is evened out: one
|
|
margin, one gap, two equal cards. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) .picker-preview-layout .ps-phone-body .ps-editorial-copy,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) .picker-preview-layout .ps-phone-body .ps-editorial-copy {
|
|
display: none;
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) .picker-preview-layout .ps-phone-body,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) .picker-preview-layout .ps-phone-body {
|
|
grid-template-rows: 31% auto auto auto 34px minmax(0, 1fr);
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) .picker-preview-layout .ps-phone-body .ps-gallery,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) .picker-preview-layout .ps-phone-body .ps-gallery {
|
|
gap: 6%;
|
|
margin-left: 0;
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) .picker-preview-layout .ps-phone-body .ps-proof,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) .picker-preview-layout .ps-phone-body .ps-proof {
|
|
padding-inline: 4%;
|
|
}
|
|
|
|
/* The bars keep a text measure instead of running to the column edge, so the
|
|
copy reads as a compact block in its half rather than a wide one. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) .picker-preview-layout .ps-hero-copy .ps-headline i,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) .picker-preview-layout .ps-hero-copy .ps-headline i {
|
|
width: 76%;
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) .picker-preview-layout .ps-hero-copy .ps-headline i:last-child,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) .picker-preview-layout .ps-hero-copy .ps-headline i:last-child {
|
|
width: 54%;
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) .picker-preview-layout .ps-hero-copy .ps-copy i,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) .picker-preview-layout .ps-hero-copy .ps-copy i {
|
|
width: 58%;
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) .picker-preview-layout .ps-hero-copy .ps-copy i:last-child,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) .picker-preview-layout .ps-hero-copy .ps-copy i:last-child {
|
|
width: 44%;
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) .picker-preview-layout .ps-hero-copy .ps-eyebrow,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) .picker-preview-layout .ps-hero-copy .ps-eyebrow {
|
|
width: 38%;
|
|
}
|
|
|
|
/* Editorial, on this screen's own preview. The option's own definition is
|
|
the spec: uneven columns, with one of them clearly leading. Every edge
|
|
still lands on the drawn lines; what changes is that the spans are ranked
|
|
instead of evened. The hero gives the copy seven columns against the
|
|
picture's five, and the headline takes the scale that span earns. The
|
|
section band drops from four columns to three, ranked four, three, two
|
|
left to right: a ladder, not a row. Balanced leans and settles around a
|
|
centered axis; this page has a first column, a second, and a third. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="editorial"]) .picker-preview-layout,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="editorial"]:checked) .picker-preview-layout {
|
|
--pvs-gutter: 6%;
|
|
--pvs-gutter-end: 6%;
|
|
/* The leading column: copy at seven against the picture's five. Balanced
|
|
leans the other way, so the two answers cannot be mistaken. */
|
|
--pvs-hero-cols: var(--pvs-w7) minmax(0, 1fr);
|
|
--pvs-hero-gap: var(--pvs-gut);
|
|
--pvs-editorial-cols: var(--pvs-w3) minmax(0, 1fr);
|
|
--pvs-editorial-gap: var(--pvs-gut);
|
|
/* Three ranked columns in the nine-column track: four, three, two. The
|
|
tracks are fr in the same proportion as the spans, and the fourth card
|
|
is removed below; its columns are what pay for the lead's width. */
|
|
--pvs-gallery-cols: 32.2667fr 23.8fr 15.3333fr;
|
|
--pvs-gallery-gap: calc(var(--pvs-gut) * 100 / 74.6);
|
|
--pvs-section-align: start;
|
|
--pvs-rows: 8.5% 48% 9% 26.5% 8%;
|
|
--pvs-phone-gutter: 6%;
|
|
}
|
|
|
|
/* The lead column's type claims the width its span gives it: a heavier
|
|
headline over a shorter second line, and an eyebrow cut to a label rather
|
|
than stretched across the wide measure. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="editorial"]) .picker-preview-layout .ps-desktop .ps-headline i,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="editorial"]:checked) .picker-preview-layout .ps-desktop .ps-headline i {
|
|
width: 88%;
|
|
height: 15px;
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="editorial"]) .picker-preview-layout .ps-desktop .ps-headline i:last-child,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="editorial"]:checked) .picker-preview-layout .ps-desktop .ps-headline i:last-child {
|
|
width: 52%;
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="editorial"]) .picker-preview-layout .ps-desktop .ps-eyebrow,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="editorial"]:checked) .picker-preview-layout .ps-desktop .ps-eyebrow {
|
|
width: 24%;
|
|
}
|
|
|
|
/* The copy holds a reading measure inside the wide column instead of running
|
|
to its edge; the width is the lead's, the text is not obliged to fill it. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="editorial"]) .picker-preview-layout .ps-desktop .ps-copy i,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="editorial"]:checked) .picker-preview-layout .ps-desktop .ps-copy i {
|
|
width: 56%;
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="editorial"]) .picker-preview-layout .ps-desktop .ps-copy i:last-child,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="editorial"]:checked) .picker-preview-layout .ps-desktop .ps-copy i:last-child {
|
|
width: 42%;
|
|
}
|
|
|
|
/* Three ranked columns, not four even ones. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="editorial"]) .picker-preview-layout .ps-desktop .ps-gallery-item:nth-child(4),
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="editorial"]:checked) .picker-preview-layout .ps-desktop .ps-gallery-item:nth-child(4) {
|
|
display: none;
|
|
}
|
|
|
|
/* The handset ranks its two cards the same way: a clear lead and a short. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="editorial"]) .picker-preview-layout .ps-phone-body .ps-gallery,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="editorial"]:checked) .picker-preview-layout .ps-phone-body .ps-gallery {
|
|
grid-template-columns: 1.7fr 0.7fr;
|
|
}
|
|
|
|
/* ── Editorial ───────────────────────────────────────────────
|
|
The committed ranked page, carried to boundaries, corners, and depth. Same
|
|
proportions as the preview above: the copy leading the hero at seven
|
|
against five, and the section band's three columns ranked four, three,
|
|
two, with the fourth card removed below. The headline scale-up is the
|
|
preview's own instrument and stays there; what travels is the ranking. */
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="editorial"]:checked) [data-carry]:not(.picker-preview-layout) {
|
|
--pvs-gutter: 6%;
|
|
--pvs-gutter-end: 6%;
|
|
--pvs-hero-cols: var(--pvs-w7) minmax(0, 1fr);
|
|
--pvs-hero-gap: var(--pvs-gut);
|
|
--pvs-editorial-cols: var(--pvs-w3) minmax(0, 1fr);
|
|
--pvs-editorial-gap: var(--pvs-gut);
|
|
--pvs-gallery-cols: 32.2667fr 23.8fr 15.3333fr;
|
|
--pvs-gallery-gap: calc(var(--pvs-gut) * 100 / 74.6);
|
|
--pvs-section-align: start;
|
|
--pvs-rows: 8.5% 48% 9% 26.5% 8%;
|
|
--pvs-phone-gutter: 6%;
|
|
--pvs-phone-gallery-cols: 1.7fr 0.7fr;
|
|
}
|
|
|
|
/* The ranked band is three columns on every screen that carries it. */
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="editorial"]:checked) [data-carry]:not(.picker-preview-layout) .ps-desktop .ps-gallery-item:nth-child(4) {
|
|
display: none;
|
|
}
|
|
|
|
/* ── Freeform ────────────────────────────────────────────────
|
|
Columns of no particular relation, and blocks that leave the field. The
|
|
margins are the first thing off it: the page hangs past the measure on the
|
|
left and stops short of it on the right, before a single block has moved.
|
|
The escapes are listed under the drift flag below. */
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="freeform"]:checked) [data-carry]:not(.picker-preview-layout) {
|
|
--pvs-gutter: 3.5%;
|
|
--pvs-gutter-end: 9%;
|
|
--pvs-hero-cols: 44% minmax(0, 1fr);
|
|
--pvs-hero-gap: 3%;
|
|
--pvs-editorial-cols: 37% minmax(0, 1fr);
|
|
--pvs-editorial-gap: 2.5%;
|
|
--pvs-gallery-cols: 1.45fr 0.72fr 1.1fr 0.83fr;
|
|
--pvs-gallery-gap: 2.5%;
|
|
--pvs-section-align: end;
|
|
--pvs-rows: 9.4% 48% 8.4% 26.2% 8%;
|
|
--pvs-phone-gutter: 4%;
|
|
--pvs-phone-gallery-cols: 1.5fr 0.9fr;
|
|
--pvs-phone-bleed: 0 -9%;
|
|
--pvs-phone-bleed-w: 109%;
|
|
--pvs-drift: 1;
|
|
}
|
|
|
|
/* ── Leaving the grid ────────────────────────────────────────
|
|
Drift is declared on every artboard and multiplied by a flag only freeform
|
|
raises, so the other three pay nothing for the rules existing.
|
|
|
|
Each escape is a transform or a negative margin, never a change of flow: a
|
|
block that steps out does not push the rest of the page around to make room
|
|
for it, which is the difference between a composition and a broken grid.
|
|
|
|
The moves are chosen so that nothing lands on top of running text. A bar
|
|
half-covered by a picture is what a mistake looks like; a picture running
|
|
off the edge of the page is what a decision looks like. */
|
|
|
|
/* The picture takes the right margin and keeps going, clipped by the frame
|
|
the way a full-bleed image is clipped by the browser window. The width has
|
|
to grow with the offset: the picture carries an explicit width, so a
|
|
negative margin alone would slide it rather than stretch it. */
|
|
[data-carry]:not(.picker-preview-layout) .ps-hero > .ps-image {
|
|
width: calc(100% + var(--pvs-drift, 0) * 16%);
|
|
translate: calc(var(--pvs-drift, 0) * 6%) 0;
|
|
}
|
|
|
|
/* The copy sinks below the picture's top edge, so the two blocks in the hero
|
|
no longer share a line. z-index is raised with the same flag: the actions
|
|
below cross onto the picture and have to sit over it. */
|
|
[data-carry]:not(.picker-preview-layout) .ps-hero-copy {
|
|
position: relative;
|
|
z-index: var(--pvs-drift, 0);
|
|
translate: 0 calc(var(--pvs-drift, 0) * 12%);
|
|
}
|
|
|
|
/* The one overlap, and the only block allowed one. Two filled controls onto a
|
|
flat picture is a composition that holds anywhere, and it is the one pair
|
|
in the wireframe where the block on top is opaque and the block underneath
|
|
has nothing to read: the same move over a line of copy is what a mistake
|
|
looks like. */
|
|
[data-carry]:not(.picker-preview-layout) .ps-hero-copy .ps-actions {
|
|
translate: calc(var(--pvs-drift, 0) * 62%) 0;
|
|
}
|
|
|
|
/* Drift is a desktop move. The handset has one column and a stack sized in
|
|
pixels, so a block stepping out of line there has nowhere to go but through
|
|
the bottom of the frame. */
|
|
[data-carry]:not(.picker-preview-layout) .ps-desktop .ps-gallery-item:nth-child(2n) {
|
|
translate: 0 calc(var(--pvs-drift, 0) * 14%);
|
|
}
|
|
|
|
/* The last card leaves the same way the picture did, so the escape reads as
|
|
one decision about the right edge rather than two unrelated nudges. Both
|
|
axes are named because this card is also an even one, and translate is a
|
|
single property. */
|
|
[data-carry]:not(.picker-preview-layout) .ps-desktop .ps-gallery-item:last-child {
|
|
margin-right: calc(var(--pvs-drift, 0) * -18%);
|
|
translate: calc(var(--pvs-drift, 0) * 22%) calc(var(--pvs-drift, 0) * 14%);
|
|
}
|
|
|
|
[data-carry]:not(.picker-preview-layout) .ps-desktop .ps-editorial-copy {
|
|
translate: 0 calc(var(--pvs-drift, 0) * -12%);
|
|
}
|
|
|
|
/* ── The handset ─────────────────────────────────────────────
|
|
One column still answers the question: in the margin, in how unevenly the
|
|
two cards divide the row, and in whether anything is allowed to cross the
|
|
measure. The picture is the block given that permission, both edges under
|
|
Editorial and the outer edge alone under Freeform. The rhythm between
|
|
blocks is left alone, because the handset's stack is sized in pixels and a
|
|
couple of points of extra gap pushes the card row through the bottom of the
|
|
frame at the narrowest window the picker supports. */
|
|
[data-carry]:not(.picker-preview-layout) .ps-phone-body {
|
|
padding-inline: var(--pvs-phone-gutter, 6%);
|
|
}
|
|
|
|
/* The picture carries an explicit width, so a negative margin moves it rather
|
|
than widening it. Both are named together or the bleed slides the block
|
|
sideways instead of stretching it past the measure. */
|
|
[data-carry]:not(.picker-preview-layout) .ps-phone-body > .ps-image {
|
|
margin-inline: var(--pvs-phone-bleed, 0);
|
|
width: var(--pvs-phone-bleed-w, 100%);
|
|
}
|
|
|
|
[data-carry]:not(.picker-preview-layout) .ps-phone-body .ps-gallery {
|
|
grid-template-columns: var(--pvs-phone-gallery-cols, 1.05fr 0.95fr);
|
|
}
|