@font-face {
    font-family: "Montserrat";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("fonts/montserrat-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
        U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
        U+FEFF, U+FFFD;
}

/*
 * Two tiers. The palette is the eleven colours the brand actually has; everything below it is
 * a name for what that colour paints, which is what a campaign overrides. A campaign can make
 * the button a different shade from the links even though they start out the same.
 *
 * The palette is named for its role and not its hue - a rebrand would otherwise turn every
 * variable name into a lie, which is exactly what happened when these were greens.
 */
:root {
    --brand-deep: #000000;
    --brand-mid: #20456a;
    --brand-rule: #65b572;
    --brand-button: #3c5c7c;
    --brand-light: #9deca9;
    --charcoal: #171a22;
    --slate: #1f2430;
    --grey: #595e72;
    --white: #ffffff;
    --off-white: #ececec;
    --orange: #e2802b;

    --page-background: var(--charcoal);
    --text-color: var(--white);
    --muted-text-color: var(--off-white);
    --link-color: var(--brand-light);

    --header-background: var(--brand-deep);
    --header-rule: var(--brand-rule);
    --footer-background: var(--brand-deep);
    /* The footer inverts the page: its prose carries the accent and its links are plain white. */
    --footer-text-color: var(--brand-light);
    --footer-link-color: var(--white);

    --headline-highlight: var(--brand-light);

    --panel-background: var(--slate);
    --panel-border: var(--brand-mid);
    --panel-header-background: var(--brand-mid);
    --panel-header-text: var(--white);
    /* The run the notes pick out - the trial end date - which is not the prose around it. */
    --panel-note-highlight: var(--headline-highlight);

    --check-background: var(--brand-light);
    --check-color: var(--charcoal);

    --success-icon-line: var(--off-white);
    --success-icon-mark: var(--brand-light);
    --success-card-background: var(--slate);

    --divider-color: var(--grey);
    --card-border: var(--grey);

    --input-background: var(--slate);
    --input-border: var(--grey);
    --input-text: var(--white);

    /*
     * A shade darker than --brand-rule. At the rule's own lightness, white on it is 2.50:1
     * and fails AA on the most important control on the page; 0.55 down to 0.36 gives 5.04:1.
     */
    --register-button-background: var(--brand-button);
    --register-button-label: var(--white);

    --not-eligible-color: var(--orange);
    --field-error-color: var(--orange);
    --focus-outline: var(--brand-light);

    --radius: 10px;
}

* { box-sizing: border-box; }

/* Every link, not a list of the places we remembered: the address on the ended-campaign
   card was falling through to the browser's own dark blue, on a dark card. The design
   distinguishes links by colour and weight rather than by a rule under them. */
a { color: var(--link-color); text-decoration: none; }

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--page-background);
    color: var(--text-color);
    font: 16px/1.5 "Montserrat", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

.bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 27px 47px;
    background: var(--header-background);
    border-bottom: 2px solid var(--header-rule);
}

.bar__logos { display: flex; align-items: center; gap: 1.5rem; }
.bar__logos img { max-height: 44px; width: auto; }
.bar__logos picture { display: flex; }
.bar__divider { width: 1px; height: 38px; background: var(--divider-color); }

.bar__langs { display: flex; align-items: center; gap: .5rem; font-size: .9rem; }
.bar__langs a { color: var(--muted-text-color); opacity: .6; }
.bar__langs a[aria-current="true"] { color: var(--text-color); opacity: 1; font-weight: 700; }
.bar__langs a:hover { opacity: 1; }

.page {
    flex: 1;
    width: 100%;
    /* Figma's own frame is 1366 with 28px of padding; wider screens centre it. */
    max-width: 1366px;
    margin: 0 auto;
    padding: 28px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    /* Row one holds the two boxes, row two the contact line under the left one. No row gap:
       the elements carry their own margins, which differ above and below. */
    column-gap: 64px;
    row-gap: 0;
    /* The block sits in the middle of whatever height is left between the bar and the footer. */
    align-content: center;
}

/*
 * The design ends both boxes on the same line, whatever the language does to the copy. That is
 * the grid's own doing - one row, both items stretched to it - which is why the contact line
 * had to come out of this column: left inside, it would have pushed the panel up by its own
 * height, and Portuguese wraps it to a different number of lines than English.
 */
.intro { grid-column: 1; grid-row: 1; display: flex; flex-direction: column; }
.card { grid-column: 2; grid-row: 1; }
.contact { grid-column: 1; grid-row: 2; }

h1 { margin: 0 0 2rem; font-size: 1.5rem; line-height: 1.667; font-weight: 400; }
h1 .highlight { color: var(--headline-highlight); font-weight: 700; }
h1 strong { font-weight: 700; }

.pitch {
    flex: 1;
    display: flex;
    flex-direction: column;
    border-top: 1px solid var(--divider-color);
    padding-top: 1.5rem;
}

/* Figma frame 178300: #1F2430 body, 2px #206A41 border, 10px radius. The header inside
   carries the same colour, so the top reads as one solid block. */
.benefits {
    flex: 1;
    display: flex;
    flex-direction: column;
    background: var(--panel-background);
    border: 2px solid var(--panel-border);
    border-radius: var(--radius);
    overflow: hidden;
}

.benefits__title {
    margin: 0;
    padding: .8rem 1.5rem;
    background: var(--panel-header-background);
    color: var(--panel-header-text);
    font-size: 1rem;
    letter-spacing: .04em;
}

/* The list does not take the slack: the notes follow it straight away, as the design draws
   them, and the room the box has over its content falls below them instead. */
.benefits__list { margin: 0; padding: 1.5rem 1.5rem 1rem; list-style: none; }
.benefits__list li { position: relative; margin-bottom: .9rem; padding-left: 2.2rem; }

/*
 * The box and the tick in it, drawn rather than fetched: hand-placing a rotated border inside
 * the box means two magic offsets that drift the moment the box changes size.
 */
.benefits__list li::before {
    content: "";
    position: absolute;
    left: 0;
    top: .15rem;
    width: 1.2rem;
    height: 1.2rem;
    border-radius: 3px;
    background: var(--check-background);
}

/* A mask, not a background image: this way the tick's colour is a token like everything else. */
.benefits__list li::after {
    content: "";
    position: absolute;
    left: 0;
    top: .15rem;
    width: 1.2rem;
    height: 1.2rem;
    background-color: var(--check-color);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / .85rem no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / .85rem no-repeat;
}

.notes {
    margin: 0;
    padding: 1rem 1.5rem 1.5rem;
    border-top: 1px solid var(--divider-color);
    color: var(--muted-text-color);
    font-size: .8rem;
}

/* No bottom margin: stacked, it would land on top of the page's gap and push the rule down. */
.contact { margin: 1.5rem 0 0; font-size: .95rem; }
.contact strong { display: block; color: var(--not-eligible-color); font-weight: 400; }

.card { padding: 2rem; border: 1px solid var(--card-border); border-radius: var(--radius); }
.card h2 { margin: 0 0 1.5rem; font-size: 1.05rem; }

.row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }

.field { margin-bottom: 1.2rem; }
.field label { display: block; margin-bottom: .4rem; font-size: .8rem; color: var(--muted-text-color); }

input {
    width: 100%;
    padding: .9rem .8rem;
    font: inherit;
    color: var(--input-text);
    background: var(--input-background);
    border: 1px solid var(--input-border);
    border-radius: var(--radius);
}

input:focus-visible, button:focus-visible, a:focus-visible {
    outline: 2px solid var(--focus-outline);
    outline-offset: 2px;
}

/*
 * A field the browser autofilled is painted by the browser, and background-color does not
 * reach it. An inset shadow does - it covers the field's own box - and text-fill-color is the
 * matching half for the glyphs.
 *
 * Both take the campaign's own colours rather than a literal, which is why this is not
 * color-scheme: dark. That would fix the same thing by telling the browser to pick its dark
 * autofill colours, but it would still be the browser choosing them, and it would be wrong
 * for a campaign whose palette is light.
 */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 1000px var(--input-background) inset;
    box-shadow: 0 0 0 1000px var(--input-background) inset;
    -webkit-text-fill-color: var(--input-text);
    caret-color: var(--input-text);
}

/*
 * :user-invalid and not :invalid - it matches only after the person has interacted with the
 * field, so a form nobody has touched yet shows no complaints. This is the whole of the
 * client-side validation feedback: no JavaScript, no round trip.
 */
.field__message { display: none; margin-top: .35rem; font-size: .78rem; color: var(--field-error-color); }
input:user-invalid { border-color: var(--field-error-color); }
input:user-invalid ~ .field__message { display: block; }

.mandatory { margin: 0 0 1.5rem; font-size: .78rem; color: var(--muted-text-color); }

button {
    width: 100%;
    padding: 1rem;
    font: inherit;
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--register-button-label);
    background: var(--register-button-background);
    border: 0;
    border-radius: var(--radius);
    cursor: pointer;
}

button:hover { filter: brightness(1.08); }

.footnote { margin: 2rem 0 0; font-size: .8rem; color: var(--muted-text-color); }

/* A centred panel on its own: the success page and the unavailable page both use it. */
.notice { grid-column: 1 / -1; padding: 0 28px; text-align: center; }
.notice h1 { color: var(--headline-highlight); font-weight: 700; }

/* The unavailable page shares this treatment, but is never themed - it must answer an
   unknown hash and a switched-off campaign with the same bytes. */
/* 637px is the card's height in the design, which is taller than its content on purpose. */
.notice__card {
    min-height: 637px;
    /* The floor is taller than the copy on purpose, so the copy sits in the middle of it rather
       than against the top with the slack below. */
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 3rem 2rem;
    background: var(--success-card-background);
    border: 1px solid var(--card-border);
    border-radius: var(--radius);
}

/*
 * Two masks rather than an inline <svg>: the artwork stays a file that can be replaced on its
 * own, and each half still takes its colour from a token. One mask would have been simpler and
 * would have flattened the envelope and the tick into a single colour, which the design does
 * not do.
 */
.notice__icon {
    display: block;
    /* The artwork's own size in the design. */
    width: 110px;
    aspect-ratio: 110 / 67;
    margin: 0 auto 24px;
    position: relative;
}

.notice__icon::before,
.notice__icon::after {
    content: "";
    position: absolute;
    inset: 0;
    -webkit-mask-position: center;
    -webkit-mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-position: center;
    mask-size: contain;
    mask-repeat: no-repeat;
}

.notice__icon::before {
    background-color: var(--success-icon-line);
    -webkit-mask-image: url("icon-envelope.svg");
    mask-image: url("icon-envelope.svg");
}

.notice__icon::after {
    background-color: var(--success-icon-mark);
    -webkit-mask-image: url("icon-check.svg");
    mask-image: url("icon-check.svg");
}

/*
 * The ended-campaign art, and the one image on these pages that is not a mask: this page is
 * never themed, so the colours can be the file's own.
 */
.notice__art { display: block; width: 159px; height: auto; margin: 0 auto 24px; }
.notice__card h1 { margin: 0 0 1rem; font-size: 1.15rem; }
.notice__card .notice__contact { margin-top: 1rem; }


/* The body is 14 on 16 in the design; the lead above it keeps its own size. */
.notice__card p { margin: 0; font-size: 14px; line-height: 16px; }
/* A run the copy picks out of a sentence: the submitted address on the confirmation, the trial
   end date in the panel's notes. The panel names its own, because it is not the same green. */
.accent { color: var(--headline-highlight); }
.notes .accent { color: var(--panel-note-highlight); }
/* By class and not by position: the ended-campaign card leads with a heading instead, and
   :first-of-type was dressing its body text as the lead. */
/* 20 on 28, and 31 down to the body: the design's numbers, in one rule rather than the two
   this class had drifted into. */
.notice__card .notice__lead {
    margin-bottom: 31px;
    font-size: 20px;
    line-height: 28px;
    color: var(--headline-highlight);
    font-weight: 700;
}

.foot {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 28px 47px;
    background: var(--footer-background);
    color: var(--footer-text-color);
    font-size: .8rem;
}

/* The one place a link is not --link-color, which is why it is said here and not left to `a`.
   The design sets the names apart by weight and colour rather than by an underline. */
.foot a { color: var(--footer-link-color); font-weight: 700; }

/* After .foot, not before: same specificity, so the later rule is the one that wins. This page
   has no campaign note to sit opposite, so the credit centres rather than being pushed to one
   side by an empty span. */
/* Both axes: stacked, .foot turns into a column and justify-content stops being the one
   that centres across. */
.foot--alone { justify-content: center; align-items: center; }

@media (max-width: 860px) {
    .page { grid-template-columns: 1fr; padding: 1.5rem 1.2rem; }
    .bar { padding: 1.4rem 1.2rem; }
    .row { grid-template-columns: 1fr; }
    /* Stacked, the card's border no longer marks where the form starts, so the design draws
       a rule instead - the same one the pitch carries. The page's gap is halved so the rule
       sits between the two sections rather than against the heading. */
    .intro, .contact, .card { grid-column: auto; grid-row: auto; }
    .card {
        margin-top: 2rem;
        padding: 2rem 0 0;
        border: 0;
        border-top: 1px solid var(--divider-color);
        border-radius: 0;
    }
    /* The 28 each side is a desktop inset: on a phone the page's own padding is the margin,
       and the card takes the rest of the width. */
    .notice { padding: 0; }
    /* Proportional rather than the design's 637: that is most of a phone, and a share of the
       viewport keeps the same shape on a screen of any height. */
    .notice__card { min-height: 70vh; }
    /* Two columns even here, as the design draws it: each half wraps inside itself rather than
       the two stacking. The page with one span keeps it centred and unstretched. */
    .foot { padding: 1.5rem 1.2rem; }
    .foot:not(.foot--alone) span { flex: 1; }
    /* The left credit is the longer sentence, so it takes the larger share and the right one
       starts further in - still left-aligned inside its own column. */
    .foot:not(.foot--alone) span:first-child { flex: 1.25; }
    h1 { font-size: 1.35rem; }
}
