/* ==========================================================================
   MOTHERLOAD DESIGN SYSTEM - COMPONENTS
   Depends on tokens.css. Nothing below hardcodes a colour.
   Prefix: .ml-

   Button hierarchy, the rule everything else follows:
     .ml-button--primary    cut-corner, red fill, white label     main action
     .ml-button--secondary  cut-corner, white fill, black label   second action
     .ml-button--outline    cut-corner, hairline, white label     tertiary action
     .ml-btn                small radius, neutral                 utilities
   Action buttons share one geometry. Utilities never borrow it, and never
   use brand red.
   ========================================================================== */

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "cv05" 1, "ss01" 1;
}

h1, h2, h3, h4 {
  margin: 0;
  font-weight: 700;
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
  color: var(--text);
}

p { margin: 0; max-width: var(--measure); }

a { color: var(--brand-text); text-decoration: none; }
a:hover { color: var(--text); }

/* White, always. Red focus would read as an error state on this palette. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

::selection { background: var(--brand); color: var(--on-brand); }

/* --------------------------------------------------------------------------
   TYPE UTILITIES
   -------------------------------------------------------------------------- */

.ml-label {
  display: inline-block;
  font-size: var(--text-2xs);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--muted-2);
}

/* Anything a person would copy, verify, or paste. */
.ml-mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.ml-num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

.ml-lead { font-size: var(--text-lg); color: var(--muted); line-height: var(--leading-snug); }

.ml-pos { color: var(--pos); }
.ml-neg { color: var(--neg); }

/* Truncated hash or address. Keeps the head and tail, which is what people
   actually verify against. */
.ml-hash {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted);
  transition: color var(--dur-quick) var(--ease-out);
}
a.ml-hash:hover { color: var(--text); }

/* --------------------------------------------------------------------------
   SHAPE
   Rounded rectangle with one corner cut at 45 degrees, both ends of the
   cut softened. system.js draws it as an inline SVG path behind the
   element's content, rather than using clip-path, because an outlined
   shape must keep its stroke along the diagonal and clip-path cannot.

   Geometry: --shape-radius, --shape-corner, --shape-corner-round (tokens).
   Paint:    --shape-fill, --shape-stroke, --shape-stroke-width.
   Cut side: data-corner="br" (default) or "bl".
   -------------------------------------------------------------------------- */

.ml-shape { position: relative; isolation: isolate; }

.ml-shape__svg {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  z-index: -1;
  overflow: visible;
  pointer-events: none;
}
.ml-shape__svg path {
  fill: var(--shape-fill, transparent);
  stroke: var(--shape-stroke, none);
  stroke-width: var(--shape-stroke-width, 1px);
  transition: fill var(--dur-quick) var(--ease-out),
              stroke var(--dur-quick) var(--ease-out);
}

/* Resolves the fluid clamp() geometry to pixels for the path builder.
   Never visible, never interactive. */
.ml-shape__probe {
  position: absolute;
  inset-block-start: 0;
  left: 0;
  visibility: hidden;
  pointer-events: none;
  padding: 0;
  border: 0;
  width: var(--shape-radius);
  height: var(--shape-corner);
  margin-left: var(--shape-corner-round);
}

/* Media layer clipped to the shape's exact outline by system.js. Sits over
   the drawn fill, under any content that follows it in the markup. The
   fill stays behind as the colour you see before media loads. */
.ml-shape__clip {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.ml-shape__clip > video,
.ml-shape__clip > img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  object-position: center;
}

/* --------------------------------------------------------------------------
   ACTION BUTTON (cut-corner)
   Primary and secondary actions. Label sits left; the arrow lives in its
   own reserved zone on the right, so the label never shifts when the arrow
   nudges on hover. Default size is fluid and resolves to 54px tall at
   1440px; --sm is a fixed 40px for dialogs, cards and dense rows.
   -------------------------------------------------------------------------- */

:root {
  /* Thin, full-bleed, square-ended: reads as a line with a head. */
  --ml-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='black' stroke-width='1.15' stroke-linecap='butt' stroke-linejoin='miter'%3E%3Cpath d='M0 6h11.2M5.9 0.7 11.2 6l-5.3 5.3'/%3E%3C/svg%3E");
  --button-arrow-size:  clamp(0.5625rem, 0.684vw, 0.75rem);
  --button-arrow-inset: clamp(1.25rem, 2.108vw, 2.25rem);
}

.ml-button {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  block-size: clamp(2.75rem, 3.75vw, 3.5rem);
  padding-inline-start: clamp(1rem, 1.627vw, 1.625rem);
  padding-inline-end: clamp(2.75rem, 4.42vw, 4.5rem);
  border: 0;
  background: transparent;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: clamp(0.8125rem, 0.96vw, 0.9375rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.ml-button::after {
  content: "";
  position: absolute;
  inset-inline-end: var(--button-arrow-inset);
  inset-block-start: 50%;
  inline-size: var(--button-arrow-size);
  block-size: var(--button-arrow-size);
  margin-block-start: calc(var(--button-arrow-size) / -2);
  background: var(--button-arrow, var(--brand-text));
  -webkit-mask: var(--ml-arrow) center / contain no-repeat;
          mask: var(--ml-arrow) center / contain no-repeat;
  transition: transform var(--dur-quick) var(--ease-out),
              background-color var(--dur-quick) var(--ease-out);
}
.ml-button:hover::after { transform: translateX(3px); }

/* Primary: brand red, white label. One per view. */
.ml-button--primary,
.ml-button--solid {
  --shape-fill: var(--brand);
  --button-arrow: var(--on-brand);
  color: var(--on-brand);
}
.ml-button--primary:hover,
.ml-button--solid:hover  { --shape-fill: var(--brand-hover); color: var(--on-brand); }
.ml-button--primary:active,
.ml-button--solid:active { --shape-fill: var(--brand-active); }

/* Secondary: white fill, black label. The red arrow ties it back to the
   primary without competing with it. */
.ml-button--secondary {
  --shape-fill: var(--white);
  --button-arrow: var(--brand);
  color: var(--black);
}
.ml-button--secondary:hover  { --shape-fill: var(--gray-12); color: var(--black); }
.ml-button--secondary:active { --shape-fill: var(--gray-11); }

/* Outline: same object, unfilled. For a third action beside a primary and
   secondary, or an action on a busy surface. */
.ml-button--outline {
  --shape-stroke: var(--ring-detail);
  --shape-stroke-width: 1.5px;
  --button-arrow: var(--brand-text);
  color: var(--text);
}
.ml-button--outline:hover { --shape-stroke: var(--muted); color: var(--text); }

.ml-button--sm {
  --shape-radius: 0.5rem;
  --shape-corner: 1rem;
  --shape-corner-round: 0.1875rem;
  --button-arrow-size: 0.5625rem;
  --button-arrow-inset: 1.125rem;
  block-size: 2.5rem;
  padding-inline-start: 1rem;
  padding-inline-end: 2.75rem;
  font-size: var(--text-sm);
}

.ml-button--block { display: flex; inline-size: 100%; }

/* The navbar CTA's geometry as a reusable size. Every page action (banner,
   game cards, entry gate) uses this, so each one matches "Start a run":
   41.1px tall at 1440 (the bar's inner height less --pad-base above and
   below), 54px at 1920, 38px on phones, 38% cut, --radius-2xl corners,
   arrow --pad-md from the edge. Set on the button itself, it also
   overrides any --shape-* values inherited from a parent panel. */
.ml-button--cta {
  block-size: calc(var(--nav-h) - 2px - 2 * var(--pad-base));
  --shape-radius: var(--radius-2xl);
  --shape-corner: 38%;
  --shape-corner-round: 4px;
  --button-arrow-inset: var(--pad-md);
}
@media (max-width: 64rem) {
  .ml-button--cta {
    block-size: 38px;
    padding-inline-start: var(--space-4);
    padding-inline-end: 2.5rem;
    font-size: var(--text-sm);
    --button-arrow-size: 0.5625rem;
    --button-arrow-inset: var(--space-4);
  }
}

/* A status shown in the action slot (Releasing soon, Final testing): the
   CTA shape and white fill, but not a link, so no arrow and no hover. */
.ml-button--status { cursor: default; padding-inline-end: var(--pad-md); }
.ml-button--status::after { content: none; }
.ml-button--status.ml-button--secondary:hover { --shape-fill: var(--white); }
@media (max-width: 64rem) {
  .ml-button--status { padding-inline-end: var(--space-4); }
}

/* Focus is drawn on the shape; a rectangular outline would ignore the cut.
   The stroke straddles the edge, so half of it always lands on the dark
   ground and stays visible even around the white secondary button. */
.ml-button:focus-visible { outline: none; --shape-stroke: var(--focus); --shape-stroke-width: 3px; }

.ml-button:disabled,
.ml-button[aria-disabled="true"] { opacity: 0.4; cursor: not-allowed; pointer-events: none; }

/* --------------------------------------------------------------------------
   NORMAL BUTTON
   Utilities: filters, pause, export, dialog cancel, copy. Neutral surface,
   radius about 15% of height. Never brand red, never a pill.
   -------------------------------------------------------------------------- */

.ml-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 12px 18px;                         /* 40px */
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--surface-control);
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-md);
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition: background-color var(--dur-quick) var(--ease-out),
              border-color var(--dur-quick) var(--ease-out),
              color var(--dur-quick) var(--ease-out),
              opacity var(--dur-quick) var(--ease-out);
}
.ml-btn:hover:not(:disabled) { background: var(--card-raised); border-color: var(--border-strong); color: var(--text); }
.ml-btn:active:not(:disabled) { background: var(--gray-4); }

/* Same as the default; kept because pages already use the name. */
.ml-btn--secondary { }

.ml-btn--outline { background: transparent; border-color: var(--border-strong); }
.ml-btn--outline:hover:not(:disabled) { background: var(--surface-nav); border-color: var(--ring-detail); }

.ml-btn--ghost { background: transparent; border-color: transparent; color: var(--muted); }
.ml-btn--ghost:hover:not(:disabled) { background: var(--surface-nav); border-color: transparent; color: var(--text); }

.ml-btn--danger { background: transparent; border-color: var(--border-strong); color: var(--neg); }
.ml-btn--danger:hover:not(:disabled) { background: transparent; border-color: var(--neg); color: var(--neg); }

.ml-btn--sm { padding: 7px 12px; font-size: var(--text-xs); border-radius: var(--radius-control-sm); }  /* 28px */
.ml-btn--lg { padding: 16px 24px; font-size: var(--text-base); border-radius: var(--radius-control-lg); } /* 48px */
.ml-btn--block { width: 100%; }

.ml-btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* DEPRECATED. A compact red button with a small radius, kept only so
   existing dialogs render until they are rebuilt. New work uses
   .ml-button--primary.ml-button--sm. */
.ml-btn--primary { background: var(--brand); border-color: transparent; color: var(--on-brand); }
.ml-btn--primary:hover:not(:disabled) { background: var(--brand-hover); border-color: transparent; color: var(--on-brand); }
.ml-btn--primary:active:not(:disabled) { background: var(--brand-active); }

/* DEPRECATED. Superseded by .ml-button--secondary. */
.ml-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 14px 22px;
  border: none;
  border-radius: var(--radius-control-lg);
  background: var(--white);
  color: var(--black);
  font-family: inherit;
  font-size: var(--text-md);
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--dur-quick) var(--ease-out);
}
.ml-cta:hover { background: var(--gray-12); color: var(--black); }

/* Wallet controls stay quiet unless connecting is the primary action. */
.ml-connect { background: transparent; color: var(--text); border: 1px solid var(--border-strong); }
.ml-connect:hover { border-color: var(--ring-detail); }
.ml-wallet {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 9px 12px; border-radius: var(--radius-control);
  background: var(--surface-nav); border: 1px solid var(--border);
  font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted);
}

/* --------------------------------------------------------------------------
   CHAMFER (DEPRECATED)
   clip-path corner cut. Cannot stroke its diagonal. Kept only for the home
   page stage panel until that page is rebuilt on .ml-shape.
   -------------------------------------------------------------------------- */

.ml-chamfer {
  --chamfer: 18px;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--chamfer)), calc(100% - var(--chamfer)) 100%, 0 100%);
}
.ml-chamfer--bl {
  clip-path: polygon(0 0, 100% 0, 100% 100%, var(--chamfer) 100%, 0 calc(100% - var(--chamfer)));
}
.ml-chamfer--lg { --chamfer: 34px; }
.ml-chamfer--xl { --chamfer: 56px; }

/* --------------------------------------------------------------------------
   NAVIGATION
   -------------------------------------------------------------------------- */

.ml-nav {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-5);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-nav);
  box-shadow: var(--shadow-nav);
}

.ml-nav__links { display: flex; gap: var(--space-1); margin-inline-start: auto; }

/* Segmented variant. One container divided into zones by full-height rules:
   identity, wayfinding, action. */
.ml-nav--split { padding: 0; gap: 0; align-items: stretch; overflow: hidden; }

.ml-nav__zone {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  min-block-size: 3.75rem;
}
.ml-nav__zone + .ml-nav__zone { border-inline-start: 1px solid var(--border); }
.ml-nav__zone--grow { flex: 1; }
.ml-nav__zone--nav  { gap: var(--space-1); justify-content: center; }
.ml-nav__zone--act  { gap: var(--space-3); padding-inline-end: var(--space-3); }

.ml-nav__cta { flex: 1 1 auto; }

.ml-nav__link {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-control);
  color: var(--muted);
  font-size: var(--text-md);
  font-weight: 500;
  transition: color var(--dur-quick) var(--ease-out),
              background-color var(--dur-quick) var(--ease-out);
}
.ml-nav__link:hover { color: var(--text); background: var(--surface-nav); }
.ml-nav__link[aria-current="page"] { color: var(--text); background: var(--surface-control); }

/* --------------------------------------------------------------------------
   NAVBAR
   Fixed, full-bleed, flush to the top of the viewport. A 1px frame in
   --frame surrounds a black fill; only the bottom corners of the frame are
   rounded. Inside, a 12-column grid splits identity (3), wayfinding (6) and
   action (3), divided by full-height 1px rules in the same frame colour.

   The grid sits inside the frame's 1px padding, so its 3-column boundary
   lands on the same x as the 1px gap between page panels below it. That
   alignment is the point: nav and page read as one grid.
   -------------------------------------------------------------------------- */

/* The wrapper element system.js renders the bar into. It takes no box of
   its own, so the fixed bar behaves exactly as if written in place. Pages
   offset their content by --nav-h. */
ml-site-nav { display: contents; }

.ml-navbar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-sticky);
  block-size: var(--nav-h);
}

.ml-navbar__frame {
  block-size: 100%;
  padding: 1px;
  background: var(--frame);
  border-radius: 0 0 var(--radius-2xl) var(--radius-2xl);
}

.ml-navbar__grid {
  position: relative;
  block-size: 100%;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  /* One fixed row. Without it the 54px CTA plus its padding stretches the
     row past the frame and the separators overrun the bottom hairline. */
  grid-template-rows: 100%;
  background: var(--bg);
  border-radius: var(--radius-2xl);
}

.ml-navbar__brand {
  grid-column: span 3;
  display: flex;
  align-items: center;
  padding-inline: var(--pad-md);
  border-inline-end: 1px solid var(--frame);
  min-inline-size: 0;
}

/* The logo is as large as the bar allows: capped by the bar's inner
   height less --pad-base above and below (the same clearance the CTA
   keeps), and by the zone's width. The browser scales to whichever limit
   it meets first and keeps the aspect ratio. At 1440 the height cap wins:
   143.7 x 41.2. */
.ml-navbar__logo {
  display: flex;
  align-items: center;
  inline-size: 100%;
  block-size: 100%;
  min-inline-size: 0;
}
.ml-navbar__logo img {
  display: block;
  inline-size: auto;
  block-size: auto;
  max-inline-size: 100%;
  max-block-size: calc(var(--nav-h) - 2px - 2 * var(--pad-base));
}

/* Right-aligned, leading into the action zone. The zone's end padding plus
   the last item's own --pad-base puts the last link exactly --pad-md from
   the separator, the same gutter the logo keeps from its edge. */
.ml-navbar__links {
  grid-column: span 6;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-inline-end: calc(var(--pad-md) - var(--pad-base));
}
.ml-navbar__links ul {
  display: flex;
  align-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}
.ml-navbar__links li { padding-inline: var(--pad-base); }
.ml-navbar__links li:first-child { padding-inline-start: var(--pad-md); }

.ml-navbar__link {
  display: inline-flex;
  align-items: center;
  gap: var(--pad-base);
  color: var(--text);
  font-size: var(--fs-nav);
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
  transition: color var(--dur-quick) var(--ease-out);
}
.ml-navbar__link:hover { color: var(--muted); }
.ml-navbar__link[aria-current="page"] { color: var(--text); }

/* A link that leaves the current context carries the house arrow in red. */
.ml-navbar__link--out::after {
  content: "";
  inline-size: 0.95em;
  block-size: 0.95em;
  background: var(--brand-text);
  -webkit-mask: var(--ml-arrow) center / contain no-repeat;
          mask: var(--ml-arrow) center / contain no-repeat;
  transition: transform var(--dur-quick) var(--ease-out);
}
.ml-navbar__link--out:hover::after { transform: translateX(3px); }

.ml-navbar__act {
  grid-column: span 3;
  display: flex;
  align-items: stretch;
  justify-content: flex-end;
  gap: 8px;
  padding: var(--pad-base);
  border-inline-start: 1px solid var(--frame);
  min-inline-size: 0;
}

/* The CTA fills the action zone inside an even --pad-base inset (11.7px at
   1440), clear of the separator, the frame, and the top and bottom edges.
   At that height the standard 26px cut would swallow the corner, so the
   cut is 38% of the button's own height, the same proportion the mobile
   menu button uses. */
.ml-navbar__cta {
  flex: 1 1 auto;
  inline-size: auto;
  min-inline-size: 0;
  block-size: auto;
  --shape-radius: var(--radius-2xl);
  --shape-corner: 38%;
  --shape-corner-round: 4px;
  --button-arrow-inset: var(--pad-md);
}

/* Mobile menu trigger: a square in brand red carrying the same cut as the
   action buttons. Hidden at desktop widths. */
.ml-navbar__menu {
  display: none;
  place-items: center;
  block-size: 100%;
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--on-brand);
  cursor: pointer;
  --shape-fill: var(--brand);
  --shape-radius: var(--radius-2xl);
  --shape-corner: 38%;
  --shape-corner-round: 4px;
}
.ml-navbar__menu:hover { --shape-fill: var(--brand-hover); }
.ml-navbar__menu:focus-visible { outline: none; --shape-stroke: var(--focus); --shape-stroke-width: 3px; }
/* Scoped to the icon: a bare "svg" selector would also shrink the shape's
   own drawn SVG, which lives inside this button. */
.ml-navbar__menu-icon { position: relative; z-index: 1; inline-size: 42%; block-size: auto; }

@media (max-width: 64rem) {
  /* The action zone sizes to its content and the brand zone takes the
     rest, so the logo gets the room and the CTA is only as wide as its
     label. Menu button sits hard right. */
  .ml-navbar__grid { grid-template-columns: minmax(0, 1fr) auto; }
  .ml-navbar__brand { grid-column: auto; }
  .ml-navbar__act { grid-column: auto; align-items: stretch; }
  .ml-navbar__menu { display: grid; flex: 0 0 auto; }

  /* Content-width, same 38px height and cut as the menu button beside it,
     so the two read as a matched pair. */
  .ml-navbar__cta {
    flex: 0 0 auto;
    block-size: auto;
    padding-inline-start: var(--space-4);
    padding-inline-end: 2.5rem;
    font-size: var(--text-sm);
    --shape-radius: var(--radius-2xl);
    --shape-corner: 38%;
    --shape-corner-round: 4px;
    --button-arrow-size: 0.5625rem;
    --button-arrow-inset: var(--space-4);
  }

  .ml-navbar__links {
    position: absolute;
    inset: 100% 0 auto 0;
    display: none;
    padding: 0 1px 1px;
    background: var(--frame);
    border-radius: 0 0 var(--radius-2xl) var(--radius-2xl);
  }
  .ml-navbar.is-open .ml-navbar__links { display: block; }
  .ml-navbar__links ul { flex-direction: column; align-items: stretch; gap: 1px; }
  .ml-navbar__links li,
  .ml-navbar__links li:first-child { padding: 0; background: var(--bg); }
  .ml-navbar__links li:last-child { border-radius: 0 0 var(--radius-2xl) var(--radius-2xl); }
  .ml-navbar__link { display: flex; padding: var(--space-4) var(--pad-md); font-size: var(--text-base); }
}

/* --------------------------------------------------------------------------
   CARD
   A small step up from black, separated by a hairline.
   -------------------------------------------------------------------------- */

.ml-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--gutter);
}
.ml-card--raised { background: var(--card-raised); }
.ml-card--flush  { padding: 0; overflow: hidden; }

.ml-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--gutter);
  border-block-end: 1px solid var(--border);
  min-block-size: 3.25rem;
}
.ml-card__head h2, .ml-card__head h3 {
  font-size: var(--text-md); font-weight: 600; letter-spacing: 0; line-height: 1.2;
}

/* --------------------------------------------------------------------------
   CHIP
   Status tags. Not buttons, but they sit beside buttons, so they share the
   small-radius family rather than being pills.
   -------------------------------------------------------------------------- */

.ml-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 4px 8px;
  border-radius: var(--radius-control-sm);
  border: 1px solid var(--border);
  background: var(--surface-nav);
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 500;
  white-space: nowrap;
}

.ml-chip--pos    { color: var(--pos); }
.ml-chip--neg    { color: var(--neg); }
.ml-chip--accent,
.ml-chip--brand  { color: var(--brand-text); border-color: var(--brand-a24); background: var(--brand-a12); }
.ml-chip--warn   { color: var(--warn); }

.ml-chip--dot::before {
  content: ""; inline-size: 5px; block-size: 5px;
  border-radius: 50%; background: currentColor; flex: 0 0 auto;
}

.ml-chip--live { color: var(--live); border-color: var(--border-strong); }
.ml-chip--live::before {
  content: ""; inline-size: 5px; block-size: 5px; border-radius: 50%;
  background: var(--live); flex: 0 0 auto;
  animation: ml-pulse 2.4s var(--ease-inout) infinite;
}

@keyframes ml-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.25; }
}

/* --------------------------------------------------------------------------
   FIELD, INPUT, SELECT
   -------------------------------------------------------------------------- */

.ml-field { display: flex; flex-direction: column; gap: var(--space-2); }

.ml-input, .ml-select {
  inline-size: 100%;
  padding: 10px 14px;
  background: var(--bg-deep);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-control);
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-md);
  transition: border-color var(--dur-quick) var(--ease-out);
}
.ml-input::placeholder { color: var(--muted-2); }
.ml-input:hover, .ml-select:hover { border-color: var(--ring-detail); }
.ml-input:focus, .ml-select:focus { outline: none; border-color: var(--muted); }
.ml-input[aria-invalid="true"] { border-color: var(--neg); }
.ml-input--mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

.ml-select {
  appearance: none;
  padding-inline-end: 34px;
  cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) center, calc(100% - 13px) center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.ml-hint  { font-size: var(--text-xs); color: var(--muted-2); }
.ml-error { font-size: var(--text-xs); color: var(--neg); }

/* Segmented control. Filter rows use this, not tabs. */
.ml-segment {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--bg-deep);
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
}
.ml-segment button {
  padding: 7px 12px;
  border: none;
  background: transparent;
  border-radius: var(--radius-control-sm);
  color: var(--muted-2);
  font-family: inherit;
  font-size: var(--text-xs);
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--dur-quick) var(--ease-out),
              color var(--dur-quick) var(--ease-out);
}
.ml-segment button:hover { color: var(--text); }
.ml-segment button[aria-selected="true"] { background: var(--surface-control); color: var(--text); }

/* --------------------------------------------------------------------------
   READOUT
   -------------------------------------------------------------------------- */

.ml-readout { display: flex; flex-direction: column; gap: var(--space-1); }
.ml-readout__label { font-size: var(--text-2xs); letter-spacing: var(--tracking-label);
                     text-transform: uppercase; color: var(--muted-2); }
.ml-readout__value {
  font-family: var(--font-mono);
  font-size: var(--text-xl);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tracking-tight);
  line-height: 1.15;
}
/* Sans, not mono. Mono letterforms are too wide for a word like "months". */
.ml-readout__unit {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 400;
  letter-spacing: 0;
  color: var(--muted-2);
  margin-inline-start: 0.3em;
}
.ml-readout--xl .ml-readout__value { font-size: var(--text-num); font-weight: 400; }

/* --------------------------------------------------------------------------
   BAR ROW
   Ranked list with the fill behind the label. Fills are neutral: red here
   would read as a loss.
   -------------------------------------------------------------------------- */

.ml-bars { display: flex; flex-direction: column; }

.ml-bar {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 7.5rem 4.5rem;
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-3) var(--gutter);
  border-block-end: 1px solid var(--border);
  font-size: var(--text-sm);
  min-block-size: 2.75rem;
  isolation: isolate;
}
.ml-bars > .ml-bar:last-child { border-block-end: none; }

.ml-bar__fill {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  background: var(--gray-3);
  border-inline-end: 1px solid var(--gray-8);
  z-index: -1;
  transition: inline-size var(--dur-slow) var(--ease-out);
}
.ml-bar__name  { display: flex; align-items: center; gap: var(--space-3); font-weight: 500;
                 color: var(--text); min-inline-size: 0; }
.ml-bar__name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ml-bar__value { font-family: var(--font-mono); font-variant-numeric: tabular-nums;
                 color: var(--muted-2); font-size: var(--text-xs); text-align: end; }
.ml-bar__pct   { font-family: var(--font-mono); font-variant-numeric: tabular-nums;
                 color: var(--text); text-align: end; }

.ml-key { inline-size: 8px; block-size: 8px; border-radius: 2px; flex: 0 0 auto; }

/* --------------------------------------------------------------------------
   TABLE
   Mono throughout, headers included, at 12px.
   -------------------------------------------------------------------------- */

.ml-tablewrap { overflow-x: auto; }

.ml-table {
  inline-size: 100%;
  border-collapse: collapse;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.ml-table th, .ml-table td { padding-inline: var(--space-4); }
.ml-table th:first-child, .ml-table td:first-child { padding-inline-start: var(--gutter); }
.ml-table th:last-child,  .ml-table td:last-child  { padding-inline-end: var(--gutter); }

.ml-table th {
  position: sticky;
  inset-block-start: 0;
  z-index: 1;
  text-align: start;
  padding-block: var(--space-3);
  background: var(--card);
  border-block-end: 1px solid var(--border-strong);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--muted-2);
  white-space: nowrap;
}
.ml-table td {
  padding-block: 0.6875rem;
  border-block-end: 1px solid var(--border);
  color: var(--muted);
  vertical-align: middle;
}
.ml-table tbody tr:last-child td { border-block-end: none; }
.ml-table tbody tr { transition: background-color var(--dur-quick) var(--ease-out); }
.ml-table tbody tr:hover { background: var(--card-raised); }
.ml-table td.ml-t-strong { color: var(--text); font-weight: 500; }
.ml-table .ml-t-num  { text-align: end; }
.ml-table .ml-t-time { color: var(--muted-2); }

.ml-table tbody tr.ml-row-new { animation: ml-rise var(--dur-base) var(--ease-out) both; }

/* --------------------------------------------------------------------------
   GAUGE
   Neutral fill by default, for the same reason as bar rows.
   -------------------------------------------------------------------------- */

.ml-gauge {
  block-size: 4px;
  inline-size: 100%;
  background: var(--gray-4);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.ml-gauge__fill {
  block-size: 100%;
  background: var(--text);
  border-radius: inherit;
  transition: inline-size var(--dur-slow) var(--ease-out);
}
.ml-gauge--pos .ml-gauge__fill { background: var(--pos); }
.ml-gauge--neg .ml-gauge__fill { background: var(--neg); }

/* --------------------------------------------------------------------------
   TABS
   -------------------------------------------------------------------------- */

.ml-tabs {
  display: flex;
  gap: var(--space-1);
  padding: 3px;
  background: var(--bg-deep);
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  inline-size: fit-content;
}
.ml-tab {
  padding: var(--space-2) var(--space-4);
  border: none;
  background: transparent;
  border-radius: var(--radius-control-sm);
  color: var(--muted-2);
  font-family: inherit;
  font-size: var(--text-xs);
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--dur-quick) var(--ease-out),
              color var(--dur-quick) var(--ease-out);
}
.ml-tab:hover { color: var(--text); }
.ml-tab[aria-selected="true"] { background: var(--surface-control); color: var(--text); }

/* --------------------------------------------------------------------------
   OVERLAYS
   Modal and sheet are native <dialog>; the dropdown uses the popover
   attribute. A modal is not the first idea.
   -------------------------------------------------------------------------- */

.ml-dialog {
  padding: 0; border: none; background: transparent;
  color: var(--text); max-inline-size: none; max-block-size: none;
}
.ml-dialog::backdrop {
  background: var(--scrim);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out), display var(--dur-base) allow-discrete;
}
.ml-dialog[open]::backdrop { opacity: 1; }
@starting-style { .ml-dialog[open]::backdrop { opacity: 0; } }

.ml-modal[open] {
  position: fixed; inset: 0; inline-size: 100%; block-size: 100%;
  display: grid; place-items: center; overflow: auto;
}
.ml-modal__body {
  inline-size: min(100% - 2rem, 27rem);
  background: var(--modal-bg);
  border: 1px solid var(--modal-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-float);
  padding: var(--space-6);
  display: flex; flex-direction: column; gap: var(--space-4);
  opacity: 1; transform: translateY(0);
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
@starting-style {
  .ml-modal[open] .ml-modal__body { opacity: 0; transform: translateY(var(--rise)); }
}

.ml-sheet[open] {
  position: fixed; inset: 0; inline-size: 100%; block-size: 100%;
  display: flex; align-items: flex-end; justify-content: center;
}
.ml-sheet__body {
  inline-size: min(100%, 32rem);
  background: var(--modal-bg);
  border: 1px solid var(--modal-border);
  border-block-end: none;
  border-radius: var(--radius-nav) var(--radius-nav) 0 0;
  box-shadow: var(--shadow-float);
  padding: var(--space-4) var(--space-5) var(--space-7);
  display: flex; flex-direction: column; gap: var(--space-4);
  transform: translateY(0);
  transition: transform var(--dur-base) var(--ease-out);
}
@starting-style { .ml-sheet[open] .ml-sheet__body { transform: translateY(100%); } }

.ml-sheet__handle {
  inline-size: 36px; block-size: 4px;
  background: var(--border-strong);
  border-radius: var(--radius-pill);
  align-self: center; margin-block-end: var(--space-2);
}

.ml-dialog__title { font-size: var(--text-xl); }
.ml-dialog__actions { display: flex; gap: var(--space-3); justify-content: flex-end; align-items: center; margin-block-start: var(--space-2); }
.ml-dialog__close { color: var(--text-a50); }

.ml-popover {
  position: absolute; margin: 0; padding: var(--space-2);
  background: var(--card-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-float);
  inline-size: 14rem;
  opacity: 1; transform: translateY(0);
  transition: opacity var(--dur-quick) var(--ease-out),
              transform var(--dur-quick) var(--ease-out),
              overlay var(--dur-quick) allow-discrete,
              display var(--dur-quick) allow-discrete;
}
.ml-popover:not(:popover-open) { opacity: 0; transform: translateY(6px); }
@starting-style { .ml-popover:popover-open { opacity: 0; transform: translateY(6px); } }

.ml-popover__item {
  display: flex; align-items: center; gap: var(--space-3);
  inline-size: 100%; padding: var(--space-2) var(--space-3);
  border: none; background: transparent; border-radius: var(--radius-control-sm);
  color: var(--muted); font-family: inherit; font-size: var(--text-md);
  text-align: start; cursor: pointer;
  transition: background-color var(--dur-quick) var(--ease-out), color var(--dur-quick) var(--ease-out);
}
.ml-popover__item:hover { background: var(--surface-control); color: var(--text); }

/* --- Toast --------------------------------------------------------------- */

.ml-toasts {
  position: fixed; inset-block-end: var(--space-5); inset-inline: 0;
  z-index: var(--z-toast);
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
  pointer-events: none; padding-inline: var(--space-4);
}
.ml-toast {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 11px 16px;
  background: var(--card-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-float);
  font-size: var(--text-md); color: var(--text);
  pointer-events: auto; max-inline-size: 100%;
  animation: ml-rise var(--dur-base) var(--ease-out) both;
}
.ml-toast--out { animation: ml-sink var(--dur-quick) var(--ease-out) both; }
.ml-toast__dot { inline-size: 6px; block-size: 6px; border-radius: 50%; flex: 0 0 auto; background: var(--muted); }
.ml-toast--success .ml-toast__dot { background: var(--pos); }
.ml-toast--danger  .ml-toast__dot { background: var(--neg); }
.ml-toast--warn    .ml-toast__dot { background: var(--warn); }

/* --------------------------------------------------------------------------
   MOTION UTILITIES
   -------------------------------------------------------------------------- */

@keyframes ml-rise {
  from { opacity: 0; transform: translateY(var(--rise)); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes ml-sink {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(calc(var(--rise) * 0.5)); }
}

.ml-stagger > * { animation: ml-rise var(--dur-base) var(--ease-out) both; }
.ml-stagger > :nth-child(1) { animation-delay: calc(var(--stagger) * 0); }
.ml-stagger > :nth-child(2) { animation-delay: calc(var(--stagger) * 1); }
.ml-stagger > :nth-child(3) { animation-delay: calc(var(--stagger) * 2); }
.ml-stagger > :nth-child(4) { animation-delay: calc(var(--stagger) * 3); }
.ml-stagger > :nth-child(5) { animation-delay: calc(var(--stagger) * 4); }
.ml-stagger > :nth-child(6) { animation-delay: calc(var(--stagger) * 5); }

/* --------------------------------------------------------------------------
   ENTRY GATE
   18+ panel shown on the first visit to any page (system.js). The house
   panel: black fill, 1px frame stroke, large cut at bottom-right, centred on
   a black scrim. Primary red "yes", secondary white "no".
   -------------------------------------------------------------------------- */

/* Until answered the page behind cannot scroll. Before the panel is built
   the page is hidden, so the site never flashes before the question; once
   it is up, the site shows faintly through the scrim. */
html.ml-gate-open { overflow: hidden; }
html.ml-gate-open:not(.ml-gate-ready) body > :not(.ml-gate) { visibility: hidden; }

.ml-gate {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: grid;
  place-items: center;
  padding: var(--pad-md);
  background: color-mix(in srgb, var(--black) 85%, transparent);
  visibility: visible;
}

.ml-gate__panel {
  inline-size: min(100%, 36rem);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--pad-md);
  padding: var(--pad-xl) var(--pad-xl) calc(var(--pad-xl) + var(--pad-base));
  --shape-fill: var(--bg);
  --shape-stroke: var(--frame);
  --shape-stroke-width: 1px;
  --shape-radius: var(--radius-panel);
  --shape-corner: var(--cut-lg);
  --shape-corner-round: var(--cut-lg-round);
}

.ml-gate__logo { inline-size: 9rem; block-size: auto; }

.ml-gate__title {
  margin: 0;
  font-size: var(--fs-card-title);
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--text);
}

.ml-gate__copy {
  margin: 0;
  font-size: var(--fs-body-lg);
  line-height: 1.4;
  color: var(--muted);
}

/* Buttons are .ml-button--cta: the navbar CTA's geometry. */

/* Focus lands on the panel, not a button, so no focus ring shows until the
   visitor tabs. */
.ml-gate__panel:focus { outline: none; }

/* Buttons stop short of the cut so neither sits under the missing corner. */
.ml-gate__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--pad-base);
  padding-inline-end: calc(var(--cut-lg) - var(--pad-xl));
}

@media (max-width: 40rem) {
  .ml-gate__panel { padding: var(--pad-md) var(--pad-md) calc(var(--pad-md) + var(--pad-base)); }
  .ml-gate__actions { flex-direction: column; align-items: stretch; inline-size: 100%; padding-inline-end: 0; }
  .ml-gate__actions .ml-button { inline-size: 100%; }
  /* Last button clears the cut. */
  .ml-gate__actions .ml-button:last-child { inline-size: calc(100% - var(--cut-lg) + var(--pad-md)); }
}


/* --------------------------------------------------------------------------
   SITE FOOTER
   Rendered by system.js into <ml-site-footer>. Black panel with the large
   cut at top-left over the --frame ground, a statement, links, and the
   logo across the full content width.
   -------------------------------------------------------------------------- */

ml-site-footer { display: block; }

.ml-footer {
  display: block;
  padding-block-start: 1px;   /* the frame line above, on pages without a panel gap */
  background: var(--frame);
}

.ml-footer__panel {
  display: flex;
  flex-direction: column;
  gap: var(--pad-xl);
  padding: var(--pad-4xl) var(--pad-md) var(--pad-md);
  --shape-fill: var(--bg);
  --shape-radius: var(--radius-panel);
  --shape-corner: var(--cut-lg);
  --shape-corner-round: var(--cut-lg-round);
}

.ml-footer__head {
  display: flex;
  align-items: center;
  gap: var(--pad-xl);
  padding-inline: var(--pad-xl);
}
.ml-footer__icon { inline-size: clamp(3rem, 4.5vw, 4.5rem); block-size: auto; flex: 0 0 auto; color: var(--text); }
.ml-footer__title {
  max-inline-size: none;
  font-size: var(--fs-card-title);
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--text);
}

/* Hairline, then the two link groups. */
.ml-footer__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--pad-md);
  margin-inline: var(--pad-xl);
  padding-block-start: var(--pad-md);
  border-block-start: 1px solid var(--frame);
}
.ml-footer__links ul,
ul.ml-footer__links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--pad-md);
  margin: 0;
  padding: 0;
  list-style: none;
}
.ml-footer__links a {
  display: inline-flex;
  align-items: center;
  color: var(--text);
  font-size: var(--fs-nav);
  font-weight: 600;
  white-space: nowrap;
  transition: color var(--dur-quick) var(--ease-out);
}
.ml-footer__links a:hover { color: var(--muted); }
.ml-footer__x svg { inline-size: 1.25rem; block-size: 1.25rem; }

.ml-footer__logo { display: block; inline-size: 100%; block-size: auto; }

.ml-footer__legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--pad-base);
  font-size: var(--text-xs);
  color: var(--muted-2);
}

@media (max-width: 64rem) {
  .ml-footer__panel { padding-block-start: var(--pad-4xl); gap: var(--pad-md); }
  .ml-footer__head { gap: var(--pad-md); padding-inline: 0; }
  .ml-footer__bar { margin-inline: 0; }
}
