/* One family, one file. The variable face below covers 300-800, so the header
   asks for it directly instead of going through an alias that listed two static
   cuts first: those cuts were 700 and 800 of this same typeface, and naming them
   ahead of the variable font meant every page downloaded 24 KB of duplicates for
   weights the preloaded file already carried. */
@font-face {
  font-family: "Plus Jakarta Sans";
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url("/assets/fonts/plus-jakarta-sans-latin.woff2") format("woff2");
}

:root {
  --site-header-font: "Plus Jakarta Sans", sans-serif;
  --site-header-forest: #1e4620;
  --site-header-gold: #c59b27;
  --site-header-border: #efeae0;
  /* The header's own cream, warmer than the page's. a11y.css names the same
     value as --a11y-focus-ring-inverse, because a focus ring drawn on the
     header has to be legible against exactly this. */
  --site-header-cream: #fcf1db;
}

header.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 1px solid var(--site-header-border);
  background: var(--site-header-cream);
  box-shadow: 0 1px 3px rgba(45, 36, 27, 0.1);
  backdrop-filter: none;
  transform: translateZ(0);
}

.site-header .header-shell {
  width: min(1280px, 100%);
  height: 80px;
  margin-inline: auto;
  padding-inline: 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.site-header .header-brand {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  color: inherit;
  text-decoration: none;
}

.site-header .header-brand-logo {
  width: 64px;
  height: 64px;
  min-width: 64px;
  max-width: 64px;
  min-height: 64px;
  max-height: 64px;
  flex: 0 0 64px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: 16px;
  background: #fff;
}

.site-header .header-brand-logo img {
  width: 64px;
  height: 64px;
  max-width: 64px;
  max-height: 64px;
  display: block;
  object-fit: cover;
  transition: transform 0.3s ease;
}

.site-header .header-brand:hover .header-brand-logo img {
  transform: scale(1.05);
}

.site-header .header-brand-copy {
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  font-family: var(--site-header-font);
  font-feature-settings: normal;
  font-variation-settings: normal;
  font-style: normal;
  font-synthesis: none;
  text-rendering: geometricPrecision;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.site-header .header-brand-name,
.site-header .header-brand-tagline {
  display: block;
  margin: 0;
  padding: 0;
  border: 0;
  font-family: var(--site-header-font);
  font-style: normal;
  text-transform: uppercase;
}

.site-header .header-brand-name {
  color: var(--site-header-forest);
  font-size: 0.875rem;
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.15;
}

/* The tagline is the one language-tagged element that must not fade in: it sits
   in the sticky header, so an entrance animation on it plays again every time
   the header is re-composited. Both attribute names are matched - see the note
   in the home template's <style> - because the tagline is written as
   lang-content there and rewritten to data-i18n in the generated pages. */
.site-header .header-brand-tagline[lang-content],
.site-header .header-brand-tagline[data-i18n] {
  animation: none !important;
  transform: none !important;
}

body.lang-es .site-header .header-brand-tagline[lang-content="es"],
body.lang-en .site-header .header-brand-tagline[lang-content="en"],
body.lang-pt .site-header .header-brand-tagline[lang-content="pt"] {
  display: block !important;
}

.site-header .header-brand-tagline {
  margin-top: 1px;
  color: var(--site-header-gold);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  line-height: 1.15;
}

.site-header .header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

.site-header .site-return-link {
  display: inline-flex;
  min-height: 32px;
  padding: 6px 12px;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid #e6d8c3;
  border-radius: 8px;
  background: transparent;
  color: #3a2719;
  font-family: "Plus Jakarta Sans", sans-serif;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  transition: background-color 160ms ease, border-color 160ms ease;
}

.site-header .site-return-link:hover {
  border-color: #d7c2a5;
  background: #f3e8d5;
}

.site-header .site-return-link:focus-visible {
  outline: 3px solid rgba(197, 155, 39, 0.35);
  outline-offset: 2px;
}

/* The language switcher, which used to sit in the simulator footers and now
   sits in the header alongside it, matching the main site.

   The home and journal headers draw the same control with Tailwind utilities
   out of assets/styles.css; the simulator pages are served a precompiled
   subset of that bundle instead, so the appearance is written out longhand
   here. The class names are deliberately not the `.header-language-switcher`
   and `.lang-btn` those pages use: this file is linked after home.css, so
   reusing the names would let these rules win over the home page's own
   responsive sizes. */
.site-header .simulator-language-switcher {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
  padding: 4px;
  border: 1px solid #efeae0;
  border-radius: 9999px;
  background: rgba(255, 255, 255, 0.8);
  box-shadow: 0 1px 2px rgba(45, 36, 27, 0.08);
}

.site-header .simulator-lang-btn {
  display: inline-flex;
  width: 40px;
  height: 32px;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  padding: 6px;
  border-radius: 9999px;
  text-decoration: none;
  transition: background-color 180ms ease, transform 180ms ease;
}

.site-header .simulator-lang-btn:hover {
  background: rgba(30, 70, 32, 0.08);
  transform: translateY(-1px);
}

.site-header .simulator-lang-btn[aria-current='page'] {
  background: rgba(197, 155, 39, 0.2);
  box-shadow: inset 0 0 0 1px rgba(197, 155, 39, 0.28);
}

.site-header .simulator-lang-btn:focus-visible {
  outline: 3px solid rgba(197, 155, 39, 0.35);
  outline-offset: 2px;
}

.site-header .simulator-lang-btn svg {
  display: block;
  width: 24px;
  height: 16px;
  overflow: hidden;
  border-radius: 2px;
  box-shadow: 0 1px 2px rgba(45, 36, 27, 0.2);
}

/* Three flags is roughly 110px that this row did not carry before, and the
   busiest simulator header — Passive Income Engine, with four controls and the
   return link — already ran close to the edge of a 360px screen. So the row is
   allowed to become two: the fixed 5rem height from `h-20` becomes a floor
   instead, and the brand and the controls wrap apart at the widths where they
   genuinely do not fit. Scoped to the simulator shell, so the home and journal
   headers are untouched.

   That safety net used to carry the whole load, and it was doing so on ordinary
   windows: three of the five simulators wrapped to two rows while the other two
   stayed at 5rem, so the header changed height depending on which tool you were
   in. Their labelled controls are now icon-only (see the rule below), which took
   somewhere between 150 and 220px out of each of those rows. Where the row does
   not wrap, `min-height: 5rem` plus a 64px logo and 8px of block padding comes
   to exactly the 5rem the other two headers are, so all five now match. */
.site-header .simulator-header-shell {
  height: auto;
  min-height: 5rem;
  padding-block: 8px;
  flex-wrap: wrap;
}

.site-header .simulator-header-shell .header-actions {
  flex-wrap: wrap;
  justify-content: flex-end;
  row-gap: 6px;
}

/* A simulator's own controls, reduced to their icons.

   The labels they used to carry were the longest things in the row - "Customize
   Income & Age Settings", "Cómo Funciona", "Clasificación" - and they were the
   reason the row wrapped. Every one of them is still in the DOM as the button's
   accessible name, and repeated in `title` so a pointer gets a tooltip; nothing
   here is icon-only to a screen reader. Advancing a year in the Passive Income
   Engine also has a labelled button in the body of that page, so the chevrons
   are a shortcut rather than the only way to do it. The sliders on Freedom
   Calendar are the exception: they are the only control that opens its profile
   drawer, since the button inside the drawer closes it. The tooltip and the
   accessible name carry the label there, and a short visible one could go back
   if the glyph turns out not to be enough.

   36x36 rather than the assorted paddings these buttons each had: it clears
   WCAG 2.2 SC 2.5.8 with room to spare, and it means the five headers draw the
   same size of control whichever simulator you are in. The font-size is set
   here because the icons are a webfont, so they inherit it. */
.site-header .simulator-header-actions .header-icon-btn {
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  line-height: 1;
}

.site-header .simulator-header-actions .header-icon-btn i {
  font-size: 0.875rem;
}

/* ---------------------------------------------------------------------------
   The desktop section nav

   The pill of seven items in the header of every page outside the home page:
   Blog, Simuladores, a Recursos menu holding the four resource sections, Sobre
   mí, Sesiones, and the FAQ and Contacto anchors on the home page.

   These are the home page's own nav rules, moved here rather than copied. They
   used to live in the inline <style> of content/home/index.html - the block
   generate-home-pages.mjs lifts into home.css - and they were the reason the
   two navigations looked like two designs of the same idea: this file carried a
   full-width strip of tabs below the header, the home page carried a pill
   inside it. The pill is now the only shape, so the rules have one home, and
   the home page still gets them because it links header.css after home.css.
   The strip they replace is gone, along with the phone-width rules that hid it
   for the menu and the script that scrolled its current tab into view.

   Nothing in blog.css, pages.css, the simulator sheets or home.css targets a
   .desktop-* selector, so moving them collides with nothing. Two values did
   have to change on the way: `font-family: inherit` became the header font
   variable, because the body font is Plus Jakarta Sans on the home page but DM
   Sans everywhere else, and the links needed `text-decoration: none`, because
   nothing outside Tailwind's preflight was resetting the underline.

   The current-item rules read `[aria-current]` as well as the home page's
   `.is-active`. The home page's scroll spy writes a class as the reader moves
   through one document; the generated pages carry the state in the attribute,
   set server-side by scripts/section-nav.mjs. Same paint, two sources. */
.desktop-section-nav {
  display: none;
}

/* 1024px until the nav gained a sixth item, 1100px until it gained a seventh.

   The pill needs about 547px for seven items with the type and the padding
   reduced as in the band below (the arithmetic is written out above it), and
   the header has roughly 437px of slack at 1024px, growing a pixel per pixel
   from there - so it does not actually fit until about 1134px. 1180px is that
   figure rounded up to somewhere a person would choose. Below it the phone
   drawer is served instead, which is the same trade the site already makes on a
   tablet in portrait: a drawer that fits beats a pill that pushes the brand
   name onto two lines.

   DESKTOP_NAV_BREAKPOINT in the home page's script and desktopNavBreakpoint in
   assets/js/section-nav.js must both match this number - the second reads 1280
   instead on the simulators, for the reason given in the band below. Each is
   what tells an open menu to close itself when a resize takes the viewport into
   pill territory, where the button that opened it is display:none and it could
   otherwise be left open with no way out. */
@media (min-width: 1180px) {
  .desktop-section-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.125rem;
    padding: 0.3rem;
    border: 1px solid rgba(239, 234, 224, 0.95);
    border-radius: 9999px;
    background: rgba(255, 255, 255, 0.58);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
  }

  .desktop-section-nav > a,
  .desktop-resources-toggle {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin: 0;
    padding: 0.65rem 0.7rem;
    border: 0;
    border-radius: 9999px;
    background: transparent;
    color: rgba(45, 36, 27, 0.68);
    font-family: var(--site-header-font);
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: color 180ms ease, background-color 180ms ease, transform 180ms ease;
  }

  .desktop-section-nav > a:hover,
  .desktop-resources-toggle:hover,
  .desktop-resources[data-open="true"] .desktop-resources-toggle,
  .desktop-resources:hover .desktop-resources-toggle,
  .desktop-resources:focus-within .desktop-resources-toggle {
    color: #1e4620;
    background: rgba(30, 70, 32, 0.08);
    transform: translateY(-1px);
  }

  /* The second selector is what keeps the Recursos label from staying grey
     while an item inside its menu is lit - which is how a reader on the
     glossary or the data page would otherwise see it, since those two and the
     calculators and the templates all live in that menu.

     `[aria-current]` and not one of its values, because the nav writes two:
     "page" on the item that links to the document being read, "true" on the one
     whose section this page is inside - a glossary term, an article, a
     calculator. A reader looking at the pill is asking which section they are
     in, so both paint the same; only what a screen reader announces differs. */
  .desktop-section-nav a.is-active,
  .desktop-section-nav a[aria-current],
  .desktop-resources:has(a.is-active) .desktop-resources-toggle,
  .desktop-resources:has(a[aria-current]) .desktop-resources-toggle {
    color: #1e4620;
    background: rgba(197, 155, 39, 0.18);
    box-shadow: inset 0 0 0 1px rgba(197, 155, 39, 0.28);
  }

  .desktop-section-nav a:focus-visible,
  .desktop-resources-toggle:focus-visible {
    outline: 2px solid rgba(197, 155, 39, 0.75);
    outline-offset: 2px;
    color: #1e4620;
    background: rgba(197, 155, 39, 0.12);
  }

  .desktop-resources {
    position: relative;
  }

  .desktop-resources-toggle svg {
    width: 0.75rem;
    height: 0.75rem;
    transition: transform 180ms ease;
  }

  .desktop-resources[data-open="true"] .desktop-resources-toggle svg,
  .desktop-resources:hover .desktop-resources-toggle svg,
  .desktop-resources:focus-within .desktop-resources-toggle svg {
    transform: rotate(180deg);
  }

  /* Opened by :hover and :focus-within as well as by the script's data-open, so
     the four sections behind this label are reachable with a mouse and with the
     keyboard on a page whose JavaScript never ran. That matters more here than
     it did on the home page: these are the only links to the calculators, the
     templates, the glossary and the data page in this header. */
  .desktop-resources-menu {
    position: absolute;
    top: calc(100% + 0.65rem);
    left: 50%;
    z-index: 40;
    width: 12rem;
    padding: 0.45rem;
    border: 1px solid rgba(239, 234, 224, 0.98);
    border-radius: 1rem;
    background: #fffdf8;
    box-shadow: 0 18px 50px rgba(45, 36, 27, 0.16);
    opacity: 0;
    pointer-events: none;
    transform: translate(-50%, -0.35rem);
    transition: opacity 160ms ease, transform 160ms ease;
  }

  /* Bridges the gap between the label and the panel, so travelling from one to
     the other does not pass over the page and close it. */
  .desktop-resources-menu::before {
    position: absolute;
    right: 0;
    bottom: 100%;
    left: 0;
    height: 0.75rem;
    content: "";
  }

  .desktop-resources[data-open="true"] .desktop-resources-menu,
  .desktop-resources:hover .desktop-resources-menu,
  .desktop-resources:focus-within .desktop-resources-menu {
    opacity: 1;
    pointer-events: auto;
    transform: translate(-50%, 0);
  }

  .desktop-resources-menu a {
    display: flex;
    padding: 0.75rem 0.8rem;
    border-radius: 0.7rem;
    color: rgba(45, 36, 27, 0.78);
    font-family: var(--site-header-font);
    font-size: 0.75rem;
    font-weight: 750;
    text-decoration: none;
    transition: color 180ms ease, background-color 180ms ease;
  }

  .desktop-resources-menu a:hover,
  .desktop-resources-menu a.is-active,
  .desktop-resources-menu a[aria-current] {
    color: #1e4620;
    background: rgba(30, 70, 32, 0.08);
  }

  /* The Freedom Compass button.

     It was the home page's alone until the nav was regrouped, on the grounds
     that it opens a band of that document rather than a section of the site.
     Every page renders it now: from anywhere else it is a link to the home page
     and a fragment, which is what FAQ and Contacto already were, and the row had
     the space once About, Sessions, FAQ and Contacto moved behind one label.
     These rules did not have to change to cover the other two hundred pages -
     they were already in this shared file rather than in home.css, and they were
     never scoped to the home page. */
  .desktop-nav-cta {
    margin-left: 0.25rem;
    padding: 0.72rem 0.9rem !important;
    background: #1e4620 !important;
    color: #ffffff !important;
    font-weight: 800 !important;
    box-shadow: 0 8px 20px rgba(30, 70, 32, 0.2);
  }

  .desktop-nav-cta:hover {
    background: #2d241b !important;
    color: #ffffff !important;
    box-shadow: 0 11px 24px rgba(45, 36, 27, 0.24);
  }
}

/* The pill was full at seven items, and this is the arithmetic it was full by.

   At its narrowest - 1180px, the width at which it replaces the phone drawer -
   about 564px is left for it on a generated page, once the brand lockup, the
   return link, the three flags and the shell's own padding have taken their
   share. The home page spends its share differently - two publication icons
   instead of the return link - and has about 620px.

   Measured with the real advances from the subsetted Plus Jakarta Sans, seven
   items plus the Freedom Compass button came to about 652px in Spanish and
   Portuguese at full size, and about 547px with the type and the padding reduced
   as below - which is why this reduced band exists and why the breakpoint had to
   move up to 1180px with it. Full size fitted from about 1239px, so the band was
   left running to 1279px and the type returns to normal at 1280px, where the
   shell stops growing.

   Both pills are now the same four items and a call to action, and the numbers
   are the same on both pages: about 459px at full size and about 392px reduced.
   Sobre mí, Sesiones, FAQ and Contacto came out of the row - roughly 264px of it
   at full size, 215px reduced, Sobre mí and Sesiones costing about 73px and 60px
   each - and one grouped label went back in for about 71px and 60px. The
   generated pages then gained the button the home page already had, which is the
   ~104px and ~70px that used to be the whole of the difference between the two
   pills; that is why there is no difference left.

   So the band below is no longer load-bearing: 459px fits the 564px a generated
   page has at 1180px and the 620px the home page has. It is left in place
   because a pill that reads a shade smaller between 1180px and 1279px is not a
   defect, and because moving a breakpoint means moving the same number in
   assets/js/home.js, in assets/js/section-nav.js and in three comments that
   explain it - a change with more ways to go wrong than the 67px it would buy
   back. The slack is the point: the row now has room the next section can be
   added to.

   The padding-block is deliberately unchanged: it is what gives these targets
   their height, and 24px is the floor WCAG 2.2 SC 2.5.8 asks for. */
@media (min-width: 1180px) and (max-width: 1279px) {
  .desktop-section-nav {
    gap: 0.08rem;
    padding: 0.2rem;
  }

  .desktop-section-nav > a,
  .desktop-resources-toggle {
    padding: 0.65rem 0.42rem;
    font-size: 0.63rem;
  }

  .desktop-nav-cta {
    margin-left: 0.12rem;
    padding: 0.72rem 0.66rem !important;
  }

  /* Except on the simulators, where the middle of the header is not free: that
     row also carries the tool's own controls - four of them on the Passive
     Income Engine - and .header-actions there is allowed to wrap, so a pill
     that does not fit does not overflow, it puts the flags on a second line
     inside an 80px header. 449px is what is left for it at 1180px, and the
     compact pill needed about 477px, so those pages keep the hamburger until
     1280px. The rule beside the menu's own breakpoint below is the other half
     of that.

     The regrouped pill is about 392px, so it would now fit that 449px. The
     exception stays anyway: what those pages gain by dropping it is the pill
     instead of the hamburger across 100px of width, and what they risk is a
     wrapped header on the busiest of the five, measured against controls this
     file does not own. Worth doing on purpose, with those pages in front of
     you; not worth taking as a side effect of a nav regrouping. */
  .simulator-header-shell .desktop-section-nav {
    display: none;
  }
}

/* And where the simulators pick the pill up: at 1280px, and at the compact size
   rather than the full one.

   The shell stops growing at 1280px, so what is left for the pill on those
   pages stops growing with it - about 549px, once the brand lockup, the return
   link, four 36px controls, the three flags and two 16px shell gaps have taken
   their share. The full-size pill is about 548px wide in Spanish and
   Portuguese. Sizing a header on a 1px margin is how a header ends up wrapping
   on someone else's font stack, so these pages keep the reduced type and
   padding at every width above the breakpoint: about 477px, which leaves 70px
   in hand and cannot be spent by a wider viewport, because there is no wider
   shell. */
@media (min-width: 1280px) {
  .simulator-header-shell .desktop-section-nav {
    gap: 0.08rem;
    padding: 0.2rem;
  }

  .simulator-header-shell .desktop-section-nav > a,
  .simulator-header-shell .desktop-resources-toggle {
    padding: 0.65rem 0.42rem;
    font-size: 0.63rem;
  }
}

/* ---------------------------------------------------------------------------
   The site menu

   Eight links need about 620px, and a phone has 360. So the hamburger in the
   header is the whole of the site navigation below 1180px: the same button the
   home page has always had, drawn from the same values, opening a panel with
   all eight pages in it. The home page keeps its own copy in home.css - that
   drawer lists the sections of one long document, not the eight pages here - so
   what is shared is the shape of the control, not the code. A reader who has
   learned that icon on the way in finds it in the same corner of every page
   after.

   It used to take over below 768px only, because a full-width strip of tabs
   below the header covered every width above that. The strip is gone - the pill
   in .desktop-section-nav replaced it - and the pill needs 1180px, so the
   button now covers everything under that. Which is also what the home page
   does, at the same width.

   In the header, and the header is sticky, so the way off a page is reachable
   from the bottom of it. On the simulators that is the whole point: their
   footer is a docked call to action rather than a set of links.

   Everything visible here waits on assets/js/section-nav.js, which removes the
   button's `hidden` attribute. The rule below honours that attribute, so there
   is no state in which a page shows a control that cannot open anything. With
   no script the header still carries the brand, the return link and the flags,
   and the footer row of the same eight links is the route on from there -
   except on the simulators, whose footer is a docked call to action, where it
   is the return link. */

/* The button and the panel, and no `position` of its own on purpose: that
   leaves the panel's containing block header.site-header, which is sticky and
   therefore positioned. `top: 100%` on the panel is then the bottom edge of the
   header whatever height it happens to be - and the simulator headers wrap to
   two rows on a narrow phone, so that height is not a number this file could
   have hardcoded. */
.site-header .site-header-menu {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}

.site-header .site-menu-toggle {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid rgba(30, 70, 32, 0.18);
  border-radius: 0.85rem;
  background: rgba(255, 255, 255, 0.82);
  color: var(--site-header-forest);
  box-shadow: 0 2px 8px rgba(45, 36, 27, 0.08);
  cursor: pointer;
  transition: color 180ms ease, background-color 180ms ease, transform 180ms ease;
}

/* The button ships with `hidden` and this is what honours it: `display` in the
   rule above would otherwise win over the UA sheet's `[hidden] { display: none }`
   on specificity alone, and the control would appear on a page whose script
   never ran. */
.site-header .site-menu-toggle[hidden] {
  display: none;
}

.site-header .site-menu-toggle:hover {
  color: #2d241b;
  background: rgba(197, 155, 39, 0.18);
  transform: translateY(-1px);
}

.site-header .site-menu-toggle:focus-visible {
  outline: 3px solid rgba(197, 155, 39, 0.48);
  outline-offset: 3px;
}

/* Three bars from one element: the middle is the span, the outer two are its
   pseudo-elements. Same 1.2rem x 2px and the same 0.38rem offsets as the home
   page's, because a reader comparing the two corners should not be able to see
   which file drew which. */
.site-menu-toggle__icon,
.site-menu-toggle__icon::before,
.site-menu-toggle__icon::after {
  display: block;
  width: 1.2rem;
  height: 2px;
  border-radius: 9999px;
  background: currentColor;
  content: "";
  transition: transform 180ms ease, opacity 180ms ease;
}

.site-menu-toggle__icon {
  position: relative;
}

.site-menu-toggle__icon::before,
.site-menu-toggle__icon::after {
  position: absolute;
  left: 0;
}

.site-menu-toggle__icon::before {
  transform: translateY(-0.38rem);
}

.site-menu-toggle__icon::after {
  transform: translateY(0.38rem);
}

/* Open: the middle bar goes, the other two cross. Keyed on aria-expanded so the
   glyph cannot disagree with what a screen reader is told - the attribute the
   script has to set anyway is the one the paint reads. */
.site-menu-toggle[aria-expanded="true"] .site-menu-toggle__icon {
  background: transparent;
}

.site-menu-toggle[aria-expanded="true"] .site-menu-toggle__icon::before {
  transform: rotate(45deg);
}

.site-menu-toggle[aria-expanded="true"] .site-menu-toggle__icon::after {
  transform: rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
  .site-header .site-menu-toggle,
  .site-menu-toggle__icon,
  .site-menu-toggle__icon::before,
  .site-menu-toggle__icon::after {
    transition: none;
  }
}

/* Anchored to the header's own gutter rather than to the button, so the panel
   lines up with the edge of the page instead of with whichever control the
   header happens to end on. 12px is .header-shell's inline padding on a phone;
   the 640px rule below follows it to 24px. */
.site-header .site-menu-panel {
  position: absolute;
  top: 100%;
  right: 12px;
  z-index: 1;
  width: min(21rem, calc(100vw - 24px));
  /* Eight 44px rows plus the label do not fit a phone held in landscape. */
  max-height: min(70vh, 30rem);
  margin-top: 8px;
  padding: 10px;
  overflow-y: auto;
  border: 1px solid var(--site-header-border);
  border-radius: 18px;
  background: #fffdf8;
  box-shadow: 0 18px 40px rgba(24, 38, 28, 0.18);
}

.site-header .site-menu-panel[hidden] {
  display: none;
}

/* The nav's name, said out loud. The panel covers part of the page, so it owes
   the reader a word about what it is; and a sighted reader gets the heading a
   screen reader gets from the aria-label either way. */
.site-menu-panel__label {
  margin: 0 0 6px;
  padding-inline: 6px;
  color: rgba(45, 36, 27, 0.55);
  font-family: var(--site-header-font);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1.2;
  text-transform: uppercase;
}

.site-menu-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.site-menu-nav a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 10px 14px;
  border-radius: 12px;
  color: rgba(45, 36, 27, 0.78);
  font-family: var(--site-header-font);
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  transition: color 0.18s ease, background-color 0.18s ease;
}

.site-menu-nav a:hover {
  color: var(--site-header-forest);
  background: rgba(30, 70, 32, 0.08);
}

/* Same reading of aria-current as the strip: the attribute rather than one of
   its values, because the nav writes "page" on the link that points at this
   document and "true" on the one whose section this page sits inside. Someone
   looking at the list is asking which section they are in, so both paint the
   same; only what a screen reader announces differs. */
.site-menu-nav a[aria-current] {
  color: var(--site-header-forest);
  background: rgba(197, 155, 39, 0.18);
  box-shadow: inset 0 0 0 1px rgba(197, 155, 39, 0.28);
}

.site-menu-nav a:focus-visible {
  outline: 2px solid rgba(197, 155, 39, 0.75);
  outline-offset: 2px;
  color: var(--site-header-forest);
}

/* The Freedom Compass button, under the list rather than in it.

   Below 1180px this panel is the whole of the header nav, so a panel without
   the button is a page without any route to the assessment - which was every
   page but the home page on every phone until the nav was regrouped.

   Drawn like the home page drawer's copy in home.css: same green, same weight,
   same arrow, and the same 0.55rem above it, a little more than the 2px between
   the links, which is what marks it as the call to action rather than a ninth
   destination. It is outside the `<nav>` for the same reason - a screen reader
   listing the site's navigation should hear eight places to go, not nine with
   one of them an invitation. */
.site-menu-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 44px;
  margin-top: 0.55rem;
  padding: 12px 14px;
  border-radius: 12px;
  background: #1e4620;
  color: #ffffff;
  font-family: var(--site-header-font);
  font-size: 0.82rem;
  font-weight: 800;
  line-height: 1.2;
  text-decoration: none;
  box-shadow: 0 10px 24px rgba(30, 70, 32, 0.2);
  transition: background-color 0.18s ease, box-shadow 0.18s ease;
}

.site-menu-cta:hover {
  background: #2d241b;
  color: #ffffff;
  box-shadow: 0 13px 28px rgba(45, 36, 27, 0.24);
}

.site-menu-cta:focus-visible {
  outline: 2px solid rgba(197, 155, 39, 0.75);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .site-menu-cta {
    transition: none;
  }
}

@media (min-width: 640px) {
  .site-header .site-menu-panel {
    right: 24px;
    width: min(21rem, calc(100vw - 48px));
  }
}

/* The button's job above the breakpoint is done by the pill, which fits from
   here up and shows all seven at once. Two navigations with the same name in
   one page would be a worse answer than either alone.

   768px until the strip was removed: that was the width the strip fitted at,
   and the pill needs 1180px. The number is the same one the home page swaps its
   own drawer for its own pill at, which is the point of the change - one
   breakpoint, one shape at each width, on every page. */
@media (min-width: 1180px) {
  .site-header .site-menu-toggle,
  .site-header .site-menu-panel {
    display: none;
  }
}

/* And the other half of the simulator exception. Their pill waits for 1280px,
   so their hamburger has to survive the rule above until then, or the band in
   between would leave those pages with no header nav at all.

   `:not([hidden])` rather than a plain override, because the button ships with
   `hidden` and assets/js/section-nav.js is what removes it. Without the guard
   this rule would out-specify the `[hidden]` rule it sits after and put a dead
   control in the header of a page whose script never ran. */
@media (min-width: 1180px) and (max-width: 1279px) {
  .site-header .simulator-header-shell .site-menu-toggle:not([hidden]) {
    display: inline-grid;
  }

  .site-header .simulator-header-shell .site-menu-panel:not([hidden]) {
    display: block;
  }
}

@media (max-width: 639px) {
  /* The same shrink home.css makes at its own narrow breakpoint. */
  .site-header .site-menu-toggle {
    width: 2.5rem;
    height: 2.5rem;
  }

  /* Except on the simulators, where the button joins a row that already holds a
     return link, up to four of the tool's own controls and three flags. 36px is
     the size the flags in that row are, so the header reads as one set of
     controls rather than as a menu bolted onto the end of one, and it is what
     keeps the busiest of the five - the Passive Income Engine - on a single row
     at 390px. Still well over the 24px WCAG 2.2 SC 2.5.8 asks for; the row is
     already free to wrap if a narrower phone needs it to. */
  .site-header .simulator-header-actions .site-menu-toggle {
    width: 36px;
    height: 36px;
    border-radius: 0.75rem;
  }
}

.site-simulator-nav {
  position: relative;
  z-index: 40;
  padding: 8px 16px;
}

.site-simulator-tabs {
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
  overflow-x: auto;
  scrollbar-width: thin;
}

@media (max-width: 639px) {
  .site-header .header-shell {
    gap: 8px;
    padding-inline: 12px;
  }

  .site-header .header-brand-logo,
  .site-header .header-brand-logo img {
    width: 48px;
    height: 48px;
    min-width: 48px;
    max-width: 48px;
    min-height: 48px;
    max-height: 48px;
  }

  .site-header .header-brand-logo {
    flex-basis: 48px;
    border-radius: 14px;
  }

  .site-header .header-brand-copy {
    display: none;
  }

  .site-header .header-actions {
    gap: 6px;
  }

  .site-header .site-return-link {
    /* Previously `display: none`, which removed the only way back to the main
       site from a simulator on a phone. Kept visible as a 40x40 icon target
       (WCAG 2.2 SC 2.5.8); the accessible name comes from aria-label. */
    min-width: 40px;
    min-height: 40px;
    padding: 6px;
    gap: 0;
  }

  .site-header .site-return-link__text {
    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;
    border: 0;
  }

  /* 32px was already the floor this rule asked for, and now that the labels are
     gone the buttons can actually be that size rather than that size plus a
     word. Four of them at 32 with 4px between, next to the return link and the
     three flags, is what puts the Passive Income Engine header on one row at
     390px instead of two. Still comfortably over the 24px WCAG 2.2 SC 2.5.8
     asks for. */
  .site-header .simulator-header-actions .header-icon-btn {
    width: 32px;
    height: 32px;
  }

  .site-header .simulator-header-actions {
    gap: 4px;
  }

  /* Square targets on a phone: 36x36 clears WCAG 2.2 SC 2.5.8 with room to
     spare, and dropping the gap keeps three flags plus the return link and the
     simulator's own buttons on one row. */
  .site-header .simulator-language-switcher {
    gap: 0;
    padding: 3px;
  }

  .site-header .simulator-lang-btn {
    width: 36px;
    height: 36px;
    padding: 6px;
  }

  .site-simulator-nav {
    padding-inline: 8px;
  }
}

@media (min-width: 640px) and (max-width: 1023px) {
  .site-header .header-shell {
    padding-inline: 24px;
  }
}

/* ---------------------------------------------------------------------------
   Simulator footer

   Six of the fifteen simulator documents ended at </main> with no footer, so
   they were the only pages on the site with no exit route and no educational
   disclaimer. The markup added there uses these classes. The footer link row
   that accompanied them on the two game simulators has since been removed at
   the site owner's request, and the language switcher these footers carried
   has moved up into the header. */
.simulator-footer {
  margin-top: 48px;
  padding: 20px 24px 22px;
  border-top: 1px solid #efeae0;
  background: #faf6ed;
}

/* The bar's contents, held to the same 80rem the header shell and `.sim-main`
   use, so the closing offer starts on the same left edge as everything above
   it. Left-aligned rather than centred: this footer used to be one short
   sentence about being educational, which centres well, and it now leads with
   a heading and two actions, which centred reads like a landing page. */
.simulator-footer__inner {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  max-width: 80rem;
  margin-inline: auto;
  text-align: left;
}

.simulator-footer__note {
  max-width: 60ch;
  margin: 0;
  font-size: 12px;
  line-height: 1.6;
  /* rgba(42,36,30,.78) on #faf6ed clears 4.5:1 at this size. */
  color: rgba(42, 36, 30, 0.78);
}

/* The Spanish home page is the site's x-default, so it no longer redirects a
   visitor whose browser prefers English or Portuguese — it offers. Fixed to the
   viewport and appended after first paint, so the offer cannot move anything
   that has already rendered. */
.language-suggestion {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 60;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 16px;
  padding: 12px 16px;
  background: #faf6ed;
  border-top: 1px solid #efeae0;
  box-shadow: 0 -4px 16px rgba(42, 36, 30, 0.08);
}

.language-suggestion__text {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  /* #2a241e on #faf6ed is 13.4:1. */
  color: #2a241e;
}

.language-suggestion__cta,
.language-suggestion__close {
  display: inline-flex;
  align-items: center;
  /* SC 2.5.8: the two controls sit side by side, so both need a real target. */
  min-height: 44px;
  padding: 0 16px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  border-radius: 8px;
  cursor: pointer;
}

.language-suggestion__cta {
  /* #ffffff on #1e4620 is 9.7:1. */
  background: #1e4620;
  color: #ffffff;
  text-decoration: none;
}

.language-suggestion__cta:hover {
  background: #163517;
}

.language-suggestion__close {
  background: transparent;
  /* rgba(42,36,30,.82) on #faf6ed clears 4.5:1 at this weight. */
  color: rgba(42, 36, 30, 0.82);
  border: 1px solid #efeae0;
}

.language-suggestion__close:hover {
  background: #efeae0;
}

/* Shown in place of a simulator chart when Chart.js has not loaded. The canvas
   is hidden at the same time, so this sits inside the height-constrained box the
   chart would have filled rather than pushing the panel open. */
.chart-unavailable {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-height: 96px;
  margin: 0;
  padding: 16px;
  max-width: 46ch;
  margin-inline: auto;
  font-size: 14px;
  line-height: 1.6;
  text-align: center;
  /* rgba(42,36,30,.82) on the cream panels clears 4.5:1 at this size. */
  color: rgba(42, 36, 30, 0.82);
}
