/* v025 | 2026-08-17 | 1652 lines
   micronturbo.com design tokens and shared patterns.
   The decisions this file implements are recorded in STYLE.md.
   Pages consume tokens, never raw hex or px. See STYLE.md section 8. */

/* ---------------------------------------------------------------
   1. TOKENS
   --------------------------------------------------------------- */

:root {
  /* Ground and surfaces */
  --mt-bg: #0C1A2B;
  --mt-surface: #12283F;
  --mt-surface-high: #1B3350;
  --mt-border: rgba(255, 255, 255, 0.08);

  /* Text on dark */
  --mt-text: #F6F3EE;
  --mt-text-2: #C6CDD6;
  --mt-text-3: #8A93A0;
  --mt-text-faint: #5E6B7A;

  /* Accent. The last three are the categorical hues added for the six-way point
     card — see STYLE.md section 3. All three clear AA on --mt-bg, so unlike
     steel they are legal as text on dark. */
  --mt-ignition: #F55B25;
  --mt-amber: #FFB020;
  --mt-steel: #2E6C8E;
  --mt-hydro: #3FB870;
  --mt-magnet: #9B7BE8;
  --mt-vortex: #E0619B;

  /* Inverted band. Defined and unused as of v001 — see STYLE.md section 3. */
  --mt-inv-bg: #F6F3EE;
  --mt-inv-surface: #FFFFFF;
  --mt-inv-border: #E4E0D8;
  --mt-inv-text: #0C1A2B;
  --mt-inv-text-2: #5E6B7A;
  --mt-inv-text-3: #A9A59C;
  --mt-inv-ignition: #A83C15;
  --mt-inv-amber: #8A5A06;
  --mt-inv-hydro: #1E7E45;
  --mt-inv-magnet: #7B5EC1;
  --mt-inv-vortex: #B7467A;

  /* Semantic, not categorical. ~5.5:1 on --mt-bg, so it is legal as text there,
     which is the only place it is used: the error message and its icon. It is
     never a field border, outline or fill — see STYLE.md section 3 for why the
     submit button is what that rule protects. It takes no slot in the c1-c6
     order above and nothing counted may reference it.

     There is deliberately no --mt-inv-error. No light-ground page exists, and
     section 3's rule is that inverted variants are not written speculatively. */
  --mt-error: #FF4F79;

  /* Type families. */
  --mt-font: 'Space Grotesk', system-ui, -apple-system, sans-serif;
  /* Simplified Chinese. Applied by the :lang(zh) rule in section 7. Loaded only
     by pages that need it — see STYLE.md section 4. */
  --mt-font-cjk: 'Noto Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif;

  /* Type scale */
  --mt-text-display: clamp(2.5rem, 5vw, 4rem);
  --mt-text-h1: 3rem;
  --mt-text-h2: 2.125rem;
  --mt-text-h3: 1.375rem;
  --mt-text-lg: 1.125rem;
  --mt-text-base: 1rem;
  --mt-text-sm: 0.875rem;
  --mt-text-xs: 0.75rem;

  /* Line heights */
  --mt-leading-display: 1.05;
  --mt-leading-heading: 1.2;
  --mt-leading-body: 1.7;

  /* Spacing */
  --mt-space-1: 4px;
  --mt-space-2: 8px;
  --mt-space-3: 12px;
  --mt-space-4: 16px;
  --mt-space-5: 24px;
  --mt-space-6: 32px;
  --mt-space-7: 48px;
  --mt-space-8: 64px;
  --mt-space-9: 96px;
  --mt-space-10: 128px;

  /* Radii */
  --mt-radius-sm: 10px;
  --mt-radius: 14px;
  --mt-radius-lg: 18px;

  /* Layout */
  --mt-container: 1180px;
  --mt-gutter: 40px;
  /* Form measure. Not --mt-lead's 62ch: a measure is set by the eye's return to
     the next line, a form by the trip from a label to its field. See STYLE.md
     section 6. */
  --mt-form-width: 38rem;

  /* --mt-bg as channels, so a translucent layer can be built from the ground
     color with rgba() instead of a hex-derived literal. The feature-row scrim
     is the only consumer; it needs two alphas of the same color. Keep this in
     step with --mt-bg above — CSS cannot derive one from the other. */
  --mt-bg-rgb: 12, 26, 43;

  /* --mt-ignition as channels, same idiom and same caveat as --mt-bg-rgb above.
     Its only consumer is the focus ring in section 11, which needs ignition at
     low alpha. Keep in step with --mt-ignition by hand. */
  --mt-ignition-rgb: 245, 91, 37;
}

@media (max-width: 768px) {
  :root {
    --mt-gutter: 24px;
    --mt-text-h1: 2.25rem;
    --mt-text-h2: 1.75rem;
  }
}

/* ---------------------------------------------------------------
   2. RESET AND BASE
   --------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--mt-bg);
  color: var(--mt-text);
  font-family: var(--mt-font);
  font-size: var(--mt-text-base);
  font-weight: 400;
  line-height: var(--mt-leading-body);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  margin: 0 0 var(--mt-space-4);
  font-weight: 700;
  line-height: var(--mt-leading-heading);
  color: var(--mt-text);
}

h1 { font-size: var(--mt-text-h1); }
h2 { font-size: var(--mt-text-h2); }
h3 { font-size: var(--mt-text-h3); }
h4 { font-size: var(--mt-text-lg); }

p {
  margin: 0 0 var(--mt-space-4);
  color: var(--mt-text-2);
}

a {
  color: var(--mt-amber);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 120ms ease;
}

a:hover {
  border-bottom-color: var(--mt-amber);
}

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

ul, ol {
  margin: 0 0 var(--mt-space-4);
  padding-left: var(--mt-space-5);
  color: var(--mt-text-2);
}

li {
  margin-bottom: var(--mt-space-2);
}

hr {
  border: 0;
  border-top: 1px solid var(--mt-border);
  margin: var(--mt-space-7) 0;
}

img, svg {
  max-width: 100%;
  height: auto;
  display: block;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--mt-text-sm);
  margin: 0 0 var(--mt-space-5);
}

th, td {
  text-align: left;
  padding: var(--mt-space-3) var(--mt-space-4);
  border-bottom: 1px solid var(--mt-border);
}

th {
  font-weight: 700;
  color: var(--mt-text);
}

td {
  color: var(--mt-text-2);
}

/* Figures use Space Grotesk tabular numerals wherever they are compared
   column-to-column. */
.mt-figures {
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------
   3. LAYOUT
   --------------------------------------------------------------- */

.mt-container {
  max-width: var(--mt-container);
  margin: 0 auto;
  padding-left: var(--mt-gutter);
  padding-right: var(--mt-gutter);
}

.mt-section {
  padding-top: var(--mt-space-9);
  padding-bottom: var(--mt-space-9);
}

@media (max-width: 768px) {
  .mt-section {
    padding-top: var(--mt-space-7);
    padding-bottom: var(--mt-space-7);
  }
}

/* ---------------------------------------------------------------
   4. INVERTED BAND
   Defined and unused as of v001. Resets the ground and text tokens for
   its subtree; component-level inverted variants are built when a page
   needs one. See STYLE.md section 3.
   --------------------------------------------------------------- */

.mt-invert {
  --mt-bg: var(--mt-inv-bg);
  --mt-surface: var(--mt-inv-surface);
  --mt-border: var(--mt-inv-border);
  --mt-text: var(--mt-inv-text);
  --mt-text-2: var(--mt-inv-text-2);
  --mt-text-3: var(--mt-inv-text-3);
  --mt-ignition: var(--mt-inv-ignition);
  --mt-amber: var(--mt-inv-amber);
  background: var(--mt-bg);
  color: var(--mt-text);
}

/* ---------------------------------------------------------------
   5. CARRIED PATTERNS
   The three patterns the identity system already uses more than once.
   See STYLE.md section 6.
   --------------------------------------------------------------- */

/* Tracked micro-label. Latin only. */
.mt-label {
  font-size: var(--mt-text-xs);
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--mt-ignition);
  margin-bottom: var(--mt-space-3);
}

/* Numbered section rule. */
.mt-rule {
  display: flex;
  align-items: center;
  gap: var(--mt-space-4);
  margin-bottom: var(--mt-space-2);
}

.mt-rule__num {
  font-size: var(--mt-text-sm);
  font-weight: 700;
  letter-spacing: 0.3em;
  color: var(--mt-ignition);
}

.mt-rule__line {
  flex: 1;
  height: 1px;
  background: var(--mt-border);
}

/* Stat card. Single-sided border, so no radius. */
.mt-stat {
  background: var(--mt-surface);
  border-top: 3px solid var(--mt-ignition);
  border-radius: 0;
  padding: var(--mt-space-5);
}

.mt-stat--amber { border-top-color: var(--mt-amber); }
.mt-stat--steel { border-top-color: var(--mt-steel); }

.mt-stat__label {
  font-size: var(--mt-text-lg);
  font-weight: 700;
  color: var(--mt-text);
}

.mt-stat__figure {
  font-size: var(--mt-text-h3);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--mt-amber);
  margin: var(--mt-space-3) 0 var(--mt-space-1);
}

.mt-stat__note {
  font-size: var(--mt-text-sm);
  color: var(--mt-text-3);
  line-height: 1.6;
}

/* Data column. Single-sided border, so no radius. */
.mt-datum {
  border-left: 2px solid var(--mt-ignition);
  border-radius: 0;
  padding-left: var(--mt-space-5);
}

.mt-datum--amber { border-left-color: var(--mt-amber); }
.mt-datum--steel { border-left-color: var(--mt-steel); }

.mt-datum__figure {
  font-size: var(--mt-text-display);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--mt-text);
}

.mt-datum__label {
  font-size: var(--mt-text-sm);
  color: var(--mt-text-3);
  margin-top: var(--mt-space-3);
}

/* ---------------------------------------------------------------
   6. UTILITIES
   --------------------------------------------------------------- */

.mt-grid {
  display: grid;
  gap: var(--mt-space-3);
}

.mt-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.mt-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 768px) {
  .mt-grid--3,
  .mt-grid--4 {
    grid-template-columns: 1fr;
  }
}

.mt-lead {
  font-size: var(--mt-text-lg);
  color: var(--mt-text-2);
  max-width: 62ch;
}

.mt-display {
  font-size: var(--mt-text-display);
  font-weight: 700;
  line-height: var(--mt-leading-display);
  margin: 0 0 var(--mt-space-5);
}

/* Inline phrase highlight, for the one term a lead is actually about.

   Amber and nothing else. Section 3 of STYLE.md gives it the role "Highlight,
   figures", and it reads ~9:1 on --mt-bg, so it is legal as text at any size —
   which ignition, at ~4.5:1, is not. Ignition would also break its own
   reservation: it belongs to the rule above a section and the one action that
   matters most on a page, and spending it on a phrase mid-paragraph is what
   makes a page stop having a primary action.

   Color and weight, not a <mark> background. A swatch behind a phrase puts a
   second surface inside running copy, and that surface then needs a radius,
   padding and an inset that no single value gets right across a line break —
   a highlight wrapping to the next line arrives as two boxes. Two channels
   already carry the emphasis here, and neither of them reflows the line.

   The selector takes the element as well as the class. The emphasis belongs in
   the markup, not only in the stylesheet: a reader with CSS off, or one hearing
   the page read out, still gets the phrase marked. Written as a bare .mt-hl the
   treatment could be hung on a <span> and that would be lost silently.

   700 holds in both scripts. Noto Sans SC carries 700 (section 4 of STYLE.md),
   so this does not quietly degrade to color-only where the CJK family takes
   over — which is the failure a weight-bearing pattern has on a Chinese page
   when nobody checks the face actually has the weight.

   The idiom is not new: .mt-table td.mt-ours strong in section 10 is already
   amber at 700. This is that treatment generalized out of the comparison table
   and into running copy. */
strong.mt-hl { color: var(--mt-amber); font-weight: 700; }

.mt-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---------------------------------------------------------------
   7. LANGUAGE
   --------------------------------------------------------------- */

:lang(zh) {
  font-family: var(--mt-font-cjk);
}

/* CJK takes neither Latin tracking nor case. Same problem and same treatment as
   the :lang(zh) .mt-btn override in section 9. Without this the tracked
   micro-label, the comparison-line label and the bio role keep the
   letter-spacing they were given for Latin — 0.28em, 0.14em and 0.16em — which
   on 产品, 锂电电源 and 首席科学家 reads as broken spacing rather than as
   tracking. text-transform is reset alongside it because uppercase is a no-op
   on CJK and would only apply to any Latin run sharing the element.

   .mt-bio__role joins the list because it is tracked and uppercased for the
   same reason .mt-label is, not because a Chinese about page exists yet. The
   selector costs nothing until one does, and a reset that arrives with the
   page it is needed on arrives after the page has already shipped wrong. */
:lang(zh) .mt-label,
:lang(zh) .mt-alt__vslbl,
:lang(zh) .mt-bio__role {
  letter-spacing: 0.1em;
  text-transform: none;
}

/* ---------------------------------------------------------------
   8. HEADER, NAV AND FOOTER
   Injected at runtime from the partials files by partials.js.
   See STYLE.md section 6 and SCOPE.md section 3.
   --------------------------------------------------------------- */

.mt-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--mt-surface);
  color: var(--mt-text);
  padding: var(--mt-space-3) var(--mt-space-4);
  border-bottom: 2px solid var(--mt-ignition);
}

.mt-skip:focus { left: 0; }

.mt-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--mt-bg);
  border-bottom: 1px solid var(--mt-border);
}

.mt-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--mt-space-5);
  min-height: 68px;
}

.mt-wordmark {
  font-size: var(--mt-text-lg);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--mt-text);
  border-bottom: 0;
  white-space: nowrap;
}

.mt-wordmark:hover { border-bottom: 0; color: var(--mt-text); }

.mt-nav__list {
  display: flex;
  align-items: center;
  gap: var(--mt-space-6);
  list-style: none;
  margin: 0;
  padding: 0;
}

.mt-nav__list li { margin: 0; }

.mt-nav__list a {
  font-size: var(--mt-text-base);
  font-weight: 500;
  color: var(--mt-text-2);
}

/* The underline treatment is for nav items only. .mt-lang is a boxed control
   and is excluded, so it keeps its own border at plain class specificity and
   works outside the nav too — the stylebook renders it standalone. */
.mt-nav__list a:not(.mt-lang) {
  padding: var(--mt-space-2) 0;
  border-bottom: 2px solid transparent;
}

.mt-nav__list a:hover {
  color: var(--mt-text);
  border-bottom-color: var(--mt-border);
}

.mt-nav__list a.is-current {
  color: var(--mt-text);
  border-bottom-color: var(--mt-amber);
}

/* Language toggle. A square control, not a nav item. A fixed box rather than
   padding, so "EN" and "简" render the same shape despite different widths. */
.mt-lang {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--mt-border);
  border-radius: var(--mt-radius-sm);
}

.mt-nav__list a.mt-lang:hover {
  border-color: var(--mt-amber);
  color: var(--mt-text);
}

/* Dropdown. One tier only, and deliberately so: a second tier needs hover
   intent, a safe-triangle cursor path and a mobile back affordance, none of
   which four nav items justify.

   The parent stays a real link. Enter follows it to the hub page, Space and
   Down open the panel — if Enter opened the panel instead, the hub page would
   have no keyboard route at all, since the panel lists only the two SKUs. */
.mt-has-dropdown {
  position: relative;
}

.mt-has-dropdown > a {
  display: inline-flex;
  align-items: center;
  gap: var(--mt-space-2);
}

.mt-dd__caret {
  width: 10px;
  height: 6px;
  flex: none;
  transition: transform 160ms ease;
}

.mt-has-dropdown > a[aria-expanded="true"] .mt-dd__caret {
  transform: rotate(180deg);
}

/* Hidden by visibility rather than display, so the panel keeps a measurable box
   and stays out of the tab order while closed.

   visibility is transitioned at 0s but with a close-delay, never faded. It has
   to flip to visible the instant the panel opens, because a visibility:hidden
   element cannot take focus and Down opens the panel and focuses its first row
   in the same tick. Delaying it on the way out instead keeps the fade visible
   while closing. Transitioning visibility over 140ms — the obvious-looking
   version — silently breaks the keyboard path and nothing else. */
.mt-dd {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 60;
  min-width: 180px;
  margin: 0;
  padding: var(--mt-space-2) 0;
  list-style: none;
  background: var(--mt-surface);
  border: 1px solid var(--mt-border);
  border-radius: var(--mt-radius-sm);
  visibility: hidden;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 140ms ease, transform 140ms ease,
              visibility 0s linear 140ms;
}

.mt-has-dropdown.is-open > .mt-dd {
  visibility: visible;
  opacity: 1;
  transform: translateY(0);
  transition: opacity 140ms ease, transform 140ms ease, visibility 0s;
}

.mt-dd li { margin: 0; }

/* Full-width rows, so the hit area is the whole panel and not just the word.
   The underline treatment from the nav list would cut across that, so these
   take a background change instead. */
.mt-nav__list .mt-dd a {
  display: block;
  padding: var(--mt-space-3) var(--mt-space-4);
  border-bottom: 0;
  color: var(--mt-text-2);
  white-space: nowrap;
}

.mt-nav__list .mt-dd a:hover,
.mt-nav__list .mt-dd a:focus-visible {
  background: var(--mt-surface-high);
  border-bottom: 0;
  color: var(--mt-text);
}

.mt-nav__list .mt-dd a.is-current {
  color: var(--mt-text);
  border-bottom: 0;
  box-shadow: inset 2px 0 0 var(--mt-amber);
}

.mt-burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
}

.mt-burger__bar {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--mt-text);
  margin: 0 auto;
  transition: transform 160ms ease, opacity 160ms ease;
}

.mt-burger[aria-expanded="true"] .mt-burger__bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.mt-burger[aria-expanded="true"] .mt-burger__bar:nth-child(2) { opacity: 0; }
.mt-burger[aria-expanded="true"] .mt-burger__bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
  .mt-burger__bar { transition: none; }
  .mt-dd,
  .mt-dd__caret { transition: none; }
}

.mt-footer {
  border-top: 1px solid var(--mt-border);
  padding-top: var(--mt-space-5);
  padding-bottom: var(--mt-space-5);
  margin-top: var(--mt-space-9);
}

.mt-footer__bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--mt-space-5);
  flex-wrap: wrap;
}

.mt-footer__legal {
  font-size: var(--mt-text-xs);
  color: var(--mt-text-3);
}

.mt-footer__links {
  display: flex;
  gap: var(--mt-space-5);
  list-style: none;
  margin: 0;
  padding: 0;
}

.mt-footer__links li { margin: 0; }

.mt-footer__links a {
  font-size: var(--mt-text-xs);
  color: var(--mt-text-3);
}

.mt-footer__links a:hover {
  color: var(--mt-text-2);
  border-bottom-color: var(--mt-text-3);
}

/* ---------------------------------------------------------------
   9. HERO AND BUTTON
   --------------------------------------------------------------- */

.mt-hero {
  display: grid;
  grid-template-columns: 1fr 1.55fr;
  gap: var(--mt-space-7);
  align-items: center;
  padding-top: var(--mt-space-9);
  padding-bottom: var(--mt-space-9);
}

.mt-hero__slogan {
  font-size: clamp(1.375rem, 1.8vw, 1.625rem);
  font-weight: 500;
  color: var(--mt-text-2);
  max-width: 24ch;
  margin: 0 0 var(--mt-space-7);
}

.mt-hero__media img {
  width: 100%;
  border-radius: var(--mt-radius);
}

.mt-btn {
  display: inline-block;
  font-size: var(--mt-text-base);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mt-text);
  background: transparent;
  border: 1px solid var(--mt-ignition);
  border-radius: var(--mt-radius-sm);
  padding: var(--mt-space-3) var(--mt-space-6);
  transition: background-color 140ms ease, color 140ms ease;
}

.mt-btn:hover {
  background: var(--mt-ignition);
  color: var(--mt-bg);
  border-bottom-color: var(--mt-ignition);
}

/* Secondary button. Same box, cool border — it sits beside the primary without
   competing with it. Ignition is reserved for the one action that matters most
   on the page. */
.mt-btn--secondary {
  border-color: var(--mt-border);
  color: var(--mt-text-2);
}

.mt-btn--secondary:hover {
  background: transparent;
  color: var(--mt-text);
  border-color: var(--mt-text-3);
  border-bottom-color: var(--mt-text-3);
}

/* Button row. */
.mt-hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--mt-space-4);
}

/* CJK does not take letter-spacing or uppercase this way. */
:lang(zh) .mt-btn {
  letter-spacing: 0.1em;
  text-transform: none;
}

@media (max-width: 768px) {

  .mt-burger { display: flex; }

  .mt-nav {
    position: fixed;
    inset: 68px 0 0;
    background: var(--mt-bg);
    transform: translateX(100%);
    transition: transform 200ms ease;
    overflow-y: auto;
    visibility: hidden;
  }

  .mt-nav.is-open { transform: translateX(0); visibility: visible; }

  .mt-nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--mt-space-4) var(--mt-gutter);
  }

  .mt-nav__list a { font-size: var(--mt-text-lg); }

  .mt-nav__list a:not(.mt-lang) {
    display: block;
    padding: var(--mt-space-4) 0;
    border-bottom: 1px solid var(--mt-border);
  }

  .mt-nav__list a.is-current { border-bottom-color: var(--mt-amber); }

  /* The dropdown expands inline inside the burger panel — it is already an
     overlay, and a panel floating above a panel has nothing to float over.
     Static positioning lets it push the items below it down instead. */
  /* Scoped through .mt-nav__list deliberately: the mobile
     `.mt-nav__list a:not(.mt-lang)` rule above sets display:block, and at equal
     weight it would win and drop the caret onto its own line. */
  .mt-nav__list .mt-has-dropdown > a {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  .mt-dd {
    position: static;
    min-width: 0;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    transform: none;
    /* Collapsed height, not just hidden, so the rows below close up. */
    max-height: 0;
    overflow: hidden;
    transition: max-height 200ms ease, opacity 140ms ease,
                visibility 0s linear 200ms;
  }

  .mt-has-dropdown.is-open > .mt-dd {
    max-height: 20rem;
    transform: none;
    transition: max-height 200ms ease, opacity 140ms ease, visibility 0s;
  }

  .mt-nav__list .mt-dd a {
    padding: var(--mt-space-4) 0 var(--mt-space-4) var(--mt-space-5);
    border-bottom: 1px solid var(--mt-border);
    font-size: var(--mt-text-base);
  }

  .mt-nav__list .mt-dd a:hover,
  .mt-nav__list .mt-dd a:focus-visible { background: none; }

  .mt-nav__list .mt-dd a.is-current {
    box-shadow: none;
    border-bottom-color: var(--mt-amber);
  }

  /* Stays the square control from section 8; only the offset changes. */
  .mt-nav__list a.mt-lang { margin-top: var(--mt-space-4); }

  body.mt-nav-open { overflow: hidden; }
}

/* The hero stacks earlier than the nav does. Between 768px and ~900px the two
   column split leaves the text column around 264px, which is narrower than the
   slogan needs on one line — it wrapped there at every wording we have tried.
   Stacking at 1000px clears it with room to spare and reads better anyway:
   two cramped columns at 900px serve neither the copy nor the image. */
@media (max-width: 1000px) {
  .mt-hero {
    grid-template-columns: 1fr;
    gap: var(--mt-space-6);
  }

  .mt-hero__media { order: -1; }
}

@media (prefers-reduced-motion: reduce) {
  .mt-nav { transition: none; }
}

/* ---------------------------------------------------------------
   10. PRODUCT PAGE PATTERNS
   Promoted from the products hub and the two SKU pages. Each carries
   its own breakpoints: these are content-shaped grids and they break
   where their content breaks, not where the page gutter does.
   See STYLE.md sections 6 and 9.
   --------------------------------------------------------------- */

/* Image slot. Stock or render until real photography lands. */
.mt-shot {
  background: var(--mt-surface);
  border: 1px dashed var(--mt-border);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: var(--mt-text-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--mt-text-faint);
  padding: var(--mt-space-4);
}

/* 3:2, not 16:9. Two reasons, and they point the same way: a taller slot puts
   the image nearer the height of the text column beside it, and 3:2 is the
   native ratio of the landscape hero source, so that one crops losslessly
   where 16:9 cost it 15.7%. The portrait source in the other slot loses 55.8%
   of its height here — less than the 62.7% that 16:9 was already taking. */
.mt-shot--hero { aspect-ratio: 3 / 2; margin-bottom: var(--mt-space-8); }
.mt-shot--use { aspect-ratio: 4 / 3; }

/* A real image standing in the same slot. object-fit keeps the ratio the
   placeholder set, so a page does not reflow when photography replaces a
   render — and the sources are a mix of portrait and landscape. */
.mt-shot--img {
  display: block;
  width: 100%;
  object-fit: cover;
  border: 0;
  padding: 0;
  background: none;
}

/* Full-measure lead. .mt-lead is capped at 62ch site-wide, which is right for
   sustained reading. A section lead is not sustained reading — it is one or two
   lines introducing the thing below it, and at 62ch it stops around 800px above
   a table or a row of cards that runs to 1190, which reads as a mistake rather
   than as a measure.

   The rule: a paragraph in a full-width section runs the full width; a paragraph
   in a grid column takes its column. A modifier rather than an edit to .mt-lead,
   because the home page uses the base class and the cap is right there. */
.mt-lead--full { max-width: none; }

/* Brand callout. Box spans the container so its edges match the feature rows;
   the text fills the box rather than being capped inside it, so the inset comes
   only from the padding. An earlier version capped the text inside a full-width
   box and left dead space down the right-hand side.

   Single-sided accent border, so no radius — the data column idiom in STYLE.md
   section 6. */
.mt-callout {
  background: var(--mt-surface);
  border-left: 3px solid var(--mt-ignition);
  border-radius: 0;
  padding: var(--mt-space-6) var(--mt-space-7);
  margin-bottom: var(--mt-space-8);
}

.mt-callout p { font-size: var(--mt-text-lg); color: var(--mt-text-2); margin: 0; }
.mt-callout strong { color: var(--mt-text); font-weight: 700; }

@media (max-width: 768px) {
  .mt-callout { padding: var(--mt-space-5); }
}

/* Alternating feature rows. Media and text swap sides down the page; the media
   always comes first in the DOM so the stacked order is image-then-text. */
.mt-alt__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--mt-space-8);
  align-items: start;
  padding: var(--mt-space-8) 0;
  border-bottom: 1px solid var(--mt-border);
}

.mt-alt__row:first-child { border-top: 1px solid var(--mt-border); }
.mt-alt__row--flip .mt-alt__media { order: 2; }

@media (max-width: 860px) {
  .mt-alt__row {
    grid-template-columns: 1fr;
    gap: var(--mt-space-5);
    padding: var(--mt-space-7) 0;
  }
  /* Stacked, the flip has nothing to flip — reset it so every row reads
     image-then-text rather than alternating for no reason. */
  .mt-alt__row--flip .mt-alt__media { order: 0; }
}

/* Muted image with the feature word over it. The scrim is what keeps the word
   legible over an arbitrary photograph. */
.mt-alt__media { position: relative; }

/* The ground behind the image is --mt-bg, not --mt-surface. Whatever shows
   through the image is the floor its shadows can reach, and a mid-navy floor
   lifts every black in the photograph off the bottom of the range. */
.mt-alt__shot {
  aspect-ratio: 4 / 3;
  background: var(--mt-bg);
  border: 1px dashed var(--mt-border);
  border-radius: var(--mt-radius);
  overflow: hidden;
}

/* 0.7, not 0.45. Muting the image and darkening it for the word are two
   different jobs, and doing both with opacity did neither well: at 0.45 over a
   mid surface, with the scrim on top, the photograph kept 7% of its tonal range
   and the brightest pixel landed barely above the page ground. It read as blue
   haze rather than as a picture. The scrim does the darkening now. */
.mt-alt__shot img { width: 100%; height: 100%; object-fit: cover; opacity: 0.7; }

/* Two modifiers on the slot, and they are INDEPENDENT: one is about the shape
   of the box, the other about the image put in it. Either may be used without
   the other, and nothing here couples them.

   --wide is 2/1 rather than the base 4/3. A letterbox suits a subject that is
   wide and short — an aircraft seen head-on, a skyline and its reflection —
   where 4/3 would either crop the width away or leave the subject stranded in
   a tall frame. The six hub rows stay 4/3 and are not affected. */
.mt-alt__shot--wide { aspect-ratio: 2 / 1; }

/* --dark-source releases the muting for an image that arrives dark already.
   The trigger is the SOURCE, not the slot: a bright photograph in a --wide box
   still wants the 0.7 above, and a dark one in a 4/3 box still wants this.

   The 0.7 and the 0.15–0.5 scrim were set together on bright photographs, and
   what they were solving was an image being darkened twice. An image that is
   already dark at source is not that case — the scrim on its own carries the
   word, and muting the image as well takes it below the floor and returns the
   blue haze the note above describes.

   Same specificity as .mt-alt__shot img, so this rule has to sit after it.
   Moving it above that line silently restores the 0.7. */
.mt-alt__shot--dark-source img { opacity: 1; }

/* Built from --mt-bg-rgb rather than a hex-derived literal, so the scrim is
   demonstrably the page ground at two alphas.

   0.15 to 0.5, lighter than it was, because the image is no longer being
   darkened twice. The gradient still runs denser downward, and the word now
   sits in that dense end rather than in the middle — which is what buys back
   the contrast the brighter image gives up. */
.mt-alt__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
              rgba(var(--mt-bg-rgb), 0.15),
              rgba(var(--mt-bg-rgb), 0.5));
  border-radius: var(--mt-radius);
}

/* Bottom-left, not centered. Centered put the word across whatever the
   photograph was of — a helicopter, a person, a drone — and stamped it there.
   Down here it reads as a label on the image instead, it clears the subject,
   and it sits in the densest part of the scrim where the contrast is best. */
.mt-alt__word {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
  font-size: var(--mt-text-h1);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--mt-text);
  text-align: left;
  padding: var(--mt-space-5);
}

/* Top-right, out of the word's corner. It only appears when there is no image
   behind the scrim, but the two would otherwise stack in the same place. */
.mt-alt__ph {
  position: absolute;
  top: var(--mt-space-4);
  right: var(--mt-space-5);
  text-align: right;
  font-size: var(--mt-text-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--mt-text-faint);
}

.mt-alt__desc {
  font-size: var(--mt-text-lg);
  color: var(--mt-text-2);
  margin: 0 0 var(--mt-space-6);
}

.mt-alt__spec {
  border-top: 1px solid var(--mt-border);
  padding-top: var(--mt-space-5);
}

/* Ours leads, at figure scale with the colored icon. */
.mt-alt__ours {
  display: flex;
  align-items: center;
  gap: var(--mt-space-3);
  font-size: var(--mt-text-h3);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--mt-text);
  line-height: 1.2;
}

.mt-alt__ours svg { display: block; flex: 0 0 auto; }

/* The two comparisons sit beneath it, muted — context, not the claim. */
.mt-alt__vs { margin: var(--mt-space-4) 0 0; }

.mt-alt__vsline {
  display: grid;
  grid-template-columns: 150px 1fr;
  gap: var(--mt-space-4);
  padding: var(--mt-space-2) 0;
  font-size: var(--mt-text-sm);
  color: var(--mt-text-3);
  line-height: 1.6;
}

@media (max-width: 520px) {
  .mt-alt__vsline { grid-template-columns: 1fr; gap: 0; }
}

.mt-alt__vslbl {
  font-size: var(--mt-text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mt-text-faint);
  padding-top: 3px;
}

/* Footnote to a feature row's claim line. The Versatility row states a count
   — "8 fuels" — and the footnote is what lets an engineer check it, which
   keeps the specification argument on the page without putting it in the
   headline. See STYLE.md section 6.

   The marker sits inside .mt-alt__ours, which is --mt-text-h3 and bold. An
   asterisk inheriting that size reads as a defect rather than as a reference
   mark, so it drops to --mt-text-xs in muted text.

   line-height: 0 is the load-bearing part. Without it the raised glyph
   expands the claim line's 1.2 leading, and the one row carrying a footnote
   sits a few pixels taller than the other five — a parallel that runs the
   length of the page, broken by a character nobody would look at. */
.mt-alt__fn-mark {
  font-size: var(--mt-text-xs);
  color: var(--mt-text-3);
  vertical-align: super;
  line-height: 0;
}

/* The footnote line itself, under the two comparators. Deliberately the same
   register as .mt-alt__vsline directly above it — same size, same color, same
   leading — so it reads as a third muted line under the claim rather than as
   a new kind of element bolted onto one row.

   Those three values are also exactly .mt-stat__note. It is NOT reused here:
   that class belongs to the stat card, every other consumer is a .mt-stat,
   and a products-hub footnote depending on it would leave the next person
   editing the stat card unable to see what they would break. One rule of
   duplication is cheaper than a class whose name lies about where it is
   used. */
.mt-alt__fn {
  margin: var(--mt-space-3) 0 0;
  font-size: var(--mt-text-sm);
  color: var(--mt-text-3);
  line-height: 1.6;
}

/* SKU cards on the hub. The third column is narrower because it holds the
   pipeline card, which is a signpost rather than a product. */
.mt-skus {
  display: grid;
  grid-template-columns: 1fr 1fr 0.7fr;
  gap: var(--mt-space-5);
  margin-bottom: var(--mt-space-9);
}

@media (max-width: 900px) { .mt-skus { grid-template-columns: 1fr; } }

.mt-sku-card {
  background: var(--mt-surface);
  border-top: 3px solid var(--mt-ignition);
  padding: var(--mt-space-6);
  display: flex;
  flex-direction: column;
}

/* Steel, so the pipeline card reads as future rather than as a third product
   competing with the two that ship. */
.mt-sku-card--quiet { border-top-color: var(--mt-steel); }

.mt-sku-card h3 { margin-bottom: var(--mt-space-2); }
.mt-sku-card p { font-size: var(--mt-text-sm); color: var(--mt-text-3); }

/* margin: auto 0 pushes the spec line to the bottom of whichever card is
   tallest, so the three spec rules align across a row of uneven copy. */
.mt-sku-card__spec {
  font-size: var(--mt-text-sm);
  color: var(--mt-text-2);
  border-top: 1px solid var(--mt-border);
  padding-top: var(--mt-space-3);
  margin: auto 0 var(--mt-space-5);
  font-variant-numeric: tabular-nums;
}

/* Comparison table. Scrolls below the breakpoint rather than wrapping: a
   three-column comparison that wraps stops being a comparison. */
.mt-table-wrap { overflow-x: auto; margin-bottom: var(--mt-space-8); }
.mt-table { min-width: 640px; margin: 0; }
.mt-table th { font-size: var(--mt-text-sm); }
.mt-table th:first-child,
.mt-table td:first-child { width: 28%; }
.mt-table .mt-metric { color: var(--mt-text-3); font-weight: 500; }

/* The emphasized column. Surface fill plus an ignition rule lifts our column
   off the ground without coloring the competitor's. */
.mt-table th.mt-ours {
  background: var(--mt-surface);
  border-top: 3px solid var(--mt-ignition);
  color: var(--mt-text);
}

.mt-table td.mt-ours { background: var(--mt-surface); color: var(--mt-text); }
.mt-table td.mt-ours strong { color: var(--mt-amber); font-weight: 700; }
.mt-table td.mt-trade strong { color: var(--mt-text-2); font-weight: 700; }

/* Use-case grid. Picture-led. */
.mt-uses {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--mt-space-5);
}

@media (max-width: 860px) { .mt-uses { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 480px) { .mt-uses { grid-template-columns: 1fr; } }

.mt-use h4 { margin: var(--mt-space-3) 0 var(--mt-space-1); font-size: var(--mt-text-base); }
.mt-use p { font-size: var(--mt-text-sm); color: var(--mt-text-3); margin: 0; line-height: 1.6; }

/* SKU hero. Reuses .mt-hero but overrides the ratio: the home page carries a
   short slogan in the text column, a SKU page carries a headline plus a
   paragraph, so the home ratio is wrong in both directions.

   1.05fr 1.1fr gives the image marginally the larger track, and align-items:
   center pairs the two columns on their midlines. The previous 1.15fr 1fr with
   align-items: start made the text column both wider and taller than the image
   and then pinned the image to the top of it, so the image sat in a half-empty
   column.

   The two tracks are near-equal rather than image-led on purpose. The copy is
   the argument on a SKU page and the image is support, so between 1000 and
   ~1150px the fix is to give the text room rather than compress it — squeezing
   the text column there only pushes the headline onto a third line. */
.mt-hero--sku { grid-template-columns: 1.05fr 1.1fr; align-items: center; }

/* Display leading on a heading-sized headline. The SKU headline is
   --mt-text-h1, not --mt-text-display — see STYLE.md section 4 — but it is
   still a headline and wants display leading rather than heading leading. */
.mt-hero--sku h1 { line-height: var(--mt-leading-display); }

@media (max-width: 1000px) { .mt-hero--sku { grid-template-columns: 1fr; } }

.mt-intro { margin-bottom: var(--mt-space-8); }
.mt-intro p { font-size: var(--mt-text-lg); color: var(--mt-text-2); }

.mt-backlink { margin-bottom: var(--mt-space-6); font-size: var(--mt-text-sm); }

/* ---------------------------------------------------------------
   11. FORM PATTERNS
   Promoted from the contact page. These are the first components on
   the site that take input rather than present it, which changes what
   they are judged on: every other pattern is judged on how it reads,
   and these on whether a reader can finish them.
   The row breakpoint is content-shaped like section 10's, not the
   global 768. See STYLE.md section 6.
   --------------------------------------------------------------- */

.mt-form { max-width: var(--mt-form-width); }

/* Name + company side by side. 560px is read off the content: a name field has
   to show a full name, roughly 26 characters at --mt-text-base — about 230px of
   text, plus --mt-space-4 of padding each side and the hairline, so about 264px
   of field. Two of those with a --mt-space-5 gap is 552px. Below that the pair
   stops being two usable fields and becomes two cramped ones. */
.mt-form__row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--mt-space-5);
}

@media (max-width: 560px) {
  .mt-form__row {
    grid-template-columns: 1fr;
    /* row-gap goes to zero on the stack. .mt-field already carries its own
       bottom margin, so the gap would sit on top of it and open twice the
       space between two stacked fields that a field outside a row gets —
       which reads as the pair having come apart rather than as spacing. */
    row-gap: 0;
  }
}

/* Label + control + message. The unit exists so the message has somewhere to
   live that is bound to its own field — an error line that is a sibling of the
   form rather than of the field drifts the moment a row reflows. */
.mt-field { margin-bottom: var(--mt-space-5); }

/* Visible, and above the control. Never a placeholder standing in for a label:
   a placeholder disappears on focus, which removes the question exactly as the
   reader starts answering it, and leaves a filled form with no way to check
   what each value was for. */
.mt-field__label {
  display: block;
  margin-bottom: var(--mt-space-2);
  font-size: var(--mt-text-sm);
  font-weight: 500;
  color: var(--mt-text-2);
}

/* display: block, not the inline-block a form control defaults to. An
   inline-block control sits on a text baseline, and the descender space under
   that baseline is real layout — it puts an 8px gap under every textarea that
   no input gets, so one field in a form is spaced differently from the rest
   for no reason anybody can see in the markup. */
.mt-field input,
.mt-field textarea {
  display: block;
  width: 100%;
  font-family: inherit;
  font-size: var(--mt-text-base);
  line-height: var(--mt-leading-body);
  color: var(--mt-text);
  background: var(--mt-surface);
  border: 1px solid var(--mt-border);
  /* Matches .mt-btn. The field and the button sit in the same form, and a form
     built from two corner radii reads as two components that merely happen to
     be adjacent. */
  border-radius: var(--mt-radius-sm);
  padding: var(--mt-space-3) var(--mt-space-4);
  transition: border-color 140ms ease, box-shadow 140ms ease;
}

.mt-field textarea {
  min-height: var(--mt-space-10);
  resize: vertical;
}

/* --mt-text-3, NOT --mt-text-faint. Faint is decorative-only and fails AA at
   every size; a placeholder is read text even when it is only a hint.
   opacity: 1 because Firefox dims placeholders by default. */
.mt-field input::placeholder,
.mt-field textarea::placeholder {
  color: var(--mt-text-3);
  opacity: 1;
}

/* Ignition border plus a soft ring, rather than a thicker border: a border that
   changes width reflows the field by a pixel and makes the row twitch on tab.

   This is the one place ignition is legal on a field edge, and it does not
   contradict the error rule below. Focus is transient and lands on exactly one
   field at a time, so it never competes with the submit button the way a set of
   persistent error outlines would.

   .mt-field--focus is a forced-state hook, and it shares this block rather than
   copying it. A focused field is invisible at rest, so the stylebook cannot
   review it any other way — the same problem the nav dropdown has in section 8.
   One declaration block behind two selectors is what keeps the specimen from
   drifting away from the real state; a stylebook rule with its own copy of these
   values would report a focus ring the site does not have. */
.mt-field input:focus-visible,
.mt-field textarea:focus-visible,
.mt-field--focus input,
.mt-field--focus textarea {
  outline: none;
  border-color: var(--mt-ignition);
  box-shadow: 0 0 0 var(--mt-space-1) rgba(var(--mt-ignition-rgb), 0.28);
}

/* The error message, below the control. The field border does NOT change — see
   STYLE.md section 3. Color is not the only channel: the icon and the words
   carry the same message, so the state survives a reader who cannot separate
   the hue from the body copy around it. */
.mt-field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--mt-space-2);
  margin-top: var(--mt-space-2);
  font-size: var(--mt-text-sm);
  line-height: 1.5;
  color: var(--mt-error);
}

/* currentColor, so the icon inherits --mt-error from the line it sits in and
   carries no color of its own. flex-shrink guards it against a long message. */
.mt-field__error svg {
  flex: 0 0 auto;
  margin-top: 0.15em;
}

/* Beside the submit rather than above it: the consent line is the last thing
   read before the action, which is where a consent statement belongs. */
.mt-form__consent {
  display: flex;
  align-items: center;
  gap: var(--mt-space-4);
  flex-wrap: wrap;
  margin-top: var(--mt-space-6);
}

.mt-form__consent p {
  margin: 0;
  flex: 1 1 16rem;
  font-size: var(--mt-text-sm);
  color: var(--mt-text-3);
}

/* The consent line names a document, and a document's name is one thing. The
   paragraph shares its row with the button, so it is narrow enough to wrap
   mid-name at full desktop width — "Privacy" ending one line and "Policy"
   starting the next reads as two links rather than one. The line still wraps;
   it just wraps around the name instead of through it. */
.mt-form__consent a { white-space: nowrap; }

/* Form-level outcome. Success reuses --mt-hydro rather than adding a success
   token: hydro already means the good outcome everywhere else on the site, and
   a second green would be a distinction nobody could name. Single-sided border
   and therefore no radius, following the data-column idiom in section 5. */
.mt-form__status {
  border-left: 2px solid var(--mt-border);
  padding: var(--mt-space-4) var(--mt-space-5);
  background: var(--mt-surface);
  margin-bottom: var(--mt-space-6);
}

.mt-form__status p { margin: 0; color: var(--mt-text-2); }
.mt-form__status h3 { margin: 0 0 var(--mt-space-2); font-size: var(--mt-text-h3); }

.mt-form__status--ok { border-left-color: var(--mt-hydro); }
.mt-form__status--ok h3 { color: var(--mt-hydro); }

.mt-form__status--error { border-left-color: var(--mt-error); }
.mt-form__status--error h3 { color: var(--mt-error); }

/* Honeypot. NOT .mt-visually-hidden, which is the reuse section 8 would lead a
   reader to expect. That utility hides something from the eye while keeping it
   in the accessibility tree, which is the opposite of what a honeypot needs: a
   screen-reader user would find the field, fill it in, and be classified as a
   bot for using assistive technology.

   The markup half is not optional. The field must also carry aria-hidden="true",
   tabindex="-1" and autocomplete="off", or this rule hides it from the eye and
   from nothing else. */
.mt-form__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .mt-field input,
  .mt-field textarea { transition: none; }
}

/* ---------------------------------------------------------------
   12. LONG-FORM DOCUMENT
   Sustained reading — a page that is prose from top to bottom, rather
   than a page whose text captions a layout. Defined by the privacy
   pages. See STYLE.md section 6.
   --------------------------------------------------------------- */

/* The cap is 62ch, the same NUMBER as .mt-lead and deliberately not the same
   width. STYLE.md's reason for 62ch was sustained reading, and this is the
   case it was describing; .mt-lead merely happens to be where the number
   first landed.

   ch resolves against the element's own font-size, so at --mt-text-base this
   comes out shorter in pixels than .mt-lead does at --mt-text-lg. That is the
   point: the same count of characters, and smaller type wants a shorter line
   to hold that count.

   The same declaration gives each language its own measure, and deliberately
   NOT the same width. :lang(zh) in section 7 swaps --mt-font-cjk onto .mt-doc
   itself, so ch resolves against Noto Sans SC on a Chinese page and against
   Space Grotesk on an English one: 636px and 551px. Measured on privacy.html
   and privacy-zh.html, not derived.

   That difference is the property worth having, not a defect to correct. ch is
   a unit of the script actually being set, so one declaration lands near 62
   Latin characters on one page and near 34 Han characters on the other, each
   inside its own comfortable measure — which a single pixel value could not do
   for both. The markup stays identical either way, which is what SCOPE.md
   section 3 asks for; it is the computed width that differs, as it does for
   every text element on a Chinese page.

   .mt-lead's 62ch behaves the same way and always has. */
.mt-doc {
  max-width: 62ch;
}

/* Section rhythm. The base h1–h4 rule carries margin-bottom only, which is
   enough where headings are separated by whole sections and not enough in a
   document where two paragraphs separate them.

   The size drop is the same judgement. --mt-text-h2 is 2.125rem against 1rem
   body, a ratio that reads as a section break on a page carrying three of them
   and as shouting on a document carrying fifteen. Here the heading is a
   signpost, not a headline. The element stays an h2 — this changes its size,
   not its level. */
.mt-doc h2 {
  margin-top: var(--mt-space-8);
  font-size: var(--mt-text-h3);
}

/* The effective-date line under the title. Muted and set apart, because it is
   metadata about the document rather than the first thing to read in it. */
.mt-doc__meta {
  font-size: var(--mt-text-sm);
  color: var(--mt-text-3);
  margin-bottom: var(--mt-space-7);
}

.mt-doc > *:last-child {
  margin-bottom: 0;
}

/* ---------------------------------------------------------------
   13. ABOUT PAGE PATTERNS
   Defined by the about page. Its own section rather than an addition
   to section 10, following the contact and privacy precedent: each
   page that defines patterns gets a section, and section 10's header
   says where its patterns came from.
   The grid breakpoints are content-shaped like section 10's and
   section 11's, not the global 768. See STYLE.md section 6.
   --------------------------------------------------------------- */

/* Four across, because the team is four people and a row of four is the whole
   set at a glance. 980 and 560 are where THIS content breaks, not where the
   page does.

   The credential line sets 980, not the role. At four columns just above the
   breakpoint a card is 212px, and the longest credential fragments to FOUR
   lines, taking the card to 457px. Dropping to two columns puts the card at
   430px, the same line to two, and the card to 323px — measured on about.html
   at 990px and 970px. A credential broken across four lines has stopped being
   one line of a list and reads as a paragraph.

   560 is the number .mt-form__row already uses, and the same reasoning arrives
   at it: two columns of a card this dense stop being two usable cards. It
   reoccupies the number rather than adding another. */
.mt-bios {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--mt-space-4);
}

@media (max-width: 980px) {
  .mt-bios { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 560px) {
  .mt-bios { grid-template-columns: 1fr; }
}

/* Single-sided border, so no radius — the .mt-stat idiom in section 5, and the
   same reason .mt-callout and .mt-sku-card take none. */
.mt-bio {
  background: var(--mt-surface);
  border-top: 3px solid var(--mt-ignition);
  border-radius: 0;
  padding: var(--mt-space-5);
}

.mt-bio__name {
  font-size: var(--mt-text-lg);
  font-weight: 700;
  color: var(--mt-text);
}

/* The Han name is the same person, not a second one, so it sits muted directly
   under the Latin name rather than beside it at equal weight. It carries
   lang="zh-Hans" in the markup, which is what switches --mt-font-cjk onto it
   from section 7 — the page around it is English and its own lang attribute
   would otherwise set these glyphs in a Latin face's fallback. */
.mt-bio__han {
  font-size: var(--mt-text-sm);
  color: var(--mt-text-3);
  margin-top: var(--mt-space-1);
}

/* Amber, not ignition. The role is the one figure-equivalent on the card — the
   thing the eye is looking for when it scans four of these — and section 3
   reserves ignition for the rule above a section and the one action that
   matters most on a page.

   Tracked at 0.16em rather than .mt-label's 0.28em because this sits inside a
   ~260px card, not across a section. Even so, the longest role on about.html
   ("Chief Technology Officer") needs 205px to hold one line, so it wraps to two
   between the 980 breakpoint and about 1145px. That band is accepted rather
   than tracked out of, the same way the 75K headline's three-line band is in
   STYLE.md section 4: the fix would be dropping the tracking that makes this a
   label, and the cards are grid items, so a two-line role lengthens all four
   together rather than breaking the row. */
.mt-bio__role {
  font-size: var(--mt-text-xs);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--mt-amber);
  margin-top: var(--mt-space-3);
}

/* Unstyled list. These are credentials, not steps and not a ranking, so a
   marker would assert an order the content does not have. The rule above them
   separates the person from what they have done without a second surface or a
   heading nobody needs to read. */
.mt-bio ul {
  list-style: none;
  margin: var(--mt-space-4) 0 0;
  padding: var(--mt-space-4) 0 0;
  border-top: 1px solid var(--mt-border);
  font-size: var(--mt-text-sm);
  color: var(--mt-text-3);
  line-height: 1.6;
}

.mt-bio li { margin-bottom: var(--mt-space-3); }
.mt-bio li:last-child { margin-bottom: 0; }
