/* The page frame, and the two-column split inside it.

   These lived in build.css and manage.css as two separate copies, and the copies
   drifted: .shell, --form-w and .panel--form were byte-identical in both, while
   the split itself was a flex row on the builder and a grid on the dashboard, so
   the same preview column came out as two different left-hand widths -- 618px and
   570px when they were meant to agree, and then 568px and 570px after they were
   corrected by hand. Two layouts cannot be kept in sync by editing both, which is
   the reason this file exists.

   Anything that both pages lay out the same way belongs here, once. Anything that
   is genuinely one page's business stays in that page's stylesheet.

   The order in each page is: that page's own stylesheet, then this, then
   preview.css. So .split wins against any single-class rule in a page file,
   because it is parsed later and specificity is equal. */

:root {
    /* The page frame. 1000px, and the same on every page including the sign-in
       page, because the width of the wordmark above the content is the one thing
       that should not change when somebody moves between /build/ and /manage/ --
       it is what says they are still on the same site.

       The 30px 18px 40px padding is what every page uses. The builder's used to
       become 42px 24px 52px at two-column widths, and the cost was that its
       wordmark sat inset further from the edge than the wordmark on the sign-in
       page: the same page reached by the same logo, laid out two different ways
       depending on the screen. The room was never needed. */
    --shell-w: 1000px;
    --shell-pad: 30px 18px 40px;

    /* The space between the header and the content below it.

       Declared here, once, rather than as a literal in build.css and
       manage.css -- which is how it was, the same number written out
       twice, both of which had to change together.

       It stays padding-bottom on .brand and is NOT a gap on .shell,
       which is the obvious way to do it and was tried and reverted.
       .shell has more children than the header and the main: on every
       page a footer, and on the builder a dialog. A gap on .shell puts
       the same space between main and .foot, and .foot already has
       padding-top: 26px, so the footer ended up with 58px above it and
       the spacing broke on every page at once. */
    --shell-gap: 22px;

    /* The split. 320px and 26px, and the left column is 618px:

         1000 - 36 (.shell padding) - 26 - 320 = 618

       So #formPanel and .dash-main.panel are the same width, which is the thing
       this file exists to guarantee.

       320px does not hold the phone at its full size. Measured at 1440px: the
       column is 320, .preview-shell's 36px of padding leaves 284, and
       max-width: 100% clamps .preview-frame from its 336px literal to a 282px
       border box. fitPreview then reads 280px of client width and scales the
       phone to 280px, where the 372px column gave 334px.

       That is the trade this pair of numbers makes: a 48px wider form in exchange
       for a 54px narrower preview, on a page whose primary task is filling in
       the form. If the preview ever needs to be the full 336 again, --split-side
       goes to 372 and the form gives the 52px back.

       Both columns are 320, so the two previews are still the same size as each
       other, which is the part that is not negotiable. 282px is still a phone,
       just a small one, and the invitation inside is laid out in vw so it is
       scaled down rather than cropped.

       These three numbers have to move together. Changing one alone brings back
       exactly the drift this file was written to end. */
    --split-side: 320px;
    --split-gap: 26px;

    /* How far down the page the phone column parks when the shell is scrolled.
       Both pages use it; only the value differs, because the two headers are not
       the same height. It is a token rather than a shared value precisely so the
       mechanism is shared and only the measurement is allowed to differ. */
    --split-sticky-top: 18px;

    /* The cap on the panels that are not the column itself -- the sign-in panel
       and the builder's result panel. 520px, declared here because the rule that
       uses it is here. */
    --form-w: 520px;
}

.shell {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    max-width: var(--shell-w);
    margin: 0 auto;
    padding: var(--shell-pad);
}

/* The two-column split: content on the left, the phone on the right.

   Grid, not flex, and the reason is the bug this replaced. As a flex row the left
   column is flex: 1 1 auto, so its final width is the leftover after the fixed
   column and the gap, rounded by flexbox's own fractional arithmetic -- and it
   came out 2px off the grid's answer on the same content, which is the sort of
   difference nobody can see in review and everybody can see in the browser.
   minmax(0, 1fr) is exact and has no rounding step to disagree about.

   minmax(0, 1fr) rather than 1fr is also what keeps the left column honest: a
   long URL or a long guest name in it cannot widen the track and push the phone
   off the right edge, it wraps instead.

   align-items: start, because the phone is fixed-height and the content beside it
   is not, and stretching the phone's column to match a long form would leave a
   tall empty sidebar. */
.split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--split-side);
    align-items: start;
    gap: 25px;
}

/* The phone column, sticky so the preview is reachable without scrolling the form
   out of the way on a laptop. The offset is a token; see --split-sticky-top. */
.split-side {
    position: sticky;
    top: var(--split-sticky-top);
}

/* One column. Below this the phone cannot have 320px and the content cannot have
   618px, so the split is not a thing that can be done at this width and the
   layout is stacked instead.

   900px, and it is one number for both pages now rather than 860 for the builder
   and 900 for the dashboard. The two were never derived from anything; they were
   whatever each page happened to carry, which is how two layouts that are the
   same shape ended up breaking at different moments.

   The phone keeps its own fixed width here -- .preview-frame is 336px and
   max-width: 100% keeps that inside a narrower screen -- so the preview is
   centred under the content rather than stretched to fill it. */
@media (max-width: 900px) {
    /* 32px, up from 22px, and this is the one place the header sits further
       from what is under it.

       Below 640px the header stops being one row -- the note is hidden and the
       nav wraps onto a second line -- so there is twice the header above the
       content than there was at 900px, and 22px under all of it reads as
       crowded. The layout is a different shape at this width, so the spacing
       should be too. One token, so this is the number to change.

       It is in a :root block and not loose in the media query, because a bare
       declaration at the top level of one is not valid CSS. A media block holds
       rules, not declarations, and the parser's recovery for the invalid
       declaration swallows the qualified rule that follows it: the .split below
       was silently dropped and the browser only ever had the two-column version.

       So mobile never stacked, .column-main was 0px wide and #formPanel came out
       at 50px, and it looked like the split itself was wrong. It was a token
       override written one line too high. */
    :root {
        --shell-gap: 32px;
    }

    .split {
        grid-template-columns: minmax(0, 1fr);
        gap: 0;
    }
}

/* The form panel's cap, for the panels that are not the column itself.

   Identical in build.css and manage.css before, down to the comment, which is how
   it is known to have been copied rather than written twice. */
.panel--form {
    max-width: var(--form-w);
    margin-inline: auto;
}
