@charset "UTF-8";

/*
 * Free custom pages, the ones typed "other": privacy policy, terms of use, legal notice...
 * (FO-CUSTOM-PAGES-01).
 *
 * The layout is the one of the about page, by decision: AC7 asks for the contributed file to stand
 * on the left of the description, "same behavior than the about page", and the text is aligned to
 * the top rather than centred vertically, whether a file is there or not.
 *
 * Mobile keeps the stacked order, media first, and everything scrolls together: standing above the
 * text, the media has nothing to stay alongside. From the large breakpoint on, the two columns sit
 * side by side and the media stops travelling with the text.
 */

.fo-custom-page {
    /*
     * The white column between the two blocks. The two widths are derived from it below, so the
     * whole row is recalled by this one length.
     */
    --fo-custom-page-gutter: 10%;

    width: 80vw; /* The white margins of the header, the footer, the galleries and the about page */
    margin: 0 auto;
    padding: 4vh 0 6vh;
}

/* Narrower than the text it introduces, and indented, as the about page does on mobile */
.fo-custom-page__illustration {
    margin: 0 5% 6vh 5%;
}

/*
 * The media is never given a height, and never a width other than the one it cannot pass: its own
 * proportions settle everything else. It is therefore impossible to stretch it, whatever the file
 * a contributor uploads, and it is never blown up past its own definition either.
 *
 * An image and an mp4 share this class: the page shows what was uploaded, it does not lay out two
 * different things. Only the markup differs, the video carrying its controls (AC7).
 */
.fo-custom-page__media {
    display: block;
    margin: 0 auto;
    max-width: 100%;
    height: auto;
}

/* --------------- D E S C R I P T I O N --------------- */

/*
 * The markup belongs to the contributor here, Quill having produced it, and so does the typography:
 * the base family below is the "Sans Serif" entry of the editor, which is its default and carries no
 * class, and the rule underneath is its "Serif" entry (AC6). Same mechanism as the about and the
 * contact pages.
 *
 * Nothing to do for the cyrillic languages: ".fo--cyrillic" has already swapped both custom
 * properties (general.css), so no locale code is written here.
 *
 * The dropdown offers a THIRD entry, "Monospace". The design system has exactly two families, a
 * serif and a sans (docs/05-maquettes/README.md), and the project ships no other face: that entry
 * is therefore deliberately left without a rule and falls back on the base. Writing a monospace
 * stack here would hard code a font the site does not own.
 */
.fo-custom-page__description {
    /*
     * Size of an h1, in multiples of the running text. It is the ONLY value a breakpoint has to
     * redefine: h6 lands exactly on the running text, and the four levels in between step down from
     * this anchor, which keeps the ladder regular whatever the screen.
     */
    --fo-heading-scale: 1.4em;

    font-family: var(--fo-font-sans);
    font-size: 5vw;
    line-height: 1.6;
    letter-spacing: 0.6vw;
    /*
     * Contributed text is beyond this stylesheet's control: a pasted address is one single
     * unbreakable word, and left alone it would widen the column until the page scrolls sideways,
     * which AC5 rules out. Breaking inside a word is a last resort the browser only takes when the
     * word cannot fit a line of its own, so running text is never cut.
     */
    word-wrap: break-word;
    overflow-wrap: break-word;
}

.fo-custom-page__description .ql-font-serif {
    font-family: var(--fo-font-serif);
}

/*
 * The size dropdown. The editor registers it as a CLASS too - "formats/size" resolves to the class
 * attributor, the style one being left under "attributors/style/size" - and its "Normal" entry
 * carries no class, exactly like the default of the font dropdown.
 *
 * The three ratios are the ones Quill applies inside its own editor, read off
 * "quill/dist/quill.snow.min.css", where they are scoped to ".ql-editor" and shipped by the
 * Back-Office entry point alone: nothing of it ever reached the Front-Office. Reusing the very same
 * values is what makes the contributor see, while typing, what the page will render.
 *
 * "em" is what turns them into a FACTOR rather than a size: a span multiplies whatever it sits in,
 * so these three rules ride on the running text and on each of the six heading levels alike, at
 * every breakpoint, with nothing to restate.
 */
.fo-custom-page__description .ql-size-small {
    font-size: 0.75em;
}

.fo-custom-page__description .ql-size-large {
    font-size: 1.5em;
}

.fo-custom-page__description .ql-size-huge {
    font-size: 2.5em;
}

/*
 * The alignment dropdown. Same class attributor as the font and the size above: the editor
 * registers "formats/align" as "ql-align", with the whitelist ["right", "center", "justify"].
 *
 * LEFT is deliberately absent from that whitelist - it is the default, and it emits NO class at
 * all, exactly like "Normal" on the size dropdown and "Sans Serif" on the font one. That is why
 * this block is given no "text-align" of its own: the base has to stay the browser default, or a
 * contributor picking "left" in the editor would have no way of saying so, and the text would
 * stay wherever the stylesheet had put it. The three rules below are therefore the ONLY
 * alignments that can ever reach this page.
 *
 * Descendant selectors on purpose: the class lands on each BLOCK it applies to - a paragraph, a
 * heading, a list item or a code block alike - never on the wrapper.
 */
.fo-custom-page__description .ql-align-center {
    text-align: center;
}

.fo-custom-page__description .ql-align-right {
    text-align: right;
}

.fo-custom-page__description .ql-align-justify {
    text-align: justify;
}

.fo-custom-page__description p {
    margin: 0 0 1.2em;
}

.fo-custom-page__description h1,
.fo-custom-page__description h2,
.fo-custom-page__description h3,
.fo-custom-page__description h4,
.fo-custom-page__description h5,
.fo-custom-page__description h6 {
    margin: 0 0 0.7em;
    font-weight: normal;
    line-height: 1.15;
    letter-spacing: 0.1em;
}

/*
 * The ladder itself, read off the anchor above. Each level sits a fixed share of the way between
 * the running text and an h1, which gives six sizes separated by a regular step, and only ONE
 * number to touch per breakpoint. An h6 is deliberately the size of the running text rather than
 * smaller: on a page whose whole content is contributed, a heading that reads smaller than a
 * paragraph is a trap, not a hierarchy.
 *
 * The margin and the spacing above are already in "em", so they follow each level down on their own.
 */
.fo-custom-page__description h1 { font-size: var(--fo-heading-scale); }
.fo-custom-page__description h2 { font-size: calc(1em + (var(--fo-heading-scale) - 1em) * 0.75); }
.fo-custom-page__description h3 { font-size: calc(1em + (var(--fo-heading-scale) - 1em) * 0.52); }
.fo-custom-page__description h4 { font-size: calc(1em + (var(--fo-heading-scale) - 1em) * 0.33); }
.fo-custom-page__description h5 { font-size: calc(1em + (var(--fo-heading-scale) - 1em) * 0.15); }
.fo-custom-page__description h6 { font-size: 1em; }

.fo-custom-page__description ul,
.fo-custom-page__description ol {
    margin: 0 0 1.2em;
    padding-left: 1.4em;
}

/*
 * The editor offers a code block, which does not wrap at all: left alone it would widen the page
 * sideways, which AC5 rules out. A legal page is one of the likeliest places to hold one.
 */
.fo-custom-page__description pre {
    max-width: 100%;
    overflow-x: auto;
}

/* A picture embedded in the text must not push the column wider than its share of the row */
.fo-custom-page__description img {
    max-width: 100%;
    height: auto;
}

/* ".fo a" clears every decoration: a link inside running text needs to stay recognisable */
.fo-custom-page__description a {
    text-decoration: underline;
    -webkit-transition: color 0.4s ease;
    -moz-transition: color 0.4s ease;
    -o-transition: color 0.4s ease;
    transition: color 0.4s ease;
}

.fo-custom-page__description a:hover {
    color: var(--fo-color-primary);
}

/* -------- R E S P O N S I V E    D E S I G N --------- */

@media only screen and (min-width: 768px) {
    .fo-custom-page__description {
        --fo-heading-scale: 1.52em;

        font-size: 3.3vw;
        letter-spacing: 0.4vw;
    }
}

@media only screen and (min-width: 992px) {
    .fo-custom-page {
        display: -webkit-box;
        display: -ms-flexbox;
        display: flex;
        /*
         * Mandatory: the default "stretch" would make the media column as tall as the text, and
         * the vertical centring below would then be measured against that height instead of the
         * height of the media itself.
         */
        -webkit-box-align: start;
        -ms-flex-align: start;
        align-items: flex-start;
        gap: var(--fo-custom-page-gutter);
        padding: 0;
    }

    /*
     * Two fifths of the row, the gutter set aside: the ratio is written here as the ratio itself
     * rather than resolved by hand into a percentage, so changing the gutter cannot silently break
     * it.
     *
     * Vertical centring is read straight off the viewport: "top: 50%" is where the sticky position
     * pins this block, and the translation on the media below pulls it back up by half of its own
     * height. There is no viewport height to compute, no cap to pick and nothing to recalculate
     * when the contributor changes the file.
     *
     * The block is given no height on purpose, so that it is a centring LINE rather than a box.
     * A sticky box is held inside its containing block, here the row, and what is held is the box
     * itself, before any transform: carrying the translation here instead would make the row run
     * out of room half a media too early, and the media would start creeping upwards near the end
     * of the text, the further up the taller the screen. Same demonstration as on the about page.
     */
    .fo-custom-page__illustration {
        -webkit-box-flex: 0;
        -ms-flex: 0 0 auto;
        flex: 0 0 auto;
        width: calc((100% - var(--fo-custom-page-gutter)) * 2 / 5);
        height: 0;
        margin: 0;
        position: -webkit-sticky;
        position: sticky;
        top: 50%;
    }

    /* Half its own height, whatever the file: this is what centres it on the line above */
    .fo-custom-page__media {
        -webkit-transform: translateY(-50%);
        -moz-transform: translateY(-50%);
        -ms-transform: translateY(-50%);
        -o-transform: translateY(-50%);
        transform: translateY(-50%);
    }

    .fo-custom-page__description {
        --fo-heading-scale: 1.58em;

        -webkit-box-flex: 0;
        -ms-flex: 0 0 auto;
        flex: 0 0 auto;
        width: calc((100% - var(--fo-custom-page-gutter)) * 3 / 5);
        /*
         * A flex item is born with "min-width: auto", which lets it grow past its width to fit its
         * widest unbreakable content: zero pins the column to the share it was given, so the two
         * fifths / three fifths hold whatever the contributor writes.
         */
        min-width: 0;
        padding: 8vh 0;
        font-size: 1.9vw;
        letter-spacing: 0.25vw;
    }

    /*
     * No file at all: the description takes the whole width it is given, between the same white
     * margins, and the page scrolls as any other. The width computed above has to be given back, a
     * block being laid out by it where a flex item was not.
     */
    .fo-custom-page--text-only {
        display: block;
        padding: 0;
    }

    .fo-custom-page--text-only .fo-custom-page__description {
        width: auto;
        padding: 8vh 0 10vh;
    }
}

@media only screen and (min-width: 1200px) {
    .fo-custom-page__description {
        --fo-heading-scale: 2em;

        font-size: 1.1vw;
        letter-spacing: 0.17vw;
    }
}
