/* ============================================================
   Landing page (docs/overrides/index.html, rendered through
   docs/overrides/home.html).

   home.html is a standalone template that hardcodes its four
   stylesheets - main.css, palette.css, tw-styles.css and this
   file - instead of emitting `extra_css`, so custom.css never
   reaches the landing page and everything it needs lives here.

   Material's html font-size is 125%, i.e. 1rem = 20px; sizes
   below follow that scale. tw-styles.css (Tailwind) is loaded
   before this file, so its preflight resets apply underneath.
   ============================================================ */

/* Reserve the scrollbar gutter whether or not the page actually scrolls. The
   landing page is short enough to fit on a tall window while content pages
   scroll, and without this the centred header grid - and with it the logo -
   shifts by the scrollbar's width when moving between the two. The same
   declaration is in custom.css for the content pages. */
html {
    scrollbar-gutter: stable;
}

/* Dark scheme: paint the page's scrollbar dark from the first frame. The root
   element's colour scheme decides it, and the theme only sets that from JS -
   see the matching rule in custom.css. */
html:has(> body[data-md-color-scheme="slate"]) {
    color-scheme: dark;
}

body {
    font-size: 14px !important;
}

.md-tag,
.md-tags {
    display: none !important;
}

.md-grid {
    max-width: 61rem;
}

@media screen and (min-width: 1536px) {
    .md-grid {
        max-width: 1536px;
    }
}

.md-tabs {
    display: none;
}

/* ------------------------------------------------------------
   Header
   ------------------------------------------------------------ */

.md-header__inner {
    align-items: center;
    display: flex;
    padding: 0 .2rem;
    justify-content: space-between;
}

.md-header {
    background-color: #000000;
    color: #eaeaea;
    padding-top: .5em;
    padding-bottom: .5em;
    border-bottom: 1px solid #1f2937;
}

/* Logo + site name, as one home link. img/logo.svg is the full lockup
   (three-bar mark at x 0-57 of a 290-wide viewBox, then the "VMS Software"
   wordmark); the box below plus object-fit crops it to just the mark, so the
   header reads "<mark> VSI How-to Portal" like the design, while the footer
   keeps the full lockup. */
.md-header__button.md-logo {
    display: inline-flex !important;
    align-items: center;
    gap: .45rem;
    margin-left: 1em !important;
    margin-right: .8em !important;
    padding: 0 !important;
}

.md-header__button.md-logo img.lp-logo {
    /* !important: partials/logo_lp.html is generated and carries an inline
       style="height:35px", which would otherwise win and skew the crop box */
    height: 1rem !important;
    /* the three bars end at x=57 of the 290-wide viewBox, so at this height
       (scale .625) the mark is 35.6px - the box is a shade wider so none of
       the third bar is clipped, and still narrow enough to exclude the
       wordmark, which starts at x=87.7 */
    width: 2.1rem;
    object-fit: cover;
    object-position: left center;
}

/* Sized to the "VMS Software" wordmark in the footer logo: that renders with
   an 18px ink height (footer logo at 22px, measured on the built page), and
   Roboto's ascender is ~0.73em, so 1.25rem = 25px lands on the same height.
   The wordmark is outlined paths in img/logo.svg - it carries no typeface
   information and the repo ships no font file - so the face itself cannot be
   reused; this matches its size and weight in the site font. */
.lp-header__brand {
    font-size: 1.2rem;
    font-weight: 400;
    /* .md-logo centres its flex items by box, and this text's box carries
       descender space that the mark's box does not - which left the letters
       sitting 1.5px below the mark's centre line (measured on the built page).
       line-height 1 tightens the box to the text, and the bottom margin is
       split by the centring, lifting the ink by half its value onto the same
       centre line as the mark. */
    line-height: 1;
    margin-bottom: 3px;
    color: #eaeaea;
    white-space: nowrap;
}

[data-md-color-scheme="default"] .lp-header__brand {
    color: #14171a;
}

.md-header__button svg {
    fill: aliceblue;
    display: block;
    height: 2rem;
    width: 2rem;
}

/* Show the palette (light/dark) toggle on the landing page.
   tw-styles.css hides it with `.md-header__option{display:none!important}`
   (added when the switch was non-functional); higher specificity +
   !important re-enables it. */
.md-header .md-header__option {
    display: flex !important;
    /* the reserved box below is taller than the switch, and a flex container
       aligns a fixed-height child to the start of the cross axis - so without
       this the pill hangs at the top of the header instead of sitting on the
       logo's centre line */
    align-items: center;
    /* the toggle is the only thing on the right once the search field has moved
       into the hero; margin-right mirrors the logo's margin-left so the gap to
       the right page edge matches the gap from the left edge to the mark. The
       .1rem discounts the toggle button's own padding, which the logo
       (padding: 0) does not have. */
    margin-left: auto;
    /* 1em would be the logo's own margin, but the toggle button carries .5rem
       of padding around its icon that the logo (padding: 0) does not - so the
       margin is reduced by that much, leaving equal *visible* gaps. Verified on
       the built page: 117px from the left edge to the mark, 117px from the
       switch to the right edge. */
    margin-right: .1rem;
    /* Material's palette script decides which of the scheme labels to unhide,
       so the icon only appears once its JS runs; reserving the box keeps that
       from nudging anything when it does. */
    min-width: 2rem;
    min-height: 2rem;
}

/* Theme switch drawn as a pill with the icon in a round knob: sun on the left
   in the light scheme, half-moon on the right in the dark one. The icon itself
   comes from the palette entries in mkdocs.yml (material/weather-sunny and
   material/weather-night); Material renders one <label> per scheme and unhides
   the active one, so only the pill and knob need styling here. */
.md-header .md-header__option label.md-header__button {
    position: relative;
    display: flex;
    align-items: center;
    width: 2.1rem;
    height: 1.15rem;
    margin: 0;
    padding: 0;
    background-color: #33445c;
    border-radius: 1rem;
    cursor: pointer;
}

/* Material renders one label per scheme and marks all but the active one
   `hidden`; the display above would otherwise override that and show both. */
.md-header .md-header__option label.md-header__button[hidden] {
    display: none;
}

.md-header .md-header__option label.md-header__button svg {
    position: absolute;
    top: 50%;
    /* dark scheme: knob to the right */
    right: .075rem;
    box-sizing: border-box;
    width: 1rem;
    height: 1rem;
    padding: .15rem;
    fill: #e2e8f0;
    background-color: #0f172a;
    border-radius: 50%;
    transform: translateY(-50%);
}

[data-md-color-scheme="default"] .md-header .md-header__option label.md-header__button {
    background-color: #d7dbe0;
}

[data-md-color-scheme="default"] .md-header .md-header__option label.md-header__button svg {
    right: auto;
    left: .075rem;
    fill: #14171a;
    background-color: #ffffff;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .2);
}

/* The search component is rendered inside the header (that is the only place
   Material will mount it) and moved into the hero by scripts_lp.js. Hiding both
   it and the magnify label that used to open it from the very first paint - not
   only after the move - is what keeps the header from briefly laying out with a
   search field in it and then reflowing the palette toggle. */
.md-header .md-search,
.md-header__button[for="__search"] {
    display: none;
}

/* scripts_lp.js keeps #__search checked so the theme keeps feeding the query to
   its search worker. In the header that state means "search is expanded", and
   Material collapses the palette toggle to make room for it - undo that, since
   here the field is in the hero and the toggle has to stay put. */
body.lp-search-moved [data-md-toggle="search"]:checked~.md-header .md-header__option {
    max-width: none;
    opacity: 1;
}

.md-search-result mark {
    background-color: #c8ddff !important;
    color: black !important;
    text-decoration: none !important;
}

/* Live-search dropdown: same scale as the content pages, which take
   Material's own sizes - .64rem teaser / .8rem title, i.e. 12.8px / 16px
   against the 20px root. These used to run 1.2x larger here, which made the
   landing's overlay text visibly bigger than the identical dropdown on every
   other page. The 768px block below keeps the touch-size bump custom.css
   applies on narrow screens. */
.md-search-result__article {
    font-size: .64rem !important;
}

.md-search-result .md-typeset h1 {
    font-size: .8rem !important;
}

@media screen and (max-width:768px) {

    .md-search-result__article {
        font-size: .8rem !important;
    }

    .md-search-result .md-typeset h1 {
        font-size: .9rem !important;
    }
}

/* Logo swaps with the theme: white wordmark on the dark header, dark
   wordmark (logo-light.svg) on the light one. Selectors match Material's
   `.md-header__button.md-logo img` (0,2,1) and add the logo class so these
   win; the footer copies use the plain .lp-logo rules further down. */
.md-header__button.md-logo img.lp-logo--light {
    display: none;
}

/* ------------------------------------------------------------
   Landing content: colour tokens

   Dark (slate) is the site's first-visit scheme, light is the
   palette toggle's other state - both are defined here so the
   page never depends on Tailwind's hardcoded colours.
   ------------------------------------------------------------ */

/* Tokens live on <body> rather than on .lp, because the footer sits outside
   .lp (so its top rule can span the page) and still needs them. This
   stylesheet is loaded by home.html only, so body scope stays landing-only. */
body {
    --lp-surface: #1e293b;
    --lp-border: #2b3a4d;
    --lp-title: #e2e8f0;
    --lp-text: #cbd5e1;
    --lp-muted: #94a3b8;
    --lp-link: #60a5fa;
    --lp-input-bg: #0f172a;
    --lp-input-border: #33445c;
    --lp-rule: #1f2937;
    --lp-shadow: 0 2px 6px rgba(0, 0, 0, .35);
}

/* The content column, shared by the sections and by .lp-footer__inner */
.lp {
    max-width: 50rem;
    margin: 0 auto;
    padding: 0 1.2rem;
    color: var(--lp-text);
}

/* home.html puts data-md-color-scheme on <body> itself, so this has to be a
   compound selector - `[data-md-color-scheme="default"] body` would look for a
   body *inside* the scheme element and match nothing. */
body[data-md-color-scheme="default"] {
    --lp-surface: #ffffff;
    --lp-border: #e3e6e9;
    --lp-title: #14171a;
    --lp-text: #2b373f;
    --lp-muted: #5a6570;
    --lp-link: #2378FF;
    --lp-input-bg: #ffffff;
    --lp-input-border: #d7dbe0;
    --lp-rule: #e6e8eb;
    --lp-shadow: 0 1px 2px rgba(16, 24, 40, .06);
}

/* Light scheme: header, page background and footer follow the same palette
   the content pages use. */
[data-md-color-scheme="default"] .md-header {
    background-color: #f9f9f9;
    color: #2b373f;
    border-bottom-color: #e6e8eb;
}

[data-md-color-scheme="default"] .md-header__button svg {
    fill: #2b373f;
}

[data-md-color-scheme="default"] .md-search__form,
[data-md-color-scheme="default"] .md-search__form:hover {
    background-color: #ffffff;
    border-color: #d7dbe0;
    color: #2b373f;
}

/* Main: drop the dark gradient home.html sets, use the light page background */
[data-md-color-scheme="default"] .md-main {
    background-image: none;
    background-color: var(--md-default-bg-color);
}

[data-md-color-scheme="default"] .md-header__button.md-logo img.lp-logo--dark {
    display: none;
}

[data-md-color-scheme="default"] .md-header__button.md-logo img.lp-logo--light {
    display: block;
}

/* ------------------------------------------------------------
   Hero
   ------------------------------------------------------------ */

.lp-hero {
    text-align: center;
    padding: 2.2rem 0 1.6rem;
    /* The hero box is exactly as wide as the card grid (.lp's content box - the
       hero adds no padding of its own), so it is the container the results
       panel below sizes itself against: `100cqw` is the card width, whatever
       the viewport does. */
    container-type: inline-size;
    /* container-type brings `contain: layout`, which makes the hero a stacking
       context painted with the in-flow content - and the cards are positioned
       (position: relative), so they would paint over the results panel inside
       it. Positioning the hero with a z-index above them puts it back on top. */
    position: relative;
    z-index: 2;
}

.lp-hero__title {
    margin: 0;
    font-size: 1.6rem;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--lp-title);
}

.lp-hero__subtitle {
    margin: .5rem 0 0;
    font-size: .65rem;
    color: var(--lp-muted);
}

/* The hero holds the theme's search component (moved here by scripts_lp.js).
   Material's layout and visibility rules for it are written against
   `.md-header` ancestry - `[data-md-toggle=search]:checked~.md-header ...` -
   and its resting state outside the header's desktop media query is
   `position: fixed; height: 0; opacity: 0`, i.e. invisible. So everything the
   field needs to render inline is restated here. */
.lp-search {
    position: relative;
    width: 100%;
    max-width: 15rem;
    /* keeps the hero's spacing while the slot is still empty (no JS, or before
       the component is moved in) */
    min-height: 2rem;
    margin: 1.2rem auto 0;
}

.lp-search .md-search {
    position: relative;
    width: 100%;
    /* Material pads the component .2rem top and bottom from 60em up (it is
       sized for the header there). In the hero that put the field 4px below
       .lp-search__placeholder and pushed the cards down, so the swap showed. */
    padding: 0;
}

/* Stand-in for the field until the real component is moved in; same box, icon
   and wording, so the swap is invisible. */
.lp-search__placeholder {
    display: flex;
    align-items: center;
    /* .5rem padding + .8rem icon + .5rem gap puts the text at 1.8rem, where
       the real field's input padding puts its placeholder text */
    gap: .5rem;
    height: 2rem;
    padding: 0 .5rem;
    font-size: .65rem;
    color: var(--lp-muted);
    background-color: var(--lp-input-bg);
    border: 1px solid var(--lp-input-border);
    border-radius: .45rem;
}

.lp-search__placeholder svg {
    width: .8rem;
    height: .8rem;
    flex: 0 0 auto;
    fill: currentcolor;
}

body.lp-search-moved .lp-search__placeholder {
    display: none;
}

/* The dimming overlay belongs to the header's expand-on-click interaction */
.lp-search .md-search__overlay {
    display: none;
}

.lp-search .md-search__inner {
    position: relative;
    float: none;
    width: 100%;
    height: auto;
    padding: 0;
    opacity: 1;
    overflow: visible;
    transform: none;
    transition: none;
}

.lp-search .md-search__form {
    height: 2rem;
    color: var(--lp-text);
    background-color: var(--lp-input-bg);
    border: 1px solid var(--lp-input-border);
    border-radius: .45rem;
    box-shadow: none;
}

.lp-search .md-search__form:hover {
    background-color: var(--lp-input-bg);
}

.lp-search .md-search__input {
    height: 100%;
    padding: 0 1.8rem;
    font-size: .65rem;
    color: var(--lp-text);
}

.lp-search .md-search__input::placeholder {
    color: var(--lp-muted);
}

.lp-search .md-search__icon {
    /* centred on the field rather than offset from its top, so the icon lands
       in the same place whatever the field's height */
    top: 50%;
    width: .8rem;
    height: .8rem;
    color: var(--lp-muted);
    transform: translateY(-50%);
}

/* The glyph itself has to be sized too: Material's .md-icon svg is 1.2rem, so
   it rendered 24px inside this 16px box - overflowing it low and appearing to
   jump when the real component replaced .lp-search__placeholder, whose icon is
   .8rem. Matching both keeps the swap invisible. */
.lp-search .md-search__icon svg {
    width: 100%;
    height: 100%;
}

[dir=ltr] .lp-search .md-search__icon {
    left: .5rem;
}

/* Below 60em the theme swaps the magnifier for a back arrow, because in the
   header's full-screen mobile search that icon closes the overlay. The hero
   field has no overlay to close, and .lp-search__placeholder shows the
   magnifier, so keep the magnifier at every width. */
@media screen and (max-width: 59.984375em) {
    .lp-search .md-search__icon[for=__search] svg:first-child {
        display: block;
    }

    .lp-search .md-search__icon[for=__search] svg:last-child {
        display: none;
    }
}

.lp-search .md-search__options {
    top: .35rem;
    right: .3rem;
}

/* Results panel: anchored under the field, shown while the field or one of the
   results has focus (in the header, Material drives this from the toggle). */
.lp-search .md-search__output {
    top: 100%;
    /* Material's phone layout (<60em) pairs `top: 2.4rem` with `bottom: 0` to
       stretch the panel down a full-screen search overlay. Only the `top` is
       restated above, so the leftover `bottom: 0` used to collapse the panel to
       zero height here - the panel simply vanished below 960px. */
    bottom: auto;
    /* wider than the field, centred on it - result titles and teasers need the
       room, and Material's header dropdown is similarly wider than its field.
       100cqw is the hero's width, i.e. the card grid's: once the viewport is
       too narrow for 32rem the panel lines up with the cards exactly (vw units
       would not - `scrollbar-gutter: stable` keeps a gutter that 100vw counts
       and the cards do not). */
    left: 50%;
    transform: translateX(-50%);
    width: min(32rem, 100cqw);
    margin-top: .25rem;
    border-radius: .45rem;
    opacity: 0;
    visibility: hidden;
    text-align: left;
    transition: opacity .15s;
}

.lp-search .md-search:focus-within .md-search__output {
    opacity: 1;
    visibility: visible;
    box-shadow: var(--md-shadow-z3);
}

/* The scrolling body is what carries the panel's surface colour, so it has to
   fill the panel: Material sizes it in absolute units for the header dropdown
   (23.4rem between 60em and 76.25em, 34.4rem above it) and gives it
   `height: 100%` for the phone overlay, which left the grey box narrower than
   the panel on mid-width windows and zero-height on narrow ones. */
.lp-search .md-search__scrollwrap {
    width: 100%;
    height: auto;
    max-height: 60vh;
    border-radius: .45rem;
    background-color: var(--lp-surface);
}

/* ------------------------------------------------------------
   Cards
   ------------------------------------------------------------ */

.lp-cards {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: .8rem;
    align-items: stretch;
}

.lp-cards--pair {
    grid-template-columns: repeat(2, 1fr);
    margin-top: .8rem;
}

.lp-card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: .9rem 1rem 1rem;
    /* scripts_lp.js makes the whole card clickable (clicks on the inner
       links are left alone), so show the pointer across the surface */
    cursor: pointer;
}

/* The card's surface (background, border, shadow) lives on this layer rather
   than on .lp-card itself, so hover can scale the box while the text is never
   transformed - scaling the card blurred the small bold title, because the
   layer was rasterized at rest size and then GPU-upscaled. */
.lp-card::before {
    content: "";
    position: absolute;
    inset: 0;
    background-color: var(--lp-surface);
    border: 1px solid var(--lp-border);
    border-radius: .5rem;
    box-shadow: var(--lp-shadow);
    transition: border-color 150ms, box-shadow 150ms, transform 150ms;
}

.lp-card:hover::before {
    border-color: var(--lp-link);
    /* grid items are stretched, so scaling up doesn't reflow the row */
    transform: scale(1.02);
}

/* ::before is positioned, so the card's own content needs to be positioned
   too to keep painting above the surface layer */
.lp-card > * {
    position: relative;
}

@media (prefers-reduced-motion: reduce) {
    .lp-card::before {
        transition: border-color 150ms, box-shadow 150ms;
    }

    .lp-card:hover::before {
        transform: none;
    }
}

.lp-card__title {
    margin: 0;
    font-size: .8rem;
    font-weight: 700;
    line-height: 1.3;
}

.lp-card__title a {
    color: var(--lp-title);
    text-decoration: none;
}

.lp-card__desc {
    margin: .4rem 0 0;
    font-size: .65rem;
    line-height: 1.45;
    color: var(--lp-muted);
}

.lp-card__links {
    list-style: none;
    margin: .7rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .35rem;
}

.lp-card__links li {
    position: relative;
    padding-left: .95rem;
    font-size: .65rem;
    line-height: 1.35;
}

.lp-card__links li::before {
    content: "\2192";
    position: absolute;
    left: 0;
    color: var(--lp-link);
}

.lp-card__links a {
    color: var(--lp-link);
    text-decoration: none;
}

.lp-card__links a:hover {
    text-decoration: underline;
}

/* "View all N guides" sits at the bottom of the card, so the two cards in a
   row line their link lists up regardless of description length */
.lp-card__all {
    margin-top: auto;
    padding-top: .15rem;
}

.lp-nowrap {
    white-space: nowrap;
}

/* ------------------------------------------------------------
   Request form
   ------------------------------------------------------------ */

.lp-request {
    text-align: center;
    padding: 2.4rem 0 0;
}

.lp-request__title {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--lp-title);
}

.lp-request__subtitle {
    margin: .4rem 0 0;
    font-size: .65rem;
    color: var(--lp-muted);
}

/* fit-content makes this block exactly as wide as its widest child, which is
   the heading - so the button below, at width 100%, matches the heading. */
.lp-request__inner {
    width: fit-content;
    max-width: 100%;
    margin: 0 auto;
}

.lp-request__submit {
    width: 100%;
    margin-top: 1.1rem;
    padding: .5rem 1rem;
    font-size: .7rem;
    font-weight: 600;
    font-family: inherit;
    color: #ffffff;
    background-color: #111827;
    border: 0;
    border-radius: .45rem;
    cursor: pointer;
}

.lp-request__submit:hover {
    background-color: #000000;
}

/* Dark scheme: a black button would disappear into the page, so it takes the
   logo blue instead - #2378FF is the fill on the three bar paths in
   img/logo.svg. Hover darkens to #1D4ED8, the same pair the cookie dialog's
   Accept button uses. */
[data-md-color-scheme="slate"] .lp-request__submit {
    color: #ffffff;
    background-color: #2378FF;
}

[data-md-color-scheme="slate"] .lp-request__submit:hover {
    background-color: #1D4ED8;
}

/* ------------------------------------------------------------
   Request modal (holds the full HubSpot form)
   ------------------------------------------------------------ */

.lp-modal {
    position: fixed;
    inset: 0;
    z-index: 10;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    overflow: auto;
    padding: 2rem 1rem;
    background-color: rgba(15, 23, 42, .55);
}

.lp-modal[hidden] {
    display: none;
}

.lp-modal__dialog {
    position: relative;
    width: 100%;
    max-width: 26rem;
    padding: 1.4rem 1.2rem 1.2rem;
    background-color: #ffffff;
    border-radius: .5rem;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .35);
}

.lp-modal__close {
    position: absolute;
    top: .35rem;
    right: .5rem;
    padding: 0 .2rem;
    font-size: 1.1rem;
    line-height: 1;
    color: #5a6570;
    background: none;
    border: 0;
    cursor: pointer;
}

.lp-modal__close:hover {
    color: #000000;
}

/* Shown in place of the HubSpot form until its cookies are accepted. The
   dialog is white in both palettes, so the colours are fixed here rather than
   inherited from the dark page. */
.lp-modal__consent {
    margin: .8rem 0 0;
    font-size: .8rem;
    line-height: 1.5;
    color: #1f2933;
}

.lp-modal__consent[hidden] {
    display: none;
}

.lp-modal__consent a {
    color: #1a56db;
    text-decoration: underline;
}

/* ------------------------------------------------------------
   Footer
   ------------------------------------------------------------ */

/* Full page width, so the rule runs from edge to edge (the footer is outside
   .lp for exactly this reason); the content is put back into the same column
   as the rest of the page by .lp-footer__inner below. */
.lp-footer {
    margin-top: 2.6rem;
    border-top: 1px solid var(--lp-rule);
    padding: 1.1rem 0 1.4rem;
    color: var(--lp-text);
}

.lp-footer__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: .6rem 1rem;
    max-width: 50rem;
    margin: 0 auto;
    padding: 0 1.2rem;
}

.lp-footer__start {
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.lp-footer__brand {
    flex: 0 0 auto;
}

/* the lockup links to vmssoftware.com; inline-flex keeps the anchor from
   adding baseline space under the image */
.lp-footer__brand a {
    display: inline-flex;
    line-height: 0;
}

.lp-footer .lp-logo {
    height: 22px;
    width: auto;
}

.lp-footer .lp-logo--light {
    display: none;
}

[data-md-color-scheme="default"] .lp-footer .lp-logo--dark {
    display: none;
}

[data-md-color-scheme="default"] .lp-footer .lp-logo--light {
    display: block;
}

.lp-footer__links {
    display: flex;
    gap: .8rem;
    font-size: .65rem;
    line-height: 1.4;
}

.lp-footer__links a {
    color: var(--lp-muted);
    text-decoration: none;
}

.lp-footer__links a:hover {
    color: var(--lp-link);
}

/* Same size and line box as .lp-footer__links, so this sits on the same line as
   "VSI Documentation" and "Support": the row aligns on flex-end, which only
   lines the text up when the two boxes match. */
.lp-footer__copyright {
    margin: 0 0 0 auto;
    font-size: .65rem;
    line-height: 1.4;
    color: var(--lp-muted);
}

/* ------------------------------------------------------------
   Narrow screens
   ------------------------------------------------------------ */

@media screen and (max-width: 76.1875em) {

    /* Material collapses the header search into an icon + overlay here, so
       the field styling above no longer applies. */
    .md-search__form {
        border: 0;
        border-radius: 0;
        height: 2.4rem;
    }
}

@media screen and (max-width: 45em) {

    .lp-cards,
    .lp-cards--pair {
        grid-template-columns: 1fr;
    }

    .lp-hero {
        padding-top: 1.6rem;
    }

    .lp-hero__title {
        font-size: 1.3rem;
    }

    .lp-footer__copyright {
        margin-left: 0;
    }
}

/* ------------------------------------------------------------
   Cookie settings dialog

   These style the banner on the landing page only. partials/consent.html is
   also included by base.html on content pages, but those load custom.css and
   not this file - home.html hardcodes its stylesheets instead of emitting
   extra_css. home.html also hardcodes data-md-color-primary=indigo, which is
   where the theme's default indigo/purple button colour comes from.

   All of its buttons, including Accept selected in the Manage panel (which
   sits outside .md-consent__controls), take the .3rem corner radius used by
   the site's other buttons instead of Material's .1rem, share one width, and
   Accept selected is drawn like Reject all.
   ------------------------------------------------------------ */

/* One width for all four buttons, fitted to the longest label: "Accept
   selected" measures 183.6px (9.18rem) on the built page. min-width rather
   than width, so a longer label would still fit. On phones Material makes the
   row's buttons full-width blocks; Accept selected follows in the media query
   below. */
.md-typeset .md-consent__controls .md-button,
.md-typeset .md-consent__save {
    min-width: 9.2rem;
    text-align: center;
    border-radius: .3rem;
}

@media screen and (max-width: 44.984375em) {
    .md-typeset .md-consent__save {
        display: block;
        width: 100%;
    }
}

/* Ticked boxes in the Manage panel take the same VSI blue as Accept all,
   instead of Material's hardcoded task-list green (#00e676). */
.md-typeset .md-consent__settings [type=checkbox]:checked + .task-list-indicator::before {
    background-color: #2378FF;
}

/* Accept takes the VSI logo blue, with the same off-white label as Reject. */
.md-typeset .md-consent__controls .md-button--primary {
    background-color: #2378FF;
    border-color: #2378FF;
    color: #E2E8F0;
}

/* Hover/focus has to be declared explicitly, otherwise Material's own
   .md-typeset .md-button:hover rule repaints the button with
   --md-accent-fg-color. #1D4ED8 is Tailwind's blue-700, the hover pair the
   landing page already used for its blue button. The fade comes from
   Material's own .md-button transition. */
.md-typeset .md-consent__controls .md-button--primary:hover,
.md-typeset .md-consent__controls .md-button--primary:focus {
    background-color: #1D4ED8;
    border-color: #1D4ED8;
    color: #E2E8F0;
}

/* In the light scheme the off-white label reads as grey against the white
   dialog, so Accept all takes the dialog's own background colour instead
   (.md-consent__inner is --md-default-bg-color, #fff in this scheme). */
[data-md-color-scheme="default"] .md-typeset .md-consent__controls .md-button--primary,
[data-md-color-scheme="default"] .md-typeset .md-consent__controls .md-button--primary:hover,
[data-md-color-scheme="default"] .md-typeset .md-consent__controls .md-button--primary:focus {
    color: var(--md-default-bg-color);
}

/* Reject is outline-only against .md-consent__inner, whose background is
   --md-default-bg-color - dark in slate, white in the light scheme, so the
   off-white outline is scoped to slate. */
[data-md-color-scheme="slate"] .md-typeset .md-consent__controls .md-button:not(.md-button--primary),
[data-md-color-scheme="slate"] .md-typeset .md-consent__save {
    background-color: transparent;
    border-color: #E2E8F0;
    color: #E2E8F0;
}

[data-md-color-scheme="slate"] .md-typeset .md-consent__controls .md-button:not(.md-button--primary):hover,
[data-md-color-scheme="slate"] .md-typeset .md-consent__controls .md-button:not(.md-button--primary):focus,
[data-md-color-scheme="slate"] .md-typeset .md-consent__save:hover,
[data-md-color-scheme="slate"] .md-typeset .md-consent__save:focus {
    background-color: #E2E8F0;
    border-color: #E2E8F0;
    color: #000000;
}

/* Light scheme: the same outline-then-fill behaviour, in the Accept all blue
   instead of the theme's indigo outline (--md-primary-fg-color) and
   light-purple hover fill (--md-accent-fg-color). The hover label takes the
   dialog's background colour, like Accept all's label above. */
[data-md-color-scheme="default"] .md-typeset .md-consent__controls .md-button:not(.md-button--primary),
[data-md-color-scheme="default"] .md-typeset .md-consent__save {
    background-color: transparent;
    border-color: #2378FF;
    color: #2378FF;
}

[data-md-color-scheme="default"] .md-typeset .md-consent__controls .md-button:not(.md-button--primary):hover,
[data-md-color-scheme="default"] .md-typeset .md-consent__controls .md-button:not(.md-button--primary):focus,
[data-md-color-scheme="default"] .md-typeset .md-consent__save:hover,
[data-md-color-scheme="default"] .md-typeset .md-consent__save:focus {
    background-color: #2378FF;
    border-color: #2378FF;
    color: var(--md-default-bg-color);
}
