/* Aspen Play primitives. Requires tokens.css; never requires page.css.
 * ap-* is the public component namespace. data-* configures variants.
 * Native attributes (disabled, aria-invalid, aria-pressed) describe state.
 */

/* @component button */
/* A soft key with an optional circular icon well. All fills are solid.
 * Use native disabled while busy. The application owns asynchronous work.
 */
.ap-button {
  --ap-button-height: var(--ap-size-md);
  --ap-button-radius: var(--ap-radius-button);
  --ap-button-bg: var(--ap-color-control);
  --ap-button-ink: var(--ap-color-text);
  --ap-button-hover: var(--ap-button-secondary-hover);
  --ap-button-well: var(--ap-color-inset);
  box-sizing: border-box;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  gap: 10px;
  min-block-size: var(--ap-button-height);
  padding: 10px 20px;
  border: 0;
  border-radius: var(--ap-button-radius);
  background: var(--ap-button-bg);
  color: var(--ap-button-ink);
  box-shadow: var(--ap-shadow-button);
  font: 500 14px/1.25 var(--ap-font-sans);
  letter-spacing: -.015em;
  text-align: center;
  text-decoration: none;
  vertical-align: middle;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--ap-duration-feedback), color var(--ap-duration-feedback), transform var(--ap-duration-enter) var(--ap-ease-enter), box-shadow var(--ap-duration-feedback);
}
.ap-button[data-variant='primary'] {
  --ap-button-bg: var(--ap-color-action);
  --ap-button-ink: var(--ap-color-on-action);
  --ap-button-hover: var(--ap-color-text);
  --ap-button-well: var(--ap-button-primary-well);
}
.ap-button[data-variant='ghost'] {
  --ap-button-bg: transparent;
  --ap-button-hover: var(--ap-color-control);
  --ap-button-ink: var(--ap-color-muted);
  box-shadow: none;
}
.ap-button[data-variant='danger'] {
  --ap-button-ink: var(--ap-color-error);
}
.ap-button[data-size='sm'] { --ap-button-height: var(--ap-size-sm); --ap-button-radius: var(--ap-radius-button-sm); padding: 8px 14px; gap: 8px; font-size: 12px; }
.ap-button[data-size='lg'] { --ap-button-height: var(--ap-size-lg); --ap-button-radius: var(--ap-radius-button-lg); padding: 12px 24px; gap: 12px; font-size: 15px; }
.ap-button__icon { display: inline-grid; place-items: center; flex: 0 0 auto; inline-size: 18px; block-size: 18px; }
.ap-button__icon svg { inline-size: 100%; block-size: 100%; }
.ap-button__well { display: inline-grid; place-items: center; flex: 0 0 auto; inline-size: calc(var(--ap-button-height) - 16px); block-size: calc(var(--ap-button-height) - 16px); border-radius: 50%; background: var(--ap-button-well); }
.ap-button__well svg { inline-size: 16px; block-size: 16px; transition: transform var(--ap-duration-enter) var(--ap-ease-enter); }
.ap-button:has(> .ap-button__well) { padding: 8px 20px 8px 8px; }
.ap-button[data-size='lg']:has(> .ap-button__well) { padding-inline-end: 24px; }
.ap-button[data-shape='icon'] { inline-size: var(--ap-button-height); padding: 0; border-radius: 50%; }
.ap-button[data-shape='icon'] svg { inline-size: 18px; block-size: 18px; }
.ap-button[aria-pressed='true'] { --ap-button-bg: var(--ap-color-action); --ap-button-ink: var(--ap-color-on-action); --ap-button-hover: var(--ap-color-text); }
.ap-button__label { display: inline-grid; align-items: center; text-align: inherit; }
/* Reserve the widest label with an aria-hidden sibling; no width jump on loading. */
.ap-button__label > span { grid-area: 1 / 1; }
.ap-button__reserve { visibility: hidden; pointer-events: none; }
.ap-button:not(:disabled):active { transform: translateY(2px) scale(.97); box-shadow: none; transition-duration: var(--ap-duration-press); }
.ap-button:focus-visible { outline: 2px solid var(--ap-color-action); outline-offset: 5px; }
.ap-button:disabled { opacity: .35; cursor: not-allowed; box-shadow: none; }
.ap-button[aria-busy='true'] { opacity: .8; cursor: wait; }
.ap-button[data-state='success'] { opacity: 1; }
.ap-spinner { display: inline-block; inline-size: 13px; block-size: 13px; border: 1.5px solid currentColor; border-inline-end-color: transparent; border-radius: 50%; animation: ap-spin .9s linear infinite; }
@keyframes ap-spin { to { transform: rotate(360deg); } }
@media (hover: hover) {
  .ap-button:not(:disabled):hover { background: var(--ap-button-hover); }
  .ap-button:not(:disabled):hover .ap-button__well svg { transform: scale(1.12); }
}
@media (pointer: coarse) { .ap-button[data-size='sm'] { --ap-button-height: var(--ap-size-md); } }
@media (prefers-reduced-motion: reduce) { .ap-button, .ap-button__well svg { transition: none; transform: none!important; } .ap-spinner { animation: none; } }

/* Color emphasis is opt-in; navigation continues to use neutral tokens. */
.ap-button[data-variant='accent'] { --ap-button-bg:var(--ap-button-accent); --ap-button-ink:var(--ap-button-on-accent); --ap-button-hover:var(--ap-button-accent-hover); }
.ap-button[data-radius='square'] { --ap-button-radius:var(--ap-radius-button-square); }
.ap-button[data-radius='soft'] { --ap-button-radius:var(--ap-radius-button); }
.ap-button[data-radius='round'] { --ap-button-radius:var(--ap-radius-button-lg); }
.ap-button[data-radius='pill'] { --ap-button-radius:var(--ap-radius-button-pill); }
.ap-button-group { display:inline-flex; align-items:center; justify-content:center; gap:var(--ap-space-2); max-inline-size:100%; }
.ap-button-group[data-layout='stack'] { flex-direction:column; align-items:stretch; }
.ap-button-group[data-layout='joined'] { gap:2px; }
.ap-button-group[data-layout='joined'] > .ap-button { border-radius:0; box-shadow:none; }
.ap-button-group[data-layout='joined'] > .ap-button:first-child { border-start-start-radius:var(--ap-button-radius); border-end-start-radius:var(--ap-button-radius); }
.ap-button-group[data-layout='joined'] > .ap-button:last-child { border-start-end-radius:var(--ap-button-radius); border-end-end-radius:var(--ap-button-radius); }
.ap-button-slot { display:inline-grid; place-items:center; inline-size:var(--ap-button-width); flex:0 0 var(--ap-button-width); vertical-align:middle; }
.ap-button--morph { inline-size:var(--ap-button-width); block-size:var(--ap-button-height); padding:0; overflow:hidden; isolation:isolate; transition: inline-size var(--ap-button-morph-duration) var(--ap-ease-enter), border-radius var(--ap-button-morph-duration) var(--ap-ease-enter), background-color var(--ap-duration-feedback), transform var(--ap-duration-enter) var(--ap-ease-enter); }
.ap-button__rest { display:inline-flex; align-items:center; justify-content:center; gap:10px; white-space:nowrap; transition:opacity 120ms, transform 280ms var(--ap-ease-enter); }
.ap-button__symbol { display:inline-grid; place-items:center; inline-size:18px; block-size:18px; }
.ap-button__symbol svg { inline-size:100%; block-size:100%; }
.ap-button__activity { position:absolute; inset:0; display:flex; align-items:center; justify-content:center; gap:3px; opacity:0; transition:opacity 160ms; }
.ap-button__activity i { display:block; inline-size:4px; block-size:14px; border-radius:2px; background:currentColor; transform:scaleY(.35); }
.ap-button--morph[aria-busy='true'] { inline-size:var(--ap-button-height); border-radius:50%; opacity:1; animation:ap-button-breathe 1600ms 420ms ease-in-out infinite; }
.ap-button--morph[data-variant='ghost'][aria-busy='true'] { background:var(--ap-color-control); }
.ap-button--morph[aria-busy='true'] .ap-button__rest { opacity:0; transform:scale(.8); }
.ap-button--morph[aria-busy='true'] .ap-button__activity { opacity:1; transition-delay:180ms; }
.ap-button--morph[aria-busy='true'] .ap-button__activity i { animation:ap-button-wave 900ms ease-in-out infinite; }
.ap-button--morph[aria-busy='true'] .ap-button__activity i:nth-child(2) { animation-delay:120ms; }
.ap-button--morph[aria-busy='true'] .ap-button__activity i:nth-child(3) { animation-delay:240ms; }
.ap-button--morph[data-state='success'] .ap-button__rest { animation:ap-button-arrive 420ms var(--ap-ease-enter) both; }
.ap-button--morph[data-state='error'] { --ap-button-bg:var(--ap-color-error); --ap-button-ink:var(--ap-color-on-action); }
@keyframes ap-button-breathe { 0%,100% { transform:scale(1) rotate(-6deg); } 50% { transform:scale(.92) rotate(6deg); } }
@keyframes ap-button-wave { 0%,100% { transform:scaleY(.35); } 50% { transform:scaleY(1); } }
@keyframes ap-button-arrive { from { opacity:0; transform:translateY(6px); } to { opacity:1; transform:translateY(0); } }
@media(prefers-reduced-motion:reduce) {
  .ap-button--morph,.ap-button__rest,.ap-button__activity { transition:none; animation:none!important; transform:none!important; }
  .ap-button--morph .ap-button__activity i { animation:none!important; transform:scaleY(.65); }
}

/* @component input */
.ap-field { display:grid; gap:var(--ap-space-2); min-inline-size:0; font-family:var(--ap-font-sans); }
.ap-label { color:var(--ap-color-muted); font-size:12px; font-weight:500; line-height:1.5; }
.ap-input {
  --ap-input-height:var(--ap-size-md);
  box-sizing:border-box;
  inline-size:100%; min-inline-size:0; min-block-size:var(--ap-input-height);
  padding:10px 16px; border:0; border-radius:var(--ap-radius-input);
  background:var(--ap-surface-input); box-shadow:none;
  color:var(--ap-color-text); font:400 16px/1.4 var(--ap-font-sans); letter-spacing:-.015em;
  caret-color:var(--ap-color-text);
  transition:background-color var(--ap-duration-feedback),outline-color var(--ap-duration-feedback);
}
.ap-input[type='search']::-webkit-search-cancel-button { -webkit-appearance:none; }
.ap-input::placeholder { color:var(--ap-color-soft); opacity:1; }
.ap-input:focus-visible { outline:2px solid var(--ap-color-action); outline-offset:3px; }
.ap-input[aria-invalid='true'] { background:var(--ap-surface-input-error); }
.ap-input:disabled { color:var(--ap-color-soft); opacity:.5; cursor:not-allowed; }
.ap-input[readonly] { color:var(--ap-color-muted); }
.ap-input[data-size='sm'],.ap-input-shell[data-size='sm'] { --ap-input-height:var(--ap-size-sm); }
.ap-input[data-size='lg'],.ap-input-shell[data-size='lg'] { --ap-input-height:var(--ap-size-lg); }
.ap-input[data-size='sm'] { padding-block:8px; font-size:14px; }
.ap-input[data-size='lg'] { padding-block:14px; }
.ap-input-shell { --ap-input-height:var(--ap-size-md); display:flex; align-items:center; gap:10px; min-inline-size:0; min-block-size:var(--ap-input-height); padding-inline:14px; border-radius:var(--ap-radius-input); background:var(--ap-surface-input); transition:background-color var(--ap-duration-feedback); }
.ap-input-shell > .ap-input { --ap-input-height:inherit; flex:1; width:0; align-self:stretch; background:transparent; border-radius:0; padding:10px 0; box-shadow:none; }
.ap-input-shell > .ap-input:focus-visible { outline:none; }
.ap-input-shell:focus-within { outline:2px solid var(--ap-color-action); outline-offset:3px; background:var(--ap-surface-input-focus); }
.ap-input-shell:has(.ap-input[aria-invalid='true']) { background:var(--ap-surface-input-error); }
.ap-input-shell:has(.ap-input:disabled) { opacity:.5; }
.ap-input-shell .ap-input:disabled { opacity:1; }
.ap-input-affix { flex:none; display:inline-flex; align-items:center; gap:8px; color:var(--ap-color-soft); font:400 13px/1 var(--ap-font-sans); }
.ap-input-affix svg { width:18px; height:18px; }
.ap-input-action { display:inline-flex; flex:none; align-items:center; justify-content:center; align-self:stretch; min-width:32px; padding:0 4px; border:0; border-radius:8px; color:var(--ap-color-muted); background:transparent; font:500 11px var(--ap-font-sans); cursor:pointer; }
.ap-input-action svg { width:15px; height:15px; }
.ap-input-action:hover { color:var(--ap-color-text); }
.ap-input-action:focus-visible { outline:2px solid var(--ap-color-action); outline-offset:0; }
.ap-input-action[hidden] { display:none; }
.ap-input-meta { display:flex; justify-content:space-between; gap:16px; }
.ap-hint { margin:0; color:var(--ap-color-soft); font-size:11px; line-height:1.7; }
.ap-hint[data-error='true'] { color:var(--ap-color-error); }
.ap-hint[data-status='valid'] { color:var(--ap-color-text); }
.ap-input-counter { flex:none; color:var(--ap-color-soft); font-size:11px; line-height:1.7; font-variant-numeric:tabular-nums; }
textarea.ap-input { resize:vertical; min-block-size:112px; line-height:1.7; }
.ap-input[data-format='code'] { font-size:26px; font-weight:500; letter-spacing:.3em; font-variant-numeric:tabular-nums; padding-block:16px; }
.ap-input[data-format='code']::placeholder { letter-spacing:.3em; color:var(--ap-color-soft); }
@media(pointer:coarse) { .ap-input[data-size='sm'],.ap-input-shell[data-size='sm'] { --ap-input-height:var(--ap-size-md); } .ap-input[data-size='sm'] { font-size:16px; } }
@media(prefers-reduced-motion:reduce) { .ap-input,.ap-input-shell { transition:none; } }

/* @component switch */
.ap-switch {
  --ap-switch-track-w: 42px;
  --ap-switch-track-h: 24px;
  --ap-switch-thumb: 18px;
  --ap-switch-on: var(--ap-color-action);
  --ap-switch-on-ink: var(--ap-color-on-action);
  --ap-switch-on-hover: var(--ap-color-text);
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  min-block-size: var(--ap-size-md);
  inline-size: calc(var(--ap-switch-track-w) + 6px);
  padding: 3px;
  border: 0;
  background: transparent;
  color: var(--ap-color-text);
  cursor: pointer;
  font-family: var(--ap-font-sans);
  touch-action: pan-y;
}
.ap-switch[data-size='sm'] { --ap-switch-track-w: 34px; --ap-switch-track-h: 20px; --ap-switch-thumb: 14px; }
.ap-switch[data-size='lg'] { --ap-switch-track-w: 52px; --ap-switch-track-h: 30px; --ap-switch-thumb: 24px; }
/* Emphasis changes only the on-state fill, in every form. */
.ap-switch[data-variant='accent'] { --ap-switch-on: var(--ap-button-accent); --ap-switch-on-ink: var(--ap-button-on-accent); --ap-switch-on-hover: var(--ap-button-accent-hover); }
.ap-switch[data-variant='danger'] { --ap-switch-on: var(--ap-color-error); --ap-switch-on-ink: var(--ap-surface-input-error); }
/* Form: pill (default). */
.ap-switch__track {
  position: relative;
  display: block;
  inline-size: var(--ap-switch-track-w);
  block-size: var(--ap-switch-track-h);
  padding: 3px;
  box-sizing: border-box;
  border-radius: var(--ap-switch-track-h);
  background: var(--ap-color-control);
  box-shadow: var(--ap-shadow-inset);
  transition: background-color var(--ap-duration-feedback);
}
.ap-switch__thumb {
  display: grid;
  place-items: center;
  inline-size: var(--ap-switch-thumb);
  block-size: var(--ap-switch-thumb);
  border-radius: 50%;
  background: var(--ap-color-muted);
  color: var(--ap-color-control);
  transition: transform var(--ap-duration-feedback) var(--ap-ease-feedback), background-color var(--ap-duration-feedback), opacity var(--ap-duration-feedback);
}
.ap-switch[aria-checked='true'] .ap-switch__track { background: var(--ap-switch-on); }
.ap-switch[aria-checked='true'] .ap-switch__thumb { background: var(--ap-switch-on-ink); color: var(--ap-switch-on); transform: translateX(calc(var(--ap-switch-track-w) - 6px - var(--ap-switch-thumb))); }
.ap-switch:not(:disabled):hover .ap-switch__track { background: var(--ap-button-secondary-hover); }
.ap-switch[aria-checked='true']:not(:disabled):hover .ap-switch__track { background: var(--ap-switch-on-hover); }
.ap-switch:not(:disabled):active .ap-switch__thumb { transition-duration: var(--ap-duration-press); scale: .92; }
.ap-switch:focus-visible { outline: 2px solid var(--ap-color-action); outline-offset: 3px; border-radius: var(--ap-radius-control); }
.ap-switch[aria-busy='true'] { cursor: progress; }
.ap-switch[aria-busy='true'] .ap-switch__thumb { animation: ap-switch-busy 1200ms ease-in-out infinite; }
@keyframes ap-switch-busy { 50% { opacity: .4; } }
.ap-switch:disabled { opacity: .42; cursor: not-allowed; }
/* Marks: a glyph in the thumb (data-marks="icons") or a word in the track (data-marks="labels"). Decorative; the state is aria-checked. */
.ap-switch__mark { grid-area: 1 / 1; display: grid; place-items: center; inline-size: 66%; block-size: 66%; opacity: 0; transition: opacity var(--ap-duration-feedback); }
.ap-switch__mark > svg { inline-size: 100%; block-size: 100%; stroke-width: 2.2; }
.ap-switch[aria-checked='true'] .ap-switch__mark[data-mark='on'], .ap-switch[aria-checked='false'] .ap-switch__mark[data-mark='off'] { opacity: 1; }
.ap-switch[data-marks='labels'] { --ap-switch-track-w: calc(var(--ap-switch-track-h) * 2.5); }
.ap-switch__text { position: absolute; inset-block-start: 50%; translate: 0 -50%; font-size: 9px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; line-height: 1; opacity: 0; transition: opacity var(--ap-duration-feedback); pointer-events: none; }
.ap-switch__text[data-state='on'] { inset-inline-start: 8px; color: var(--ap-switch-on-ink); }
.ap-switch__text[data-state='off'] { inset-inline-end: 8px; color: var(--ap-color-muted); }
.ap-switch[aria-checked='true'] .ap-switch__text[data-state='on'], .ap-switch[aria-checked='false'] .ap-switch__text[data-state='off'] { opacity: 1; }
/* Form: slim. A thin rail with a larger thumb riding over it. */
.ap-switch[data-form='slim'] { --ap-switch-track-w: 36px; --ap-switch-track-h: 14px; --ap-switch-thumb: 20px; inline-size: calc(var(--ap-switch-track-w) + 6px); }
.ap-switch[data-form='slim'] .ap-switch__track { padding: 0; }
.ap-switch[data-form='slim'] .ap-switch__thumb { margin-block-start: calc((var(--ap-switch-track-h) - var(--ap-switch-thumb)) / 2); background: var(--ap-color-text); box-shadow: var(--ap-shadow-raised); }
.ap-switch[data-form='slim'][aria-checked='true'] .ap-switch__track { background: var(--ap-color-soft); }
.ap-switch[data-form='slim'][aria-checked='true'] .ap-switch__thumb { background: var(--ap-switch-on); color: var(--ap-switch-on-ink); transform: translateX(calc(var(--ap-switch-track-w) - var(--ap-switch-thumb))); }
/* Form: rocker. Two halves; the active half is pressed in. */
.ap-switch[data-form='rocker'], .ap-switch[data-form='flip'], .ap-switch[data-form='segment'], .ap-switch[data-form='chip'], .ap-switch[data-form='tile'], .ap-switch[data-form='text'] { inline-size: auto; padding: 0; }
.ap-switch__rocker { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; inline-size: 68px; block-size: 30px; padding: 2px; box-sizing: border-box; border-radius: 9px; background: var(--ap-color-inset); box-shadow: var(--ap-shadow-inset); font-size: 10px; font-weight: 600; line-height: 1; }
.ap-switch__half { display: grid; place-items: center; border-radius: 7px; background: var(--ap-surface-raised); box-shadow: var(--ap-shadow-raised); color: var(--ap-color-soft); transition: background-color var(--ap-duration-feedback), color var(--ap-duration-feedback), box-shadow var(--ap-duration-feedback), translate var(--ap-duration-feedback); }
.ap-switch[data-form='rocker'][aria-checked='false'] .ap-switch__half[data-half='off'], .ap-switch[data-form='rocker'][aria-checked='true'] .ap-switch__half[data-half='on'] { background: var(--ap-color-inset); box-shadow: var(--ap-shadow-inset); color: var(--ap-color-text); translate: 0 1px; }
.ap-switch[data-form='rocker'][aria-checked='true'] .ap-switch__half[data-half='on'] { color: var(--ap-switch-on); }
/* Form: flip. A lever that travels up for on. */
.ap-switch__plate { position: relative; display: block; inline-size: 30px; block-size: 44px; border-radius: 8px; background: var(--ap-color-inset); box-shadow: var(--ap-shadow-inset); }
.ap-switch__lever { position: absolute; inset-inline: 4px; inset-block-start: 4px; block-size: 18px; border-radius: 5px; background: var(--ap-color-muted); box-shadow: var(--ap-shadow-raised); translate: 0 18px; transform: perspective(40px) rotateX(-10deg); transition: translate var(--ap-duration-feedback) var(--ap-ease-feedback), transform var(--ap-duration-feedback), background-color var(--ap-duration-feedback); }
.ap-switch[data-form='flip'][aria-checked='true'] .ap-switch__lever { translate: 0 0; transform: perspective(40px) rotateX(10deg); background: var(--ap-switch-on); }
/* Form: segment. Both states are named; the raised segment slides. */
.ap-switch__segments { position: relative; display: grid; grid-template-columns: 1fr 1fr; padding: 3px; border-radius: 11px; background: var(--ap-color-inset); box-shadow: var(--ap-shadow-inset); font-size: 11px; font-weight: 500; line-height: 1; }
.ap-switch__segments::before { content: ''; position: absolute; inset-block: 3px; inset-inline-start: 3px; inline-size: calc(50% - 3px); border-radius: 8px; background: var(--ap-surface-raised); box-shadow: var(--ap-shadow-raised); transition: translate var(--ap-duration-feedback) var(--ap-ease-feedback), background-color var(--ap-duration-feedback); }
.ap-switch[data-form='segment'][aria-checked='true'] .ap-switch__segments::before { translate: 100% 0; background: var(--ap-switch-on); }
.ap-switch__segment { position: relative; min-inline-size: 44px; padding: 7px 14px; text-align: center; color: var(--ap-color-soft); transition: color var(--ap-duration-feedback); }
.ap-switch[data-form='segment'][aria-checked='false'] .ap-switch__segment[data-state='off'] { color: var(--ap-color-text); }
.ap-switch[data-form='segment'][aria-checked='true'] .ap-switch__segment[data-state='on'] { color: var(--ap-switch-on-ink); }
/* Form: chip. The name is inside; a check appears when on. */
.ap-switch[data-form='chip'] { min-block-size: var(--ap-size-sm); }
.ap-switch__chip { display: inline-flex; align-items: center; gap: 0; padding: 8px 14px; border-radius: 999px; background: var(--ap-surface-raised); box-shadow: var(--ap-shadow-raised); color: var(--ap-color-muted); font-size: 12px; font-weight: 500; line-height: 1; transition: background-color var(--ap-duration-feedback), color var(--ap-duration-feedback), gap var(--ap-duration-feedback); }
.ap-switch__chip > .ap-switch__mark { inline-size: 0; block-size: 12px; overflow: hidden; color: inherit; transition: inline-size var(--ap-duration-feedback), opacity var(--ap-duration-feedback); }
.ap-switch[data-form='chip'][aria-checked='true'] .ap-switch__chip { gap: 6px; background: var(--ap-switch-on); color: var(--ap-switch-on-ink); }
.ap-switch[data-form='chip'][aria-checked='true'] .ap-switch__chip > .ap-switch__mark { inline-size: 12px; }
/* Form: tile. A small card for a board of settings. */
.ap-switch[data-form='tile'] { text-align: start; }
.ap-switch__tile { display: grid; gap: 12px; inline-size: 104px; padding: 14px; box-sizing: border-box; border-radius: 16px; background: var(--ap-surface-raised); box-shadow: var(--ap-shadow-raised); color: var(--ap-color-muted); font-size: 12px; font-weight: 500; line-height: 1.2; transition: background-color var(--ap-duration-feedback), color var(--ap-duration-feedback); }
.ap-switch__tile-icon { display: grid; place-items: center; inline-size: 32px; block-size: 32px; border-radius: 10px; background: var(--ap-color-inset); color: var(--ap-color-text); transition: background-color var(--ap-duration-feedback), color var(--ap-duration-feedback); }
.ap-switch__tile-label { color: var(--ap-color-text); transition: color var(--ap-duration-feedback); }
.ap-switch__tile-state { font-size: 10px; color: var(--ap-color-soft); }
.ap-switch__tile-state[data-state='on'], .ap-switch[data-form='tile'][aria-checked='true'] .ap-switch__tile-state[data-state='off'] { display: none; }
.ap-switch[data-form='tile'][aria-checked='true'] .ap-switch__tile-state[data-state='on'] { display: block; }
.ap-switch[data-form='tile'][aria-checked='true'] .ap-switch__tile { background: var(--ap-switch-on); color: var(--ap-switch-on-ink); }
.ap-switch[data-form='tile'][aria-checked='true'] .ap-switch__tile-label, .ap-switch[data-form='tile'][aria-checked='true'] .ap-switch__tile-state { color: var(--ap-switch-on-ink); }
.ap-switch[data-form='tile'][aria-checked='true'] .ap-switch__tile-icon { background: var(--ap-switch-on-ink); color: var(--ap-switch-on); }
/* Form: text. The name, a dot and the value. For dense places. */
.ap-switch[data-form='text'] { gap: 8px; min-block-size: 32px; padding: 4px 0; color: var(--ap-color-muted); font-size: 13px; font-weight: 500; line-height: 1; }
.ap-switch__word { color: var(--ap-color-text); }
.ap-switch__value { display: inline-flex; align-items: center; gap: 6px; }
.ap-switch__value::before { content: ''; inline-size: 6px; block-size: 6px; border-radius: 50%; background: var(--ap-color-soft); transition: background-color var(--ap-duration-feedback); }
.ap-switch__value > [data-state='on'], .ap-switch[data-form='text'][aria-checked='true'] .ap-switch__value > [data-state='off'] { display: none; }
.ap-switch[data-form='text'][aria-checked='true'] .ap-switch__value > [data-state='on'] { display: inline; }
.ap-switch[data-form='text'][aria-checked='true'] .ap-switch__value::before { background: var(--ap-switch-on); }
/* Behavior: hold (data-hold="600"). The track fills for the duration; releasing early cancels. */
.ap-switch__track::before { content: ''; position: absolute; inset: 0; border-radius: inherit; background: var(--ap-switch-on); opacity: 0; transform: scaleX(0); transform-origin: 0 50%; }
.ap-switch[data-holding='true'] .ap-switch__track::before { opacity: .45; transform: scaleX(1); transition: transform var(--ap-switch-hold, 600ms) linear; }
.ap-switch[data-holding='true'] .ap-switch__thumb { scale: .92; }
/* Behavior: drag (data-drag). The thumb follows the pointer, then settles. */
.ap-switch[data-dragging='true'] .ap-switch__thumb { transition: none; transform: translateX(var(--ap-switch-drag, 0px)); }
/* Two named sides around a pill: neither state fills. Clicking a name selects that side. */
.ap-switch-options { display: inline-flex; align-items: center; gap: 10px; font-family: var(--ap-font-sans); font-size: 12px; color: var(--ap-color-soft); cursor: pointer; }
.ap-switch-options > .ap-switch { flex: none; }
.ap-switch-options > [data-side] { transition: color var(--ap-duration-feedback); }
.ap-switch-options .ap-switch[aria-checked='true'] .ap-switch__track { background: var(--ap-color-control); }
.ap-switch-options .ap-switch[aria-checked='true'] .ap-switch__thumb { background: var(--ap-color-action); }
.ap-switch-options:has(.ap-switch[aria-checked='true']) > [data-side='on'], .ap-switch-options:has(.ap-switch[aria-checked='false']) > [data-side='off'] { color: var(--ap-color-text); }
/* A setting row: the name and an optional description beside the switch. Clicking the text toggles the switch. */
.ap-switch-field { display: flex; align-items: center; justify-content: space-between; gap: var(--ap-space-4); min-inline-size: 0; font-family: var(--ap-font-sans); cursor: pointer; }
.ap-switch-field[data-layout='trailing'] { flex-direction: row-reverse; justify-content: flex-end; }
.ap-switch-field > .ap-switch { flex: none; }
.ap-switch-field__text { display: grid; gap: 2px; min-inline-size: 0; }
.ap-switch-field .ap-label { color: var(--ap-color-text); font-size: 14px; font-weight: 500; line-height: 1.4; }
.ap-switch-field:has(.ap-switch:disabled) { cursor: not-allowed; }
.ap-switch-field:has(.ap-switch:disabled) .ap-switch-field__text { opacity: .5; }
/* A group of related settings. Give the list a heading and role="group". */
.ap-switch-list { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; overflow: hidden; border-radius: var(--ap-radius-card); }
.ap-switch-list > li { padding: var(--ap-space-3) var(--ap-space-4); background: var(--ap-surface-raised); }
@media (prefers-reduced-motion: reduce) {
  .ap-switch__thumb, .ap-switch__track, .ap-switch__mark, .ap-switch__text, .ap-switch__half, .ap-switch__lever, .ap-switch__segments::before, .ap-switch__segment, .ap-switch__chip, .ap-switch__chip > .ap-switch__mark, .ap-switch__tile, .ap-switch__tile-icon, .ap-switch__tile-label, .ap-switch__value::before, .ap-switch-options > [data-side] { transition: none; }
  .ap-switch[aria-busy='true'] .ap-switch__thumb { animation: none; opacity: .5; }
  .ap-switch[data-holding='true'] .ap-switch__track::before { transition: none; }
}

/* @component segmented */
.ap-segmented {
  --ap-segmented-height: var(--ap-size-md);
  --ap-segmented-on: var(--ap-surface-raised);
  --ap-segmented-on-ink: var(--ap-color-text);
  --ap-segmented-count: 1;
  --ap-segmented-index: 0;
  position: relative;
  display: inline-flex;
  gap: var(--ap-space-1);
  max-inline-size: 100%;
  padding: var(--ap-space-1);
  box-sizing: border-box;
  border-radius: var(--ap-radius-control);
  background: var(--ap-color-inset);
  box-shadow: var(--ap-shadow-inset);
  font-family: var(--ap-font-sans);
  touch-action: pan-y;
}
.ap-segmented[data-size='sm'] { --ap-segmented-height: var(--ap-size-sm); }
.ap-segmented[data-size='lg'] { --ap-segmented-height: var(--ap-size-lg); }
.ap-segmented > button {
  position: relative;
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-block-size: var(--ap-segmented-height);
  padding: var(--ap-space-2) var(--ap-space-4);
  border: 0;
  border-radius: calc(var(--ap-radius-control) - 2px);
  background: transparent;
  color: var(--ap-color-muted);
  font: 500 14px/1.4 var(--ap-font-sans);
  white-space: nowrap;
  min-inline-size: 0; /* a set that cannot fit gives way inside itself, never by widening the page; use data-wrap or the stack form */
  overflow: hidden;
  cursor: pointer;
  transition: color var(--ap-duration-feedback), background-color var(--ap-duration-feedback);
}
.ap-segmented > button > span:not(.ap-segmented__count) { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; }
.ap-segmented[data-size='sm'] > button { padding-inline: var(--ap-space-3); font-size: 12px; }
.ap-segmented[data-size='lg'] > button { padding-inline: var(--ap-space-6); font-size: 15px; }
.ap-segmented > button[aria-pressed='true'] { background: var(--ap-segmented-on); box-shadow: var(--ap-shadow-raised); color: var(--ap-segmented-on-ink); }
.ap-segmented > button:not(:disabled):not([aria-pressed='true']):hover { color: var(--ap-color-text); background: var(--ap-color-line); }
.ap-segmented > button:not(:disabled):active { transition-duration: var(--ap-duration-press); scale: .97; }
.ap-segmented > button:focus-visible { outline: 2px solid var(--ap-color-action); outline-offset: 2px; }
.ap-segmented > button:disabled { opacity: .42; cursor: not-allowed; }
.ap-segmented > button > svg { flex: none; }
.ap-segmented[aria-busy='true'] { cursor: progress; }
.ap-segmented[aria-busy='true'] > button[aria-pressed='true'] { animation: ap-segmented-busy 1200ms ease-in-out infinite; }
@keyframes ap-segmented-busy { 50% { opacity: .55; } }
/* Content inside an option. */
.ap-segmented__count { min-inline-size: 18px; padding: 2px 6px; border-radius: 999px; background: var(--ap-color-inset); color: var(--ap-color-soft); font-size: 10px; font-weight: 600; line-height: 1.2; text-align: center; }
.ap-segmented > button[aria-pressed='true'] .ap-segmented__count { background: var(--ap-segmented-on-ink); color: var(--ap-segmented-on); }
.ap-segmented__title { font-weight: 500; }
.ap-segmented__hint { font-size: 11px; font-weight: 400; line-height: 1.5; color: var(--ap-color-soft); white-space: normal; }
/* Fit and wrap. */
.ap-segmented[data-fit='content'] > button { flex: none; }
.ap-segmented[data-wrap] { flex-wrap: wrap; }
/* Form: slider. One raised piece glides between equal-width options. */
.ap-segmented[data-form='slider'] { gap: 0; }
.ap-segmented[data-form='slider']::before { content: ''; position: absolute; inset-block: var(--ap-space-1); inset-inline-start: var(--ap-space-1); inline-size: calc((100% - 2 * var(--ap-space-1)) / var(--ap-segmented-count)); border-radius: calc(var(--ap-radius-control) - 2px); background: var(--ap-segmented-on); box-shadow: var(--ap-shadow-raised); translate: calc(var(--ap-segmented-index) * 100%) 0; transition: translate var(--ap-duration-feedback) var(--ap-ease-feedback), background-color var(--ap-duration-feedback); }
.ap-segmented[data-form='slider'] > button { flex: 1 1 0; }
.ap-segmented[data-form='slider'] > button[aria-pressed='true'] { background: transparent; box-shadow: none; }
/* Form: underline. No trough; a bar marks the choice. For headers. */
.ap-segmented[data-form='underline'] { padding: 0; gap: var(--ap-space-4); border-radius: 0; background: transparent; box-shadow: none; }
.ap-segmented[data-form='underline'] > button { flex: none; padding: var(--ap-space-2) 2px; border-radius: 0; }
.ap-segmented[data-form='underline'] > button::after { content: ''; position: absolute; inset-inline: 0; inset-block-end: 0; block-size: 2px; border-radius: 2px; background: var(--ap-color-action); scale: 0 1; transition: scale var(--ap-duration-feedback) var(--ap-ease-feedback); }
.ap-segmented[data-form='underline'] > button[aria-pressed='true'] { background: transparent; box-shadow: none; color: var(--ap-color-text); }
.ap-segmented[data-form='underline'] > button[aria-pressed='true']::after { scale: 1 1; }
.ap-segmented[data-form='underline'] > button:not(:disabled):not([aria-pressed='true']):hover { background: transparent; }
.ap-segmented[data-form='underline'] > button:focus-visible { outline-offset: 4px; border-radius: 6px; }
/* Form: pills. Detached options; the choice fills. For filter bars. */
.ap-segmented[data-form='pills'] { --ap-segmented-on: var(--ap-color-action); --ap-segmented-on-ink: var(--ap-color-on-action); padding: 0; gap: var(--ap-space-2); background: transparent; box-shadow: none; }
.ap-segmented[data-form='pills'] > button { flex: none; min-block-size: calc(var(--ap-segmented-height) - 8px); padding: 6px 14px; border-radius: 999px; background: var(--ap-surface-raised); box-shadow: var(--ap-shadow-raised); }
.ap-segmented[data-form='pills'] > button[aria-pressed='true'] { background: var(--ap-segmented-on); }
.ap-segmented[data-form='pills'] > button:not(:disabled):not([aria-pressed='true']):hover { background: var(--ap-button-secondary-hover); }
/* Form: icons. Square options named by aria-label. For toolbars. */
.ap-segmented[data-form='icons'] > button { flex: none; inline-size: var(--ap-segmented-height); padding: 0; }
/* Form: stack. Options with a title and a description, one per line. */
.ap-segmented[data-form='stack'] { flex-direction: column; align-items: stretch; inline-size: min(100%, 320px); }
.ap-segmented[data-form='stack'] > button { flex: none; display: grid; grid-template-columns: auto 1fr; gap: 2px 12px; justify-items: start; text-align: start; padding: 12px 16px; white-space: normal; }
.ap-segmented[data-form='stack'] > button > svg { grid-row: 1 / span 2; align-self: center; }
.ap-segmented[data-form='stack'] > button > .ap-segmented__title, .ap-segmented[data-form='stack'] > button > .ap-segmented__hint { grid-column: 2; }
.ap-segmented[data-form='stack'] > button[aria-pressed='true'] .ap-segmented__hint { color: var(--ap-color-muted); }
/* Form: steps. Equal squares for a scale. */
.ap-segmented[data-form='steps'] > button { flex: none; inline-size: calc(var(--ap-segmented-height) - 8px); min-block-size: calc(var(--ap-segmented-height) - 8px); padding: 0; font-variant-numeric: tabular-nums; }
/* Form: joined. Raised options side by side; the choice is pressed in and filled. */
.ap-segmented[data-form='joined'] { --ap-segmented-on: var(--ap-color-action); --ap-segmented-on-ink: var(--ap-color-on-action); gap: 2px; padding: 0; background: transparent; box-shadow: none; overflow: hidden; }
.ap-segmented[data-form='joined'] > button { border-radius: 0; background: var(--ap-surface-raised); box-shadow: var(--ap-shadow-raised); }
.ap-segmented[data-form='joined'] > button:first-child { border-start-start-radius: var(--ap-radius-control); border-end-start-radius: var(--ap-radius-control); }
.ap-segmented[data-form='joined'] > button:last-child { border-start-end-radius: var(--ap-radius-control); border-end-end-radius: var(--ap-radius-control); }
.ap-segmented[data-form='joined'] > button[aria-pressed='true'] { background: var(--ap-segmented-on); box-shadow: var(--ap-shadow-inset); }
.ap-segmented[data-form='joined'] > button:not(:disabled):not([aria-pressed='true']):hover { background: var(--ap-button-secondary-hover); }
/* Emphasis: only the fill of the choice changes, in every form. Declared last so it wins over the forms. */
.ap-segmented[data-variant='accent'] { --ap-segmented-on: var(--ap-button-accent); --ap-segmented-on-ink: var(--ap-button-on-accent); }
/* Behavior: sweep (data-drag). While the pointer is down and moving, the choice follows it; the change is reported on release. */
.ap-segmented[data-dragging='true'] > button, .ap-segmented[data-dragging='true']::before, .ap-segmented[data-dragging='true'] > button::after { transition: none; }
@media (prefers-reduced-motion: reduce) {
  .ap-segmented > button, .ap-segmented::before, .ap-segmented > button::after { transition: none; }
  .ap-segmented[aria-busy='true'] > button[aria-pressed='true'] { animation: none; opacity: .7; }
}

/* @component card */
/* Quiet game covers: solid surface, unframed typography, one link per card. */
.ap-card {
  box-sizing:border-box;
  display:block;
  min-inline-size:0;
  color:var(--ap-color-text);
  font-family:var(--ap-font-sans);
  text-decoration:none;
  border-radius:var(--ap-radius-card);
  -webkit-tap-highlight-color:transparent;
}
.ap-card__cover {
  position:relative;
  display:grid;
  place-items:center;
  aspect-ratio:4 / 5;
  overflow:hidden;
  border-radius:var(--ap-radius-card);
  background:var(--ap-surface-card);
  transition:background-color var(--ap-duration-enter),transform var(--ap-duration-enter) var(--ap-ease-enter);
}
.ap-card__art {
  display:block;
  inline-size:128%;
  max-inline-size:none;
  block-size:100%;
  object-fit:contain;
  transform:translateY(-3%);
  transition:transform 650ms var(--ap-ease-enter);
}
.ap-card__mode {
  position:absolute;
  inset-block-start:var(--ap-space-6);
  inset-inline-start:var(--ap-space-6);
  display:flex;
  align-items:center;
  gap:6px;
  font-size:11px;
  color:var(--ap-color-muted);
}
.ap-card__mode svg { inline-size:14px; block-size:14px; }
.ap-card__launch {
  position:absolute;
  inset-block-end:var(--ap-space-6);
  inset-inline-end:var(--ap-space-6);
  display:grid;
  place-items:center;
  inline-size:38px;
  block-size:38px;
  border-radius:50%;
  background:var(--ap-color-text);
  color:var(--ap-color-page);
  opacity:0;
  transform:translateY(7px) scale(.92);
  transition:opacity var(--ap-duration-enter),transform 400ms var(--ap-ease-enter);
}
.ap-card__launch svg { inline-size:16px; block-size:16px; }
.ap-card__caption {
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:var(--ap-space-3);
  padding:var(--ap-space-4) 2px 0;
}
.ap-card__title { margin:0; font-size:21px; font-weight:500; letter-spacing:-.025em; line-height:1.3; overflow-wrap:anywhere; }
.ap-card__genre { color:var(--ap-color-soft); font-size:11px; line-height:1.5; }
.ap-card:focus-visible { outline:2px solid var(--ap-color-action); outline-offset:6px; }
.ap-card:focus-visible .ap-card__launch { opacity:1; transform:none; }
@media(hover:hover) {
  .ap-card:hover .ap-card__cover { background:var(--ap-color-control); }
  .ap-card:hover .ap-card__art { transform:translateY(-5%) scale(1.065) rotate(-3deg); }
  .ap-card:hover .ap-card__launch { opacity:1; transform:none; }
}
.ap-card:active .ap-card__cover { transform:scale(.985); transition-duration:var(--ap-duration-press); }
/* Touch has no hover to reveal it: the whole card is the target and the cover's press is the feedback, so the launch stays hidden at rest. */
@media(prefers-reduced-motion:reduce) {
  .ap-card .ap-card__cover,.ap-card .ap-card__art,.ap-card .ap-card__launch { transition:none; }
  .ap-card:hover .ap-card__art { transform:translateY(-3%); }
  .ap-card:active .ap-card__cover { transform:none; }
}

/* @component toast */
.ap-toast {
  box-sizing: border-box;
  position: fixed;
  inset-inline-start: 50%;
  inset-block-end: max(24px, env(safe-area-inset-bottom));
  z-index: 200;
  inline-size: max-content;
  max-inline-size: calc(100vw - 40px);
  padding: var(--ap-space-3) var(--ap-space-6);
  border-radius: var(--ap-radius-control);
  background: var(--ap-color-text);
  box-shadow: var(--ap-shadow-overlay);
  color: var(--ap-color-page);
  font: 400 14px/1.6 var(--ap-font-sans);
  overflow-wrap: anywhere;
  transform: translateX(-50%);
  pointer-events: none;
}
.ap-toast:empty { display: none; }
.ap-toast:not(:empty) { animation: ap-toast-enter var(--ap-duration-enter) var(--ap-ease-enter); }
@keyframes ap-toast-enter { from { opacity: 0; transform: translate(-50%, 7px); } to { opacity: 1; transform: translate(-50%, 0); } }
@media (prefers-reduced-motion: reduce) { .ap-toast:not(:empty) { animation: none; } }

/* @component dialog */
.ap-dialog {
  box-sizing: border-box;
  inline-size: min(440px, calc(100vw - 32px));
  max-block-size: calc(100dvh - 48px);
  margin: auto;
  overflow: auto;
  padding: var(--ap-space-6);
  border: 0;
  border-radius: var(--ap-radius-dialog);
  background: var(--ap-color-control);
  box-shadow: var(--ap-shadow-overlay);
  color: var(--ap-color-text);
  font-family: var(--ap-font-sans);
}
.ap-dialog::backdrop { background: #101010b3; backdrop-filter: blur(7px); }
.ap-dialog__title { margin: 0 0 var(--ap-space-3); font-size: var(--ap-type-heading); font-weight: 400; line-height: 1.3; }
.ap-dialog__description { color: var(--ap-color-muted); font-size: 14px; line-height: 1.8; }
.ap-dialog__actions { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: var(--ap-space-3); margin-block-start: var(--ap-space-6); }

.ap-dialog[open] { animation: ap-dialog-enter var(--ap-duration-enter) var(--ap-ease-enter); }
.ap-dialog[open]::backdrop { animation: ap-backdrop-enter var(--ap-duration-enter) ease-out; }
@keyframes ap-dialog-enter { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes ap-backdrop-enter { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .ap-dialog[open], .ap-dialog[open]::backdrop { animation: none; } }

/* @component icon */
.ap-icon {
  display: inline-block;
  flex: none;
  vertical-align: middle;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--ap-icon-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}
.ap-icon[data-size='sm'] { width: var(--ap-icon-sm); height: var(--ap-icon-sm); }
.ap-icon[data-size='md'] { width: var(--ap-icon-md); height: var(--ap-icon-md); }
.ap-icon[data-size='lg'] { width: var(--ap-icon-lg); height: var(--ap-icon-lg); }

/* @component loader */
/* Loops live on the leaf (opacity and the individual translate/scale/rotate properties); enter and exit live on .ap-loader-visual. Loops match only [data-state='pending'][data-visible]; loader.js freezes the computed pose before that stops matching, and the leaf transition resolves it. Solid fills only. */
.ap-loader {
  --loader-size:var(--ap-loader-md); --loader-duration:var(--ap-loader-duration); --loader-gap:4px; --loader-radius:3px; --loader-stroke:2.5; --loader-rest:.26;
  position:relative; display:grid; justify-items:center; align-content:center;
  gap:var(--ap-space-6); color:var(--ap-color-text); min-height:160px;
}
.ap-loader[data-size='sm'] { --loader-size:var(--ap-loader-sm); --loader-gap:2px; --loader-radius:2px; --loader-stroke:3.6; }
.ap-loader[data-size='lg'] { --loader-size:var(--ap-loader-lg); --loader-gap:6px; --loader-radius:4px; --loader-stroke:2.1; }
.ap-loader[data-speed='slow'] { --loader-duration:var(--ap-loader-slow); }
.ap-loader[data-speed='fast'] { --loader-duration:var(--ap-loader-fast); }
.ap-loader[data-tone='quiet'] { color:var(--ap-color-soft); }
.ap-loader[data-layout='inline'] { grid-template-columns:auto minmax(0,1fr); justify-items:start; align-items:center; gap:var(--ap-space-3); min-height:0; }
.ap-loader[data-layout='bare'] { gap:0; min-height:0; }
.ap-loader-content { display:none; }
/* Nothing for the first 160 ms, then the mark arrives; layout is reserved throughout. */
.ap-loader-visual { position:relative; width:var(--loader-size); height:var(--loader-size); display:grid; place-items:center; opacity:0; scale:.92; transition:opacity var(--ap-loader-exit) var(--ap-ease-feedback),scale var(--ap-loader-exit) var(--ap-ease-feedback); }
.ap-loader:is([data-visible],[data-shown]):not([data-state='cancelled']) .ap-loader-visual { opacity:1; scale:1; transition:opacity var(--ap-duration-feedback) var(--ap-ease-feedback),scale var(--ap-loader-enter) var(--ap-ease-enter); }
.ap-loader-status { font:var(--ap-type-label)/1.5 var(--ap-font-sans); color:var(--ap-color-muted); transition:opacity var(--ap-duration-feedback) var(--ap-ease-feedback) 60ms; }
.ap-loader[data-tone='quiet'] .ap-loader-status { color:var(--ap-color-soft); }
.ap-loader[data-state='pending']:not([data-visible]) .ap-loader-status { opacity:0; transition:none; }
.ap-loader[data-state='error'] .ap-loader-status { color:var(--ap-color-error); }
.ap-loader[data-state='pending'][data-visible]:is([data-wait='1'],[data-wait='3']) .ap-loader-status { animation:ap-loader-say var(--ap-duration-enter) var(--ap-ease-enter); }
.ap-loader[data-state='pending'][data-visible]:is([data-wait='2'],[data-wait='4']) .ap-loader-status { animation:ap-loader-say-again var(--ap-duration-enter) var(--ap-ease-enter); }
.ap-loader[data-layout='bare'] .ap-loader-status,.ap-loader[data-variant='word'] .ap-loader-status,.ap-loader:is([data-variant='line'],[data-variant='orbit']) .ap-loader-progress { position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
.ap-loader-value { font:500 11px/1 var(--ap-font-mono); font-variant-numeric:tabular-nums; color:var(--ap-color-muted); }
.ap-loader-value:empty { visibility:hidden; }
.ap-loader-value:empty::before { content:'0%'; }
.ap-loader-mark { width:100%; height:100%; display:grid; grid-template-columns:1fr 1fr; gap:var(--loader-gap); }
.ap-loader-mark i { display:block; background:currentColor; border-radius:var(--loader-radius); opacity:var(--loader-rest); scale:.86; transition:opacity var(--ap-duration-feedback) var(--ap-ease-feedback),scale var(--ap-duration-feedback) var(--ap-ease-feedback),translate var(--ap-duration-feedback) var(--ap-ease-feedback); }
/* Tiles: one light travelling clockwise. */
.ap-loader[data-variant='tiles'][data-state='pending'][data-visible] .ap-loader-mark i { animation:ap-loader-turn var(--loader-duration) infinite; animation-delay:calc(var(--turn) * var(--loader-duration) / -4); }
.ap-loader[data-state='success'] .ap-loader-mark i { opacity:.9; scale:1; }
/* Activity marks: indeterminate motion, with the same task lifecycle. */
.ap-loader:is([data-variant='converge'],[data-variant='satellite']) .ap-loader-mark { position:relative; display:block; }
.ap-loader:is([data-variant='converge'],[data-variant='satellite']) .ap-loader-mark i { position:absolute; inset:35%; border-radius:50%; rotate:calc(var(--cell) * 90deg); translate:0 0; transform:translateY(-110%); }
.ap-loader[data-variant='converge'][data-state='pending'][data-visible] .ap-loader-mark i { animation:ap-loader-converge calc(var(--loader-duration) * 2) ease-in-out infinite; animation-delay:calc(var(--cell) * var(--loader-duration) / -4); }
.ap-loader[data-variant='satellite'] .ap-loader-mark i { inset:42%; transform:translateY(-240%); }
.ap-loader[data-variant='satellite'][data-state='pending'][data-visible] .ap-loader-mark i { animation:ap-loader-satellite calc(var(--loader-duration) * 3) linear infinite; animation-delay:calc(var(--cell) * var(--loader-duration) / -2); }
.ap-loader[data-variant='scan'] .ap-loader-mark { grid-template-columns:repeat(3,1fr); gap:calc(var(--loader-size) / 9); }
.ap-loader[data-variant='scan'] .ap-loader-mark i { border-radius:2px; }
.ap-loader[data-variant='scan'][data-state='pending'][data-visible] .ap-loader-mark i { animation:ap-loader-glint calc(var(--loader-duration) * 2) ease-in-out infinite; animation-delay:calc(var(--cell) * var(--loader-duration) / -9); }
.ap-loader[data-variant='helix'] .ap-loader-mark { display:flex; align-items:center; justify-content:space-between; width:calc(var(--loader-size) * 1.6); }
.ap-loader[data-variant='helix'] .ap-loader-mark i { width:6%; height:60%; border-radius:var(--loader-radius); scale:1 .3; }
.ap-loader[data-variant='helix'][data-state='pending'][data-visible] .ap-loader-mark i { animation:ap-loader-helix calc(var(--loader-duration) * 1.5) ease-in-out infinite; animation-delay:calc(var(--cell) * var(--loader-duration) / -8); }
@keyframes ap-loader-converge { 0%,100% { transform:translateY(-110%); scale:.7; opacity:.3; } 50% { transform:translateY(-40%); scale:1; opacity:1; } }
@keyframes ap-loader-satellite { from { rotate:calc(var(--cell) * 90deg); opacity:.5; } 50% { opacity:1; } to { rotate:calc(var(--cell) * 90deg + 360deg); opacity:.5; } }
@keyframes ap-loader-helix { 0%,100% { scale:1 .3; opacity:.3; translate:0 -12%; } 50% { scale:1 1; opacity:1; translate:0 12%; } }
/* Ripple, pendulum and comet use the same cancellable task lifecycle. */
.ap-loader:is([data-variant='ripple'],[data-variant='comet'],[data-variant='pendulum']) .ap-loader-mark { position:relative; display:block; }
.ap-loader[data-variant='ripple'] .ap-loader-mark i { position:absolute; inset:0; border-radius:50%; background:none; box-shadow:inset 0 0 0 1.5px currentColor; scale:.2; }
.ap-loader[data-variant='ripple'][data-state='pending'][data-visible] .ap-loader-mark i { animation:ap-loader-ripple calc(var(--loader-duration) * 2) ease-out infinite; animation-delay:calc(var(--cell) * var(--loader-duration) / -2); }
.ap-loader[data-variant='pendulum'] .ap-loader-mark i { position:absolute; left:calc(var(--cell) * 25%); top:40%; width:20%; aspect-ratio:1; border-radius:50%; transform-origin:50% -180%; }
.ap-loader[data-variant='pendulum'][data-state='pending'][data-visible] .ap-loader-mark i { animation:ap-loader-pendulum calc(var(--loader-duration) * 2) ease-in-out infinite; animation-delay:calc(var(--cell) * var(--loader-duration) / -4); }
.ap-loader[data-variant='comet'] .ap-loader-mark i { position:absolute; inset:0; background:none; border-radius:50%; transform:rotate(calc(var(--cell) * -18deg)); }
.ap-loader[data-variant='comet'] .ap-loader-mark i::after { content:''; position:absolute; top:0; left:42%; width:16%; aspect-ratio:1; border-radius:50%; background:currentColor; scale:calc(1 - var(--cell) * .18); }
.ap-loader[data-variant='comet'][data-state='pending'][data-visible] .ap-loader-mark i { animation:ap-loader-comet calc(var(--loader-duration) * 1.5) cubic-bezier(.4,0,.6,1) infinite; animation-delay:calc(var(--cell) * var(--loader-duration) / -24); }
@keyframes ap-loader-ripple { 0% {scale:.15;opacity:0;} 20% {opacity:.8;} 100% {scale:1;opacity:0;} }
@keyframes ap-loader-pendulum { 0%,100% {rotate:-28deg;opacity:.4;} 50% {rotate:28deg;opacity:1;} }
@keyframes ap-loader-comet { from {rotate:0deg;opacity:.9;} to {rotate:360deg;opacity:.4;} }
/* Orbit: an arc chasing itself. Measured, it counts from 12 o'clock; done, the ring closes. */
.ap-loader[data-variant='orbit'] .ap-loader-mark { display:block; }
.ap-loader-mark svg { display:block; width:100%; height:100%; overflow:visible; fill:none; }
.ap-loader-track,.ap-loader-arc { transform-box:fill-box; transform-origin:center; transition:opacity var(--ap-duration-feedback) var(--ap-ease-feedback),scale var(--ap-duration-feedback) var(--ap-ease-feedback); }
.ap-loader-track { stroke:var(--ap-color-control); stroke-width:var(--loader-stroke); }
.ap-loader-spin { transform-box:view-box; transform-origin:50% 50%; rotate:0deg; transition:rotate var(--ap-loader-reveal) var(--ap-ease-enter); }
.ap-loader-arc { stroke:currentColor; stroke-width:var(--loader-stroke); stroke-linecap:round; stroke-dasharray:0 100; stroke-dashoffset:0; opacity:.9; transition:stroke-dasharray var(--ap-duration-feedback) var(--ap-ease-feedback),stroke-dashoffset var(--ap-duration-feedback) var(--ap-ease-feedback),opacity var(--ap-duration-feedback) var(--ap-ease-feedback),scale var(--ap-duration-feedback) var(--ap-ease-feedback); }
.ap-loader[data-variant='orbit'][data-state='pending'][data-visible]:not([data-measured]) .ap-loader-spin { animation:ap-loader-spin var(--loader-duration) linear infinite; }
.ap-loader[data-variant='orbit'][data-state='pending'][data-visible]:not([data-measured]) .ap-loader-arc { animation:ap-loader-arc calc(var(--loader-duration) * 1.5) cubic-bezier(.45,0,.55,1) infinite; }
.ap-loader[data-measured] .ap-loader-arc { stroke-dasharray:calc(var(--ap-loader-progress) * 100) 100; }
.ap-loader[data-measured='first'] .ap-loader-arc { transition-duration:var(--ap-duration-enter); transition-timing-function:var(--ap-ease-enter); }
.ap-loader[data-state='success'] .ap-loader-arc { stroke-dasharray:100 0; transition-duration:var(--ap-duration-enter); transition-timing-function:var(--ap-ease-enter); }
.ap-loader:is([data-state='error'],[data-state='cancelled'],[data-state='idle']) .ap-loader-arc { stroke-dasharray:0 100; opacity:0; }
/* Pulse: three dots, half of every cycle at rest. */
.ap-loader[data-variant='pulse'] { --loader-rest:.3; }
.ap-loader[data-variant='pulse'] .ap-loader-mark { grid-template-columns:repeat(3,1fr); align-items:center; gap:calc(var(--loader-size) / 7); }
.ap-loader[data-variant='pulse'] .ap-loader-mark i { aspect-ratio:1; border-radius:50%; scale:1; }
.ap-loader[data-variant='pulse'][data-state='pending'][data-visible] .ap-loader-mark i { animation:ap-loader-pulse var(--loader-duration) infinite; animation-delay:calc(var(--cell) * var(--loader-duration) / 6 - var(--loader-duration)); }
.ap-loader[data-variant='pulse'][data-state='success'] .ap-loader-mark i { opacity:.9; }
/* Word: the label is the loader. A per-letter opacity wave, never a moving fill. Label and body sizes only: spans break kerning. */
.ap-loader[data-variant='word'] { --loader-rest:.5; }
.ap-loader[data-variant='word'] .ap-loader-visual { width:auto; height:auto; }
.ap-loader[data-variant='word'] .ap-loader-mark { display:block; width:auto; height:auto; font:var(--ap-type-label)/1.5 var(--ap-font-sans); }
.ap-loader[data-variant='word'][data-size='sm'] .ap-loader-mark { font-size:11px; }
.ap-loader[data-variant='word'][data-size='lg'] .ap-loader-mark { font-size:14px; }
.ap-loader-word { display:inline-block; white-space:pre; }
.ap-loader[data-variant='word'] .ap-loader-mark i { display:inline; background:none; border-radius:0; font-style:normal; }
.ap-loader[data-variant='word'][data-state='pending'] .ap-loader-word::after { content:'…'; opacity:var(--loader-rest); }
.ap-loader[data-variant='word'][data-state='pending'][data-visible] .ap-loader-word { animation:ap-loader-say var(--ap-duration-enter) var(--ap-ease-enter); }
.ap-loader[data-variant='word'][data-state='pending'][data-visible] .ap-loader-mark i { animation:ap-loader-glint var(--cycle) cubic-bezier(.4,0,.6,1) infinite; animation-delay:calc(var(--i) / var(--n) * var(--pass) - var(--cycle)); }
.ap-loader[data-variant='word']:not([data-state='pending']) .ap-loader-mark i { opacity:1; }
.ap-loader[data-variant='word'][data-state='error'] .ap-loader-mark { color:var(--ap-color-error); }
/* Line: a region is loading. Indeterminate travels; measured grows from the left; on the edge it is two pixels of the container. */
.ap-loader[data-variant='line'] .ap-loader-visual { width:min(var(--ap-loader-line-width),100%); height:auto; gap:8px; scale:1; }
.ap-loader[data-variant='line'] .ap-loader-mark { display:block; height:var(--ap-loader-line); border-radius:9px; overflow:hidden; background:var(--ap-color-control); }
.ap-loader[data-variant='line'][data-size='sm'] .ap-loader-mark { height:2px; }
.ap-loader[data-variant='line'][data-size='lg'] .ap-loader-mark { height:4px; }
.ap-loader[data-variant='line'] .ap-loader-mark i { width:100%; height:100%; border-radius:0; background:var(--ap-color-action); transform-origin:left; opacity:0; translate:0 0; scale:0 1; }
.ap-loader[data-variant='line'][data-state='pending'][data-visible]:not([data-measured]) .ap-loader-mark i { animation:ap-loader-travel var(--loader-duration) cubic-bezier(.45,0,.55,1) infinite; }
.ap-loader[data-variant='line'][data-measured] .ap-loader-mark i { opacity:1; scale:var(--ap-loader-progress) 1; }
.ap-loader[data-variant='line'][data-measured='first'] .ap-loader-mark i { transition-duration:var(--ap-duration-enter); transition-timing-function:var(--ap-ease-enter); }
.ap-loader[data-variant='line'][data-state='success'] .ap-loader-mark i { opacity:1; scale:1 1; }
.ap-loader[data-variant='line']:is([data-state='error'],[data-state='cancelled'],[data-state='idle']) .ap-loader-mark i { opacity:0; }
.ap-loader[data-placement='top'] { display:block; justify-items:normal; min-height:0; } /* block layout honours justify-items now; the content keeps its full width */
.ap-loader[data-placement='top'] .ap-loader-content { display:block; }
.ap-loader[data-placement='top'] .ap-loader-visual { position:absolute; z-index:1; inset:0 0 auto; width:100%; height:2px; transform-origin:top; scale:1 0; }
.ap-loader[data-placement='top']:is([data-visible],[data-shown]):not([data-state='cancelled']) .ap-loader-visual { scale:1 1; }
.ap-loader[data-placement='top'] .ap-loader-mark { height:2px; border-radius:0; background:transparent; }
.ap-loader[data-placement='top']:not([data-state='pending']) .ap-loader-visual { opacity:0; transition:opacity var(--ap-duration-enter) var(--ap-ease-enter) var(--ap-duration-feedback); }
/* Skeleton: the shape arrives before the data. It only fades, so the layout never moves. */
.ap-loader[data-variant='skeleton'] { justify-items:stretch; width:100%; }
.ap-loader[data-variant='skeleton'] .ap-loader-visual { width:100%; height:auto; scale:1; }
.ap-loader[data-variant='skeleton'] .ap-loader-mark { height:auto; grid-template-columns:minmax(0,1fr); gap:10px 12px; align-items:center; }
.ap-loader[data-shape='row'] .ap-loader-mark { grid-template-columns:auto minmax(0,1fr); }
.ap-loader[data-shape='row'] .ap-loader-mark [data-part='circle'] { grid-row:span 2; }
.ap-loader[data-shape='list'] .ap-loader-mark { grid-template-columns:auto minmax(0,1fr) 44px; gap:16px 12px; }
.ap-loader[data-variant='skeleton'] .ap-loader-mark i { background:var(--ap-color-line); opacity:.7; scale:1; } /* a translucent solid, so the shape reads on any surface */
.ap-loader-mark [data-part='line'] { width:var(--w,100%); height:10px; border-radius:5px; }
.ap-loader-mark [data-part='circle'] { width:32px; height:32px; border-radius:50%; }
.ap-loader[data-shape='list'] .ap-loader-mark [data-part='circle'] { width:20px; height:20px; }
.ap-loader-mark [data-part='block'] { width:100%; aspect-ratio:16 / 9; border-radius:10px; }
.ap-loader[data-variant='skeleton'][data-state='pending'][data-visible] .ap-loader-mark i { animation:ap-loader-breathe var(--ap-loader-slow) ease-in-out infinite; animation-delay:calc((var(--x) * .5 + var(--y) * .25) * var(--ap-loader-slow) * -1); }
/* Hand-off. swap: the wait becomes the thing, in the same cell, and height never animates. check: the mark gives way to a drawn glyph. */
.ap-loader[data-handoff='swap']:not([data-variant='reveal']) :is(.ap-loader-content,.ap-loader-visual) { grid-area:1 / 1; }
.ap-loader[data-handoff='swap']:not([data-variant='reveal']) .ap-loader-content { display:block; min-width:0; opacity:0; visibility:hidden; translate:0 4px; }
.ap-loader[data-handoff='swap']:not([data-variant='reveal']) .ap-loader-visual { align-self:center; }
.ap-loader[data-handoff='swap']:not([data-variant='reveal'])[data-state='success'] .ap-loader-content { opacity:1; visibility:visible; translate:0 0; transition:opacity var(--ap-duration-enter) var(--ap-ease-enter) 120ms,translate var(--ap-duration-enter) var(--ap-ease-enter) 120ms,visibility 0s 120ms; }
.ap-loader[data-handoff='swap']:not([data-variant='reveal'])[data-state='success'] .ap-loader-visual { opacity:0; scale:1; transition:opacity var(--ap-duration-feedback) var(--ap-ease-feedback); }
.ap-loader-glyph { position:absolute; inset:0; display:grid; place-items:center; pointer-events:none; }
.ap-loader-glyph svg { width:72%; height:72%; overflow:visible; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.ap-loader-glyph path { stroke-dasharray:1; stroke-dashoffset:1; opacity:0; }
.ap-loader-glyph__dot { fill:currentColor; stroke:none; transform-box:fill-box; transform-origin:center; scale:0; }
.ap-loader[data-handoff='check']:is([data-state='success'],[data-state='error']) .ap-loader-mark :is(i,.ap-loader-arc,.ap-loader-track) { opacity:0; scale:.6; }
.ap-loader[data-handoff='check'][data-state='success'] .ap-loader-glyph__check { opacity:1; stroke-dashoffset:0; transition:stroke-dashoffset var(--ap-duration-enter) var(--ap-ease-enter) 90ms,opacity 0s 90ms; }
.ap-loader[data-handoff='check'][data-state='error'] .ap-loader-glyph { color:var(--ap-color-error); }
.ap-loader[data-handoff='check'][data-state='error'] .ap-loader-glyph__alert { opacity:1; stroke-dashoffset:0; transition:stroke-dashoffset var(--ap-duration-feedback) var(--ap-ease-feedback) 90ms,opacity 0s 90ms; }
.ap-loader[data-handoff='check'][data-state='error'] .ap-loader-glyph__dot { scale:1; transition:scale var(--ap-duration-press) var(--ap-ease-feedback) 270ms; }
.ap-loader-progress { appearance:none; width:120px; height:3px; border:0; border-radius:9px; overflow:hidden; background:var(--ap-color-control); accent-color:var(--ap-color-action); }
.ap-loader-progress::-webkit-progress-bar { background:var(--ap-color-control); }
.ap-loader-progress::-webkit-progress-value { background:var(--ap-color-action); border-radius:9px; }
.ap-loader-progress::-moz-progress-bar { background:var(--ap-color-action); }
.ap-loader-progress[hidden] { display:none; }
/* Reveal: a quiet mosaic that lets go of the artwork from the top-left. */
.ap-loader[data-variant='reveal'] { width:min(100%,300px); aspect-ratio:4/3; min-height:0; overflow:hidden; border-radius:var(--ap-radius-card); background:var(--ap-color-inset); }
.ap-loader[data-variant='reveal'] .ap-loader-content { display:block; position:absolute; inset:0; opacity:0; scale:1.02; transition:opacity var(--ap-loader-reveal) var(--ap-ease-enter),scale var(--ap-loader-reveal) var(--ap-ease-enter); }
.ap-loader-content img { width:100%; height:100%; display:block; object-fit:cover; }
.ap-loader[data-variant='reveal'] .ap-loader-visual { position:absolute; inset:0; width:100%; height:100%; scale:1; }
.ap-loader[data-variant='reveal'] .ap-loader-mark { grid-template-columns:repeat(4,1fr); grid-template-rows:repeat(4,1fr); gap:3px; padding:3px; }
.ap-loader[data-variant='reveal'] .ap-loader-mark i { border-radius:4px; background:var(--ap-color-action); opacity:.08; scale:1; }
.ap-loader[data-variant='reveal'][data-state='pending'][data-visible] .ap-loader-mark i { animation:ap-loader-mosaic var(--loader-duration) ease-in-out infinite; animation-delay:calc(var(--order) * -75ms); }
.ap-loader[data-variant='reveal'][data-state='success'] .ap-loader-mark i { opacity:0; scale:.6; transition-duration:252ms; transition-delay:calc((var(--col) + var(--row)) * 28ms); }
.ap-loader[data-variant='reveal'] .ap-loader-status { z-index:1; position:absolute; bottom:16px; left:16px; background:var(--ap-color-page); color:var(--ap-color-text); padding:6px 10px; border-radius:var(--ap-radius-control); font-size:11px; }
.ap-loader[data-variant='reveal'] .ap-loader-progress { z-index:2; position:absolute; bottom:0; left:0; width:100%; }
.ap-loader[data-variant='reveal'][data-state='success'] .ap-loader-content { opacity:1; scale:1; }
.ap-loader[data-variant='reveal'] .ap-loader-status { transition:opacity var(--ap-duration-feedback) var(--ap-ease-feedback); }
.ap-loader[data-variant='reveal']:is([data-state='success'],[data-state='idle']) .ap-loader-status { opacity:0; } /* the artwork speaks for itself; the words stay announced */
/* The application or the page sets data-offscreen; a paused loop costs nothing and resumes where it stopped. */
.ap-loader[data-state='pending'][data-visible][data-offscreen] .ap-loader-mark :is(i,.ap-loader-spin,.ap-loader-arc) { animation-play-state:paused; }
@keyframes ap-loader-turn { 0% {opacity:var(--loader-rest);scale:.86;animation-timing-function:var(--ap-ease-feedback);} 12% {opacity:1;scale:1;animation-timing-function:cubic-bezier(.4,0,.6,1);} 40%,100% {opacity:var(--loader-rest);scale:.86;} }
@keyframes ap-loader-spin { to {rotate:360deg;} }
@keyframes ap-loader-arc { 0% {stroke-dasharray:22 78;stroke-dashoffset:0;} 50% {stroke-dasharray:64 36;stroke-dashoffset:-29;} 100% {stroke-dasharray:22 78;stroke-dashoffset:-100;} }
@keyframes ap-loader-pulse { 0% {translate:0 0;opacity:var(--loader-rest);animation-timing-function:var(--ap-ease-feedback);} 20% {translate:0 calc(var(--loader-size) / -12);opacity:1;animation-timing-function:cubic-bezier(.4,0,.6,1);} 50%,100% {translate:0 0;opacity:var(--loader-rest);} }
@keyframes ap-loader-glint { 0% {opacity:var(--loader-rest);} 14% {opacity:1;} 28%,100% {opacity:var(--loader-rest);} }
@keyframes ap-loader-travel { 0% {translate:-40% 0;scale:.4 1;opacity:0;} 12%,88% {opacity:1;} 100% {translate:100% 0;scale:.4 1;opacity:0;} }
@keyframes ap-loader-breathe { 0%,100% {opacity:.55;} 50% {opacity:1;} }
@keyframes ap-loader-mosaic { 0%,100% {opacity:.08;} 50% {opacity:.28;} }
@keyframes ap-loader-say { from {opacity:0;} to {opacity:1;} }
@keyframes ap-loader-say-again { from {opacity:0;} to {opacity:1;} }
@media(prefers-reduced-motion:reduce) {
  .ap-loader,.ap-loader * { animation:none!important; transition:none!important; }
  .ap-loader[data-state='pending'] .ap-loader-mark i { opacity:.5; scale:1; }
  .ap-loader[data-variant='pulse'][data-state='pending'] .ap-loader-mark i { opacity:calc(.5 + var(--cell) * .2); }
  .ap-loader[data-variant='orbit'][data-state='pending']:not([data-measured]) .ap-loader-arc { stroke-dasharray:75 25; }
  .ap-loader[data-variant='orbit'][data-state='pending']:not([data-measured]) .ap-loader-spin { rotate:-90deg; }
  .ap-loader[data-variant='line'][data-state='pending']:not([data-measured]) .ap-loader-mark i { scale:.4 1; }
  .ap-loader[data-variant='word'] .ap-loader-mark i,.ap-loader[data-variant='word'][data-state='pending'] .ap-loader-word::after { opacity:1; }
  .ap-loader[data-variant='skeleton'][data-state='pending'] .ap-loader-mark i { opacity:.7; }
  .ap-loader[data-variant='reveal'][data-state='pending'] .ap-loader-mark i { opacity:.16; }
  .ap-loader-glyph path { stroke-dasharray:none; }
}
@media(prefers-contrast:more) {
  .ap-loader { --loader-rest:.45; }
  .ap-loader[data-variant='pulse'] { --loader-rest:.5; }
  .ap-loader[data-variant='word'] { --loader-rest:1; }
  .ap-loader-track { stroke:var(--ap-color-soft); }
}
@media(forced-colors:active) {
  .ap-loader { color:CanvasText; }
  .ap-loader-mark i,.ap-loader[data-variant='line'] .ap-loader-mark i,.ap-loader[data-variant='reveal'] .ap-loader-mark i { forced-color-adjust:none; background:CanvasText; }
  .ap-loader[data-variant='word'] .ap-loader-mark i { background:none; }
  .ap-loader[data-variant='line'] .ap-loader-mark,.ap-loader[data-variant='skeleton'] .ap-loader-mark i { forced-color-adjust:none; background:GrayText; }
  .ap-loader-track { stroke:GrayText; }
  .ap-loader-arc,.ap-loader-glyph svg { stroke:CanvasText; }
}

/* @component voice */
/* One state machine, six bodies. Bars, orb, wave and matrix draw on one canvas each; speaker and button are DOM. The state is a word; the picture is decoration. At rest the loop sleeps and idle breathes here, in CSS. Solid fills only. */
.ap-voice { --voice-size:var(--ap-voice-md); --voice-w:var(--voice-size); --voice-ink:var(--ap-voice-ink); --voice-dim:var(--ap-voice-dim); position:relative; display:inline-grid; justify-items:center; gap:var(--ap-space-3); min-width:0; color:var(--voice-ink); transition:opacity var(--ap-duration-feedback) var(--ap-ease-feedback); }
.ap-voice[data-size='sm'] { --voice-size:var(--ap-voice-sm); }
.ap-voice[data-size='lg'] { --voice-size:var(--ap-voice-lg); }
.ap-voice[data-form='bars'] { --voice-w:102px; }
.ap-voice[data-form='bars'][data-size='sm'] { --voice-w:33px; }
.ap-voice[data-form='bars'][data-size='lg'] { --voice-w:146px; }
.ap-voice[data-form='orb'] { --voice-size:var(--ap-voice-orb-md); }
.ap-voice[data-form='orb'][data-size='sm'] { --voice-size:var(--ap-voice-orb-sm); }
.ap-voice[data-form='orb'][data-size='lg'] { --voice-size:var(--ap-voice-orb-lg); }
.ap-voice[data-form='matrix'][data-size='sm'] { --voice-size:32px; }
.ap-voice[data-form='wave'] { --voice-size:44px; --voice-w:100%; display:grid; width:100%; min-width:120px; }
.ap-voice[data-form='wave'][data-size='sm'] { --voice-size:32px; }
.ap-voice[data-form='wave'][data-size='lg'] { --voice-size:64px; }
.ap-voice-visual { position:relative; display:block; width:var(--voice-w); height:var(--voice-size); scale:1; transition:scale var(--ap-duration-enter) var(--ap-ease-enter); }
.ap-voice-visual[data-breathing] { animation:ap-voice-breathe var(--ap-voice-breath) ease-in-out infinite; }
.ap-voice[data-paused] .ap-voice-visual,.ap-voice[data-paused] .ap-voice-button__activity i { animation-play-state:paused; }
.ap-voice-canvas { display:block; width:100%; height:100%; }
.ap-voice-status { min-height:1.5em; font:var(--ap-type-label)/1.5 var(--ap-font-sans); color:var(--ap-color-muted); text-align:center; }
.ap-voice:is([data-state='error'],[data-state='denied']) .ap-voice-status { color:var(--ap-color-error); }
.ap-voice[data-label='hidden'] .ap-voice-status,.ap-voice-speaker__said { position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
.ap-voice[data-hidden]:not([data-form='bars'],[data-form='orb'],[data-form='wave'],[data-form='matrix']) { opacity:0; }
/* Glyphs are DOM: they confirm an outcome, and they carry the state when there is no motion or no canvas. */
.ap-voice-glyph { position:absolute; inset:0; display:grid; place-items:center; pointer-events:none; color:var(--voice-ink); }
.ap-voice[data-form='wave'] .ap-voice-glyph { inset:0 auto 0 0; width:var(--voice-size); }
.ap-voice-glyph [data-glyph],.ap-voice-button__icon [data-glyph] { grid-area:1 / 1; display:grid; opacity:0; scale:.8; transition:opacity var(--ap-duration-feedback) var(--ap-ease-feedback),scale var(--ap-duration-enter) var(--ap-ease-enter); }
.ap-voice-glyph svg { width:min(24px,var(--voice-size)); height:min(24px,var(--voice-size)); }
.ap-voice [data-glyph='check'] path,.ap-voice [data-glyph='close'] path { stroke-dasharray:1; stroke-dashoffset:1; transition:stroke-dashoffset var(--ap-duration-enter) var(--ap-ease-enter) 120ms; }
.ap-voice[data-state='success'] [data-glyph='check'] path,.ap-voice[data-state='error'] [data-glyph='close'] path { stroke-dashoffset:0; }
.ap-voice:not([data-form='matrix'])[data-state='success'] .ap-voice-glyph [data-glyph='check'],.ap-voice:not([data-form='matrix'])[data-state='error'] .ap-voice-glyph [data-glyph='close'],.ap-voice:not([data-form='matrix']):is([data-state='muted'],[data-state='denied']) .ap-voice-glyph [data-glyph='mic-off'] { opacity:1; scale:1; }
.ap-voice:is([data-state='error'],[data-state='denied']) .ap-voice-glyph { color:var(--ap-color-error); }
.ap-voice[data-state='muted'] .ap-voice-glyph { color:var(--ap-color-muted); }
.ap-voice[data-form='orb'][data-state='success'] .ap-voice-glyph { color:var(--ap-color-on-action); }
.ap-voice[data-degraded] .ap-voice-canvas { display:none; }
.ap-voice[data-degraded][data-state='idle'] [data-glyph='mic'],.ap-voice[data-degraded][data-state='listening'] [data-glyph='mic'],.ap-voice[data-degraded]:is([data-state='connecting'],[data-state='thinking']) [data-glyph='dots'],.ap-voice[data-degraded][data-state='speaking'] [data-glyph='sound'],.ap-voice[data-degraded][data-state='success'] [data-glyph='check'],.ap-voice[data-degraded][data-state='error'] [data-glyph='close'],.ap-voice[data-degraded]:is([data-state='muted'],[data-state='denied']) [data-glyph='mic-off'] { opacity:1; scale:1; }
/* Speaker: who is talking, in a room. A ring for the voice, an echo behind it, a badge when muted. */
.ap-voice[data-form='speaker'] { --voice-size:36px; display:inline-grid; place-items:center; width:var(--voice-size); height:var(--voice-size); border-radius:50%; color:var(--ap-color-action); }
.ap-voice[data-form='speaker'][data-size='sm'] { --voice-size:28px; }
.ap-voice[data-form='speaker'][data-size='lg'] { --voice-size:48px; }
.ap-voice[data-form='speaker'] > :not(i,span) { grid-area:1 / 1; }
.ap-voice-speaker__ring,.ap-voice-speaker__echo { position:absolute; inset:-2px; border-radius:50%; box-shadow:0 0 0 2px currentColor; opacity:0; pointer-events:none; }
.ap-voice-speaker__echo { box-shadow:0 0 0 1px currentColor; }
.ap-voice-speaker__badge { position:absolute; right:-3px; bottom:-3px; display:grid; place-items:center; width:14px; height:14px; border-radius:50%; background:var(--ap-color-page); color:var(--ap-color-muted); opacity:0; scale:.8; transition:opacity var(--ap-duration-feedback) var(--ap-ease-feedback),scale var(--ap-duration-feedback) var(--ap-ease-feedback); }
.ap-voice-speaker__badge svg { width:10px; height:10px; }
.ap-voice[data-form='speaker']:is([data-state='muted'],[data-state='denied']) .ap-voice-speaker__badge { opacity:1; scale:1; }
.ap-voice[data-form='speaker']:is([data-state='muted'],[data-state='denied']) :is(.ap-voice-speaker__ring,.ap-voice-speaker__echo) { visibility:hidden; }
/* Mic button: a native button named Talk. It reports the press; the application opens the microphone. */
.ap-voice[data-form='button'] { --voice-size:var(--ap-size-md); }
.ap-voice[data-form='button'][data-size='sm'] { --voice-size:var(--ap-size-sm); }
.ap-voice[data-form='button'][data-size='lg'] { --voice-size:var(--ap-size-lg); }
.ap-voice-button { position:relative; display:inline-grid; place-items:center; width:var(--voice-size); height:var(--voice-size); margin:0; padding:0; border:0; border-radius:50%; background:var(--ap-surface-raised); color:var(--ap-color-text); box-shadow:var(--ap-shadow-raised); font:inherit; cursor:pointer; touch-action:manipulation; -webkit-user-select:none; user-select:none; transition:background-color var(--ap-duration-feedback) var(--ap-ease-feedback),color var(--ap-duration-feedback) var(--ap-ease-feedback),scale var(--ap-duration-press) var(--ap-ease-feedback); }
.ap-voice-button::before { content:''; position:absolute; inset:0; border-radius:50%; }
.ap-voice-button:active { scale:.97; }
.ap-voice-button:focus-visible { outline:2px solid var(--ap-color-action); outline-offset:3px; }
.ap-voice[data-state='listening'] .ap-voice-button { background:var(--ap-surface-action); color:var(--ap-color-on-action); }
.ap-voice:is([data-state='muted'],[data-state='denied']) .ap-voice-button { background:transparent; box-shadow:inset 0 0 0 1.5px var(--ap-color-control); color:var(--ap-color-muted); }
.ap-voice[data-state='denied'] .ap-voice-button { color:var(--ap-color-error); cursor:not-allowed; }
.ap-voice-button__halo { position:absolute; z-index:-1; inset:0; border-radius:50%; background:var(--ap-color-text); opacity:0; pointer-events:none; transition:opacity var(--ap-duration-feedback) var(--ap-ease-feedback); }
.ap-voice[data-state='listening'] .ap-voice-button__halo { opacity:.18; }
.ap-voice[data-form='button'] { isolation:isolate; }
.ap-voice-button__icon { display:grid; place-items:center; pointer-events:none; }
.ap-voice-button__icon svg { width:calc(var(--voice-size) * .45); height:calc(var(--voice-size) * .45); }
.ap-voice:is([data-state='idle'],[data-state='listening'],[data-state='connecting'],[data-state='speaking']) .ap-voice-button__icon [data-glyph='mic'],.ap-voice[data-state='success'] .ap-voice-button__icon [data-glyph='check'],.ap-voice[data-state='error'] .ap-voice-button__icon [data-glyph='close'],.ap-voice:is([data-state='muted'],[data-state='denied']) .ap-voice-button__icon [data-glyph='mic-off'] { opacity:1; scale:1; }
.ap-voice-button__activity { position:absolute; inset:0; display:flex; align-items:center; justify-content:center; gap:3px; opacity:0; pointer-events:none; transition:opacity var(--ap-duration-feedback) var(--ap-ease-feedback); }
.ap-voice-button__activity i { width:3px; height:30%; border-radius:2px; background:currentColor; opacity:.65; scale:1 .4; }
.ap-voice[data-state='thinking'] .ap-voice-button__activity { opacity:1; }
.ap-voice[data-state='thinking'] .ap-voice-button__activity i { animation:ap-voice-think var(--ap-loader-duration) infinite; }
.ap-voice[data-state='thinking'] .ap-voice-button__activity i:nth-child(2) { animation-delay:calc(var(--ap-loader-duration) / -6 * 5); }
.ap-voice[data-state='thinking'] .ap-voice-button__activity i:nth-child(3) { animation-delay:calc(var(--ap-loader-duration) / -6 * 4); }
.ap-voice-button__time { position:absolute; left:50%; top:calc(100% + 6px); translate:-50% 0; font:500 11px/1 var(--ap-font-mono); font-variant-numeric:tabular-nums; color:var(--ap-color-muted); white-space:nowrap; opacity:0; pointer-events:none; transition:opacity var(--ap-duration-feedback) var(--ap-ease-feedback); }
.ap-voice[data-state='listening'] .ap-voice-button__time { opacity:1; }
@keyframes ap-voice-breathe { 0%,100% {scale:1;} 50% {scale:1.025;} }
@keyframes ap-voice-think { 0% {scale:1 .4;opacity:.45;animation-timing-function:var(--ap-ease-feedback);} 12% {scale:1 1;opacity:1;animation-timing-function:cubic-bezier(.4,0,.6,1);} 40%,100% {scale:1 .4;opacity:.45;} }
@media(pointer:coarse) { .ap-voice-button::before { inset:min(0px,calc((100% - 44px) / 2)); } }
@media(prefers-reduced-motion:reduce) {
  .ap-voice,.ap-voice * { animation:none!important; transition:none!important; }
  .ap-voice-button__activity i { scale:1 .65; opacity:.65; }
  .ap-voice [data-glyph] path { stroke-dasharray:none; }
}
@media(prefers-contrast:more) { .ap-voice { --ap-voice-dim:var(--ap-color-muted); --ap-voice-dim-ink:var(--ap-color-text); --ap-voice-tone-1:#5a5a5a; --ap-voice-tone-2:#8c8c8c; } }
@media(forced-colors:active) {
  .ap-voice { --ap-voice-ink:CanvasText; --ap-voice-dim-ink:CanvasText; --ap-voice-dim:GrayText; --ap-voice-tone-1:GrayText; --ap-voice-tone-2:GrayText; --ap-voice-tone-3:CanvasText; --ap-color-error:CanvasText; }
  .ap-voice-speaker__ring,.ap-voice-speaker__echo { forced-color-adjust:none; color:Highlight; }
  .ap-voice[data-state='listening'] .ap-voice-button { forced-color-adjust:none; background:Highlight; color:HighlightText; }
  .ap-voice-button { border:1px solid ButtonText; }
}
