/* GENERATED by `node scripts/i18n.mjs build` from fonts.css, chrome.css, lang.css. Edit those; this file is overwritten. */

/* ---- fonts.css ---- */
/* Self-hosted copies of the three faces the paper system uses (Newsreader,
   Geist, Geist Mono), subset per script exactly as Google Fonts serves them.
   Served from our own CloudFront instead of fonts.googleapis.com: one fewer
   third-party connection, no render-blocking cross-origin stylesheet, and no
   font request leaving the EU for a GDPR-sensitive audience (SEO audit,
   2026-09-13). Regenerate by re-fetching the Google Fonts CSS with a modern
   browser UA and mapping each url() to assets/fonts/. */
@font-face{font-family:'Geist';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/geist-400-cyrillic-ext.woff2) format('woff2');unicode-range:U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F}
@font-face{font-family:'Geist';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/geist-400-cyrillic.woff2) format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Geist';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/geist-400-vietnamese.woff2) format('woff2');unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB}
@font-face{font-family:'Geist';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/geist-400-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Geist';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/geist-400-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}
@font-face{font-family:'Geist';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/geist-400-cyrillic-ext.woff2) format('woff2');unicode-range:U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F}
@font-face{font-family:'Geist';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/geist-400-cyrillic.woff2) format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Geist';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/geist-400-vietnamese.woff2) format('woff2');unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB}
@font-face{font-family:'Geist';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/geist-400-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Geist';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/geist-400-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}
@font-face{font-family:'Geist';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/geist-400-cyrillic-ext.woff2) format('woff2');unicode-range:U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F}
@font-face{font-family:'Geist';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/geist-400-cyrillic.woff2) format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Geist';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/geist-400-vietnamese.woff2) format('woff2');unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB}
@font-face{font-family:'Geist';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/geist-400-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Geist';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/geist-400-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}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/geist-mono-400-cyrillic-ext.woff2) format('woff2');unicode-range:U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/geist-mono-400-cyrillic.woff2) format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/geist-mono-400-symbols2.woff2) format('woff2');unicode-range:U+2000-2001, U+2004-2008, U+200A, U+23B8-23BD, U+2500-259F}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/geist-mono-400-vietnamese.woff2) format('woff2');unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/geist-mono-400-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/geist-mono-400-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}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/geist-mono-400-cyrillic-ext.woff2) format('woff2');unicode-range:U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/geist-mono-400-cyrillic.woff2) format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/geist-mono-400-symbols2.woff2) format('woff2');unicode-range:U+2000-2001, U+2004-2008, U+200A, U+23B8-23BD, U+2500-259F}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/geist-mono-400-vietnamese.woff2) format('woff2');unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/geist-mono-400-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/geist-mono-400-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}
@font-face{font-family:'Newsreader';font-style:normal;font-weight:300;font-display:swap;src:url(/assets/fonts/newsreader-300-vietnamese.woff2) format('woff2');unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB}
@font-face{font-family:'Newsreader';font-style:normal;font-weight:300;font-display:swap;src:url(/assets/fonts/newsreader-300-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Newsreader';font-style:normal;font-weight:300;font-display:swap;src:url(/assets/fonts/newsreader-300-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}
@font-face{font-family:'Newsreader';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/newsreader-300-vietnamese.woff2) format('woff2');unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB}
@font-face{font-family:'Newsreader';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/newsreader-300-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Newsreader';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/newsreader-300-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}

/* ---- chrome.css ---- */
/* Site chrome — the one header and the one footer.
 *
 * These rules used to be retyped inside every page's inline <style>, in two
 * incompatible versions: a 80px grid bar on the fourteen pages that carry their
 * own stylesheet, and a 64px flex bar in styles.css on the six that don't. Same
 * class names, different heights, layouts, CTA shapes and breakpoints — which
 * is why shared/nav-mobile.js has to MEASURE whether the links are visible
 * instead of just asking a media query. This file is the single version; the
 * markup that uses it is generated by scripts/i18n.mjs into the
 * <!-- i18n:header --> and <!-- i18n:footer --> blocks. Do not hand-edit either.
 *
 * Every page links this, including index.html, which carries a full inline
 * stylesheet and never loads styles.css — the same reason shared/lang.css is
 * its own file.
 *
 * Nothing here may depend on a page-local custom property, because the pages
 * define different ones. --accent is the single exception and it is always
 * given a literal fallback: index.html and styles.css both declare it, but a
 * new page might not, and a missing accent would render the CTA invisible.
 */

/* ---------------------------------------------------------------------------
 * Header
 *
 * position:fixed is what fourteen pages already do, and their heroes reserve
 * the space with their own top padding. A page without a hero (the legal pages,
 * 404) reserves it in its own layout rule — see .legal in styles.css.
 * ------------------------------------------------------------------------- */

.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 60;
  background: rgba(13, 13, 15, .9);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(255, 255, 255, .1);
}

/* The homepage nav sits over the top of a full-bleed hero video, so it starts
 * almost invisible and fades to solid once you scroll past the fold. Only the
 * homepage opts in, via variant="overlay" on the generated block; the class is
 * what shared/nav-mobile.js looks for before it binds the scroll listener. */
.nav--overlay {
  background: rgba(13, 13, 15, .12);
  backdrop-filter: none; -webkit-backdrop-filter: none;
  border-bottom-color: transparent;
  transition: background .35s ease, backdrop-filter .35s ease, border-color .35s ease;
}
.nav--overlay.scrolled {
  background: rgba(13, 13, 15, .9);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom-color: rgba(255, 255, 255, .1);
}

/* The homepage is a light document, so its header is paper rather than ink: the
 * same overlay behaviour (near-transparent over the fold, solid once you scroll
 * past it) painted the other way round. It opts in with variant="light" on the
 * generated block, and shared/nav-mobile.js binds .scrolled for both variants.
 * Every colour below is a literal for the same reason the rest of this file is:
 * a page must not have to declare a token to get a working header. */
.nav--light {
  /* A gradient rather than a flat translucent fill: the homepage photograph
   * runs up behind the bar, and a flat fill drew a hard horizontal edge across
   * it at 80px. This keeps the links legible over the dark hair and dissolves
   * into the photograph instead of ending on it. */
  background: linear-gradient(180deg, rgba(243, 242, 238, .96) 0%, rgba(243, 242, 238, .82) 62%, rgba(243, 242, 238, 0) 100%);
  border-bottom-color: transparent;
  transition: background .35s ease, border-color .35s ease;
}
.nav--light.scrolled {
  background: rgba(243, 242, 238, .94);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-bottom-color: #dcd9d2;
}
.nav--light .nav-logo,
.nav--light .nav-logo svg { color: #111113; }
.nav--light .nav-links a.navlink {
  color: #4a4a51;
  position: relative; padding-bottom: 3px;
}
.nav--light .nav-links a.navlink:hover,
.nav--light .nav-links a.navlink[aria-current="page"] { color: #111113; }
/* The rule grows from the left rather than appearing: on a page this quiet the
 * hover has to be visible without being loud. */
.nav--light .nav-links a.navlink::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 1px; width: 0;
  background: currentColor; transition: width .28s cubic-bezier(.2, .7, .2, 1);
}
.nav--light .nav-links a.navlink:hover::after,
.nav--light .nav-links a.navlink[aria-current="page"]::after { width: 100%; }
@media (prefers-reduced-motion: reduce) {
  .nav--light .nav-links a.navlink::after { transition: none; }
}
.nav--light .nav-login { color: #111113; }
/* The light bar takes the DARKER accent: the brand orange is 2.7:1 on paper and
 * this is text, not a hairline. --accent-ink is home.css's; the literal is here
 * so the rule still works on a page that has not declared it. */
.nav--light .nav-login:hover { color: var(--accent-ink, #B83E08); }
/* Ink pill, not accent: the homepage's one accent is a hairline, never a surface. */
.nav--light .nav-cta {
  background: #111113; color: #fff !important;
  border-radius: 6px; padding: 12px 22px;
  font-size: 13px; font-weight: 600; text-transform: none; letter-spacing: -.005em;
}
.nav--light .nav-cta:hover { filter: none; background: #2d2d33; }
/* The burger is injected by shared/nav-mobile.js with a hardcoded white; the
 * drawer it opens is a dark full-width overlay and stays that way. */
.nav--light .mp-burger { color: #111113; }
/* The selector is generated with the dark variant on every page. Repaint it
 * here rather than teach the generator a second one. The border is 3.2:1 on
 * paper, not the page's decorative hairline: it is the edge of a control. */
.nav--light .lang-switch--dark > summary {
  color: #4a4a51; border-color: #888279; background: rgba(255, 255, 255, .5);
}
.nav--light .lang-switch--dark > summary:hover { color: #111113; border-color: #111113; }

.nav .wrap {
  max-width: 1240px; margin: 0 auto; padding: 0 24px;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; height: 80px;
}

.nav-logo {
  justify-self: start; display: flex; align-items: center; gap: 12px;
  text-decoration: none; font-weight: 800; letter-spacing: -.01em; color: #fff;
}
.nav-logo svg { height: 28px; width: auto; color: #fff; }
.nav-logo span { font-size: 22px; }

.nav-links {
  justify-self: center; display: flex; align-items: center; gap: 32px;
  font-size: 13px; font-weight: 600;
}
/* font-size/weight are repeated here on purpose. styles.css still ships on the
 * legal pages and its `.nav-links a` beats the 13px/600 inherited from
 * `.nav-links`, closing the language pill to a 0px gap against the last link. */
.nav-links a.navlink {
  font-size: 13px; font-weight: 600;
  text-decoration: none; color: rgba(255, 255, 255, .7); transition: color .15s;
}
.nav-links a.navlink:hover,
.nav-links a.navlink[aria-current="page"] { color: #fff; }

/* Log in sits beside Start now: a returning owner and a new one want different
 * doors, and only one of them was on the page. */
.nav-actions { justify-self: end; display: flex; align-items: center; gap: 20px; }
.nav-login {
  font-size: 13px; font-weight: 700; color: rgba(255, 255, 255, .9);
  text-decoration: none; transition: color .15s; white-space: nowrap;
}
.nav-login:hover { color: var(--accent, #FF2D78); }
.nav-cta {
  background: var(--accent, #FF2D78); color: #fff !important;
  padding: 11px 22px; border-radius: 4px;
  font-size: 13px; font-weight: 800; text-decoration: none;
  text-transform: uppercase; letter-spacing: .03em; white-space: nowrap;
}
.nav-cta:hover { filter: brightness(1.08); }

/* One breakpoint, not two. 820px is where the eight links stop fitting beside
 * the logo and the actions; below it nav-mobile.js clones them into a drawer. */
@media (max-width: 820px) {
  .nav-links { display: none; }
  .nav .wrap { grid-template-columns: 1fr auto; }
}
@media (max-width: 420px) { .nav-actions { gap: 13px; } }

/* One "Start free" at a time on a phone.
 *
 * The hero carries the primary CTA and the bar carries a second one 60px above
 * it: on a 390px screen that is the same words twice in one glance. The bar's
 * copy is held back until you have scrolled past the hero, at which point it is
 * the only one on screen and earns its place. Desktop shows both, where they
 * are far enough apart to read as a persistent bar and a page CTA.
 * `.scrolled` is set by shared/nav-mobile.js at 36px. */
@media (max-width: 820px) {
  .nav--light .nav-cta {
    opacity: 0; transform: scale(.94); pointer-events: none;
    transition: opacity .3s ease, transform .3s cubic-bezier(.2, .7, .2, 1);
  }
  .nav--light.scrolled .nav-cta { opacity: 1; transform: none; pointer-events: auto; }
  @media (prefers-reduced-motion: reduce) {
    .nav--light .nav-cta { transition: none; }
  }
}

/* An in-page jump must not land under the fixed bar. */
html { scroll-padding-top: 96px; }

/* shared/lang.js inserts its "also available in Portuguese" bar as the body's
 * first child, which worked when the header was in normal flow and the bar
 * pushed it down. The header is fixed now, so in flow the bar lands underneath
 * it and is unreadable. Pin it directly below instead. Scoped to this file, so
 * the help centre — which loads lang.css but not chrome.css and has its own
 * header — keeps the in-flow bar it was built for.
 *
 * `html .lang-nudge` rather than `.lang-nudge`: lang.css is linked AFTER this
 * file on every page, so at equal specificity its `position: relative` would
 * win and the bar would only appear to move (a relative offset still reserves
 * its space at the top of the flow).
 *
 * z-index 55 puts it under the mobile drawer (59) and its scrim (58), which
 * open at the same 80px. lang.css's 80 sat on top of both, so on a phone the
 * nudge bar painted through an open menu. */
html .lang-nudge { position: fixed; top: 80px; left: 0; right: 0; z-index: 55; }

/* The language menu opens and closes with motion.
 *
 * A <details> flips instantly by nature, so the open half is a keyframe on the
 * panel and the close half needs `::details-content` with
 * `transition-behavior: allow-discrete` (Chrome 131+) to hold the element
 * around long enough to animate out. Where that is unsupported the panel simply
 * appears on close-out, which is what it did before, so nothing regresses.
 * Scoped to the chrome's two switchers; the help centre has its own header. */
@media (prefers-reduced-motion: no-preference) {
  .nav details[open] > .lang-menu,
  .site-foot details[open] > .lang-menu {
    animation: langMenuIn .22s cubic-bezier(.2, .7, .2, 1) both;
  }
  @keyframes langMenuIn {
    from { opacity: 0; transform: translateY(-6px) scale(.985); }
    to   { opacity: 1; transform: none; }
  }
  .site-foot details[open] > .lang-menu { animation-name: langMenuInUp; }
  @keyframes langMenuInUp {
    from { opacity: 0; transform: translateY(6px) scale(.985); }
    to   { opacity: 1; transform: none; }
  }
  /* the closing half, where the browser can keep the content around for it */
  .nav details.lang-switch::details-content,
  .site-foot details.lang-switch::details-content {
    opacity: 0;
    transition: opacity .18s ease, content-visibility .18s allow-discrete;
  }
  .nav details.lang-switch[open]::details-content,
  .site-foot details.lang-switch[open]::details-content { opacity: 1; }
  /* the chevron turns with it */
  .nav .lang-switch > summary .lang-chevron,
  .site-foot .lang-switch > summary .lang-chevron { transition: transform .22s cubic-bezier(.2, .7, .2, 1); }
  .nav .lang-switch[open] > summary .lang-chevron,
  .site-foot .lang-switch[open] > summary .lang-chevron { transform: rotate(180deg); }
}

/* A runtime page (404.html) carries one copy of the chrome per language and
 * shows the reader's. Stated rather than left to the UA stylesheet, because a
 * header that fails to hide is a second fixed bar on top of the first. */
.chrome-lang[hidden] { display: none; }

/* ---------------------------------------------------------------------------
 * Footer
 *
 * Dark, because it has to sit at the bottom of a white marketing page, a white
 * legal page and a near-black article page without knowing which. The light
 * variant the homepage used to carry read its colours from that page's own
 * --bg2 / --ink / --border, none of which exist on a page served by styles.css.
 * Self-contained literals are what make one footer possible.
 * ------------------------------------------------------------------------- */

footer.site-foot {
  background: #0d0d0f; color: #fff; padding: 70px 0 34px;
  border-top: 0;
}
footer.site-foot .wrap { max-width: 1240px; margin: 0 auto; padding: 0 24px; }

/* The brand block, then one implicit 1fr column per link group, however many
   there are: a language with two groups and one with three (the English footer
   grew a Compare column, 14 Sep 2026) both lay out on one row. Not auto-fit:
   an auto-repeat beside an fr track is an invalid declaration and the whole
   footer stacked. */
.foot-top { display: grid; grid-auto-flow: column; grid-template-columns: 1.6fr; grid-auto-columns: 1fr; gap: 48px; }
.foot-brand {
  display: flex; align-items: center; gap: 10px;
  font-weight: 800; font-size: 20px; margin-bottom: 14px; color: #fff;
}
.foot-brand svg { height: 24px; width: auto; color: #fff; }
.foot-tag {
  font-size: 14px; line-height: 1.6; color: rgba(255, 255, 255, .5);
  max-width: 42ch; margin: 0 0 22px;
}
.foot-badges { display: flex; gap: 12px; flex-wrap: wrap; }
.foot-badges img { height: 40px; width: auto; display: block; }
.foot-badges a { transition: transform .15s; }
.foot-badges a:hover { transform: translateY(-2px); }

.foot-col h3 {
  font-size: 11px; letter-spacing: .18em; text-transform: uppercase;
  /* .58, not .4: .4 measured 3.80:1 on the footer ground, under AA for 11px */
  color: rgba(255, 255, 255, .58); margin: 0 0 16px; font-weight: 800;
}
.foot-col a {
  display: block; font-size: 14px; color: rgba(255, 255, 255, .72);
  text-decoration: none; padding: 5px 0; transition: color .15s;
  /* styles.css sets margin-bottom on this same selector and is not overridden
   * by the padding above, which made footer rows 9px taller on the legal pages
   * than on the homepage. */
  margin-bottom: 0;
}
.foot-col a:hover,
.foot-col a[aria-current="page"] { color: #fff; }

.foot-bottom {
  display: flex; justify-content: space-between; align-items: center;
  gap: 16px; flex-wrap: wrap;
  margin-top: 52px; padding-top: 24px;
  border-top: 1px solid rgba(255, 255, 255, .1);
  font-size: 12.5px; color: rgba(255, 255, 255, .58);
}

@media (max-width: 820px) {
  .foot-top { grid-auto-flow: row; grid-template-columns: 1fr; gap: 36px; }
  .foot-bottom { flex-direction: column; align-items: flex-start; }
}

/* The footer's language selector.
 *
 * shared/lang.css's `--light` variant means two things at once: opens upward,
 * and painted for a light surface. The footer is dark now, so only the first
 * half still applies, and the second left a white pill sitting on #0d0d0f.
 * Repaint it here rather than in lang.css, because the help centre uses the
 * same file against a genuinely light page.
 */
footer.site-foot .lang-switch--light > summary {
  color: rgba(255, 255, 255, .72);
  border-color: rgba(255, 255, 255, .18);
  background: rgba(255, 255, 255, .06);
}
footer.site-foot .lang-switch--light > summary:hover {
  color: #fff;
  border-color: rgba(255, 255, 255, .38);
}
footer.site-foot .lang-switch--light .lang-menu {
  background: #17171a;
  border-color: rgba(255, 255, 255, .14);
  box-shadow: 0 -8px 28px rgba(0, 0, 0, .45);
}
footer.site-foot .lang-switch--light .lang-menu a,
footer.site-foot .lang-switch--light .lang-menu button { color: rgba(255, 255, 255, .72); }
footer.site-foot .lang-switch--light .lang-menu a:hover,
footer.site-foot .lang-switch--light .lang-menu button:hover,
footer.site-foot .lang-switch--light .lang-menu a[aria-current="page"],
footer.site-foot .lang-switch--light .lang-menu button[aria-current="true"] {
  background: rgba(255, 255, 255, .08);
  color: #fff;
}

/* ---- lang.css ---- */
/* Language selector — matpilot.io
   ---------------------------------------------------------------------------
   Lives in its own file rather than in styles.css because index.html carries a
   full inline stylesheet and never loads styles.css. One file, linked by every
   page that has a selector, keeps the widget from existing in two places.
   Every custom property below has a literal fallback, so this drops onto a page
   with any token set (or none).

   The selector is a <details>/<summary> disclosure. The expanded state is a
   browser primitive and each row is a plain <a href>, so it opens, closes and
   switches language with JavaScript disabled. shared/lang.js only adds
   conveniences on top. The markup is generated into each page by
   scripts/i18n.mjs from i18n.config.json.

   Built to grow: .lang-menu scrolls once the list outgrows its height, which is
   the point of a list rather than a two-way toggle. */

.lang-switch { position: relative; display: inline-block; }
.lang-switch > summary {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 9999px; cursor: pointer;
  font-size: 12px; font-weight: 700; letter-spacing: 0.02em; line-height: 1.2;
  list-style: none; -webkit-user-select: none; user-select: none;
}
.lang-switch > summary::-webkit-details-marker { display: none; }
.lang-switch > summary::marker { content: ""; }
.lang-switch > summary:focus-visible { outline: 2px solid var(--accent, #ff2d78); outline-offset: 2px; }
/* The flag is sized in em by the .fi rule below, so this font-size IS its size:
   12px of font gives a 16x12 box. It was 14px while the flag was an emoji glyph,
   which needed the extra to match the label optically; a solid rectangle does
   not, and at 14px it overpowered the 12px code beside it. */
.lang-switch .lang-flag { font-size: 12px; line-height: 1; }
.lang-switch .lang-chevron {
  width: 0; height: 0; margin-left: 1px;
  border-left: 3.5px solid transparent; border-right: 3.5px solid transparent;
  border-top: 4px solid currentColor; opacity: 0.75;
  transition: transform 0.15s ease;
}
.lang-switch[open] > summary .lang-chevron { transform: rotate(180deg); }

/* Flags — a trimmed subset of flag-icons 7.5.0 (MIT), NOT the library.
   ---------------------------------------------------------------------------
   Why not the emoji it replaced: Windows Chrome ships no country-flag font, so
   🇬🇧 rendered there as the bare letters "GB". SVG images render everywhere.

   Why not the full flag-icons.min.css: it is ~250 background-image rules, one
   per country, and web/ has no build step to tree-shake — `aws s3 sync web/`
   ships whatever is committed. Two languages do not need 250 rules or the
   ~10MB of SVGs behind them. So the base `.fi` rule and one `.fi-<cc>` rule per
   shipped country are copied here by hand, and only those countries' SVGs are
   vendored into shared/flags/. The class NAMES are flag-icons' own, so the
   generated markup stays portable: if a third language ever makes the real
   package worth carrying, swap this block for it and the HTML is unchanged.

   ADDING A LANGUAGE — three steps, none of them automatic:
     1. copy node_modules/flag-icons/flags/4x3/<cc>.svg to shared/flags/<cc>.svg
     2. add `.fi-<cc> { background-image: url("flags/<cc>.svg"); }` below
     3. set `country: "<cc>"` on the language in i18n.config.json, then
        `node scripts/i18n.mjs build`
   `node scripts/i18n.mjs check` fails if 1 or 2 is missed.

   The url()s are relative to THIS FILE, not to the page that links it, so the
   single copy at /shared/lang.css resolves to /shared/flags/<cc>.svg for a root
   page, a /pt/ page and a /help/ page alike.

   Unscoped, and at flag-icons' own specificity, so that swap stays a clean
   replacement rather than a fight neither rule wins. */
.fi {
  background-size: contain; background-position: 50%; background-repeat: no-repeat;
  position: relative; display: inline-block; width: 1.333333em; line-height: 1em;
}
.fi::before { content: "\00a0"; } /* the span is empty; this gives it height */
.fi-ie { background-image: url("flags/ie.svg"); }
.fi-gb { background-image: url("flags/gb.svg"); }
.fi-br { background-image: url("flags/br.svg"); }
.fi-us { background-image: url("flags/us.svg"); }
/* Spanish takes two flags, not one: shared/lang.js swaps a reader in the Americas
   onto the Mexican one, so both are shipped even though only `es` is named in
   i18n.config.json. Same reason `gb` sits above `ie` for English. */
.fi-es { background-image: url("flags/es.svg"); }
.fi-mx { background-image: url("flags/mx.svg"); }
/* Local touch, not from the library: the flags sit against a dark header and a
   white footer, and both tricolour and union flags reach the edge of their box
   in each. */
.lang-switch .lang-flag.fi { border-radius: 1px; }

.lang-menu {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 70;
  min-width: 128px; max-height: 264px;
  overflow-y: auto; overscroll-behavior: contain;
  margin: 0; padding: 6px; list-style: none;
  border-radius: 12px; box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28);
}
/* On a phone the menu is IN FLOW, not floating.
   Anchoring it to the left edge stopped it growing off the side, and it was
   still cut off: on mobile the header's actions are cloned into .mp-drawer,
   which scrolls (`overflow-y: auto`), and a scroll container clips an
   absolutely positioned child at its own edge no matter where that child is
   anchored. The footer's switcher has the same shape. So below 820px the menu
   stops floating and simply takes its place in the column, pushing whatever is
   under it down and scrolling with the drawer. Nothing can crop what is not
   positioned out of the flow (reported twice on an iPhone, 10 Sep 2026). */
@media (max-width: 820px) {
  .lang-switch { display: block; }
  .lang-switch > summary { display: flex; width: max-content; }
  .lang-menu {
    position: static; left: auto; right: auto; top: auto; bottom: auto;
    width: 100%; min-width: 0; max-width: none; max-height: none;
    margin-top: 8px; box-shadow: none;
  }
  .lang-switch--light .lang-menu { top: auto; bottom: auto; }
}
.lang-menu li { margin: 0; }
/* A row is an <a> when the selector links to a sibling page, and a <button>
   when the page switches language in place (scripts/i18n.mjs mode="runtime",
   used by /help/). They are the same control to a reader, so every rule below
   names both rather than letting one mode quietly go unstyled. */
.lang-menu a,
.lang-menu button {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; border-radius: 8px; text-decoration: none;
  font-size: 12px; font-weight: 700; letter-spacing: 0.02em; white-space: nowrap;
  width: 100%; border: 0; background: none; font-family: inherit;
  cursor: pointer; text-align: left;
}
.lang-menu .lang-check { margin-left: auto; padding-left: 14px; min-width: 10px; }
/* A ROW IS A COUNTRY, WITH ITS LANGUAGE UNDER IT: "Brasil / Português",
   "United States / English". The pages differ by country (prices, terms), so
   the picker is a country picker and says so (Vinny, 11 Sep 2026). The code
   stays in the closed pill, now the country's own (BR, IE, ES, US), where a
   flag and two letters are all that fit; in a row it is for screen readers. */
.lang-menu .lang-code {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.lang-menu a, .lang-menu button { padding-top: 7px; padding-bottom: 7px; }
.lang-menu .lang-place { display: flex; flex-direction: column; gap: 1px; line-height: 1.25; }
.lang-menu .lang-country { font-size: 13px; font-weight: 600; letter-spacing: 0; }
/* .85 of the row's own ink, not a fixed grey: on the dark menu that is 6:1,
   where a fixed muted grey measured under 4.5:1 behind the country above it */
.lang-menu .lang-name { font-size: 11.5px; font-weight: 400; letter-spacing: 0; opacity: .85; }
/* And the list says what it is a list OF. */
.lang-menu-head {
  white-space: nowrap;
  padding: 5px 10px 6px; font-size: 10px; font-weight: 800;
  letter-spacing: 0.09em; text-transform: uppercase; opacity: 0.6;
}

/* Dark variant — the black site header. */
.lang-switch--dark > summary { color: rgba(255, 255, 255, 0.7); border: 1px solid rgba(255, 255, 255, 0.2); }
.lang-switch--dark > summary:hover { color: #ffffff; border-color: rgba(255, 255, 255, 0.34); }
.lang-switch--dark .lang-menu { background: #141416; border: 1px solid rgba(255, 255, 255, 0.12); }
.lang-switch--dark .lang-menu-head { color: rgba(255, 255, 255, 0.5); }
.lang-switch--dark .lang-menu a,
.lang-switch--dark .lang-menu button { color: rgba(255, 255, 255, 0.7); }
.lang-switch--dark .lang-menu a:hover,
.lang-switch--dark .lang-menu button:hover { background: rgba(255, 255, 255, 0.08); color: #ffffff; }
/* A linked row carries aria-current="page"; a runtime row is repainted by
   the page script, which uses "true". Both mean "the language you are in". */
.lang-switch--dark .lang-menu a[aria-current="page"],
.lang-switch--dark .lang-menu button[aria-current="true"] { background: rgba(255, 255, 255, 0.1); color: #ffffff; }

/* Light variant — the footer. Opens upward: it sits at the bottom of the page. */
.lang-switch--light > summary {
  color: var(--text-secondary, #56565c); border: 1px solid var(--border, #e7e7ea);
  background: var(--bg, #ffffff);
}
.lang-switch--light > summary:hover { color: var(--ink, #0a0a0a); border-color: var(--text-muted, #8e8e95); }
.lang-switch--light .lang-menu {
  top: auto; bottom: calc(100% + 8px);
  background: var(--bg, #ffffff); border: 1px solid var(--border, #e7e7ea);
  box-shadow: 0 -8px 28px rgba(0, 0, 0, 0.12);
}
.lang-switch--light .lang-menu-head { color: var(--text-muted, #8e8e95); }
.lang-switch--light .lang-menu a,
.lang-switch--light .lang-menu button { color: var(--text-secondary, #56565c); }
.lang-switch--light .lang-menu a:hover,
.lang-switch--light .lang-menu button:hover { background: var(--surface, #f6f6f7); color: var(--ink, #0a0a0a); }
/* A linked row carries aria-current="page"; a runtime row is repainted by
   the page script, which uses "true". Both mean "the language you are in". */
.lang-switch--light .lang-menu a[aria-current="page"],
.lang-switch--light .lang-menu button[aria-current="true"] { background: var(--surface, #f6f6f7); color: var(--ink, #0a0a0a); }

/* Suggestion bar injected by shared/lang.js when the reader's language and the
   page's language disagree. It is a link, never a redirect, so there is no loop
   to get stuck in and nothing about it is required for switching to work. */
.lang-nudge {
  display: flex; align-items: center; justify-content: center; gap: 14px;
  flex-wrap: wrap; padding: 10px 16px; position: relative; z-index: 80;
  background: var(--surface, #f6f6f7); border-bottom: 1px solid var(--border, #e7e7ea);
  font-family: inherit; font-size: 13px; color: var(--text-secondary, #56565c);
}
.lang-nudge a { font-weight: 600; color: var(--ink, #0a0a0a); text-decoration: underline; }
.lang-nudge button {
  border: 0; background: transparent; cursor: pointer;
  font: inherit; font-size: 16px; color: #64646c; padding: 2px 6px; line-height: 1;
}
.lang-nudge button:hover { color: var(--ink, #0a0a0a); }
