mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-15 15:46:30 +03:00
570 lines
33 KiB
CSS
570 lines
33 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. Three
|
|
pages with the columns nudged a few points apart are three identical pages.
|
|
|
|
So the ruler is drawn. The measure below is a real twelve-column grid, and
|
|
the two 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.
|
|
|
|
── One instrument, four pages ──────────────────────────────
|
|
The question is put to the landing page and the index only (see
|
|
picker/data/surfaces.js), so those are the two boards this screen draws. The
|
|
answer is still one value for the run, so the shell and the document meet it
|
|
on the screens after this one, and their bodies are sized here. The paragraph
|
|
below used to end by saying the instrument is the same one under all three
|
|
answers and what moves is the page standing on it. That reading is kept, and
|
|
it decides how a surface is handled.
|
|
|
|
The argument was never about answers in particular. It is that a measure must
|
|
not be cut from the thing it is measuring, because then the thing and the
|
|
ruler agree by construction and the ruler says nothing. A surface is another
|
|
thing being measured. Re-cutting the field per surface would fail in exactly
|
|
the same way and lose something the single field buys: with one origin and one
|
|
pitch under all four, an answer can be compared across them, and a dashboard
|
|
whose regions sit on the same lines a landing page's blocks sit on is making a
|
|
claim you can check.
|
|
|
|
So the field is unchanged. Six and six, twelve columns, one pitch, on every
|
|
board. What is now per surface is the body standing on it, and the answer is
|
|
read where each body actually keeps its proportion:
|
|
|
|
- the landing page, in the spans its hero and its card row take;
|
|
- the app shell, in where the rail, the working column, and the panel divide;
|
|
- the document, in how wide the measure runs beside its rail;
|
|
- the index, in how each entry splits between the work and its caption.
|
|
|
|
Two consequences worth stating, because both look like oversights otherwise.
|
|
|
|
The three region bodies pin their margin to the field's own six rather than to
|
|
the answer's page gutter. On the landing page the margin *is* part of the
|
|
answer, which is why Balanced keeps the artboard's 5.5 and 3.2 and leans; a
|
|
shell's regions are checked against the lines, and a rail three pixels shy of
|
|
one reads as a mistake rather than as a lean. The margin on those boards is
|
|
the field's, and the answer moves what is inside it.
|
|
|
|
And a region's dividing rule sits down the middle of a gutter rather than
|
|
against one edge, which is why the tracks below add half a gutter and a whole
|
|
one. A page's blocks are told apart by air and stop at column edges; a shell's
|
|
regions abut and are told apart by a line. Both land on the drawn field, in
|
|
the two different ways the drawn field can be met.
|
|
|
|
Neither the shell nor the document is asked the question, so neither answers
|
|
freeform and neither has a freeform reading here. None is drawn.
|
|
============================================================ */
|
|
|
|
/* ── 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 nav, the section band, and the footer inset both sides by the page
|
|
gutter, where the hero and the proof band read the end gutter on the right.
|
|
A drawn grid makes it obvious when only some rows honor the same margin, so
|
|
chrome and the section band are brought onto the one measure. Scoped to the
|
|
structural artboards: screens 03 and 04 are judging color and glyphs, and
|
|
their page is not under a ruler.
|
|
|
|
The landing board only. The nav and the footer are shared chrome, and on the
|
|
three region boards they take the field's margin on both sides along with the
|
|
body under them, for the reason in the header. */
|
|
[data-carry][data-surface="persuade"]: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 three pages each
|
|
checked against a ruler cut to fit would be three pages checked against
|
|
nothing. The instrument is the same one under every answer and on every
|
|
surface. What moves is the page standing on it, which is the whole of what
|
|
this screen is asking.
|
|
|
|
Balanced is the answer that still disagrees. Its page is the shared
|
|
artboard's own 5.5 and 3.2 margins, so a field cut from those numbers would
|
|
slide the ruler onto the very lean the ruler is there to show. */
|
|
.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[data-surface="persuade"] .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[data-surface="persuade"] .ps-phone-body {
|
|
grid-template-rows: minmax(0, 31%) auto auto auto 34px minmax(min-content, 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%;
|
|
}
|
|
|
|
/* Freeform, on this screen's own preview. The option's own definition is the
|
|
spec: blocks step out of the grid and overlap where it pays off. That is
|
|
not a looser grid; it is the same measure with permission granted. So the
|
|
base composition sits on the drawn lines exactly like the disciplined
|
|
answers, margins on the field, spans on whole columns, and then specific
|
|
blocks play against it: the picture is set down at a slight angle like a
|
|
print laid on a table, the buttons cross onto its corner, and the card row
|
|
bounces, leaning cards answering each other along the baseline. Held next
|
|
to the grid it is teasing, each move reads as a decision; without the held
|
|
grid it would read as the page being broken. The escape rules live under
|
|
the drift flag below. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="freeform"]) .picker-preview-layout,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="freeform"]:checked) .picker-preview-layout {
|
|
--pvs-gutter: 6%;
|
|
--pvs-gutter-end: 6%;
|
|
/* Copy at five, picture at seven: the picture is the block that leaves,
|
|
so it gets the mass that makes the exit legible. */
|
|
--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);
|
|
/* Four even cards on the lines. The stagger below breaks the row's
|
|
baseline, not its columns: one axis escapes at a time. */
|
|
--pvs-gallery-cols: repeat(4, minmax(0, 1fr));
|
|
--pvs-gallery-gap: calc(var(--pvs-gut) * 100 / 74.6);
|
|
--pvs-section-align: start;
|
|
--pvs-rows: 9.4% 48% 8.4% 26.2% 8%;
|
|
--pvs-phone-gutter: 6%;
|
|
--pvs-drift: 1;
|
|
}
|
|
|
|
/* The handset's cards divide the row unevenly; its print tilts under the
|
|
drift rules below instead of bleeding, so the angle stays whole. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="freeform"]) .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="freeform"]:checked) .picker-preview-layout .ps-phone-body .ps-gallery {
|
|
grid-template-columns: 1.5fr 0.9fr;
|
|
}
|
|
|
|
/* ── Freeform ────────────────────────────────────────────────
|
|
The committed page, carried to boundaries, corners, and depth. Same terms
|
|
as the preview above: the measure every other answer uses, with the drift
|
|
flag up. What travels is the permission, not a different grid. */
|
|
: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: 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);
|
|
--pvs-gallery-cols: repeat(4, minmax(0, 1fr));
|
|
--pvs-gallery-gap: calc(var(--pvs-gut) * 100 / 74.6);
|
|
--pvs-section-align: start;
|
|
--pvs-rows: 9.4% 48% 8.4% 26.2% 8%;
|
|
--pvs-phone-gutter: 6%;
|
|
--pvs-phone-gallery-cols: 1.5fr 0.9fr;
|
|
--pvs-drift: 1;
|
|
}
|
|
|
|
/* ── Leaving the grid ────────────────────────────────────────
|
|
Freeform's one move, made big: everything on the page sits exactly on the
|
|
grid, straight and level, except the hero photograph, which is cut into an
|
|
angular shape that starts mid-page, bleeds off the frame's right edge, and
|
|
ends mid-band on a slanted bottom, its left side falling away on a steep
|
|
diagonal. One block granted the permission; the rest of the page refusing
|
|
to join in is what makes the shape read as a decision.
|
|
|
|
The hero is a change of structure, not a nudge, so it is gated on the same
|
|
selectors as the measure blocks above; the handset's echo rides the
|
|
--pvs-drift flag inside its polygon, so the other answers keep a
|
|
rectangle. */
|
|
|
|
/* The band loses its own gutter so the image can reach the frame edge; the
|
|
copy re-applies it and keeps the page's left measure. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="freeform"]) .picker-preview-layout .ps-desktop .ps-hero,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="freeform"]:checked) [data-carry] .ps-desktop .ps-hero {
|
|
position: relative;
|
|
display: block;
|
|
padding: 0;
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="freeform"]) .picker-preview-layout .ps-desktop .ps-hero > .ps-image,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="freeform"]:checked) [data-carry] .ps-desktop .ps-hero > .ps-image {
|
|
position: absolute;
|
|
inset: 0;
|
|
height: 100%;
|
|
/* The shape: top edge from mid-page to the frame's right edge, right edge
|
|
dropping to just past the band's midpoint, a slanted bottom running
|
|
uphill to the right, and the steep diagonal falling back to the top. */
|
|
clip-path: polygon(40% 0, 100% 0, 100% 78%, 66% 84%);
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="freeform"]) .picker-preview-layout .ps-desktop .ps-hero > .ps-hero-copy,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="freeform"]:checked) [data-carry] .ps-desktop .ps-hero > .ps-hero-copy {
|
|
position: relative;
|
|
z-index: 1;
|
|
box-sizing: border-box;
|
|
width: 44%;
|
|
height: 100%;
|
|
align-content: center;
|
|
padding-left: var(--pvs-gutter, 6%);
|
|
}
|
|
|
|
/* ── The handset ─────────────────────────────────────────────
|
|
The same permission at pocket scale: the print's bottom edge takes the
|
|
angular cut, running uphill to the right like the desktop shape. The cut
|
|
depth rides the flag inside the polygon, so the other answers keep a
|
|
rectangle. Everything else on the handset stays on its lines. */
|
|
[data-carry][data-surface="persuade"] .ps-phone-body > .ps-image {
|
|
clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--pvs-drift, 0) * 16%), 0 100%);
|
|
}
|
|
|
|
/* ── 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. Freeform is the answer that takes that permission, and it takes it
|
|
on the picture's bottom edge rather than on the measure. 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%);
|
|
}
|
|
|
|
[data-carry]:not(.picker-preview-layout) .ps-phone-body .ps-gallery {
|
|
grid-template-columns: var(--pvs-phone-gallery-cols, 1.05fr 0.95fr);
|
|
}
|
|
|
|
/* ── The regions, per surface ────────────────────────────────
|
|
One block per answer, and each one says the same thing four ways because that
|
|
is the point of the four boards: the answer is a claim about proportion, and
|
|
proportion lives somewhere different on each kind of page.
|
|
|
|
The tracks are whole counts of the drawn field's columns. A number is written
|
|
as the span variable plus the gutter arithmetic that lands its edge on a line,
|
|
never as the percentage that comes out, so a reader can check the count: the
|
|
shell below is two, seven, and three, and it says so.
|
|
|
|
Both selectors, as everywhere on this screen: the hover preview, then the
|
|
committed answer. Unlike the landing blocks above, the two carry the same
|
|
values. A region's proportion is the answer, so there is no separate reading
|
|
of it to preview. */
|
|
|
|
/* ── Simple grid, on the three region bodies ─────────────────
|
|
Even shares and one rule for the whole board. The shell divides two, seven,
|
|
three, which is the count a tool falls into when nothing is being emphasised.
|
|
The document runs its measure to the end of the page beside a three-column
|
|
rail. The index splits every entry six and six and stops alternating, because
|
|
two entries mirrored are two different rhythms and this is the answer with
|
|
one. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) [data-carry],
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) [data-carry] {
|
|
--pvs-shell-cols:
|
|
calc(var(--pvs-w2) + var(--pvs-gut) / 2)
|
|
calc(var(--pvs-w7) + var(--pvs-gut))
|
|
minmax(0, 1fr);
|
|
--pvs-measure-cols:
|
|
calc(var(--pvs-w3) + var(--pvs-gut) / 2)
|
|
minmax(0, 1fr);
|
|
--pvs-metric-cols: repeat(3, minmax(0, 1fr));
|
|
--pvs-entry-cols: var(--pvs-w6) minmax(0, 1fr);
|
|
--pvs-entry-flip-cols: var(--pvs-w6) minmax(0, 1fr);
|
|
}
|
|
|
|
/* The stagger is placement rather than order, so undoing it is placement too:
|
|
both entries put the work first and the caption second. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) [data-carry] .ps-index-row--flip > .ps-image,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) [data-carry] .ps-index-row--flip > .ps-image {
|
|
grid-area: 1 / 1;
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="simple-grid"]) [data-carry] .ps-index-row--flip > .ps-index-cap,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="simple-grid"]:checked) [data-carry] .ps-index-row--flip > .ps-index-cap {
|
|
grid-area: 1 / 2;
|
|
}
|
|
|
|
/* ── Balanced, on the three region bodies ────────────────────
|
|
The same field spent unevenly, and each body spends it on the block that
|
|
carries the emphasis. The shell gives the working column a column off the
|
|
panel and lets its lead figure take more of the metrics row than its
|
|
neighbours. The document is the clearest of the three: the measure stops three
|
|
columns short of the page instead of running to the edge, which is the choice
|
|
a considered document actually makes and the one a strict grid will not.
|
|
The index leans each entry seven and five, and keeps the alternation, so the
|
|
run reads as a rhythm rather than a column. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="balanced"]) [data-carry],
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="balanced"]:checked) [data-carry] {
|
|
--pvs-shell-cols:
|
|
calc(var(--pvs-w2) + var(--pvs-gut) / 2)
|
|
calc(var(--pvs-w8) + var(--pvs-gut))
|
|
minmax(0, 1fr);
|
|
--pvs-measure-cols:
|
|
calc(var(--pvs-w3) + var(--pvs-gut) / 2)
|
|
calc(var(--pvs-w6) + var(--pvs-gut))
|
|
minmax(0, 1fr);
|
|
--pvs-metric-cols: 1.45fr 1fr 1fr;
|
|
--pvs-entry-cols: var(--pvs-w7) minmax(0, 1fr);
|
|
--pvs-entry-flip-cols: minmax(0, 1fr) var(--pvs-w7);
|
|
}
|
|
|
|
/* ── Freeform, on the index ──────────────────────────────────
|
|
Asked of Persuade and Experience only, so this is the one region body that
|
|
draws it. Same reading as the landing page's: the composition sits on the
|
|
lines, and then one thing is granted permission to leave them. On an index
|
|
that thing is the work itself, set down at a slight angle like a print laid on
|
|
a table, with the caption stepping onto the corner it left. Held next to the
|
|
drawn field it is teasing, each move reads as a decision.
|
|
|
|
The plates lean opposite ways so the run has a beat, and the angle is under
|
|
two degrees: a print laid down askew, not a page falling over. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="freeform"]) [data-carry],
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="freeform"]:checked) [data-carry] {
|
|
--pvs-entry-cols: var(--pvs-w7) minmax(0, 1fr);
|
|
--pvs-entry-flip-cols: minmax(0, 1fr) var(--pvs-w7);
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="freeform"]) [data-carry][data-surface="experience"] .ps-index-row > .ps-image,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="freeform"]:checked) [data-carry][data-surface="experience"] .ps-index-row > .ps-image {
|
|
rotate: -1.7deg;
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="freeform"]) [data-carry][data-surface="experience"] .ps-index-row--flip > .ps-image,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="freeform"]:checked) [data-carry][data-surface="experience"] .ps-index-row--flip > .ps-image {
|
|
rotate: 1.4deg;
|
|
}
|
|
|
|
/* The caption crosses the gutter onto the plate's corner, which is the move the
|
|
landing page makes with its buttons. It stays above the plate it is crossing,
|
|
and it is the caption that moves rather than the work, because a caption
|
|
overlapping a photograph is a printed page's own habit. */
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="freeform"]) [data-carry][data-surface="experience"] .ps-index-cap,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="freeform"]:checked) [data-carry][data-surface="experience"] .ps-index-cap {
|
|
position: relative;
|
|
z-index: 1;
|
|
translate: -9% 0;
|
|
}
|
|
|
|
#picker-form:has(.picker-strategy-option:hover input[name="layout-structure"][value="freeform"]) [data-carry][data-surface="experience"] .ps-index-row--flip > .ps-index-cap,
|
|
:where(#picker-form:not(:has(.picker-strategy-option:hover input[name="layout-structure"]))):has(input[name="layout-structure"][value="freeform"]:checked) [data-carry][data-surface="experience"] .ps-index-row--flip > .ps-index-cap {
|
|
translate: 9% 0;
|
|
}
|