/* ===========================================================================
   Site chrome: the header (with its mobile menu) and the footer.
   These wrap every marketing page and come from
   partials/marketing-header.html and partials/marketing-footer.html.
   =========================================================================== */

/* ==========================================================================
   Header
   ========================================================================== */

.mz-nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--mz-ink);
  width: 100%;
}

.mz-nav-inner {
  max-width: var(--mz-page-max);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px var(--mz-gutter);
}

/* On desktop the hamburger is hidden and the logo should participate directly
   in the nav's space-between layout, so this wrapper dissolves itself. At
   <= 1023px it becomes a real flex row again (see the mobile block below). */
.mz-nav-left {
  display: contents;
}

.mz-nav-logo img {
  width: 90px;
  height: 26px;
}

.mz-nav-links {
  display: flex;
  align-items: center;
  gap: 32px;
  list-style: none;
}

.mz-nav-links a {
  font-size: 16px;
  font-weight: 600;
  color: var(--mz-white);
  position: relative;
  padding-bottom: 4px;
}

/* The underline grows from the left on hover, and stays put on the current
   page. `is-active` is applied at build time by build.mjs, which matches each
   [data-nav-link] href against the route being emitted. */
.mz-nav-links a::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0;
  height: 2px;
  background: var(--mz-lime);
  transition: width var(--mz-transition-slow);
}
.mz-nav-links a:hover::after,
.mz-nav-links a.is-active::after {
  width: 100%;
}

.mz-nav-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.mz-nav-hamburger {
  display: none;
  padding: 8px;
}

/* ==========================================================================
   Mobile menu — a full-screen overlay, opened by the hamburger.
   Hidden at every width until .is-open is set by js/marketing.js.
   ========================================================================== */

.mz-mobile-menu {
  display: none;
  position: fixed;
  inset: 0;
  background: var(--mz-scrim-menu);
  flex-direction: column;
  /* Above .mz-nav's 100: the nav is sticky, so anything lower leaves the bar
     -- and its hamburger -- painted over the open dialog and still clickable. */
  z-index: 101;
  overflow-y: auto;
}

.mz-mobile-menu.is-open {
  display: flex;
}

.mz-mobile-menu-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px;
  flex-shrink: 0;
}

.mz-mobile-menu-header-left {
  display: flex;
  align-items: center;
  gap: 4px;
}

.mz-mobile-menu-close {
  padding: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
}

/* `.mz-nav-logo img` sets 90x26 on a near-identical element and outranks this
   single-class rule, so the mobile logo's anchor must not gain `mz-nav-logo`. */
.mz-mobile-logo {
  width: 78px;
  height: 22px;
}

.mz-mobile-menu-card {
  background: var(--mz-surface);
  border-radius: 0;
  margin: 0 12px;
  overflow: hidden;
}

.mz-mobile-menu-links {
  display: flex;
  flex-direction: column;
}

.mz-mobile-menu-links a {
  font-size: 20px;
  font-weight: 600;
  color: var(--mz-white);
  padding: 24px;
  border-bottom: 1px solid var(--mz-rule-faint);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.mz-mobile-menu-links a:last-child {
  border-bottom: none;
}

/* The chevron is a text glyph rather than an icon: it is decoration on a
   row that is already a link, and one character costs nothing to ship.

   The empty alt text after the slash keeps the glyph out of the link's
   accessible name, so the row announces "Home" and not "Home ›". The plain
   declaration above it is the fallback: where the alt-text syntax is not
   understood the whole declaration is dropped, which would take the chevron
   with it. */
.mz-mobile-menu-links a::after {
  content: '\203A';
  content: '\203A' / '';
  font-size: 24px;
  color: rgba(255, 255, 255, 0.4);
  font-weight: 400;
}

/* Current page: the whole row fills lime rather than carrying an inset rule
   under it, so the state survives the row's new padding. */
.mz-mobile-menu-links a.is-active {
  background: var(--mz-lime);
  color: var(--mz-ink);
}

.mz-mobile-menu-links a.is-active::after {
  color: rgba(0, 0, 0, 0.4);
}

/* Log in sits outside the card as an outlined button, so it reads as an
   action rather than a fifth destination. */
.mz-mobile-menu-login {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 12px;
  padding: 18px 24px;
  font-size: 20px;
  font-weight: 600;
  color: var(--mz-white);
  border: 1px solid rgba(255, 255, 255, 0.7);
  text-decoration: none;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.mz-footer {
  background: var(--mz-ink);
  color: var(--mz-white);
  font-family: var(--mz-font-sans);
}

.mz-footer-inner {
  max-width: var(--mz-page-max);
  margin: 0 auto;
  padding: 60px var(--mz-gutter);
}

/* Logo beside the link columns, all on a 5-column grid so they align
   with the article columns below. */
.mz-footer-top {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 24px;
}

.mz-footer-logo {
  grid-column: 1;
}

.mz-footer-cols {
  display: contents;
}

.mz-footer-articles {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 24px;
}

.mz-footer-col,
.mz-footer-article-col {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.mz-footer-col-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--mz-white);
  margin-bottom: 8px;
}

.mz-footer-col a,
.mz-footer-article-col a {
  font-size: 14px;
  font-weight: 400;
  color: var(--mz-text-tertiary);
  line-height: 1.6;
  transition: color var(--mz-transition);
}
.mz-footer-col a:hover,
.mz-footer-article-col a:hover {
  color: var(--mz-white);
}

/* Sits under the last link in the Legal column rather than beside it, so the
   number reads as contact detail and not as another nav item. */
.mz-footer-phone {
  font-size: 14px;
  font-weight: 400;
  color: var(--mz-text-tertiary);
  line-height: 1.6;
  margin-top: 12px;
  display: block;
}

.mz-footer-divider {
  border: none;
  border-top: 1px solid var(--mz-rule-soft);
  margin: 40px 0;
}

.mz-footer-bottom {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 24px;
  align-items: center;
  margin-top: 40px;
  padding-top: 40px;
  border-top: 1px solid var(--mz-rule-soft);
}

.mz-footer-copyright {
  grid-column: 1 / 3;
}

.mz-footer-social {
  grid-column: 5;
  justify-self: end;
}

.mz-footer-bottom .mz-footer-copyright {
  font-size: 14px;
  font-weight: 400;
  color: var(--mz-text-quiet);
}

.mz-footer-social {
  display: flex;
  gap: 16px;
}

.mz-footer-social a {
  color: var(--mz-text-quiet);
  transition: color var(--mz-transition);
}
.mz-footer-social a:hover {
  color: var(--mz-white);
}

.mz-footer-disclosure {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 24px;
  padding-top: 40px;
}

.mz-footer-disclosure-label {
  font-size: 14px;
  font-weight: 600;
  color: var(--mz-white);
  grid-column: 1;
}

.mz-footer-disclosure-text {
  display: flex;
  flex-direction: column;
  gap: 16px;
  grid-column: 2 / -1;
}

.mz-footer-disclosure-text p {
  font-size: 13px;
  font-weight: 400;
  line-height: 1.5;
  color: var(--mz-text-faint);
}

.mz-footer-disclosure-text a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

.home-only-disclosure { display: none; }
.home-page .home-only-disclosure { display: block; }

/* The wordmark is set to the footer's full width and clipped, so it scales
   with the page rather than sitting at one size. */
/* Oversized lilac wordmark, cropped along its baseline.

   The crop is a ratio, not a fixed height: `max-height: 280px` cut a different
   part of the letterforms at every width, and stopped cropping at all once the
   footer was narrow enough that the mark fitted inside 280px. 1360 / 280 is the
   design's own crop — Figma's footer wordmark (65848:6381) is a 1320x382
   drawing shown 1320x280 — so holding that ratio keeps the cut on the same
   point of the glyphs at every breakpoint. */
.mz-footer-wordmark {
  width: 100%;
  overflow: hidden;
  margin-top: 40px;
  aspect-ratio: 1320 / 280;
}

.mz-footer-wordmark img {
  width: 100%;
  height: auto;
  display: block;
}

.mz-footer-wordmark-svg {
  width: 100%;
  height: auto;
  display: block;
  color: var(--mz-lilac);
  /* The dot springs above its rest position, which sits within half a unit of
     the viewBox's top edge and would clip against it. The wrapper's own
     `overflow: hidden` still makes the crop. */
  overflow: visible;
}

/* --- Wordmark entrance ----------------------------------------------------
   The mark assembles itself the first time it is scrolled into view:

     1. the dot fades in, low, where the i's body will be
     2. it springs up past that, then falls back down to meet the body
     3. the body fades in and the two rise into place together
     4. m, e, z, z follow, one every 120ms

   Distances are in the SVG's own user units — the design's 1320x382 frame —
   so the motion scales with the mark and reads the same at 1360px and at
   335px. On a desktop footer one unit is about a pixel; on a phone, a
   quarter of one. They are named here rather than repeated through the
   keyframes, so the three a designer would want to change are in one place.

   Both are bounded by the crop below them. The wrapper shows the top 280 of
   the mark's 382, the letters' tops sit at y=112, and the dot's underside at
   y=83, so `--wm-lift` past ~165 starts the letters below the crop and the
   opening second plays against an empty footer. `--wm-drop` of 37 is what
   puts the dot on the body: the body's top edge is at y=112, and 83 + 37
   lands just inside it. `--wm-spring` of 59 keeps the dot's top (y=0 at rest)
   inside the frame on the way up.

   The dot and the body finish on the same timing function over the same
   window (0.85s-1.55s), which is what makes the last leg read as one object
   rising rather than two things arriving.
   ------------------------------------------------------------------------- */

.mz-footer-wordmark {
  --wm-lift: 71;     /* how far below its rest position each part starts */
  --wm-spring: 59;   /* how far above that the dot springs on the way in */
  --wm-drop: 37;     /* how far below it then falls, to meet the body    */
}

/* Hidden only once js/marketing.js has armed the sequence, so a page that
   never runs it shows the assembled mark rather than an empty gap. */
.mz-footer-wordmark.is-armed .mz-wm-letter,
.mz-footer-wordmark.is-armed .mz-wm-i-body,
.mz-footer-wordmark.is-armed .mz-wm-dot {
  opacity: 0;
}

/* The body and the four letters share one move and differ only in delay. */
@keyframes mz-wm-rise {
  from { opacity: 0; transform: translateY(calc(var(--wm-lift) * 1px)); }
  to   { opacity: 1; transform: translateY(0); }
}

/* The dot's whole path in one animation, so its legs cannot drift apart. */
@keyframes mz-wm-dot {
  0%   { opacity: 0; transform: translateY(calc(var(--wm-lift) * 1px)); }
  16%  { opacity: 1; transform: translateY(calc(var(--wm-lift) * 1px)); }
  35%  { opacity: 1; transform: translateY(calc((var(--wm-lift) - var(--wm-spring)) * 1px)); }
  55%  { opacity: 1; transform: translateY(calc((var(--wm-lift) + var(--wm-drop)) * 1px)); }
  100% { opacity: 1; transform: translateY(0); }
}

.mz-footer-wordmark.is-visible .mz-wm-dot {
  animation: mz-wm-dot 1.55s cubic-bezier(0.33, 0, 0.2, 1) forwards;
}

.mz-footer-wordmark.is-visible .mz-wm-i-body {
  animation: mz-wm-rise 0.7s cubic-bezier(0.33, 0, 0.2, 1) 0.85s forwards;
}

.mz-footer-wordmark.is-visible .mz-wm-letter {
  animation: mz-wm-rise 0.5s cubic-bezier(0.33, 0, 0.2, 1) forwards;
}

.mz-footer-wordmark.is-visible .mz-wm-letter[data-letter="1"] { animation-delay: 1.20s; }
.mz-footer-wordmark.is-visible .mz-wm-letter[data-letter="2"] { animation-delay: 1.32s; }
.mz-footer-wordmark.is-visible .mz-wm-letter[data-letter="3"] { animation-delay: 1.44s; }
.mz-footer-wordmark.is-visible .mz-wm-letter[data-letter="4"] { animation-delay: 1.56s; }

/* Decoration: someone who asked for less motion gets the assembled mark. */
@media (prefers-reduced-motion: reduce) {
  .mz-footer-wordmark.is-armed .mz-wm-letter,
  .mz-footer-wordmark.is-armed .mz-wm-i-body,
  .mz-footer-wordmark.is-armed .mz-wm-dot {
    opacity: 1;
  }

  .mz-footer-wordmark.is-visible .mz-wm-dot,
  .mz-footer-wordmark.is-visible .mz-wm-i-body,
  .mz-footer-wordmark.is-visible .mz-wm-letter {
    animation: none;
  }
}


/* ==========================================================================
   Mobile — the header collapses to hamburger + logo, and the footer's
   five-column grids fold to two.
   ========================================================================== */

@media (max-width: 1023px) {
  .mz-nav-inner { padding: 12px; }
  .mz-nav-links { display: none !important; }
  .mz-nav-actions .mz-btn--outline { display: none; }

  .mz-nav-left {
    display: flex;
    align-items: center;
    gap: 4px;
  }

  .mz-nav-hamburger {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
  }

  .mz-nav-logo img {
    width: 78px;
    height: 22px;
  }

  .mz-footer-inner { padding: 40px var(--mz-gutter-mobile); }
  .mz-footer-top { grid-template-columns: repeat(2, 1fr); gap: 32px 24px; }
  .mz-footer-logo { display: none; }
  .mz-footer-articles { grid-template-columns: repeat(2, 1fr); gap: 32px 24px; }
  /* The copyright row folds to one column. */
  .mz-footer-bottom { grid-template-columns: 1fr; gap: 24px; }
  .mz-footer-bottom .mz-footer-copyright { grid-column: 1; }
  .mz-footer-bottom .mz-footer-social { grid-column: 1; justify-self: start; }

  /* The disclosure label stacks above its text. Both need their desktop
     `grid-column` cleared, or they stay pinned to columns of a track list
     that no longer exists. */
  .mz-footer-disclosure { grid-template-columns: 1fr; gap: 16px; }
  .mz-footer-disclosure-label,
  .mz-footer-disclosure-text { grid-column: auto; }
}

/* ==========================================================================
   Page transitions
   ========================================================================== */

/* The page slides 80px either way, which would otherwise be 80px of
   horizontal scroll. `clip` rather than `hidden`: `hidden` would make this a
   scroll container and trap `position: sticky` inside it. */
.mz-page {
  overflow-x: clip;
}
