/* ==========================================================================
   Mpalo icon layer (font-backed subsets, our names)
   Built by design/icons/build.py from Material Symbols Rounded (Apache 2.0).
   Markup contract: <span class="mi mi-16" aria-hidden="true">home</span>
   Name list is frozen by design/icons/manifest.json and enforced with
   scripts/check-icons.mjs.  See design/ICON_SYSTEM.md.

   Four rules live in this file, do not move them into page CSS:

   1. Icon color is always inherited (currentColor).  Neutral variation
      modifiers read context tokens; nothing renders without an inheriting
      color.
   2. Size and optical size are paired: each size class sets font-size and
      opsz together.  Random font-variation-settings is disabled.
   3. Weight is owned by the layer, not the consumer: 500 interface,
      300 editorial, filled micro via --mi-filled.
   4. Icons never animate.  Motion belongs to drawn scribbles and GIFs that
      are their own accessible media (see brand doctrine 0-5 motion rules).
   ========================================================================== */

@font-face {
  font-family: 'Mpalo Symbols';
  /* Shipped family: Rounded, locked by the founder on 2026-11-04.
     Outlined/Sharp are regenerable via `npm run build:icons -- --sharp`
     for family review, but never served alongside the shipped face. */
  src: url('/assets/fonts/mpalo-icons.woff2?v=6e209ffa53') format('woff2-variations');
  font-weight: 100 700;
  font-style: normal;
  font-display: block;
}

:root {
  /* Axis contract. Read by every .mi; page CSS may override via variables only. */
  --mi-family: 'Mpalo Symbols';
  --mi-size: 24px;
  --mi-wght: 500;
  --mi-grad: 0;
  --mi-fill: 0;
  --mi-opsz: 24;
}

.mi {
  /* The Mind typeface contract sets font-family on bare `span` elements with
     !important (mind-framework.css). That would silently collapse icon glyphs
     into the body face and print the ligature name as text instead of the
     drawing. `.mi.mi` carries one extra class of specificity with the same
     !important, so the icon layer wins without anything else moving. */
  font-family: var(--mi-family) !important;
  font-weight: normal;
  font-style: normal;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: -0.125em;   /* sits on the text baseline like an <img> did */
  white-space: nowrap;
  letter-spacing: normal;
  font-feature-settings: 'liga' 1;
  font-variation-settings: 'FILL' var(--mi-fill), 'wght' var(--mi-wght), 'GRAD' var(--mi-grad), 'opsz' var(--mi-opsz);
  font-size: var(--mi-size);
  color: inherit;
  font-variant-emoji: text;   /* never let the icon dump become system emoji */
  user-select: none;
  transform: rotate(var(--mi-rotate, 0deg));
  transform-origin: center;
}

/* Canonical render path. `.mi-<name>` from the generated map carries a fixed
   codepoint, so drawing does not depend on ligature shaping (which Degraded
   in Chromium for names where a shorter subject shares their LigatureSet). */
.mi::before {
  content: var(--mi-glyph, attr(data-mi, ''));
}

/* --- Mpalo drawn art ------------------------------------------------------------------ */
/* Every icon subject now ships from the font. This mask layer remains for
   non-icon art only: the homepage security spiral, the terminal brand mark,
   and the native-select arrow. Painting happens through a CSS mask, so the
   art inherits the surrounding `color` instead of carrying a baked-in fill.
   Usage looks like:
   <span class="mpalo-mark w-48" style="--mark-url:/assets/brand/logos/security-spiral-hand.svg;"></span>
   Sizing stays on the element (1em inline, or any class that sets it).        */
.mpalo-mark {
  display: inline-block;
  flex: 0 0 auto;
  vertical-align: -0.125em;
  position: relative;
  user-select: none;
}

/* The paint happens on the pseudo layer so a failed or missing --mark-url
   paints nothing instead of an opaque square. The fill still comes from
   currentColor, exactly like a font glyph. */
.mpalo-mark::before {
  content: "";
  position: absolute;
  inset: 0;
  background-color: currentColor;
  -webkit-mask: var(--mark-url) center / contain no-repeat;
  mask: var(--mark-url) center / contain no-repeat;
}

/* Fallback size lives here so any sizing class the caller already carries
   (Tailwind utilities, layout paddings) wins on cascade order instead of
   being locked out by a style-sheet ordering clash. */
:where(.mpalo-mark) {
  width: 1em;
  height: 1em;
}

/* Double-class bump: beats the `body.font-default span` !important contract
   (specificity 0,2,0 vs 0,1,2) so glyph text stays in the icon family. */
.mi.mi {
  font-family: var(--mi-family) !important;
}

/* --- Size + optical size pairings (interface register) --------------------------------- */
.mi-12 { --mi-size: 12px; --mi-opsz: 20; --mi-wght: 500; }
.mi-16 { --mi-size: 16px; --mi-opsz: 20; --mi-wght: 500; }
.mi-20 { --mi-size: 20px; --mi-opsz: 20; --mi-wght: 500; }
.mi-24 { --mi-size: 24px; --mi-opsz: 24; --mi-wght: 500; }
.mi-32 { --mi-size: 32px; --mi-opsz: 32; --mi-wght: 500; }
.mi-40 { --mi-size: 40px; --mi-opsz: 48; --mi-wght: 400; }
.mi-48 { --mi-size: 48px; --mi-opsz: 48; --mi-wght: 300; }

/* --- Direction reuse ------------------------------------------------------------------- */
/* One chevron drawing. Direction is rotation, never a second glyph. */
.mi-rotate-90 { --mi-rotate: 90deg; }
.mi-rotate-180 { --mi-rotate: 180deg; }
.mi-rotate-270 { --mi-rotate: 270deg; }

/* --- Micro register: below 12px or inside dense controls -------------------------------- */
/* Solid fill reads where a 1px hairline would vanish. Uses the filled master plus   */
/* slight grade reduction. .mi-12 micro is redundant; apply it at 10 and under only when a  */
/* tiny slot genuinely exists.                                                             */
.mi-micro {
  --mi-fill: 1;
  --mi-grad: -25;
}

/* --- Editorial register: marketing and display ------------------------------------------ */
.mi-editorial { --mi-wght: 300; --mi-opsz: 48; }

/* --- Fill / weight modifiers ------------------------------------------------------------ */
.mi-filled { --mi-fill: 1; }
.mi-strong { --mi-wght: 700; }
.mi-light { --mi-wght: 200; }

/* --- Color modifiers. Tokens come from the owning surface, never a literal here. -------- */
.mi-muted { color: var(--color-text-muted); }
.mi-accent { color: var(--color-accent); }
.mi-success { color: var(--color-status-success); }
.mi-warning { color: var(--color-status-warning); }
.mi-danger { color: var(--color-status-error); }

/* Decorative usages stay visible to screen readers' neighbors but remain silent;
   that contract is enforced in markup (aria-hidden="true"), not CSS. Only
   meaningful icons skip aria-hidden and pair with text or a label. */

@media (prefers-reduced-motion: reduce) {
  /* Icons are static by construction. This guard exists for any future
     pseudo-element icon composition so no motion can slip in underneath us. */
  .mi,
  .mi * {
    animation: none !important;
    transition: none !important;
  }
}
