/* ============================================================
   MATERIAL 3 — COMPONENTS

   The component layer, shared by every page that shows one.

   It was page-local while only the pattern page rendered these.
   The library home now draws its card thumbnails from the SAME
   markup the Live preview mounts, so the rules have to be
   reachable from both — and a second copy would be the exact
   drift this library exists to avoid.

   Everything resolves to a --md-sys-* token from
   material-tokens.css. Page chrome (frames, tabs, the demo
   surface) stays in each page's own <style>; only components
   live here.
   ============================================================ */

/* ════════════════════════════════════════════════════════════
   DISCLOSURE — built from Material 3 components

   Every colour, radius, shadow and type style below resolves to
   a --md-sys-* token from material-tokens.css, which in turn came
   out of the Material 3 Design Kit. There are no literal hex
   values and no Nucleux expressive tokens in this block: on a
   Material page the palette is Material's.

   The pieces are the kit's own components rather than bespoke
   shapes — a list item, an assist chip, a basic dialog, text and
   filled buttons — so a reader recognises them before they read
   the labels.
   ════════════════════════════════════════════════════════════ */

/* ── Assist chip (M3) ─────────────────────────────────────
   Small corner (8px), outline-variant border, label-large.
   This is the disclosure marker itself in all three examples. */
/* The disclosure marker. M3's assist chip is a 32dp label-large
   control, but this one is never pressed — it is a label riding
   alongside a name, and at full chip size it out-weighed the
   agent's own name beside it. Dropped to 24dp on label-medium:
   still unmissable, no longer the loudest thing in the row. */
.md-assist-chip {
  display: inline-flex; align-items: center; gap: 5px;
  height: 24px; padding: 0 9px;
  border-radius: var(--md-sys-shape-corner-small);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: transparent;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-ref-typeface-plain);
  font-size: var(--md-sys-typescale-label-medium-size);
  line-height: var(--md-sys-typescale-label-medium-line);
  font-weight: var(--md-sys-typescale-label-medium-weight);
  letter-spacing: var(--md-sys-typescale-label-medium-tracking);
}
.md-assist-chip--tonal {
  border-color: transparent;
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}
.md-assist-chip__icon {
  width: 14px; height: 14px; flex: 0 0 auto;
  fill: var(--md-sys-color-primary);
}
.md-assist-chip--tonal .md-assist-chip__icon {
  fill: var(--md-sys-color-on-secondary-container);
}

/* ── Avatar / monogram ────────────────────────────────────
   Primary container, not primary: an identity marker is a
   container role in M3, and on-primary-container gives 7.4:1
   against it. */
.md-avatar {
  flex: 0 0 auto;
  width: 40px; height: 40px;
  border-radius: var(--md-sys-shape-corner-full);
  display: grid; place-items: center;
  background: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
  font-family: var(--md-ref-typeface-plain);
  font-size: var(--md-sys-typescale-title-medium-size);
  font-weight: var(--md-sys-typescale-title-medium-weight);
}
.md-avatar--lg { width: 56px; height: 56px; }

/* ── List item (M3 two-line) ──────────────────────────────
   Headline is body-large on-surface; supporting text is
   body-medium on-surface-variant. Those pairings are the M3
   spec for a list item, not a choice made here. */
.md-list-item {
  display: flex; gap: 16px; align-items: flex-start;
  padding: 12px 16px;
  background: var(--md-sys-color-surface-container-lowest);
  border-radius: var(--md-sys-shape-corner-medium);
  max-width: 560px;
}
.md-list-item__content { min-width: 0; }
.md-list-item__line {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.md-list-item__headline { color: var(--md-sys-color-on-surface); margin: 0; }
.md-list-item__supporting {
  margin: 4px 0 0;
  color: var(--md-sys-color-on-surface-variant);
  max-width: 48ch;
}
.md-list-item__trailing {
  margin-left: auto; flex: 0 0 auto;
  color: var(--md-sys-color-on-surface-variant);
}

/* ── Buttons (M3) ─────────────────────────────────────────
   Full corner, 40dp height, label-large. Filled and text are
   the two the dialog needs. */
.md-button {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 40px; padding: 0 24px;
  border: none; border-radius: var(--md-sys-shape-corner-full);
  font-family: var(--md-ref-typeface-plain);
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line);
  font-weight: var(--md-sys-typescale-label-large-weight);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
  cursor: pointer;
  transition: box-shadow var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
              background-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.md-button--filled {
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
}
/* The hover state layer is on-primary at 8% over primary, which
   is how M3 defines it — not a second, darker brand colour. */
.md-button--filled:hover {
  background:
    linear-gradient(rgba(255,255,255,var(--md-sys-state-hover-opacity)),
                    rgba(255,255,255,var(--md-sys-state-hover-opacity))),
    var(--md-sys-color-primary);
  box-shadow: var(--md-sys-elevation-1);
}
.md-button--text {
  background: transparent;
  color: var(--md-sys-color-primary);
  padding: 0 12px;
}
.md-button--text:hover {
  background: color-mix(in srgb,
    var(--md-sys-color-primary) calc(var(--md-sys-state-hover-opacity) * 100%),
    transparent);
}
.md-button--outlined {
  background: transparent;
  color: var(--md-sys-color-primary);
  border: 1px solid var(--md-sys-color-outline-variant);
}
/* Tonal: the middle emphasis of the M3 button set — used where a
   trigger should be the obvious action on the surface without
   claiming the page's single filled slot. */
.md-button--tonal {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  border-color: transparent;
}
.md-button--tonal:hover {
  box-shadow: var(--md-sys-elevation-1, 0 1px 3px rgba(16, 16, 20, 0.16));
}
.md-button--sm { height: 32px; padding: 0 16px; }
/* Filled, in the error role — the one destructive confirmation in
   the kit that should read as unmistakably different from a
   normal filled action, without inventing a fifth button shape. */
.md-button--filled-error {
  background: var(--md-sys-color-error);
  color: var(--md-sys-color-on-error);
}
.md-button--filled-error:hover {
  background:
    linear-gradient(rgba(0,0,0,.08), rgba(0,0,0,.08)),
    var(--md-sys-color-error);
}

/* ── Small size (M3 Expressive kit, Button · Size: Small) ─
   40dp container on a 48dp touch target, 16dp side padding, 8dp
   icon-label gap, 20dp icon, Label Large. Every state from the
   kit: an 8% state layer on hover, 10% on focus and press (the
   layer is the label colour, so it is right for every variant),
   a 3dp secondary focus ring, and the pressed shape morph — the
   full corner tightens to Corner/Small while held. Disabled is
   the kit's: 38% content, 10% on-surface container where the
   variant has one.

   The state layer is a pseudo-element rather than a background
   change, so it sits over any container colour (text, tonal,
   filled) without each variant re-deriving its own hover mix. */
.md-button--small {
  position: relative; isolation: isolate;
  height: 40px; padding: 0 16px; gap: 8px;
  transition: border-radius var(--mx-motion-fast-duration, 120ms) var(--md-sys-motion-easing-standard),
              background-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
              box-shadow var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.md-button--small::before,
.md-icon-button::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  border-radius: inherit; background: currentColor; opacity: 0;
  pointer-events: none;
  transition: opacity var(--mx-motion-fast-duration, 120ms) var(--md-sys-motion-easing-standard);
}
/* The 48dp touch target, larger than the 40dp container. */
.md-button--small::after,
.md-icon-button::after {
  content: ''; position: absolute; inset: -4px; border-radius: inherit;
}
.md-button--small svg { width: 20px; height: 20px; flex: 0 0 auto; fill: currentColor; }
/* The variants' own hover backgrounds are replaced by the layer. */
.md-button--small.md-button--text:hover { background: transparent; }
.md-button--small.md-button--filled:hover { background: var(--md-sys-color-primary); }
.md-button--small.md-button--tonal:hover { box-shadow: none; }

.md-button--small:hover::before,
.md-icon-button:hover::before { opacity: var(--md-sys-state-hover-opacity); }
.md-button--small:focus-visible::before,
.md-icon-button:focus-visible::before { opacity: var(--md-sys-state-focus-opacity); }
.md-button--small:active::before,
.md-icon-button:active::before { opacity: var(--md-sys-state-pressed-opacity); }
.md-button--small:active,
.md-icon-button:active { border-radius: var(--md-sys-shape-corner-small); }
.md-button--small:focus-visible,
.md-icon-button:focus-visible {
  outline: 3px solid var(--md-sys-color-secondary); outline-offset: 2px;
}
.md-button--small:disabled,
.md-icon-button:disabled {
  cursor: default; color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
}
.md-button--small:disabled::before,
.md-icon-button:disabled::before { opacity: 0; }
.md-button--small.md-button--filled:disabled,
.md-button--small.md-button--tonal:disabled,
.md-icon-button--filled:disabled,
.md-icon-button--tonal:disabled {
  background: color-mix(in srgb, var(--md-sys-color-on-surface) 10%, transparent);
}

/* ── Icon button (M3 Expressive kit) · Size: Small ────────
   40dp container, 24dp icon, 48dp touch target, full corner.
   Standard has no container; filled is primary; tonal is
   secondary-container. A toggle (aria-pressed) in the standard
   style shows its selected state in primary. */
.md-icon-button {
  position: relative; isolation: isolate; flex: 0 0 auto;
  display: inline-grid; place-items: center;
  width: 40px; height: 40px; padding: 0;
  border: 0; border-radius: var(--md-sys-shape-corner-full);
  background: transparent; color: var(--md-sys-color-on-surface-variant);
  cursor: pointer;
  transition: border-radius var(--mx-motion-fast-duration, 120ms) var(--md-sys-motion-easing-standard),
              background-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
              color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.md-icon-button svg { width: 24px; height: 24px; fill: currentColor; }
.md-icon-button--standard[aria-pressed="true"] { color: var(--md-sys-color-primary); }
.md-icon-button--filled {
  background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary);
}
.md-icon-button--tonal {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}

/* ── Basic dialog (M3) ────────────────────────────────────
   Extra-large corner (28), surface-container-high, elevation 3.
   All three read from the kit. */
.md-dialog {
  max-width: 400px;
  padding: 24px;
  border-radius: var(--md-sys-shape-corner-extra-large);
  background: var(--md-sys-color-surface-container-high);
  box-shadow: var(--md-sys-elevation-3);
}
.md-dialog__icon {
  display: block; width: 24px; height: 24px; margin: 0 auto 16px;
  fill: var(--md-sys-color-secondary);
}
.md-dialog__headline {
  margin: 0; text-align: center;
  color: var(--md-sys-color-on-surface);
}
.md-dialog__body {
  margin: 16px 0 0;
  color: var(--md-sys-color-on-surface-variant);
}
.md-dialog__actions {
  display: flex; justify-content: flex-end; gap: 8px;
  margin-top: 24px;
}

/* ── Dialog fact list ─────────────────────────────────────
   body-medium on-surface-variant, with a primary bullet. */
.md-facts { list-style: none; margin: 16px 0 0; padding: 0; }
.md-facts li {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 6px 0;
  color: var(--md-sys-color-on-surface-variant);
}
.md-facts__bullet {
  flex: 0 0 auto; margin-top: 7px;
  width: 6px; height: 6px;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-primary);
}

/* ── Banner (M3 pattern) ──────────────────────────────────
   Tertiary container: in the baseline scheme that is the third
   accent, and it separates a generated-content notice from the
   primary actions around it without inventing a colour. */
.md-banner {
  display: flex; align-items: center; gap: 16px;
  max-width: 560px;
  padding: 12px 12px 12px 16px;
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-tertiary-container);
  color: var(--md-sys-color-on-tertiary-container);
}
.md-banner__icon {
  flex: 0 0 auto; width: 20px; height: 20px;
  fill: var(--md-sys-color-on-tertiary-container);
}
.md-banner__text { margin: 0; flex: 1 1 auto; }
.md-banner__action {
  flex: 0 0 auto;
  color: var(--md-sys-color-on-tertiary-container);
}
.md-banner__action:hover {
  background: color-mix(in srgb,
    var(--md-sys-color-on-tertiary-container)
    calc(var(--md-sys-state-hover-opacity) * 100%), transparent);
}

/* ── Text field with generated content (M3 outlined) ──────
   Used by the third example: the strip travels with the
   generated value, inside the field that holds it. */
.md-field {
  /* It is a <label>, which is inline by default — and an inline box
     wraps its border around text fragments rather than around the
     field, which is what made the outline render in pieces. */
  display: block;
  max-width: 560px;
  border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-sys-shape-corner-extra-small);
  background: var(--md-sys-color-surface-container-lowest);
  padding: 12px 16px;
}
.md-field__label {
  display: block;
  color: var(--md-sys-color-on-surface-variant);
}
.md-field__value {
  margin: 6px 0 0;
  color: var(--md-sys-color-on-surface);
}
.md-field__foot {
  display: flex; align-items: center; gap: 8px;
  margin-top: 12px; padding-top: 12px;
  border-top: 1px solid var(--md-sys-color-outline-variant);
}
.md-field__spacer { margin-left: auto; }

@media (prefers-reduced-motion: reduce) {
  .md-button, .md-icon-button,
  .md-button--small::before, .md-icon-button::before { transition: none; }
}



/* ── Consent & Caveat ─────────────────────────────────────
   Not yet rebuilt on Material components, but retoned onto the
   M3 roles so nothing off-palette appears beside a Material
   component — the rose these used is a Nucleux expressive tone
   and read as pink on this page, including inside the demo.
   The shapes are still bespoke; that is the next move. */
/* ── Consent ──────────────────────────────────────────── */
.m3-consent {
  max-width: 520px;
  padding: 26px 26px 22px;
  border-radius: var(--md-sys-shape-corner-extra-large);
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: 0 20px 44px -34px var(--md-sys-color-on-primary-container);
}
.m3-consent__k {
  display: inline-block; padding: 4px 12px; border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container);
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase;
}
.m3-consent__title {
  margin: 14px 0 0; font-size: 18px; font-weight: 650;
  letter-spacing: -0.015em; color: var(--fg);
}
.m3-consent__sub { margin: 7px 0 0; font-size: 13px; color: var(--fg-muted); }
.m3-consent__foot { display: flex; gap: 10px; margin-top: 22px; }

.m3-scopes { list-style: none; margin: 20px 0 0; padding: 0; }
.m3-scope {
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 13px 0;
  border-bottom: 1px solid var(--border);
}
.m3-scope:last-child { border-bottom: 0; }
.m3-scope__n { font-size: 13.5px; font-weight: 620; color: var(--fg); }
.m3-scope__d { margin-top: 3px; font-size: 12.5px; line-height: 1.45; color: var(--fg-muted); }

.m3-toggle {
  flex: 0 0 auto;
  width: 46px; height: 27px; padding: 3px;
  border-radius: var(--md-sys-shape-corner-full);
  border: 0; background: var(--ink-100, #e6e6e2);
  cursor: pointer;
  display: flex; align-items: center;
  transition: background var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.m3-toggle__knob {
  width: 21px; height: 21px; border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.22);
  transition: transform 420ms var(--md-sys-motion-easing-standard);
}
.m3-toggle.is-on { background: var(--md-sys-color-primary); }
.m3-toggle.is-on .m3-toggle__knob { transform: translateX(19px); }

.m3-jit {
  max-width: 470px;
  padding: 18px 20px 16px;
  border-radius: 6px 20px 20px 20px;
  background: color-mix(in oklab, var(--md-sys-color-secondary-container) 70%, #fff);
  border: 1px solid color-mix(in oklab, var(--md-sys-color-primary) 22%, transparent);
}
.m3-jit__row { display: flex; gap: 11px; align-items: flex-start; }
.m3-jit__dot {
  flex: 0 0 auto; margin-top: 6px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--md-sys-color-primary);
}
.m3-jit__text { margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--fg-alt); }
.m3-jit__text b { color: var(--fg); font-weight: 640; }
.m3-jit__foot { display: flex; gap: 8px; margin-top: 15px; flex-wrap: wrap; }

.m3-granted {
  max-width: 470px; padding: 18px 20px;
  border-radius: 14px;
  border: 1px solid var(--border); background: #fff;
}
.m3-granted__head {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
}
.m3-granted__t { font-size: 12.5px; font-weight: 640; color: var(--fg); }
.m3-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.m3-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 5px 6px 5px 12px; border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container);
  font-size: 12px; font-weight: 580;
}
.m3-chip--off {
  padding-right: 12px;
  background: var(--ink-50); color: var(--fg-muted);
}
.m3-chip__x {
  width: 17px; height: 17px; border-radius: 50%;
  border: 0; background: transparent; color: inherit;
  font: inherit; font-size: 13px; line-height: 1;
  cursor: pointer; opacity: 0.6;
}
.m3-chip__x:hover { opacity: 1; background: rgba(0,0,0,0.07); }

/* ── Caveat ───────────────────────────────────────────── */
.m3-answer { max-width: 540px; }
.m3-answer__text { margin: 0; font-size: 14.5px; line-height: 1.65; color: var(--fg-alt); }
.m3-answer__text b { color: var(--fg); font-weight: 650; }

/* Sharp corners (6px), amber ground: this is data ABOUT the
   answer, and it shares its hue with citations on purpose. */
.m3-caveat {
  display: flex; gap: 11px; align-items: flex-start;
  margin-top: 16px; padding: 14px 16px;
  border-radius: 6px;
  border-left: 3px solid var(--md-sys-color-outline);
  background: color-mix(in oklab, var(--md-sys-color-surface-container) 75%, #fff);
}
.m3-caveat__ico {
  flex: 0 0 auto; margin-top: 1px;
  width: 16px; height: 16px;
  fill: none; stroke: var(--md-sys-color-on-surface-variant); stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
.m3-caveat__t { margin: 0; font-size: 13px; font-weight: 650; color: var(--md-sys-color-on-surface-variant); }
.m3-caveat__d { margin: 5px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--fg-alt); }

.m3-stamp {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 7px 8px 7px 13px; border-radius: 6px;
  background: color-mix(in oklab, var(--md-sys-color-surface-container) 80%, #fff);
  border: 1px solid color-mix(in oklab, var(--md-sys-color-outline) 22%, transparent);
  font-size: 12.5px; color: var(--fg-alt);
}
.m3-stamp__dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--md-sys-color-outline);
}
.m3-stamp__text b { color: var(--fg); font-weight: 640; }

/* The flag marks ONE clause. Underline rather than highlight so the
   sentence still reads as a sentence. */
.m3-flag {
  border-bottom: 2px dotted var(--md-sys-color-outline);
  color: var(--fg); cursor: help;
}
.m3-flag__note {
  display: block; margin-top: 12px;
  padding: 11px 14px; border-radius: 6px;
  background: color-mix(in oklab, var(--md-sys-color-surface-container) 80%, #fff);
  border-left: 3px solid var(--md-sys-color-outline);
  font-size: 12.5px; line-height: 1.55; color: var(--fg-alt);
}

@media (prefers-reduced-motion: reduce) {
  .m3-btn, .m3-toggle, .m3-toggle__knob { transition: none; }
  .m3-btn:active { transform: none; }
}


/* ════════════════════════════════════════════════════════════
   IDENTITY — Avatar · Name · Personality · Iconography · Color

   The five patterns in this category answer one question between
   them: who is speaking. Trust & Disclosure says "this is a
   machine"; Identity says "and this is WHICH machine, every time
   you meet it".

   Everything here is drawn in the neural expressive language:
   colour carries state rather than decorating it, one glyph is
   reserved for generation and never spent elsewhere, shape
   separates the agent's surfaces from the person's, and motion
   appears only where something is genuinely happening. Every
   value resolves to a --md-sys-* token; there are no literal
   colours in this block.
   ════════════════════════════════════════════════════════════ */

/* ── The agent mark ───────────────────────────────────────
   Primary-container ground with the reserved glyph in primary.
   A container role, not primary itself: the mark identifies, it
   does not call for a press, and M3 keeps those two apart. */
.md-agentav {
  flex: 0 0 auto; position: relative;
  width: 40px; height: 40px;
  border-radius: var(--md-sys-shape-corner-full);
  display: grid; place-items: center;
  background: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
  font-family: var(--md-ref-typeface-plain);
  font-size: var(--md-sys-typescale-title-medium-size);
  font-weight: var(--md-sys-typescale-title-medium-weight);
}
.md-agentav svg { width: 20px; height: 20px; fill: var(--md-sys-color-primary); }
.md-agentav--sm { width: 28px; height: 28px; font-size: var(--md-sys-typescale-label-medium-size); }
.md-agentav--sm svg { width: 15px; height: 15px; }
.md-agentav--lg { width: 56px; height: 56px; }
.md-agentav--lg svg { width: 28px; height: 28px; }

/* The person's mark is deliberately a different ROLE, not a
   different shade of the same one: a reader separates the two at
   a glance without having to compare hues. */
.md-agentav--human {
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface-variant);
}
.md-agentav--human svg { fill: var(--md-sys-color-on-surface-variant); }

/* State on the mark. The ring is the only animation in this
   category, and it runs only while the agent is actually
   working — motion here is a status, not a flourish. */
.md-agentav--thinking::after {
  content: ""; position: absolute; inset: -4px;
  border-radius: var(--md-sys-shape-corner-full);
  border: 2px solid var(--md-sys-color-primary);
  opacity: 0.55;
  animation: md-agentav-pulse 1600ms var(--md-sys-motion-easing-standard) infinite;
}
@keyframes md-agentav-pulse {
  0%   { transform: scale(0.92); opacity: 0.55; }
  70%  { transform: scale(1.08); opacity: 0;    }
  100% { transform: scale(1.08); opacity: 0;    }
}
.md-agentav--muted { background: var(--md-sys-color-surface-container-high); }
.md-agentav--muted svg { fill: var(--md-sys-color-outline); }

/* ── Identity row / card ──────────────────────────────────── */
.md-idrow { display: flex; align-items: center; gap: 12px; }
.md-idrow + .md-idrow { margin-top: 12px; }
.md-idrow__name {
  margin: 0; color: var(--md-sys-color-on-surface);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.md-idrow__sub { margin: 2px 0 0; color: var(--md-sys-color-on-surface-variant); }

.md-idcard {
  max-width: 440px; padding: 20px;
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container-lowest);
  border: 1px solid var(--md-sys-color-outline-variant);
}
.md-idcard__head { display: flex; align-items: center; gap: 16px; }
.md-idcard__name { margin: 0; color: var(--md-sys-color-on-surface); }
.md-idcard__role { margin: 2px 0 0; color: var(--md-sys-color-on-surface-variant); }
.md-idcard__foot {
  display: flex; align-items: center; gap: 8px;
  margin-top: 16px; padding-top: 14px;
  border-top: 1px solid var(--md-sys-color-outline-variant);
}
.md-idcard__spacer { margin-left: auto; }

/* ── State specimen strip ─────────────────────────────────── */
.md-states { display: flex; gap: 28px; flex-wrap: wrap; }
.md-state { display: grid; justify-items: center; gap: 8px; }
.md-state__label {
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-ref-typeface-plain);
}

/* ── Voice card (Personality) ─────────────────────────────── */
.md-voice {
  max-width: 480px; padding: 20px;
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container-lowest);
  border: 1px solid var(--md-sys-color-outline-variant);
}
.md-voice__k {
  display: inline-flex; align-items: center; gap: 6px;
  height: 24px; padding: 0 10px;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}
.md-voice__title { margin: 12px 0 0; color: var(--md-sys-color-on-surface); }
.md-voice__list { list-style: none; margin: 14px 0 0; padding: 0; }
.md-voice__list li {
  display: flex; gap: 12px; align-items: flex-start; padding: 5px 0;
  color: var(--md-sys-color-on-surface-variant);
}
.md-voice__tick {
  flex: 0 0 auto; width: 16px; height: 16px; margin-top: 2px;
  fill: none; stroke: var(--md-sys-color-primary);
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
}
.md-voice__tick--no { stroke: var(--md-sys-color-outline); }
/* The sample is set against the rules, not beside them: a voice
   defined only in adjectives is a voice nobody can implement. */
.md-voice__sample {
  margin: 16px 0 0; padding: 12px 14px;
  border-left: 3px solid var(--md-sys-color-primary);
  border-radius: var(--md-sys-shape-corner-extra-small);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
}

/* ── Register comparison ──────────────────────────────────── */
.md-registers {
  display: grid; gap: 12px; max-width: 560px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.md-register {
  padding: 14px 16px;
  border-radius: var(--md-sys-shape-corner-medium);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container-lowest);
}
.md-register--on {
  border-color: transparent;
  background: var(--md-sys-color-secondary-container);
}
.md-register__k {
  display: block; margin-bottom: 6px;
  color: var(--md-sys-color-on-surface-variant);
  text-transform: uppercase; letter-spacing: 0.08em;
}
.md-register--on .md-register__k { color: var(--md-sys-color-on-secondary-container); }
.md-register__t { margin: 0; color: var(--md-sys-color-on-surface); }

/* ── Reserved glyph set (Iconography) ─────────────────────── */
.md-icons { display: flex; gap: 16px; flex-wrap: wrap; }
.md-icontile { display: grid; justify-items: center; gap: 8px; width: 92px; }
.md-icontile__box {
  width: 56px; height: 56px;
  border-radius: var(--md-sys-shape-corner-large);
  display: grid; place-items: center;
  background: var(--md-sys-color-surface-container);
}
.md-icontile__box svg { width: 24px; height: 24px; fill: var(--md-sys-color-primary); }
.md-icontile__box--tonal { background: var(--md-sys-color-secondary-container); }
.md-icontile__box--tonal svg { fill: var(--md-sys-color-on-secondary-container); }
.md-icontile__box--filled { background: var(--md-sys-color-primary); }
.md-icontile__box--filled svg { fill: var(--md-sys-color-on-primary); }
.md-icontile__label {
  color: var(--md-sys-color-on-surface-variant); text-align: center;
}

/* A menu is where "reserved" is provable: the AI rows carry the
   glyph, the others carry their own icons, and nobody has to be
   told which is which. */
.md-menu {
  max-width: 320px; padding: 8px;
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-low);
  box-shadow: var(--md-sys-elevation-2);
}
.md-menu__item {
  display: flex; align-items: center; gap: 12px;
  height: 40px; padding: 0 12px;
  border-radius: var(--md-sys-shape-corner-small);
  color: var(--md-sys-color-on-surface);
}
.md-menu__item svg {
  width: 18px; height: 18px; flex: 0 0 auto;
  fill: none; stroke: var(--md-sys-color-on-surface-variant);
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.md-menu__item--ai svg { fill: var(--md-sys-color-primary); stroke: none; }
.md-menu__rule {
  height: 1px; margin: 6px 12px;
  background: var(--md-sys-color-outline-variant);
}

/* ── Reserved colour roles (Color) ────────────────────────── */
.md-swatches { display: flex; gap: 12px; flex-wrap: wrap; }
.md-swatch { width: 116px; }
.md-swatch__chip {
  height: 56px; border-radius: var(--md-sys-shape-corner-medium);
  border: 1px solid var(--md-sys-color-outline-variant);
}
.md-swatch__chip--primary   { background: var(--md-sys-color-primary);           border-color: transparent; }
.md-swatch__chip--container { background: var(--md-sys-color-primary-container);  border-color: transparent; }
.md-swatch__chip--secondary { background: var(--md-sys-color-secondary-container);border-color: transparent; }
.md-swatch__chip--tertiary  { background: var(--md-sys-color-tertiary-container); border-color: transparent; }
.md-swatch__use { display: block; margin-top: 8px; color: var(--md-sys-color-on-surface); }
.md-swatch__tok {
  display: block; margin-top: 2px;
  color: var(--md-sys-color-on-surface-variant);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
}

/* Two bubbles, two roles. This is the whole argument for a
   reserved colour: the reader knows which one the machine wrote
   before reading a word of either. */
.md-turns { display: grid; gap: 10px; max-width: 480px; }
.md-bubble {
  padding: 12px 16px; max-width: 82%;
  color: var(--md-sys-color-on-surface);
}
.md-bubble--human {
  justify-self: end; text-align: left;
  background: var(--md-sys-color-surface-container-high);
  border-radius: var(--md-sys-shape-corner-large) var(--md-sys-shape-corner-large)
                 var(--md-sys-shape-corner-extra-small) var(--md-sys-shape-corner-large);
}
.md-bubble--agent {
  justify-self: start;
  background: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
  border-radius: var(--md-sys-shape-corner-large) var(--md-sys-shape-corner-large)
                 var(--md-sys-shape-corner-large) var(--md-sys-shape-corner-extra-small);
}

/* Presence, not decoration: the outline appears while the agent
   is in the surface and goes when it leaves. */
.md-presence {
  max-width: 480px; padding: 16px;
  border-radius: var(--md-sys-shape-corner-large);
  border: 2px solid var(--md-sys-color-primary);
  background: var(--md-sys-color-surface-container-lowest);
}
.md-presence__head { display: flex; align-items: center; gap: 10px; }
.md-presence__dot {
  width: 8px; height: 8px; flex: 0 0 auto;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-primary);
}
.md-presence__label { color: var(--md-sys-color-primary); }
.md-presence__body { margin: 10px 0 0; color: var(--md-sys-color-on-surface-variant); }

@media (prefers-reduced-motion: reduce) {
  .md-agentav--thinking::after { animation: none; opacity: 0.55; transform: none; }
}

/* Two identity rows share a left edge only if something establishes
   one. The live stage centres its content, so without this wrapper
   the wider row pushes its own avatar left of the narrower row's and
   the marks stop reading as a set. */
.md-idstack { display: grid; gap: 16px; }
.md-idstack .md-idrow + .md-idrow { margin-top: 0; }


/* ════════════════════════════════════════════════════════════
   CAPABILITY DISCOVERY — Example Gallery · Templates · Nudges ·
   Disclaimer

   Identity answers "who is speaking". This category answers the
   question immediately after it: "and what can it do for me?"
   All four exist because a blank input is a terrible interface
   for a system whose range nobody can guess — and because the
   honest half of that answer is the part about what it CANNOT
   do, which is why Disclaimer sits in the same set as the three
   patterns that sell the capability.

   Every value resolves to a --md-sys-* token.
   ════════════════════════════════════════════════════════════ */

/* ── Example gallery ──────────────────────────────────────
   Worked examples, each showing the ask AND what came back.
   A gallery of prompts alone teaches phrasing; a gallery of
   results teaches range, which is the thing being discovered. */
/* A definite width, not a shrink-wrap: the stage centres its child,
   so without `width: 100%` the auto-fit grid resolves to a single
   column at content width and the Layout control moves nothing. */
.md-gallery { display: grid; gap: 12px; width: 100%; max-width: 620px; }
.md-gallery__filters { display: flex; gap: 8px; flex-wrap: wrap; }
.md-filter {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 14px;
  border-radius: var(--md-sys-shape-corner-small);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: transparent;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-ref-typeface-plain);
  font-size: var(--md-sys-typescale-label-large-size);
  font-weight: var(--md-sys-typescale-label-large-weight);
  cursor: pointer;
  transition: background-color var(--md-sys-motion-duration-short4)
              var(--md-sys-motion-easing-standard);
}
.md-filter:hover {
  background: color-mix(in srgb, var(--md-sys-color-on-surface)
    calc(var(--md-sys-state-hover-opacity) * 100%), transparent);
}
/* M3 filter chips carry a leading tick when selected — the state is
   never colour alone. */
.md-filter.is-on {
  background: var(--md-sys-color-secondary-container);
  border-color: transparent;
  color: var(--md-sys-color-on-secondary-container);
}
.md-filter__tick { width: 0; height: 18px; overflow: hidden;
  fill: none; stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
  transition: width var(--md-sys-motion-duration-short4)
              var(--md-sys-motion-easing-emphasized); }
.md-filter.is-on .md-filter__tick { width: 18px; }

.md-grid {
  display: grid; gap: 10px;
  /* 180px, not 240: the stage is ~390px wide once the Customize
     panel is open, and 240 could not fit two columns there — so Grid
     and List rendered identically exactly where a reader compares
     them. Empty tracks collapse, so a two-example gallery still
     shows two equal columns at full width. */
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
/* List is one column, whatever the width — for a gallery whose
   examples are long enough that two of them side by side stop being
   readable. Below ~370px the grid has already collapsed to one column
   on its own, so the column count alone cannot carry the difference:
   a list row also turns the card sideways, putting the category in a
   leading column instead of stacked above the ask. */
.md-gallery[data-layout="list"] .md-grid { grid-template-columns: 1fr; }
.md-gallery[data-layout="list"] .md-ex {
  display: grid; grid-template-columns: auto 1fr;
  column-gap: 12px; align-items: baseline;
}
.md-gallery[data-layout="list"] .md-ex__k { margin-bottom: 0; }
.md-gallery[data-layout="list"] .md-ex__ask,
.md-gallery[data-layout="list"] .md-ex__out,
.md-gallery[data-layout="list"] .md-ex__use { grid-column: 2; }

.md-ex {
  display: block; width: 100%; text-align: left;
  padding: 14px 16px;
  border-radius: var(--md-sys-shape-corner-large);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container-lowest);
  cursor: pointer; font-family: var(--md-ref-typeface-plain);
  transition: box-shadow var(--md-sys-motion-duration-short4)
                var(--md-sys-motion-easing-standard),
              transform var(--md-sys-motion-duration-short4)
                var(--md-sys-motion-easing-standard),
              background-color var(--md-sys-motion-duration-short4)
                var(--md-sys-motion-easing-standard);
}
.md-ex:hover { box-shadow: var(--md-sys-elevation-2); transform: translateY(-2px); }
.md-ex:active { transform: translateY(0) scale(0.995); }
.md-ex__k {
  display: inline-block; margin-bottom: 8px;
  padding: 2px 8px; border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  font-size: var(--md-sys-typescale-label-small-size); font-weight: 600;
}
.md-ex__ask { margin: 0; color: var(--md-sys-color-on-surface); font-weight: 550; }
.md-ex__out {
  margin: 8px 0 0; padding-top: 8px;
  border-top: 1px dashed var(--md-sys-color-outline-variant);
  color: var(--md-sys-color-on-surface-variant);
}
.md-ex__use {
  display: inline-flex; align-items: center; gap: 5px;
  margin-top: 10px; color: var(--md-sys-color-primary);
  font-size: var(--md-sys-typescale-label-medium-size); font-weight: 600;
}

/* The opened example: the full ask, the full result, and the one
   control that matters — put it in my composer. */
.md-ex-open {
  max-width: 560px; padding: 20px;
  border-radius: var(--md-sys-shape-corner-extra-large);
  background: var(--md-sys-color-surface-container-lowest);
  border: 1px solid var(--md-sys-color-outline-variant);
  box-shadow: var(--md-sys-elevation-2);
}
.md-ex-open__ask {
  margin: 10px 0 0; padding: 12px 14px;
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
}
.md-ex-open__out { margin: 14px 0 0; color: var(--md-sys-color-on-surface-variant); }
.md-ex-open__foot {
  display: flex; align-items: center; gap: 8px;
  margin-top: 18px; padding-top: 14px;
  border-top: 1px solid var(--md-sys-color-outline-variant);
}

/* ── Templates ────────────────────────────────────────────
   A sentence with slots. The scaffold is the teaching: it shows
   which decisions a good request has to make, and refuses to
   let the user forget one. */
.md-tpl {
  max-width: 560px; padding: 20px;
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container-lowest);
  border: 1px solid var(--md-sys-color-outline-variant);
}
.md-tpl__name { margin: 0; color: var(--md-sys-color-on-surface); }
.md-tpl__desc { margin: 4px 0 0; color: var(--md-sys-color-on-surface-variant); }
.md-tpl__line {
  margin: 16px 0 0; padding: 14px 16px;
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
  line-height: 2.1;
}
/* An empty slot is dashed and reads as a gap; a filled one is a
   solid tonal chip. The difference is shape and weight, not hue. */
.md-slot {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; margin: 0 2px;
  border-radius: var(--md-sys-shape-corner-small);
  border: 1px dashed var(--md-sys-color-outline);
  background: transparent;
  color: var(--md-sys-color-on-surface-variant);
  font: inherit; cursor: pointer;
  transition: background-color var(--md-sys-motion-duration-short4)
                var(--md-sys-motion-easing-standard),
              border-color var(--md-sys-motion-duration-short4)
                var(--md-sys-motion-easing-standard);
}
.md-slot:hover { border-color: var(--md-sys-color-primary); }
.md-slot.is-set {
  border-style: solid; border-color: transparent;
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  font-weight: 550;
}
.md-slot__caret {
  width: 12px; height: 12px; fill: none; stroke: currentColor;
  stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
}
.md-tpl__foot {
  display: flex; align-items: center; gap: 8px; margin-top: 16px;
}
.md-tpl__count { margin-left: auto; color: var(--md-sys-color-on-surface-variant); }

.md-tpl-list { display: grid; gap: 8px; max-width: 520px; }
.md-tpl-row {
  display: flex; align-items: center; gap: 14px; width: 100%;
  padding: 13px 16px; text-align: left;
  border-radius: var(--md-sys-shape-corner-medium);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container-lowest);
  font-family: var(--md-ref-typeface-plain); cursor: pointer;
  transition: background-color var(--md-sys-motion-duration-short4)
              var(--md-sys-motion-easing-standard);
}
.md-tpl-row:hover { background: var(--md-sys-color-surface-container); }
.md-tpl-row__n { display: block; color: var(--md-sys-color-on-surface); font-weight: 600; }
.md-tpl-row__d { display: block; margin-top: 2px; color: var(--md-sys-color-on-surface-variant); }
.md-tpl-row__go {
  margin-left: auto; flex: 0 0 auto; width: 18px; height: 18px;
  fill: none; stroke: var(--md-sys-color-on-surface-variant);
  stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round;
}

/* ── Nudge ────────────────────────────────────────────────
   Small, anchored to the thing it is about, and genuinely
   dismissible. The tail is what makes it a nudge rather than a
   notification: it points at the control it is describing. */
.md-nudge {
  position: relative; max-width: 340px;
  padding: 14px 16px 12px;
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
  box-shadow: var(--md-sys-elevation-2);
  animation: md-nudge-in 320ms var(--md-sys-motion-easing-emphasized) both;
}
@keyframes md-nudge-in {
  from { opacity: 0; transform: translateY(6px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}
.md-nudge::after {
  content: ""; position: absolute; left: 26px; bottom: -6px;
  width: 12px; height: 12px; transform: rotate(45deg);
  background: var(--md-sys-color-primary-container);
}
.md-nudge--above::after { bottom: auto; top: -6px; }
.md-nudge__head { display: flex; align-items: flex-start; gap: 10px; }
.md-nudge__ico { flex: 0 0 auto; width: 18px; height: 18px; margin-top: 1px;
  fill: var(--md-sys-color-primary); }
.md-nudge__t { margin: 0; font-weight: 620; }
.md-nudge__d { margin: 4px 0 0; opacity: 0.86; }
.md-nudge__foot { display: flex; align-items: center; gap: 6px; margin-top: 12px; }
.md-nudge__x {
  margin-left: auto; width: 26px; height: 26px; border: 0; border-radius: 50%;
  background: transparent; color: inherit; cursor: pointer;
  display: grid; place-items: center; font-size: 15px; line-height: 1; opacity: 0.7;
}
.md-nudge__x:hover { opacity: 1; background: rgba(0,0,0,0.07); }
.md-nudge .md-button--text { color: var(--md-sys-color-on-primary-container); }

/* The quietest form: a hint riding on the control itself, for
   surfaces where a floating card would be too much. */
.md-hint {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px 6px 10px;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface-variant);
}
.md-hint__dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--md-sys-color-primary);
}

/* ── Disclaimer ───────────────────────────────────────────
   The standing statement of limits. Full form once, compact
   form forever after — and the compact form must reopen the
   full one, or the limits have been said and then hidden. */
.md-disclaim {
  max-width: 440px; padding: 24px;
  border-radius: var(--md-sys-shape-corner-extra-large);
  background: var(--md-sys-color-surface-container-high);
  box-shadow: var(--md-sys-elevation-3);
}
.md-disclaim__ico {
  display: block; width: 24px; height: 24px; margin: 0 auto 16px;
  fill: var(--md-sys-color-secondary);
}
.md-disclaim__t { margin: 0; text-align: center; color: var(--md-sys-color-on-surface); }
.md-disclaim__b { margin: 14px 0 0; color: var(--md-sys-color-on-surface-variant); }
.md-disclaim__list { list-style: none; margin: 18px 0 0; padding: 0; display: grid; gap: 10px; }
.md-disclaim__list li {
  display: grid; grid-template-columns: 74px minmax(0, 1fr); gap: 12px;
  align-items: baseline;
  color: var(--md-sys-color-on-surface-variant);
}
/* Can / Cannot / Does not know as three labelled rows rather than a
   paragraph: the middle one is the row people actually need, and in
   prose it is the row they skip. */
.md-disclaim__k {
  color: var(--md-sys-color-on-surface); font-weight: 640;
}
.md-disclaim__foot {
  display: flex; justify-content: flex-end; gap: 8px; margin-top: 22px;
}

/* The line IS the control. A second labelled button beside it was
   longer than the reminder itself and wrapped badly at the sizes this
   actually ships in — and the whole line is a bigger, easier target
   than the label ever was. */
.md-disclaim-line {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 14px;
  border: 0; border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface-variant);
  text-align: left; cursor: pointer;
  /* Typography stated in tokens rather than `font: inherit`. As a
     <button> this element carries a UA font, and the shorthand was
     beating the .md-body-small class it is marked up with — so the
     reminder rendered at whatever size its parent happened to use.
     Body-small is the size this pattern is specified at everywhere:
     a caption, never a paragraph. */
  font-family: var(--md-ref-typeface-plain);
  font-size: var(--md-sys-typescale-body-small-size);
  line-height: var(--md-sys-typescale-body-small-line);
  letter-spacing: var(--md-sys-typescale-body-small-tracking);
  font-weight: 400;
  transition: background-color var(--md-sys-motion-duration-short4)
              var(--md-sys-motion-easing-standard);
}
.md-disclaim-line:hover {
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
}
.md-disclaim-line__ico { width: 15px; height: 15px; flex: 0 0 auto;
  fill: var(--md-sys-color-on-surface-variant); }

@media (prefers-reduced-motion: reduce) {
  .md-disclaim-line { transition: none; }
}

@media (prefers-reduced-motion: reduce) {
  .md-ex, .md-filter, .md-filter__tick, .md-slot, .md-tpl-row { transition: none; }
  .md-nudge { animation: none; }
}


/* ── Caveat ───────────────────────────────────────────────
   The quietest pattern in the library, and deliberately so.
   It is a standing condition of the medium — generated output
   can be wrong — not a fault, so it never takes the error role
   and never animates. Caption size, muted, one per surface.

   Colouring this like an error would make people discount the
   real errors, which is the opposite of what it is for. */
.md-caveat {
  display: flex; align-items: flex-start; gap: 7px;
  margin: 10px 0 0; max-width: 56ch;
  color: var(--md-sys-color-on-surface-variant);
}
.md-caveat__ico {
  flex: 0 0 auto; width: 13px; height: 13px; margin-top: 2px;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
/* Under output the reminder gets a ground, because it has to
   separate from the content it qualifies. Next to an input it does
   not — there is nothing to separate from. */
.md-caveat--boxed {
  margin-top: 14px; padding: 9px 12px;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface-container);
}

/* Caution is the exception, not the register. It borrows the TERTIARY
   role rather than error: the output is not wrong, it is unverified,
   and painting every caption red teaches readers to discount the real
   errors — which is the opposite of what this pattern is for.

   Two cues, because one was not enough. The first attempt coloured the
   text alone with on-tertiary-container, and against on-surface-variant
   that is two dark greys at caption size: the setting was reaching the
   markup and changing nothing anybody could see. So the inline form
   also takes a leading rule in the same role — colour AND shape, which
   is the rule the rest of this library follows anyway. */
.md-caveat--caution {
  color: var(--md-sys-color-tertiary);
}
.md-caveat--caution .md-caveat__ico { stroke-width: 2.2; }

/* Inline: no ground of its own, so the rule carries it. */
.md-caveat--caution:not(.md-caveat--boxed) {
  padding: 4px 0 4px 10px;
  border-inline-start: 2px solid var(--md-sys-color-tertiary);
}

/* Boxed: the ground moves from neutral to the tertiary container, and
   the text takes the on- role that ground is paired with. */
.md-caveat--caution.md-caveat--boxed {
  background: var(--md-sys-color-tertiary-container);
  color: var(--md-sys-color-on-tertiary-container);
}

.md-composer {
  max-width: 520px; padding: 14px 16px 12px;
  border-radius: var(--md-sys-shape-corner-large);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container-lowest);
}
.md-composer__field {
  margin: 0; padding: 10px 14px;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface-variant);
}

/* The tooltip form: shown on hover AND focus, because a caveat only
   reachable with a mouse is a caveat some users never get. */
.md-caveat-action { display: inline-flex; align-items: center; gap: 10px; }
.md-caveat-tip {
  display: inline-flex; align-items: center;
  padding: 6px 12px;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface-variant);
}


/* ════════════════════════════════════════════════════════════
   INITIALLY · ENTRY POINTS

   The eight doors into the agent. Three rules run through all of
   them and are worth stating once here rather than eight times
   below:

   SHAPE CARRIES HIERARCHY. Capsule is the human's action —
   the CTA, send, a chosen suggestion, the dice. Rounded (18–28dp)
   is a surface the agent speaks from. Sharp (4–8dp) is data the
   reader is meant to verify: the filter chips that say how a
   query was understood are 8dp for exactly that reason.

   MOTION MATCHES CAUSALITY. A user-initiated change springs; a
   system-initiated one arrives on emphasized easing, from below.
   Nothing here uses `transition: all`, and every ambient loop
   stops under prefers-reduced-motion.

   CERTAINTY IS EDGE DEFINITION. Content the agent is still
   producing is not boxed. It sits on a tinted ground with a soft
   edge, and the boundary resolves as the thing settles.
   ════════════════════════════════════════════════════════════ */

/* ── Initial CTA ──────────────────────────────────────────
   The single saturated element in an otherwise empty view. It is
   allowed to be the largest thing on the screen because it is the
   only thing on the screen. */
.md-cta {
  max-width: 520px; margin: 0 auto; text-align: center;
  padding: 32px 28px;
  border-radius: var(--md-sys-shape-corner-extra-large);
  background: var(--md-sys-color-surface-container-low);
  border: 1px solid var(--md-sys-color-outline-variant);
}
.md-cta__ico {
  width: 32px; height: 32px;
  fill: var(--md-sys-color-primary);
  /* Awake, not asking for attention: one very slow breath, and
     none at all when the reader has said they do not want it. */
  animation: md-cta-breathe 18s ease-in-out infinite;
}
@keyframes md-cta-breathe {
  0%, 100% { opacity: 0.86; transform: scale(1); }
  50%      { opacity: 1;    transform: scale(1.04); }
}
.md-cta__t { margin: 12px 0 0; color: var(--md-sys-color-on-surface); }
.md-cta__d {
  margin: 8px auto 0; max-width: 42ch;
  color: var(--md-sys-color-on-surface-variant);
}
.md-cta__foot {
  display: flex; justify-content: center; align-items: center;
  gap: 8px; flex-wrap: wrap; margin-top: 22px;
}
.md-cta--quiet {
  background: transparent; border-style: dashed;
}

/* ── Open Input ───────────────────────────────────────────
   A capsule, because sending a request is the reader's action.
   Focus is one property changing colour, not a glow. */
.md-entry {
  display: flex; align-items: center; gap: 10px;
  max-width: 560px; padding: 5px 5px 5px 16px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-lowest);
  transition: border-color 180ms var(--md-sys-motion-easing-standard);
}
.md-entry:focus-within { border-color: var(--md-sys-color-primary); }
.md-entry--busy { border-color: var(--md-sys-color-outline-variant); }
.md-entry__glyph {
  width: 18px; height: 18px; flex: 0 0 auto;
  fill: var(--md-sys-color-primary);
}
.md-entry__input {
  flex: 1 1 auto; min-width: 0;
  border: 0; background: transparent; font: inherit;
  color: var(--md-sys-color-on-surface); padding: 10px 0;
}
.md-entry__input:focus { outline: none; }
.md-entry__input::placeholder { color: var(--md-sys-color-on-surface-variant); }
.md-entry__send {
  flex: 0 0 auto; width: 36px; height: 36px; border: 0; cursor: pointer;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-primary);
  display: grid; place-items: center;
  transition: transform var(--mx-motion-spatial-duration) var(--mx-motion-spatial-easing);
}
.md-entry__send:active { transform: scale(0.92); }
.md-entry__send svg { width: 17px; height: 17px; fill: var(--md-sys-color-on-primary); }
/* Stop is the same control, retoned. The busy state belongs to the
   action; the field stays live so nobody loses what they typed. */
.md-entry__send--stop { background: var(--md-sys-color-secondary-container); }
.md-entry__send--stop svg { fill: var(--md-sys-color-on-secondary-container); }
.md-entry__hint {
  display: block; max-width: 560px; margin: 8px 2px 0;
  color: var(--md-sys-color-on-surface-variant);
}

/* ── Suggestion chip (M3) ─────────────────────────────────
   Kit Chips · Suggestion: 32dp, Corner/Small (8dp), Label Large in
   on-surface-variant, optional 18dp leading icon in primary (the
   padding drops to 8dp on the icon side), 48dp touch target.
   Outlined (1dp outline-variant) or Elevated (surface-container-low,
   level 1, no outline). States from the kit: an on-surface-variant
   layer at 8% hover, 10% focus, 10% pressed; level 2 on hover for
   Elevated; disabled at 38% / 12%. */
.md-suggestion-chip {
  position: relative; isolation: isolate; box-sizing: border-box;
  display: inline-flex; align-items: center; gap: 8px; max-width: 100%;
  height: 32px; padding: 0 16px; margin: 0;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small);
  background: transparent; color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-ref-typeface-plain);
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line);
  font-weight: var(--md-sys-typescale-label-large-weight);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
  white-space: nowrap; cursor: pointer; text-align: left;
  transition: background-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
              border-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
              box-shadow var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
              color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.md-suggestion-chip--icon { padding-left: 8px; }
.md-suggestion-chip > .mi.mi {
  width: 18px; height: 18px; flex: 0 0 auto; fill: var(--md-sys-color-primary);
}
.md-suggestion-chip > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.md-suggestion-chip--elevated {
  border-color: transparent;
  background: var(--md-sys-color-surface-container-low);
  box-shadow: var(--md-sys-elevation-1);
}
.md-suggestion-chip--elevated:hover { box-shadow: var(--md-sys-elevation-2); }

/* Entrance used by the filter chips below. */
@keyframes md-suggest-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* ── List item, interactive (M3) ─────────────────────────
   Kit Lists: one-line 56dp / two-line 72dp, 16dp leading and 24dp
   trailing padding, 16dp between a 24dp leading icon
   (on-surface-variant) and the text; headline Body Large in
   on-surface, supporting Body Medium in on-surface-variant. The whole
   row is the control; an on-surface layer at 8 / 10 / 10%. */
.md-list-row {
  position: relative; isolation: isolate; box-sizing: border-box;
  display: flex; align-items: center; gap: 16px; width: 100%;
  min-height: 56px; padding: 8px 24px 8px 16px; margin: 0;
  border: 0; border-radius: var(--md-sys-shape-corner-medium);
  background: transparent; color: var(--md-sys-color-on-surface);
  font-family: var(--md-ref-typeface-plain); text-align: left; cursor: pointer;
  transition: background-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.md-list-row > .mi.mi {
  width: 24px; height: 24px; flex: 0 0 auto; fill: var(--md-sys-color-on-surface-variant);
}

/* ── Card, outlined and actionable (M3) ──────────────────
   Kit Cards · Outlined: Corner/Medium (12dp), 1dp outline-variant on
   surface. The whole card is one control: an on-surface layer at
   8 / 10 / 10%, and the kit's 3dp focus ring. */
.md-card {
  position: relative; isolation: isolate; box-sizing: border-box;
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface);
}
.md-card--outlined { border: 1px solid var(--md-sys-color-outline-variant); }
.md-card--action {
  display: flex; align-items: flex-start; gap: 12px; width: 100%; margin: 0;
  padding: 12px 16px; font-family: var(--md-ref-typeface-plain);
  text-align: left; cursor: pointer;
  transition: background-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
              border-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.md-card--action > .mi.mi {
  width: 24px; height: 24px; flex: 0 0 auto; fill: var(--md-sys-color-primary);
}

/* The three share their states: a pseudo-element layer in the
   content colour, so it sits over any container colour. */
.md-suggestion-chip::before, .md-list-row::before, .md-card--action::before {
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  background: currentColor; opacity: 0; pointer-events: none;
  transition: opacity var(--mx-motion-fast-duration, 120ms) var(--md-sys-motion-easing-standard);
}
.md-suggestion-chip::after {
  content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 48px;
  transform: translateY(-50%);
}
.md-suggestion-chip:hover::before, .md-list-row:hover::before, .md-card--action:hover::before {
  opacity: var(--md-sys-state-hover-opacity);
}
/* Outlined suggestion chip, hover (user request, 1 Oct): a solid
   surface-container-high fill with the same outline-variant stroke,
   in place of the grey state layer. Focus and pressed keep their layer. */
.md-suggestion-chip:not(.md-suggestion-chip--elevated):not(:disabled):hover {
  background: var(--md-sys-color-surface-container-high);
  border-color: var(--md-sys-color-outline-variant);
}
.md-suggestion-chip:not(.md-suggestion-chip--elevated):not(:disabled):hover:not(:active):not(:focus-visible)::before { opacity: 0; }
.md-suggestion-chip:focus-visible::before, .md-list-row:focus-visible::before,
.md-card--action:focus-visible::before { opacity: var(--md-sys-state-focus-opacity); }
.md-suggestion-chip:active::before, .md-list-row:active::before,
.md-card--action:active::before { opacity: var(--md-sys-state-pressed-opacity); }
.md-suggestion-chip:focus-visible, .md-list-row:focus-visible, .md-card--action:focus-visible {
  outline: 3px solid var(--md-sys-color-secondary); outline-offset: 2px;
}
.md-suggestion-chip:disabled, .md-list-row:disabled, .md-card--action:disabled {
  cursor: default; color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
  border-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
}
.md-suggestion-chip:disabled::before, .md-list-row:disabled::before,
.md-card--action:disabled::before { opacity: 0; }

/* ── Icons ────────────────────────────────────────────────
   One glyph, one meaning. Violet wherever it is genuinely the
   agent, which is what makes an audit a matter of looking. */
.md-glyph { width: 16px; height: 16px; fill: currentColor; }
.md-field__row { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.md-field__input {
  flex: 1 1 auto; min-width: 0; border: 0; background: transparent;
  font: inherit; color: var(--md-sys-color-on-surface); padding: 2px 0;
}
.md-field__input:focus { outline: none; }
.md-field-glyph {
  flex: 0 0 auto; width: 32px; height: 32px; border: 0; cursor: pointer;
  border-radius: var(--md-sys-shape-corner-full);
  background: transparent; color: var(--md-sys-color-primary);
  display: grid; place-items: center;
  transition: background 180ms var(--md-sys-motion-easing-standard),
              transform var(--mx-motion-spatial-duration) var(--mx-motion-spatial-easing);
}
.md-field-glyph:hover  { background: var(--md-sys-color-primary-container); }
.md-field-glyph:active { transform: scale(0.94); }
/* Thinking is a hue rotation, never a spin: a spinner says wait,
   a hue shift says the agent is doing something. */
.md-glyph--thinking {
  animation: md-glyph-think 1.6s var(--mx-motion-effects-easing) infinite;
}
@keyframes md-glyph-think {
  0%, 100% { fill: var(--md-sys-color-primary); }
  50%      { fill: var(--md-sys-color-tertiary); }
}
.md-iconrow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.md-icononly {
  width: 36px; height: 36px; border-radius: var(--md-sys-shape-corner-full);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-primary);
  display: grid; place-items: center; cursor: pointer;
}
.md-icononly:hover { background: var(--md-sys-color-primary-container); }

/* ── Searching & Filtering ────────────────────────────────
   The query is a capsule; what it was understood as is 8dp,
   because those chips are evidence the reader has to check. */
.md-nlsearch {
  display: flex; align-items: center; gap: 10px;
  width: 100%; max-width: 560px; padding: 10px 16px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-lowest);
}
.md-nlsearch__ico { width: 18px; height: 18px; fill: var(--md-sys-color-on-surface-variant); }
.md-nlsearch__input {
  flex: 1 1 auto; min-width: 0; border: 0; background: transparent;
  font: inherit; color: var(--md-sys-color-on-surface);
}
.md-nlsearch__input:focus { outline: none; }
.md-applied {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  max-width: 560px; margin-top: 14px;
}
.md-applied__k { color: var(--md-sys-color-on-surface-variant); }
.md-applied__n { margin-left: auto; color: var(--md-sys-color-on-surface-variant); }
/* Evidence, in THIS palette, is carried by shape and edge rather
   than by hue. The expressive system reserves a third hue for
   grounding, but Material 3's tertiary is already spent here on
   Caveat's caution tone — and two meanings on one colour is exactly
   the failure the Iconography page argues against. So a filter chip
   is neutral, outlined and sharp: 8dp says "data you can check",
   and nothing else on the surface is 8dp. */
.md-fchip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 6px 5px 10px;
  border-radius: var(--md-sys-shape-corner-small);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
  animation: md-suggest-in 380ms var(--md-sys-motion-easing-emphasized) both;
}
.md-fchip:nth-of-type(2) { animation-delay: 50ms; }
.md-fchip:nth-of-type(3) { animation-delay: 100ms; }
.md-fchip button {
  border: 0; background: transparent; cursor: pointer; color: inherit;
  width: 18px; height: 18px; border-radius: var(--md-sys-shape-corner-full);
  line-height: 1; font-size: 15px;
  transition: transform var(--mx-motion-spatial-duration) var(--mx-motion-spatial-easing);
}
.md-fchip button:hover  { background: rgba(0, 0, 0, 0.08); }
.md-fchip button:active { transform: scale(0.85); }
.md-ignored {
  max-width: 560px; margin-top: 10px;
  color: var(--md-sys-color-on-surface-variant);
}

/* ── Autocomplete ─────────────────────────────────────────
   The ghost is the same face and size as the typed text, so it
   aligns to the pixel and separates on colour alone. */
.md-ghostfield {
  max-width: 560px; padding: 14px 16px;
  border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-sys-shape-corner-extra-small);
  background: var(--md-sys-color-surface-container-lowest);
}
.md-ghostfield__line { margin: 0; color: var(--md-sys-color-on-surface); }
.md-ghostfield__ghost {
  color: var(--md-sys-color-on-surface-variant);
  /* Accepting it is the one moment with motion: the boundary of
     certainty resolving as the words stop being the agent's. */
  transition: color 180ms var(--md-sys-motion-easing-standard);
}
.md-ghostfield__ghost--taken { color: var(--md-sys-color-on-surface); }
.md-ghostfield__caret {
  display: inline-block; width: 1.5px; height: 1em;
  vertical-align: text-bottom;
  background: var(--md-sys-color-primary);
  animation: md-caret 1s steps(2, start) infinite;
}
@keyframes md-caret { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }
.md-ghostfield__hint {
  margin: 10px 0 0; display: flex; align-items: center; gap: 6px;
  color: var(--md-sys-color-on-surface-variant);
}
.md-kbd {
  display: inline-block; padding: 1px 6px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-bottom-width: 2px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  background: var(--md-sys-color-surface-container);
  font-family: var(--md-ref-typeface-plain); font-size: 11px;
}

/* ── Proactive Suggestions ────────────────────────────────
   Rounded, not capsule: this is the agent speaking, and the only
   capsule in the card is the action it offers. It arrives on
   emphasized easing because the reader did not cause it. */
.md-proactive {
  max-width: 480px; padding: 16px 18px;
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
  animation: md-proactive-in 380ms var(--md-sys-motion-easing-emphasized) both;
}
@keyframes md-proactive-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.md-proactive__head { display: flex; gap: 10px; align-items: flex-start; }
.md-proactive__ico { width: 18px; height: 18px; flex: 0 0 auto; fill: currentColor; }
.md-proactive__obs { margin: 0; font-weight: 600; }
.md-proactive__offer { margin: 8px 0 0 28px; opacity: 0.86; }
.md-proactive__foot {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 16px 0 0 28px;
}
/* The quiet form, for surfaces too dense for a card. */
.md-proactive--line {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 8px 8px 8px 14px;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
}

/* ── Randomize ────────────────────────────────────────────
   The one place motion is allowed to be playful — and the reason
   nothing else on the screen moves while it does. */
.md-dice {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 18px; border: 0; cursor: pointer;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  font: inherit;
  transition: transform var(--mx-motion-spatial-duration) var(--mx-motion-spatial-easing);
}
.md-dice:active { transform: scale(0.94); }
.md-dice__ico { width: 18px; height: 18px; fill: currentColor; }
.md-dice.is-rolling .md-dice__ico {
  animation: md-dice-roll var(--mx-motion-spatial-duration) var(--mx-motion-spatial-easing);
}
@keyframes md-dice-roll {
  from { transform: rotate(0deg)   scale(1); }
  60%  { transform: rotate(240deg) scale(1.18); }
  to   { transform: rotate(360deg) scale(1); }
}
/* Settling: tinted ground, undefined edge. A roll is uncertain
   until it is a result, and the container says so. */
.md-roll {
  max-width: 520px; margin-top: 16px; padding: 16px 18px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container-lowest);
  transition: border-color 380ms var(--md-sys-motion-easing-emphasized),
              background 380ms var(--md-sys-motion-easing-emphasized);
}
.md-roll--settling {
  border-color: transparent;
  background: linear-gradient(180deg,
              var(--md-sys-color-primary-container), transparent);
}
.md-roll__k { margin: 0; color: var(--md-sys-color-on-surface-variant); }
.md-roll__v { margin: 8px 0 0; color: var(--md-sys-color-on-surface); }
.md-roll__foot {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 16px;
}

@media (prefers-reduced-motion: reduce) {
  .md-cta__ico, .md-fchip, .md-proactive,
  .md-glyph--thinking, .md-ghostfield__caret,
  .md-dice.is-rolling .md-dice__ico { animation: none; }
  .md-entry__send, .md-suggestion-chip, .md-list-row, .md-card--action,
  .md-suggestion-chip::before, .md-list-row::before, .md-card--action::before,
  .md-field-glyph, .md-dice,
  .md-roll, .md-ghostfield__ghost, .md-fchip button { transition: none; }
}


/* ════════════════════════════════════════════════════════════
   INITIALLY · EXPRESSIVE INPUT

   Five ways in that are not typing, and one property they all
   share: each is a GUESS about what somebody meant. Speech is
   transcribed, an image is interpreted, ink is recognised, a
   gesture is classified, an entity is resolved.

   So the visual rule is the same in all five: the agent's reading
   arrives at reduced emphasis and HARDENS when it becomes
   certain — the edge-of-certainty move used everywhere else in
   this system, applied to a transcript, a bounding box, a
   recognised word and a chip. Doubt is never a second hue; the
   system already has one colour for the agent, and adding
   another would make it mean something on every other screen.
   ════════════════════════════════════════════════════════════ */

/* ── Voice ────────────────────────────────────────────────
   Listening is the one honest use of an ambient loop in the
   system: the meter has to move with the voice, or a speaker
   cannot tell listening from frozen. */
.md-voice {
  display: flex; align-items: center; gap: 14px;
  max-width: 560px; padding: 12px 16px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-lowest);
  transition: border-color 200ms var(--md-sys-motion-easing-standard);
}
.md-voice[data-state="listening"] { border-color: var(--md-sys-color-secondary); }
.md-voice__mic {
  flex: 0 0 auto; width: 40px; height: 40px; border: 0; cursor: pointer;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface-variant);
  display: grid; place-items: center;
  transition: transform var(--mx-motion-spatial-duration) var(--mx-motion-spatial-easing),
              background 180ms var(--md-sys-motion-easing-standard);
}
.md-voice__mic svg { width: 20px; height: 20px; fill: currentColor; }
.md-voice__mic:active { transform: scale(0.92); }
/* Armed carries SECONDARY, not primary: this is the one state the
   product cannot enter on its own, so it wears the human's colour. */
.md-voice__mic.is-live {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}
.md-voice__meter { display: flex; align-items: center; gap: 3px; height: 22px; }
.md-voice__meter span {
  width: 3px; border-radius: 2px; height: 6px;
  background: var(--md-sys-color-secondary);
  animation: md-voice-level 900ms ease-in-out infinite;
}
.md-voice__meter span:nth-child(2) { animation-delay: 120ms; }
.md-voice__meter span:nth-child(3) { animation-delay: 240ms; }
.md-voice__meter span:nth-child(4) { animation-delay: 90ms; }
.md-voice__meter span:nth-child(5) { animation-delay: 300ms; }
@keyframes md-voice-level {
  0%, 100% { height: 6px; }
  50%      { height: 20px; }
}
.md-voice__partial {
  margin: 0; min-width: 0; flex: 1 1 auto;
  color: var(--md-sys-color-on-surface-variant);
}
.md-voice__final {
  max-width: 560px; margin-top: 14px; padding: 14px 16px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-lowest);
}
.md-voice__text {
  margin: 0 0 12px; color: var(--md-sys-color-on-surface);
  transition: color 180ms var(--md-sys-motion-easing-standard);
}
.md-voice__foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.md-voice__none {
  margin: 0; color: var(--md-sys-color-on-surface-variant);
}

/* Low-confidence words inside a final transcript. Doubt is a
   state of the READING, so it wears the agent's own colour as an
   underline rather than acquiring a hue of its own. */
.md-voice__doubt {
  border: 0; padding: 0 1px; font: inherit; cursor: pointer;
  background: transparent; color: inherit;
  border-bottom: 2px dotted var(--md-sys-color-primary);
  transition: background 160ms var(--md-sys-motion-easing-standard);
}
.md-voice__doubt:hover { background: var(--md-sys-color-primary-container); }
.md-voice__edit {
  width: 100%; box-sizing: border-box; margin: 0 0 12px; padding: 10px 12px;
  border: 1px solid var(--md-sys-color-primary);
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface-container-lowest);
  font: inherit; font-size: 14.5px; color: var(--md-sys-color-on-surface);
}

/* ── Voice session ────────────────────────────────────────
   A session has TWO stops, and they must not look alike: Hold
   turns your microphone off and the agent waits; Mute turns your
   microphone off and the agent carries on. Who holds the floor is
   said in words and carried by WHICH SURFACE IS MOVING — never by
   colour alone, because this gets read at a glance from a
   driver's seat. */
.md-vsess {
  display: grid; justify-items: center; gap: 10px; max-width: 560px;
  padding: 22px 20px 18px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container-lowest);
  text-align: center;
}
.md-vsess__orb {
  width: 68px; height: 68px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--md-sys-color-surface-container-high);
  border: 1px solid var(--md-sys-color-outline-variant);
}
.md-vsess__orb i {
  display: block; width: 26px; height: 26px; border-radius: 50%;
  background: var(--md-sys-color-outline-variant);
}
/* The person has the floor: the human colour, and the pulse is
   the one ambient loop in this pattern that is honest — in a real
   implementation it is driven by the signal, not by a clock. */
.md-vsess[data-floor="user"] .md-vsess__orb {
  background: var(--md-sys-color-secondary-container);
  border-color: var(--md-sys-color-secondary);
}
.md-vsess[data-floor="user"] .md-vsess__orb i {
  background: var(--md-sys-color-secondary);
  animation: md-vsess-pulse 1100ms var(--md-sys-motion-easing-standard) infinite;
}
.md-vsess[data-floor="agent"] .md-vsess__orb {
  background: var(--md-sys-color-primary-container);
  border-color: var(--md-sys-color-primary);
}
.md-vsess[data-floor="agent"] .md-vsess__orb i {
  background: var(--md-sys-color-primary);
  animation: md-vsess-speak 900ms var(--md-sys-motion-easing-standard) infinite;
}
/* Held and muted both mean "your microphone is off", and they are
   drawn differently because they are different intentions: held
   is still (nobody is talking), muted keeps the agent's surface
   moving (it has not stopped). */
.md-vsess[data-floor="held"] .md-vsess__orb i { background: var(--md-sys-color-outline); }
.md-vsess[data-floor="muted"] .md-vsess__orb {
  background: var(--md-sys-color-primary-container);
  border-color: var(--md-sys-color-primary);
}
.md-vsess[data-floor="muted"] .md-vsess__orb i {
  background: var(--md-sys-color-primary);
  animation: md-vsess-speak 900ms var(--md-sys-motion-easing-standard) infinite;
}
.md-vsess[data-floor="muted"] .md-vsess__orb::after,
.md-vsess[data-floor="held"] .md-vsess__orb::after {
  content: ''; position: absolute; width: 44px; height: 2px;
  background: var(--md-sys-color-on-surface); transform: rotate(-45deg);
  border-radius: 2px;
}
.md-vsess[data-floor="muted"] .md-vsess__orb,
.md-vsess[data-floor="held"] .md-vsess__orb { position: relative; overflow: hidden; }
@keyframes md-vsess-pulse {
  0%, 100% { transform: scale(1); opacity: .9; }
  50%      { transform: scale(1.35); opacity: 1; }
}
@keyframes md-vsess-speak {
  0%, 100% { transform: scaleX(1) scaleY(1); border-radius: 50%; }
  50%      { transform: scaleX(1.6) scaleY(.55); border-radius: 40%; }
}
.md-vsess__who {
  margin: 0; font-size: 14px; font-weight: 600;
  color: var(--md-sys-color-on-surface);
}
.md-vsess__line {
  margin: 0; max-width: 44ch;
  color: var(--md-sys-color-on-surface-variant);
}
/* A sentence that was cut off should LOOK cut off. Drawn rather
   than set in a glyph, because the glyph that means "stopped
   here" is not in every font the product will be read in. */
.md-vsess__line--cut::after {
  content: ''; display: inline-block; vertical-align: -1px;
  width: 3px; height: 13px; margin-left: 6px; border-radius: 2px;
  background: var(--md-sys-color-primary);
}
.md-vsess__ctrls { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 4px; }
.md-vsess__btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 18px; cursor: pointer; font: inherit; font-size: 13.5px;
  border-radius: var(--md-sys-shape-corner-full);
  border: 1px solid var(--md-sys-color-outline);
  background: transparent; color: var(--md-sys-color-on-surface);
  transition: background 160ms var(--md-sys-motion-easing-standard),
              color 160ms var(--md-sys-motion-easing-standard);
}
.md-vsess__btn:hover { background: var(--md-sys-color-surface-container-high); }
.md-vsess__btn.is-on {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  border-color: transparent;
}
.md-vsess__btn--end {
  border-color: transparent; background: var(--md-sys-color-error-container, #f9dedc);
  color: var(--md-sys-color-on-error-container, #410e0b);
}
.md-vsess__note {
  margin: 2px 0 0; max-width: 46ch;
  font-size: 12.5px; color: var(--md-sys-color-on-surface-variant);
}

/* ── Visual ───────────────────────────────────────────────
   The region the answer came from is the only tinted thing on
   the image, so "where it looked" needs no legend. */
.md-vis { margin: 0; max-width: 460px; }
.md-vis__frame {
  position: relative; border-radius: var(--md-sys-shape-corner-medium);
  overflow: hidden; border: 1px solid var(--md-sys-color-outline-variant);
}
.md-vis__img {
  aspect-ratio: 4 / 3; width: 100%;
  background:
    radial-gradient(circle at 36% 48%, #6b6f76 0 18%, transparent 19%),
    linear-gradient(155deg, #9aa0a6 0%, #6f747a 48%, #4a4e53 100%);
}
.md-vis__img::after {
  content: ""; position: absolute; left: 30%; top: 44%;
  width: 26%; height: 3px; border-radius: 2px;
  background: #2b2d30; transform: rotate(-14deg);
}
.md-vis__region {
  position: absolute; left: var(--x); top: var(--y);
  width: var(--w); height: var(--h);
  border: 2px solid var(--md-sys-color-primary);
  border-radius: 6px;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.28);
  transition: border-color 380ms var(--md-sys-motion-easing-emphasized),
              border-style 380ms var(--md-sys-motion-easing-emphasized);
}
/* Still reading, or unsure: the edge is unresolved rather than a
   different colour. Certainty is edge definition. */
.md-vis__region--soft { border-style: dashed; }
.md-vis__read { margin-top: 12px; }
.md-vis__t { margin: 0; color: var(--md-sys-color-on-surface); }
.md-vis__gap {
  margin: 8px 0 0; padding-left: 12px;
  border-left: 2px solid var(--md-sys-color-outline);
  color: var(--md-sys-color-on-surface-variant);
}

/* A screenshot of text — the commonest visual input there is, and
   the one where "which part did you read" is a question with a
   precise answer. Drawn rather than photographed so the region
   lands on real lines. */
.md-vis__shot {
  position: relative; width: 100%; aspect-ratio: 2 / 1;
  padding: 14px 16px 18px; box-sizing: border-box;
  display: flex; flex-direction: column; gap: 7px; justify-content: flex-start;
  background: #1e1f22;
}
.md-vis__shot b {
  display: block; height: 7px; border-radius: 2px; background: #4a4d55;
}
.md-vis__shot b:nth-child(3n)   { width: 74%; }
.md-vis__shot b:nth-child(3n+1) { width: 92%; }
.md-vis__shot b:nth-child(3n+2) { width: 61%; }
/* The lines the answer was actually about read hotter than the
   rest — the same "content under the region highlights" rule the
   selection layer uses. */
.md-vis__shot b.is-hot { background: #b9a6ef; }
/* A line the crop went through: half a line, not a short one —
   so "the top of this is missing" is visible in the image rather
   than only stated beneath it. */
.md-vis__shot b.is-cut {
  background: #3a3c42; width: 48%; height: 3px; margin-top: 2px;
}

/* Attaching is not asking, so the attached state must not look
   like a working state: no shimmer, no spinner, nothing that
   suggests an answer is on its way. */
.md-vis__drop {
  display: grid; place-items: center; gap: 6px; text-align: center;
  padding: 28px 20px; max-width: 460px;
  border: 1.5px dashed var(--md-sys-color-outline);
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface-variant); font-size: 13.5px;
}
.md-vis__drop.is-over {
  border-style: solid; border-color: var(--md-sys-color-primary);
  background: color-mix(in srgb, var(--md-sys-color-primary) 7%, transparent);
  color: var(--md-sys-color-on-surface);
}
.md-vis__meta {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 8px 0 0; font-size: 11.5px;
  color: var(--md-sys-color-on-surface-variant);
}
.md-vis__wait {
  margin: 8px 0 0; font-size: 12.5px;
  color: var(--md-sys-color-on-surface-variant);
}
.md-vis__strip { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.md-vis__thumb {
  position: relative; width: 72px; height: 52px; overflow: hidden;
  border-radius: var(--md-sys-shape-corner-small);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: #1e1f22; cursor: pointer; padding: 0;
}
.md-vis__thumb.is-on { border-color: var(--md-sys-color-primary); border-width: 2px; }
.md-vis__thumb span {
  position: absolute; left: 4px; bottom: 3px;
  font-size: 9.5px; color: #c8ccd4;
}
.md-vis__err {
  margin: 10px 0 0; padding: 10px 14px; max-width: 460px;
  border-radius: var(--md-sys-shape-corner-medium);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface-variant); font-size: 13px;
}

/* ── Handwriting ──────────────────────────────────────────
   The ink is the original and stays exactly as drawn; the
   reading sits beneath it, never instead of it. */
.md-ink {
  max-width: 560px; padding: 16px 18px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-lowest);
}
.md-ink__strokes {
  display: block; width: 100%; height: auto;
  fill: none; stroke: var(--md-sys-color-on-surface);
  stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
}
.md-ink__read {
  margin: 14px 0 0; padding-top: 14px;
  border-top: 1px solid var(--md-sys-color-outline-variant);
  color: var(--md-sys-color-on-surface);
  display: flex; align-items: baseline; gap: 5px; flex-wrap: wrap;
}
.md-ink__read--pending { color: var(--md-sys-color-on-surface-variant); }
/* Doubt is a dotted underline in the SAME primary. A second hue
   would have to mean something everywhere else too. */
.md-ink__doubt {
  border: 0; background: transparent; cursor: pointer; font: inherit;
  padding: 0 2px; color: inherit;
  border-bottom: 2px dotted var(--md-sys-color-primary);
  transition: transform var(--mx-motion-spatial-duration) var(--mx-motion-spatial-easing),
              background 180ms var(--md-sys-motion-easing-standard);
}
.md-ink__doubt:hover  { background: var(--md-sys-color-primary-container); }
.md-ink__doubt:active { transform: scale(0.94); }
.md-ink__doubt.is-fixed {
  border-bottom-color: transparent;
  background: var(--md-sys-color-primary-container);
}
.md-ink__word { animation: md-ink-in 300ms var(--md-sys-motion-easing-emphasized) both; }

/* A field a pen can write into — which is to say, an ordinary
   field. The only chrome the pattern adds is the bounds, and
   they are bigger than the field on purpose: nobody aims a
   stylus at a 40dp target. */
.md-ink__field {
  position: relative; display: flex; align-items: center; gap: 2px;
  max-width: 420px; min-height: 52px; padding: 12px 16px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-lowest);
  font-size: 14.5px; color: var(--md-sys-color-on-surface);
}
.md-ink__field--focus { border-color: var(--md-sys-color-primary); }
.md-ink__bounds {
  position: absolute; left: -10px; right: -10px; top: -40px; bottom: -40px;
  border: 1.5px dashed var(--md-sys-color-primary);
  border-radius: var(--md-sys-shape-corner-large);
  background: color-mix(in srgb, var(--md-sys-color-primary) 5%, transparent);
  pointer-events: none;
}
.md-ink__value { min-width: 0; }
.md-ink__value--ghost { color: var(--md-sys-color-on-surface-variant); }
.md-ink__caret {
  display: inline-block; width: 2px; height: 18px; vertical-align: -3px;
  background: var(--md-sys-color-primary);
  animation: md-ink-caret 1s steps(1) infinite;
}
@keyframes md-ink-caret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
.md-ink__hint {
  margin: 52px 0 0; color: var(--md-sys-color-on-surface-variant);
}
/* The ink that has not converted yet, sitting ON the text line
   directly after the words that have. Drawn inline rather than as
   an overlay: an overlay spans the whole bounds and ends up
   striking through whatever else is up there, and it also hides
   the thing this state is actually about — text appearing behind
   the nib as the pen moves. */
.md-ink__live {
  display: inline-block; height: 21px; width: 104px;
  vertical-align: -4px; margin-left: 1px; overflow: visible;
}
.md-ink__live path {
  fill: none; stroke: var(--md-sys-color-on-surface);
  stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round;
}
/* Correction gestures, drawn over the word they act on. Ink, not
   iconography — because that is what the person actually made. */
.md-ink__gest {
  position: relative; display: inline-block;
}
.md-ink__gest svg {
  position: absolute; left: -6px; right: -6px; top: -10px; bottom: -10px;
  width: calc(100% + 12px); height: calc(100% + 20px); overflow: visible;
}
.md-ink__gest svg path {
  fill: none; stroke: var(--md-sys-color-primary); stroke-width: 2.2;
  stroke-linecap: round;
}
.md-ink__gone { text-decoration: line-through; opacity: .45; }
.md-ink__sel { background: var(--md-sys-color-primary-container); border-radius: 3px; }
/* Ink at maths size: an exponent has to be legible enough that
   misreading it is believable rather than a contrivance. */
.md-ink__strokes--eq { stroke-width: 2.8; }
.md-ink__unread {
  margin: 14px 0 0; padding-top: 14px;
  border-top: 1px solid var(--md-sys-color-outline-variant);
  color: var(--md-sys-color-on-surface-variant);
}
.md-ink__pen {
  display: inline-flex; align-items: center; gap: 7px; margin-bottom: 10px;
  padding: 4px 11px; border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface-variant); font-size: 11.5px;
}


@keyframes md-ink-in {
  from { opacity: 0; transform: translateY(3px); }
  to   { opacity: 1; transform: none; }
}

/* ══════════════════════════════════════════════════════════
   VOICE ACTIVITY INDICATOR

   Five capsules, about as tall as a line of text, living inside
   the shared prompt composer. Everything is driven from two
   custom properties: `--amp`, written per frame by the driver,
   and `--w`, each stroke's share of it. Nothing here re-lays-out;
   the only animated property is a transform.

   The row must not read as an equaliser, and three things keep
   it from doing so: the strokes are capsules rather than bars,
   their rest length is a dot rather than a flat line, and the
   middle ones take more of the amplitude than the outer ones.
   ══════════════════════════════════════════════════════════ */
.md-va {
  --va-h: 18px;         /* the tallest a stroke may be */
  /* What silence looks like. Low enough to be unmistakably not
     speech, tall enough that five of them read as short STROKES
     rather than as a typographic ellipsis — which is what happens
     as soon as the resting height approaches the width. */
  --va-floor: .38;
  --va-w: 2.5px;
  --amp: 0;
  display: inline-flex; align-items: center; gap: 3px;
  height: var(--va-h); flex: 0 0 auto;
  color: var(--md-sys-color-primary);
}
.md-va i {
  display: block; width: var(--va-w); height: 100%;
  /* The sway is a separate element from the amplitude so the two
     can animate at once without fighting over one transform. */
  animation: va-sway 4.2s ease-in-out infinite alternate;
}
.md-va i:nth-child(1) { animation-delay: -.0s; }
.md-va i:nth-child(2) { animation-delay: -.9s; }
.md-va i:nth-child(3) { animation-delay: -1.8s; }
.md-va i:nth-child(4) { animation-delay: -2.6s; }
.md-va i:nth-child(5) { animation-delay: -3.4s; }
.md-va i b {
  display: block; width: 100%; height: 100%;
  border-radius: 999px; background: currentColor;
  transform: scaleY(clamp(var(--va-floor),
    calc(var(--va-floor) + var(--amp) * var(--w) * (1 - var(--va-floor))), 1));
  transform-origin: center;
  /* Short enough to feel immediate, long enough that a frame of
     noise never shows up as a twitch. */
  transition: transform 70ms linear, background-color 240ms linear;
}
@keyframes va-sway {
  0%   { transform: translateY(-.5px); opacity: .88; }
  100% { transform: translateY(.5px);  opacity: 1; }
}

/* Listening: open, and visibly not reacting. Full colour, because
   the microphone IS on — it is the LENGTH that says nothing is
   being said, which is the distinction the whole pattern turns on. */
.md-va[data-state="listening"] { color: var(--md-sys-color-primary); }

/* Speaking: the same colour, longer strokes. No new hue, because
   a colour change here would claim something changed about the
   microphone, and nothing did. */
.md-va[data-state="speaking"] { --va-floor: .2; }

/* Processing: shorter and slower. Not a spinner dropped where the
   voice used to be — the same object, doing less. */
.md-va[data-state="processing"] {
  --va-h: 13px; --va-floor: .22;
  color: color-mix(in oklab, var(--md-sys-color-primary) 62%, var(--md-sys-color-on-surface-variant));
}
.md-va[data-state="processing"] i { animation-duration: 6.5s; }

/* Muted and unavailable: no motion with speech, and the colour
   drains. An indicator that still moves while muted is claiming
   to hear you. */
.md-va[data-state="muted"],
.md-va[data-state="permission"],
.md-va[data-state="pause"] {
  --va-h: 11px; --va-floor: .5; --amp: 0;
  color: var(--md-sys-color-outline);
}
.md-va[data-state="error"] {
  --va-h: 11px; --va-floor: .5; --amp: 0;
  color: var(--md-sys-color-error);
}
.md-va[data-state="muted"] i,
.md-va[data-state="permission"] i,
.md-va[data-state="pause"] i,
.md-va[data-state="error"] i { animation: none; transform: none; }

/* ── Reduced motion ───────────────────────────────────────
   The sway stops and the driver never runs, so `--amp` sits at
   the middle of its profile. Length and colour then carry the
   state on their own — which is the test of whether they were
   ever carrying it. */
@media (prefers-reduced-motion: reduce) {
  .md-va i { animation: none; transform: none; }
  .md-va i b { transition: none; }
}

/* ── Contextual selection ────────────────────────────────
   A layer over a frozen screen. Three rules do most of the work
   here: the dim is exactly one surface step so the content being
   selected stays readable; the region's EDGE carries certainty —
   soft and dashed while it is being classified, solid primary
   once it snaps; and the region and the chip are the same object
   in two positions, which is why the chip needs no caption
   saying where it came from. */
.md-sel { max-width: 640px; }
.md-sel__stage {
  position: relative; overflow: hidden;
  border-radius: var(--md-sys-shape-corner-medium);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container-lowest);
}
.md-sel__screen { position: relative; padding: 16px; }
/* The teach line sits at the bottom of the layer, so the screen
   makes room for it only while the layer is up — an unexplained
   band of empty space under an ordinary chart is worse than the
   pill briefly pushing the axis up. */
.md-sel__stage:has(.md-sel__layer) .md-sel__screen { padding-bottom: 56px; }

/* The layer is a real modal surface: while it is up, nothing
   underneath can be pressed. The dim says so; the title and the
   control bar say so too, because a dim alone disappears under
   high-contrast settings. */
.md-sel__layer {
  position: absolute; inset: 0; z-index: 2;
  background: color-mix(in srgb, var(--md-sys-color-scrim, #000) 14%, transparent);
  animation: md-sel-in 200ms var(--md-sys-motion-easing-emphasized) both;
}
@keyframes md-sel-in { from { opacity: 0; } to { opacity: 1; } }
.md-sel__teach {
  position: absolute; left: 12px; right: 12px; bottom: 12px; margin: 0;
  padding: 8px 14px; text-align: center;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-inverse-surface, #313033);
  color: var(--md-sys-color-inverse-on-surface, #f4eff4);
  font-size: 12.5px;
}

/* The mark, at one-to-one. No smoothing while the pointer is
   down: motion that leads the input reads as the product
   guessing at what you meant. */
.md-sel__ink { position: absolute; inset: 0; width: 100%; height: 100%; }
.md-sel__ink path {
  fill: none; stroke: var(--md-sys-color-primary); stroke-width: 3;
  stroke-linecap: round; stroke-linejoin: round;
}

.md-sel__region {
  position: absolute;
  left: var(--x); top: var(--y); width: var(--w); height: var(--h);
  border-radius: var(--md-sys-shape-corner-small);
  border: 2px solid var(--md-sys-color-primary);
  background: color-mix(in srgb, var(--md-sys-color-primary) 10%, transparent);
  animation: md-sel-snap var(--mx-motion-spatial-duration) var(--mx-motion-spatial-easing) both;
}
@keyframes md-sel-snap {
  from { opacity: 0; transform: scale(1.06); }
  to   { opacity: 1; transform: none; }
}
/* Unresolved: the boundary has not hardened, because the product
   does not yet know what is inside it. */
.md-sel__region--soft {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--md-sys-color-primary) 55%, transparent);
  background: color-mix(in srgb, var(--md-sys-color-primary) 5%, transparent);
}
.md-sel__label {
  position: absolute; left: 6px; top: 6px; max-width: calc(100% - 12px);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: 4px 9px; border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary);
  font-size: 11.5px; font-weight: 600; letter-spacing: .01em;
}
.md-sel__region--soft .md-sel__label {
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface-variant);
}
/* Drawn at 12, hit at 48. */
.md-sel__h {
  position: absolute; width: 12px; height: 12px; border-radius: 50%;
  background: var(--md-sys-color-primary);
  border: 2px solid var(--md-sys-color-on-primary);
  cursor: pointer;
}
.md-sel__h::after {
  content: ''; position: absolute; inset: -18px;
}
.md-sel__h--nw { left: -7px; top: -7px; }
.md-sel__h--ne { right: -7px; top: -7px; }
.md-sel__h--sw { left: -7px; bottom: -7px; }
.md-sel__h--se { right: -7px; bottom: -7px; }

/* The keyboard route to the identical region. Not a lesser path:
   the same outline, the same label, the same resulting chip. */
.md-sel__focusable {
  position: absolute;
  left: var(--x); top: var(--y); width: var(--w); height: var(--h);
  border: 1.5px dashed transparent;
  border-radius: var(--md-sys-shape-corner-small);
  background: transparent; cursor: pointer; padding: 0;
  transition: border-color 140ms var(--md-sys-motion-easing-standard),
              background 140ms var(--md-sys-motion-easing-standard);
}
/* At rest it is invisible, because a dashed box sitting on the chart
   reads as a selection somebody has already made. It appears on
   hover and on focus — which is the only moment it means anything.
   `--shown` is for documentation surfaces that have to display the
   state rather than wait for it. */
.md-sel__focusable:focus-visible,
.md-sel__focusable:hover,
.md-sel__focusable--shown {
  border-color: var(--md-sys-color-primary);
  background: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent);
  outline: none;
}
.md-sel__focusable:focus-visible {
  outline: 2px solid var(--md-sys-color-primary); outline-offset: 3px;
}

/* ── The composer the region arrives on ── */
.md-sel__bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 12px; padding: 10px 12px; min-height: 56px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container-lowest);
}
.md-sel__bar:focus-within { border-color: var(--md-sys-color-primary); }
.md-sel__chip {
  display: inline-flex; align-items: center; gap: 8px; flex: 0 0 auto;
  padding: 6px 10px 6px 9px; border: 0; cursor: pointer; font: inherit;
  font-size: 13px;
  /* 8dp, sharp: this is evidence, and it uses the same corner the
     Searching page gives a filter it wants you to check. */
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
  animation: md-sel-land var(--mx-motion-spatial-duration) var(--mx-motion-spatial-easing) both;
}
/* It arrives from the layer above it, because it IS the region —
   one object in a second position, not a new one. */
@keyframes md-sel-land {
  from { opacity: 0; transform: translateY(-22px) scale(1.12); }
  to   { opacity: 1; transform: none; }
}
.md-sel__chip-i {
  width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2;
}
.md-sel__x { font-size: 15px; line-height: 1; opacity: .7; }
.md-sel__chip:hover .md-sel__x { opacity: 1; }
.md-sel__chip:active { transform: scale(0.96); }
.md-sel__q {
  flex: 1 1 160px; min-width: 0; border: 0; outline: none; background: transparent;
  font: inherit; font-size: 14.5px; color: var(--md-sys-color-on-surface);
}
.md-sel__q::placeholder { color: var(--md-sys-color-on-surface-variant); }
/* The screen being selected ON. Scaffolding, deliberately quiet:
   the pattern is the layer over it, not the chart under it. */
.md-sel__head {
  margin: 0 0 2px; font-size: 13.5px; font-weight: 650;
  color: var(--md-sys-color-on-surface);
}
.md-sel__sub {
  margin: 0 0 14px; font-size: 12px;
  color: var(--md-sys-color-on-surface-variant);
}
.md-sel__chart {
  display: flex; align-items: flex-end; gap: 6px; height: 132px;
  padding-bottom: 20px; border-bottom: 1px solid var(--md-sys-color-outline-variant);
}
.md-sel__col {
  position: relative; flex: 1; display: flex; flex-direction: column;
  justify-content: flex-end; height: 100%;
}
.md-sel__col i {
  display: block; height: var(--h); border-radius: 3px 3px 0 0;
  background: var(--md-sys-color-surface-container-highest);
}
.md-sel__col--hot i { background: var(--md-sys-color-secondary-container); }
.md-sel__col b {
  position: absolute; top: 100%; left: 0; right: 0; padding-top: 5px;
  font-size: 9.5px; font-weight: 400; text-align: center;
  color: var(--md-sys-color-on-surface-variant);
}

.md-sel__miss {
  margin: 10px 0 0; padding: 10px 14px;
  border-radius: var(--md-sys-shape-corner-medium);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface-variant); font-size: 13px;
}

/* ── Structured input ─────────────────────────────────────
   A resolved entity is 8dp and filled; the rest of the sentence
   stays prose, so the eye sees which words are pinned. */
.md-struct {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  max-width: 600px; padding: 12px 16px; min-height: 52px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-lowest);
  font-size: 14.5px; line-height: 1.5; color: var(--md-sys-color-on-surface);
}
.md-struct:focus-within { border-color: var(--md-sys-color-primary); }
.md-struct__typing { color: var(--md-sys-color-on-surface-variant); }
.md-echip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 4px 10px; border: 0; cursor: pointer; font: inherit; font-size: 13.5px;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
  animation: md-echip-in var(--mx-motion-spatial-duration) var(--mx-motion-spatial-easing) both;
  transition: transform var(--mx-motion-spatial-duration) var(--mx-motion-spatial-easing);
}
.md-echip:active { transform: scale(0.95); }
@keyframes md-echip-in {
  from { opacity: 0; transform: scale(0.88); }
  to   { opacity: 1; transform: none; }
}
.md-echip__k {
  font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase;
  opacity: .72;
}
/* ── Structured input · asking afterwards ────────────────
   The request stays prose at full emphasis; the structure sits
   beneath it. A chosen value and an assumed one must not look
   alike — that distinction is the whole safety property here. */
.md-struct__req {
  max-width: 600px; margin: 0 0 14px;
  font-size: 15.5px; line-height: 1.5; color: var(--md-sys-color-on-surface);
}
.md-struct__ask {
  display: grid; gap: 14px; max-width: 600px;
}
.md-struct__q {
  padding: 14px 16px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-lowest);
  animation: md-struct-q 320ms var(--md-sys-motion-easing-emphasized) both;
}
@keyframes md-struct-q {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
.md-struct__q:nth-child(2) { animation-delay: 70ms; }
.md-struct__q:nth-child(3) { animation-delay: 140ms; }
.md-struct__qt {
  margin: 0; font-weight: 600; color: var(--md-sys-color-on-surface);
}
/* A question that cannot explain its own effect should not be
   asked, so the line saying what it changes is part of the
   component rather than optional copy. */
.md-struct__qw {
  margin: 4px 0 10px; color: var(--md-sys-color-on-surface-variant);
}
.md-struct__opts { display: flex; gap: 8px; flex-wrap: wrap; }
.md-struct__set {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
  max-width: 600px; margin-top: 14px;
}
.md-struct__setk {
  font-size: 11.5px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--md-sys-color-on-surface-variant); margin-right: 2px;
}
/* An assumption, not a choice: lower emphasis until somebody
   touches it, and the word "default" is in its label as well. */
.md-echip--default {
  background: transparent; color: var(--md-sys-color-on-surface-variant);
  border: 1px solid var(--md-sys-color-outline-variant);
}
.md-struct__note {
  max-width: 600px; margin: 12px 0 0;
  font-size: 13px; color: var(--md-sys-color-on-surface-variant);
}

.md-echip--unresolved {
  background: transparent; color: var(--md-sys-color-on-surface-variant);
  border: 1px dashed var(--md-sys-color-outline);
}
.md-struct__menu {
  max-width: 600px; margin-top: 8px; padding: 6px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-lowest);
  box-shadow: var(--md-sys-elevation-2);
}
.md-struct__opt {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 10px; border: 0; background: transparent; cursor: pointer;
  font: inherit; font-size: 13.5px; text-align: left;
  border-radius: var(--md-sys-shape-corner-small);
  color: var(--md-sys-color-on-surface);
}
.md-struct__opt:hover { background: var(--md-sys-color-surface-container-high); }
.md-struct__opt-k {
  margin-left: auto; font-size: 10.5px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--md-sys-color-on-surface-variant);
}

@media (prefers-reduced-motion: reduce) {
  .md-voice__meter span, .md-ink__word, .md-echip, .md-struct__q,
  .md-sel__layer, .md-sel__region, .md-sel__chip { animation: none; }
  /* Matched at the same specificity as the rules that set these
     loops — [data-floor] and all — or the floor selectors win and
     the orb keeps pulsing for the people who asked it not to. */
  .md-vsess[data-floor] .md-vsess__orb i { animation: none; }
  .md-voice__mic, .md-voice__text, .md-vis__region, .md-ink__doubt,
  .md-sel__chip, .md-sel__focusable, .md-echip { transition: none; }
  .md-ink__caret { animation: none; opacity: 1; }
  /* The meter must still read as "listening" without moving. */
  .md-voice__meter span { height: 14px; }
}
