/* ============================================================
 * app-demo.css — a drawn, played copy of a RebateRight web app page, for
 * the How it works sections (/patient-verification, /eligibility-check).
 *
 * One clock drives each demo. --t counts seconds from 0 to --demo-length
 * (set on each demo, at the end of this file), and every part works out its own state from
 * it, so Pause holds one animation and Play from the start restarts one,
 * by swapping it for its twin. Each part's moment is set on it as --at, or
 * as a --t-* on .demo. Each move lasts at most 600 ms and enters on
 * ease-out. Past 5 s, WCAG 2.2.2 asks for Pause. Under reduced motion
 * the clock stands at --demo-still, which shows the answer, and the
 * controls leave.
 *
 * The drawing copies the App (RebateRight.App): FormSection, the identity
 * fields, ActionCard, ApiActionButton, VerificationResultCard and
 * EligibilityResultCard, drawn smaller. It is inert and described by its
 * label; the steps under it are the text. Working marks (the light round
 * an edge, the turning arc) are the home page's.
 * ============================================================ */

@property --t {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

/* Each demo sets, on .demo: --demo-length and --demo-still (seconds), and
   the moments --t-click (Verify clicked), --t-send (the question leaves),
   --t-check (the record is read), --t-answer (the tick leaves), --t-result
   (the result shows) and --t-clear (the form starts to clear). */
.demo {
  /* 1 until the form clears, then 0 over 400 ms. What it held comes
     back over the next 200 ms, after the old text has gone. */
  --keep: clamp(0, (var(--t-clear) + 0.4 - var(--t)) / 0.4, 1);
  --back: clamp(0, (var(--t) - var(--t-clear) - 0.4) / 0.2, 1);
  animation: demo-clock calc(var(--demo-length) * 1s) linear infinite;
  /* Off screen, the browser skips it: no style, layout or paint, so it costs
   nothing while the reader is elsewhere. It remembers the size it last drew;
     720px stands in until it has drawn once. */
  content-visibility: auto;
  contain-intrinsic-size: auto 720px;
}
/* The controls (/css/player.css): the clock's twin runs while Start B or
   End A is picked, and it starts at the page's --demo-skip while End A or
   End B is, so every press starts it again. */
.demo:has(.demo-jump:is(.is-start-b, .is-end-a):checked) { animation-name: demo-clock-b; }
.demo:has(.demo-jump:is(.is-end-a, .is-end-b):checked) { animation-delay: calc(var(--demo-skip) * -1s); }
.demo:has(.demo-pause:checked) { animation-play-state: paused; }
@keyframes demo-clock   { from { --t: 0; } to { --t: var(--demo-length); } }
@keyframes demo-clock-b { from { --t: 0; } to { --t: var(--demo-length); } }

/* The drawing is sized in em and its type scales with the space it has,
   so it keeps one layout at every width down to 880px. The link to the
   engine room sits midway down beside them. */
.demo-stage { container: demo-stage / inline-size; }
.app-sprite { position: absolute; inline-size: 0; block-size: 0; }   /* the icons each drawing repeats, drawn once */
.demo-scene {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  grid-template-rows: auto 1fr;
  font-size: 1.25cqi;
  line-height: 1.4;
  color: var(--color-midnight);
  text-align: start;
  user-select: none;
}

/* — Where the check is sent from: the web app here, pointing down into
     it; your own software and the browser extension send the same one. — */
.demo-callers {
  grid-column: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5em;
  margin-block-end: 1.1em;
  font-size: 0.82em;
}
.demo-callers-label {
  margin-inline-end: 0.3em;
  font-size: 0.8em;
  font-weight: 600;
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--color-stone-60);
}
.demo-callers > :not(.demo-callers-label) {
  position: relative;
  white-space: nowrap;
  padding: 0.35em 0.9em;
  border: 1px solid var(--color-stone-20);
  border-radius: var(--radius-pill);
  background: var(--color-paper);
  font-weight: 500;
  color: var(--color-stone-60);
}
.demo-callers > .is-on { background: var(--color-royal); border-color: var(--color-royal); color: var(--color-paper); }
.demo-callers > .is-on::after {
  content: "";
  position: absolute;
  inset-block-end: -5px;
  inset-inline-start: 50%;
  inline-size: 8px;
  block-size: 8px;
  background: inherit;
  transform: translateX(-50%) rotate(45deg);
}
.app-window, .demo-link-wrap, .demo-engine { grid-row: 2; }

/* — The browser window and the App inside it. — */
.app-window {
  min-inline-size: 0;
  background: var(--color-paper);
  border: 1px solid var(--color-stone-20);
  border-radius: var(--radius-soft);
  box-shadow: var(--shadow-card-hero);
  overflow: hidden;
}
.app-toolbar {
  display: flex;
  padding: 0.6em 1em;
  background: var(--color-stone-05);
  border-block-end: 1px solid var(--color-stone-20);
}
.app-address {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.3em 0.9em;
  border-radius: var(--radius-pill);
  background: var(--color-paper);
  font-size: 0.78em;
  color: var(--color-stone-60);
}
.app-address svg { inline-size: 0.95em; block-size: 0.95em; flex: none; }

.app-body { display: grid; grid-template-columns: 13em minmax(0, 1fr); }

/* The App's sidebar: the medallion, the wordmark and the menu. */
.app-side {
  display: grid;
  align-content: start;
  justify-items: center;
  gap: 0.55em;
  padding: 1.3em 0.75em;
  background: linear-gradient(180deg, var(--color-navy) 0%, var(--color-midnight) 100%);
  color: color-mix(in srgb, var(--color-mist) 78%, transparent);
}
.app-medallion {
  display: grid;
  place-items: center;
  inline-size: 3.6em;
  block-size: 3.6em;
  border-radius: 50%;
  background: var(--color-paper);
  color: var(--color-navy);
}
.app-medallion svg { inline-size: 2.5em; block-size: auto; }
.app-wordmark {
  inline-size: 100%;
  padding-block-end: 0.9em;
  border-block-end: 1px solid color-mix(in srgb, var(--color-mist) 12%, transparent);
  font-family: var(--font-display);
  font-size: 1.05em;
  text-align: center;
  color: var(--color-paper);
}
.app-nav {
  list-style: none;
  display: grid;
  gap: 0.2em;
  inline-size: 100%;
  padding-block-start: 0.3em;
  font-size: 0.72em;
}
.app-nav li {
  display: flex;
  align-items: center;
  gap: 0.75em;
  padding: 0.65em 0.85em;
  border-radius: 0.75em;
  white-space: nowrap;
}
.app-nav li.is-current { background: var(--color-royal); color: var(--color-paper); }
.app-nav svg { inline-size: 1.2em; block-size: 1.2em; flex: none; }

/* The page. */
.app-main {
  display: grid;
  align-content: start;
  gap: 0.85em;
  min-inline-size: 0;
  padding: 1.15em 1.4em 1.4em;
}
.app-title {
  display: flex;
  align-items: center;
  gap: 0.45em;
  font-size: 1.2em;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.app-title svg { inline-size: 1em; block-size: 1em; }

.app-section {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0 1em;
  padding: 0.95em 1.1em;
  border: 1px solid var(--color-stone-20);
  border-radius: var(--radius-default);
  box-shadow: 0 0.125em 0.25em color-mix(in srgb, var(--color-midnight) 7%, transparent);
}
.app-section-head { display: grid; gap: 0.2em; }
.app-section-title { display: flex; align-items: center; gap: 0.45em; font-size: 0.95em; font-weight: 600; }
.app-step {
  display: inline-grid;
  place-items: center;
  inline-size: 1.5em;
  block-size: 1.5em;
  border-radius: 50%;
  background: var(--color-royal);
  color: var(--color-paper);
  font-size: 0.8em;
}
.app-section-sub { font-size: 0.76em; color: var(--color-stone-60); }
.app-chevron { inline-size: 0.95em; block-size: 0.95em; color: var(--color-stone-60); }
.app-chevron.is-open { align-self: start; margin-block-start: 0.2em; transform: rotate(180deg); }

.app-fields {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.95em 1.2em;
  margin-block-start: 0.9em;
  padding-block-start: 1em;
  border-block-start: 1px solid var(--color-stone-20);
}
.app-field { display: grid; align-content: start; gap: 0.4em; min-inline-size: 0; }
.app-label { font-size: 0.76em; font-weight: 500; }
.app-switch { display: inline-flex; align-items: center; gap: 0.6em; block-size: 2em; font-size: 0.8em; }
.app-switch-track {
  position: relative;
  inline-size: 2em;
  block-size: 1.1em;
  border: 1px solid var(--color-stone-20);
  border-radius: var(--radius-pill);
}
.app-switch-track::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 0.15em;
  inline-size: 0.7em;
  block-size: 0.7em;
  border-radius: 50%;
  background: var(--color-stone-20);
  translate: 0 -50%;
}

/* An input. It takes the App's focus treatment, a Royal edge and ring,
   for as long as the clock has it focused (--fin to --fout). */
.app-input,
.app-segment {
  --focus: calc(clamp(0, (var(--t) - var(--fin)) * 20, 1) - clamp(0, (var(--t) - var(--fout)) * 20, 1));
}
.app-input {
  position: relative;
  display: grid;
  align-items: center;
  block-size: 2.4em;
  padding-inline: 0.75em;
  border: 1px solid color-mix(in srgb, var(--color-royal) calc(var(--focus) * 100%), var(--color-stone-20));
  border-radius: var(--radius-sm);
  background: var(--color-paper);
  box-shadow: 0 0 0 calc(var(--focus) * 0.2em) color-mix(in srgb, var(--color-royal) 30%, transparent);
  font-size: 0.82em;
  white-space: nowrap;
}
.app-input > .app-placeholder,
.app-input > .app-value { grid-area: 1 / 1; }
.app-placeholder {
  color: var(--color-stone-40);
  opacity: max(1 - clamp(0, (var(--t) - var(--at)) * 50, 1), var(--back));
}
.app-value { display: flex; align-items: center; min-inline-size: 0; }

/* Typing: each character takes its width at --at plus its place times
   --gap, so the caret after them moves as the text grows. */
.app-typed { opacity: var(--keep); }
.app-typed > * {
  --i: 0;
  font-size: calc(clamp(0, (var(--t) - var(--at) - var(--i) * var(--gap)) * 50, 1) * 1em);
}
.app-typed > :nth-child(2)  { --i: 1; }
.app-typed > :nth-child(3)  { --i: 2; }
.app-typed > :nth-child(4)  { --i: 3; }
.app-typed > :nth-child(5)  { --i: 4; }
.app-typed > :nth-child(6)  { --i: 5; }
.app-typed > :nth-child(7)  { --i: 6; }
.app-typed > :nth-child(8)  { --i: 7; }
.app-typed > :nth-child(9)  { --i: 8; }
.app-typed > :nth-child(10) { --i: 9; }
.app-caret {
  inline-size: 1.5px;
  block-size: 1.15em;
  margin-inline-start: 1px;
  background: var(--color-midnight);
  opacity: var(--focus);
}

/* Date of Birth: three segments that advance by themselves, as in the App. */
.app-input.is-date { display: flex; }
.app-segment { display: grid; justify-items: center; inline-size: 3ch; }
.app-segment.is-year { inline-size: 5ch; }
.app-segment > * { grid-area: 1 / 1; }
.app-segment.is-free { justify-items: start; inline-size: auto; }
.app-input > .app-segment { grid-area: 1 / 1; }
.app-slash { padding-inline: 0.35ch; color: var(--color-stone-40); }

/* Medicare card details: the number and the IRN, joined. */
.app-group { display: grid; grid-template-columns: minmax(0, 1fr) 4.6em; }
.app-group .app-input { z-index: calc(1 + var(--focus)); }
.app-group .app-input:first-child { border-start-end-radius: 0; border-end-end-radius: 0; }
.app-group .app-input + .app-input { margin-inline-start: -1px; border-start-start-radius: 0; border-end-start-radius: 0; }

/* Sex: Select gives way to Female, picked from the open list. */
.app-input.is-select { grid-template-columns: minmax(0, 1fr) auto; }
.app-input.is-select .app-placeholder { color: var(--color-midnight); }
.app-chosen { opacity: calc(clamp(0, (var(--t) - var(--at)) * 50, 1) * var(--keep)); }
.app-select-caret { grid-area: 1 / 2; inline-size: 0.9em; block-size: 0.9em; color: var(--color-stone-60); }
.app-menu {
  --open: calc(clamp(0, (var(--t) - var(--at) + 0.3) * 10, 1) - clamp(0, (var(--t) - var(--at) - 0.05) * 10, 1));
  position: absolute;
  inset-inline: -1px;
  inset-block-start: calc(100% + 0.3em);
  z-index: 2;
  display: grid;
  padding: 0.3em;
  background: var(--color-paper);
  border: 1px solid var(--color-stone-20);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-card-elevated);
  opacity: var(--open);
  transform: translateY(calc((1 - var(--open)) * -0.3em));
}
.app-menu > * { padding: 0.3em 0.6em; border-radius: 0.4em; }
.app-menu > .is-picked {
  background: color-mix(in srgb, var(--color-mist) calc(clamp(0, (var(--t) - var(--at) + 0.15) * 20, 1) * 100%), var(--color-paper));
  color: var(--color-navy);
}

/* The consent card and its buttons. */
.app-action {
  display: flex;
  align-items: center;
  gap: 1em 1.5em;
  padding: 0.85em 1.1em;
  border: 1px solid var(--color-stone-20);
  border-radius: var(--radius-default);
}
.app-action-text { flex: 1 1 auto; display: flex; align-items: center; gap: 0.55em; min-inline-size: 0; font-size: 0.8em; }
.app-action-text svg { inline-size: 1.6em; block-size: 1.6em; flex: none; color: var(--color-royal); }
.app-action-text strong { font-weight: 600; }
.app-buttons { position: relative; display: flex; gap: 0.5em; flex: none; }

/* Verify with Medicare: pressed at --t-click, then busy, dimmed with the
   App's spinner in place of its icon, until the result shows. */
.app-verify {
  --press: clamp(0, (var(--t) - var(--t-click)) / 0.2, 1);
  --bump: calc(2 * min(var(--press), 1 - var(--press)));
  --busy: calc(clamp(0, (var(--t) - var(--t-click) - 0.1) * 20, 1) - clamp(0, (var(--t) - var(--t-result)) * 20, 1));
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.65em 1.1em;
  border: 1px solid var(--color-navy);
  border-radius: var(--radius-default);
  background: color-mix(in srgb, var(--color-navy) calc(var(--bump) * 100%), var(--color-royal));
  color: var(--color-paper);
  font-size: 0.82em;
  font-weight: 500;
  white-space: nowrap;
  opacity: calc(1 - 0.35 * var(--busy));
  transform: scale(calc(1 - 0.03 * var(--bump)));
}
.app-verify-icon { display: grid; inline-size: 1.1em; block-size: 1.1em; }
.app-verify-icon > * { grid-area: 1 / 1; inline-size: 100%; block-size: 100%; }
.app-verify-icon svg { opacity: calc(1 - var(--busy)); }
.app-spinner {
  border: 0.15em solid currentColor;
  border-inline-end-color: transparent;
  border-radius: 50%;
  opacity: var(--busy);
  transform: rotate(calc(var(--t) * 1.3turn));
}
.app-clear {
  display: grid;
  place-items: center;
  padding-inline: 0.8em;
  border: 1px solid var(--color-stone-60);
  border-radius: var(--radius-default);
  color: var(--color-stone-60);
}
.app-clear svg { inline-size: 1em; block-size: 1em; }

/* The cursor glides in from below right over 600 ms (ease-out), clicks
   with a Royal ring, and leaves. Each one waits for its --at. */
.app-cursor {
  --go: clamp(0, (var(--t) - var(--at)) / 0.6, 1);
  --ease: calc(1 - (1 - var(--go)) * (1 - var(--go)));
  --ring: clamp(0, (var(--t) - var(--at) - 0.6) / 0.35, 1);
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 35%;
  z-index: 3;
  inline-size: 1.4em;
  block-size: 1.4em;
  opacity: calc(clamp(0, (var(--t) - var(--at)) * 10, 1) - clamp(0, (var(--t) - var(--at) - 0.85) / 0.3, 1));
  transform: translate(calc((1 - var(--ease)) * 5em), calc((1 - var(--ease)) * 3em));
}
.app-buttons > .app-cursor { inset-inline-start: 38%; font-size: 0.82em; }
.app-cursor svg {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  translate: -3px -2px;
  overflow: visible;
  fill: var(--color-midnight);
  stroke: var(--color-paper);
  stroke-width: 1.4;
  stroke-linejoin: round;
}
.app-cursor::after {
  content: "";
  position: absolute;
  inset-block-start: -0.6em;
  inset-inline-start: -0.6em;
  inline-size: 1.2em;
  block-size: 1.2em;
  border: 2px solid var(--color-royal);
  border-radius: 50%;
  opacity: calc(0.9 * (1 - var(--ring)) * clamp(0, (var(--t) - var(--at) - 0.6) * 100, 1));
  transform: scale(calc(0.4 + 0.9 * var(--ring)));
}

/* The answer, in the App's verified card. Its place is held open, so
   nothing moves when it arrives. */
.app-result { min-block-size: 3.4em; }
.app-verdict {
  --in: clamp(0, (var(--t) - var(--t-result)) / 0.3, 1);
  --out: calc((1 - var(--in)) * (1 - var(--in)));
  display: flex;
  align-items: flex-start;
  gap: 0.75em;
  padding: 0.85em 1em;
  border: 1px solid color-mix(in srgb, var(--verdict-eligible) 25%, transparent);
  border-inline-start: 4px solid var(--verdict-eligible);
  border-radius: var(--radius-default);
  background: color-mix(in srgb, var(--verdict-eligible) 4%, var(--color-paper));
  opacity: calc((1 - var(--out)) * var(--keep));
  transform: translateY(calc(var(--out) * 0.6em));
}
.app-verdict-icon { display: inline-flex; margin-block-start: 1px; color: var(--verdict-eligible); }
.app-verdict-icon svg { inline-size: 1.2em; block-size: 1.2em; }
.app-verdict-line { font-size: 0.85em; }
.app-verdict-title { margin-inline-end: 0.35em; font-weight: 700; }
.app-verdict-reason { color: var(--color-stone-60); }

/* — The engine room: RebateRight, and the Services Australia systems it
     consults, as tall as the App beside it. One line joins them, level
     with the action card at the moment it is clicked: the question goes
     in, each system is consulted in turn, and the tick comes back. — */
.demo-link-wrap { align-self: center; display: flex; align-items: center; }
.demo-link {
  --sending: calc(clamp(0, (var(--t) - var(--t-send)) * 10, 1) - clamp(0, (var(--t) - var(--t-send) - 0.6) * 10, 1));
  --answering: calc(clamp(0, (var(--t) - var(--t-answer)) * 10, 1) - clamp(0, (var(--t) - var(--t-result)) * 10, 1));
  --rest: color-mix(in srgb, var(--color-navy) 55%, var(--color-paper-dark));
  position: relative;
  inline-size: 7em;
  block-size: 2em;
}
/* One arrow, from a port on the App into the API. The question rides it
   in and the tick rides it back, and it takes their colour while they
   travel: Royal in, green back. */
.demo-lane {
  position: absolute;
  inset-block-start: calc(50% - 1px);
  inset-inline: 0.15em;
  block-size: 2px;
  border-radius: 2px;
  background: currentColor;
  color: color-mix(in srgb, var(--verdict-eligible) calc(var(--answering) * 100%), color-mix(in srgb, var(--color-royal) calc(var(--sending) * 100%), var(--rest)));
}
.demo-lane::before,
.demo-lane::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  translate: 0 -50%;
}
.demo-lane::before {          /* the port on the App */
  inset-inline-start: -0.25em;
  inline-size: 0.5em;
  block-size: 0.5em;
  border: 2px solid currentColor;
  border-radius: 50%;
  background: var(--color-paper-dark);
}
.demo-lane::after {           /* the arrowhead into the API */
  inset-inline-end: -0.1em;
  inline-size: 0.65em;
  block-size: 0.75em;
  background: currentColor;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}
/* A token rides the line, as on the home page's map: a question in, a
   tick back. */
.demo-packet {
  position: absolute;
  display: grid;
  place-items: center;
  inline-size: 1.6em;
  block-size: 1.6em;
  margin: -0.8em 0 0 -0.8em;
  border: 0.12em solid var(--color-paper);
  border-radius: 50%;
  color: var(--color-paper);
}
.demo-packet svg { inline-size: 58%; block-size: 58%; }
.demo-packet.is-out {
  --p: clamp(0, (var(--t) - var(--t-send)) / 0.6, 1);
  inset-block-start: 50%;
  inset-inline-start: calc(var(--p) * var(--p) * (3 - 2 * var(--p)) * 100%);
  background: var(--verdict-not-checked);
  opacity: var(--sending);
}
.demo-packet.is-back {
  --p: clamp(0, (var(--t) - var(--t-answer)) / 0.6, 1);
  inset-block-start: 50%;
  inset-inline-start: calc((1 - var(--p) * var(--p) * (3 - 2 * var(--p))) * 100%);
  background: var(--verdict-eligible);
  opacity: var(--answering);
}

.demo-engine {
  display: grid;
  align-content: start;
  gap: 0.6em;
  inline-size: 17.2em;
  padding: 1.3em 1.1em;
  background: var(--color-midnight);
  border-radius: var(--radius-soft);
  box-shadow: var(--shadow-card-hero);
  color: var(--color-paper);
}
.demo-engine-head {
  display: flex;
  align-items: center;
  gap: 0.55em;
  padding-block-end: 0.9em;
  border-block-end: 1px solid color-mix(in srgb, var(--color-mist) 14%, transparent);
  font-family: var(--font-display);
  font-size: 1.15em;
}
.demo-engine-mark { inline-size: 1.6em; block-size: auto; flex: none; }
.demo-engine-group {
  margin-block-start: 0.6em;
  font-size: max(0.62em, 9px);
  font-weight: 600;
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-mist) 70%, transparent);
}
.demo-systems { list-style: none; display: grid; gap: 0.5em; }
/* A system: at rest, being consulted (--from to --to), then done. */
.demo-system {
  --working: calc(clamp(0, (var(--t) - var(--from)) * 10, 1) - clamp(0, (var(--t) - var(--to)) * 10, 1));
  --done: calc(clamp(0, (var(--t) - var(--to)) * 10, 1) * var(--keep));
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-content: center;
  column-gap: 0.6em;
  inline-size: 15em;
  block-size: 3.6em;          /* fixed, so the light's outline (150 by 36) fits it exactly */
  padding-inline: 0.85em;
  border-radius: 0.6em;
  background: color-mix(in srgb, var(--color-paper) calc(6% + var(--working) * 6%), transparent);
}
.demo-system-name { font-size: 0.82em; font-weight: 600; }
.demo-system-sub { grid-column: 1; font-size: 0.7em; color: color-mix(in srgb, var(--color-mist) 72%, transparent); }
.demo-system-state {
  position: relative;
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  display: grid;
  place-items: center;
  inline-size: 1.3em;
  block-size: 1.3em;
  border-radius: 50%;
  background: color-mix(in srgb, var(--verdict-eligible) calc(var(--done) * 100%), transparent);
  color: var(--color-paper);
}
.demo-system-state svg { inline-size: 0.75em; block-size: 0.75em; opacity: var(--done); }
/* While consulted: a turning arc, one turn in 1.4 s, as on the home page.
   At rest: a quiet dot. */
.demo-system-state::before {
  content: "";
  position: absolute;
  inset: 0;
  border: 0.14em solid var(--color-sky);
  border-inline-end-color: color-mix(in srgb, var(--color-sky) 25%, transparent);
  border-radius: 50%;
  opacity: var(--working);
  transform: rotate(calc(var(--t) / 1.4 * 1turn));
}
.demo-system-state::after {
  content: "";
  position: absolute;
  inset: 0.45em;
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-mist) 30%, transparent);
  opacity: calc(1 - var(--working) - var(--done));
}
/* The light round a system's edge while it is consulted: four dashes of a
   fifth of the edge, their heads together and their tails fading. */
.demo-trace {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  overflow: visible;
  opacity: var(--working);
}
.demo-trace path {
  --f: 1;
  --pos: calc(clamp(0, (var(--t) - var(--from)) / (var(--to) - var(--from)), 1) * 150);
  vector-effect: non-scaling-stroke;
  fill: none;
  stroke: var(--color-sky);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: calc(var(--f) * 20) calc(100 - var(--f) * 20);
  stroke-dashoffset: calc(-1 * (var(--pos) + 20 * (1 - var(--f))));
  opacity: 0.23;
}
.demo-trace path:nth-child(2) { --f: 0.75; opacity: 0.3; }
.demo-trace path:nth-child(3) { --f: 0.5; opacity: 0.43; }
.demo-trace path:nth-child(4) { --f: 0.25; opacity: 0.74; }

/* — Pieces of the Eligibility Check page. — */
/* Medicare Item: the input and its Add button, joined. */
.app-add {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  padding-inline: 0.8em;
  border: 1px solid var(--color-royal);
  border-start-end-radius: var(--radius-sm);
  border-end-end-radius: var(--radius-sm);
  margin-inline-start: -1px;
  color: var(--color-royal);
  font-size: 0.82em;
  font-weight: 500;
}
.app-add svg { inline-size: 0.95em; block-size: 0.95em; }
.app-group.is-add { grid-template-columns: minmax(0, 1fr) auto; }
.app-group.is-add .app-input { border-start-end-radius: 0; border-end-end-radius: 0; }

/* The results under the action card. Each card's place is held, so the
   page never jumps; the item card waits in the verification card's place
   until the verification arrives, then moves down into its own. */
.app-stack { display: grid; gap: 1em; }
.app-stack .app-verdict { block-size: 3.2em; }
.app-item {
  --added: clamp(0, (var(--t) - var(--at)) / 0.3, 1);
  --done: clamp(0, (var(--t) - var(--t-result)) / 0.3, 1);
  --verdict-final: var(--verdict-eligible);
  --tone: color-mix(in srgb, var(--verdict-final) calc(var(--done) * 100%), var(--color-stone-60));
  border: 1px solid color-mix(in srgb, var(--tone) 25%, transparent);
  border-inline-start: 4px solid color-mix(in srgb, var(--verdict-final) calc(var(--done) * 100%), var(--color-stone-20));
  border-radius: var(--radius-default);
  background: color-mix(in srgb, var(--verdict-final) calc(var(--done) * 4%), var(--color-paper));
  opacity: calc(var(--added) * var(--keep));
  transform: translateY(calc((1 - var(--done)) * -4.2em));
}
.app-item-head { display: flex; align-items: center; gap: 0.6em; padding: 0.95em 1.2em; font-size: 0.82em; }
.app-item.is-no { --verdict-final: var(--verdict-not-eligible); }
.app-item-caret { inline-size: 0.9em; block-size: 0.9em; color: var(--color-stone-60); }
.app-item.is-open .app-item-caret { transform: rotate(calc(var(--done) * 90deg)); }
.app-item-name { font-weight: 600; }
.app-item-name b { font-weight: 600; color: var(--color-royal); }
.app-pill {
  display: inline-flex;
  padding-inline: 0.6em;
  border: 1px solid var(--tone);
  border-radius: var(--radius-pill);
  color: var(--tone);
  font-size: 0.86em;
  font-weight: 600;
  line-height: 1.6;
}
/* One label at a time, and the pill fits it: the other takes no width. */
.app-pill > * { display: inline-flex; align-items: center; gap: 0.3em; overflow: hidden; white-space: nowrap; }
.app-pill svg { inline-size: 0.95em; block-size: 0.95em; flex: none; }
.app-pill .is-waiting { max-inline-size: calc((1 - var(--done)) * 8em); opacity: calc(1 - var(--done)); }
.app-pill .is-result { max-inline-size: calc(var(--done) * 8em); opacity: var(--done); }
.app-trace { display: inline-flex; gap: 2px; margin-inline-start: auto; opacity: var(--done); }
.app-trace i { inline-size: 0.35em; block-size: 1em; border-radius: 1px; background: var(--verdict-eligible); }
.app-trace i.is-no { background: var(--verdict-not-eligible); }
/* The checks take no room until the answer arrives, then unfold. */
.app-item-detail {
  display: grid;
  gap: 0.75em;
  max-block-size: calc(var(--done) * 20em);
  overflow: hidden;
  padding: calc(var(--done) * 1.1em) 1.25em calc(var(--done) * 1.3em);
  border-block-start: 1px solid color-mix(in srgb, var(--verdict-final) calc(var(--done) * 20%), transparent);
  font-size: 0.78em;
  opacity: var(--done);
}
.app-item-reason { color: var(--color-stone-90); }
.app-checks-title {
  font-size: 0.86em;
  font-weight: 600;
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--color-stone-60);
}
/* The checks share three columns, so every reason starts on one line and
   a long one wraps under itself. */
.app-checks {
  list-style: none;
  display: grid;
  grid-template-columns: auto max-content minmax(0, 1fr);
  gap: 0.65em 0.75em;
}
.app-checks li {
  --in: clamp(0, (var(--t) - var(--at)) / 0.3, 1);
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: subgrid;
  align-items: baseline;
  opacity: var(--in);
}
.app-tick {
  display: grid;
  place-items: center;
  inline-size: 1.3em;
  block-size: 1.3em;
  align-self: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--verdict-eligible) 16%, transparent);
  color: var(--verdict-eligible);
  transform: scale(calc(0.4 + 0.6 * var(--in)));
}
.app-tick svg { inline-size: 0.75em; block-size: 0.75em; }
.app-checks b { font-weight: 600; }
/* The check that did not clear: its mark and its finding in the verdict red. */
.app-checks li.is-flag .app-tick { background: color-mix(in srgb, var(--verdict-not-eligible) 14%, transparent); color: var(--verdict-not-eligible); }
.app-checks li.is-flag span:last-child { color: var(--verdict-not-eligible); }
/* A reason keeps to one line; a long one ends in an ellipsis. */
.app-checks span:last-child { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; color: var(--color-stone-60); }

/* — Below 880px the drawing stops scaling: the App takes the width, and
     the engine room sits under it, the line running down to it. — */
@container demo-stage (max-width: 879.98px) {
  .demo-scene { grid-template-columns: minmax(0, 1fr); font-size: 13px; }
  .demo-callers, .app-window, .demo-link-wrap, .demo-engine { grid-column: 1; grid-row: auto; }
  .demo-link-wrap { justify-self: center; }
  .app-body { grid-template-columns: 12em minmax(0, 1fr); }
  .app-fields { grid-template-columns: repeat(auto-fit, minmax(12em, 1fr)); }
  .demo-link { inline-size: 2em; block-size: 5em; }
  .demo-lane { inset-inline: auto; inset-inline-start: calc(50% - 1px); inset-block: 0.15em; inline-size: 2px; block-size: auto; }
  .demo-lane::before, .demo-lane::after { inset-inline-start: 50%; translate: -50% 0; }
  .demo-lane::before { inset-block-start: -0.25em; }
  .demo-lane::after { inset-inline-end: auto; inset-block-start: auto; inset-block-end: -0.1em; inline-size: 0.75em; block-size: 0.65em; clip-path: polygon(0 0, 100% 0, 50% 100%); }
  /* The tokens ride the line down and back up, on its centre. */
  .demo-packet.is-out { inset-inline-start: 50%; inset-block-start: calc(var(--p) * var(--p) * (3 - 2 * var(--p)) * 100%); }
  .demo-packet.is-back { inset-inline-start: 50%; inset-block-start: calc((1 - var(--p) * var(--p) * (3 - 2 * var(--p))) * 100%); }
  .demo-engine { inline-size: auto; }
  .demo-systems { grid-template-columns: repeat(auto-fill, 15em); justify-content: start; }
}
@container demo-stage (max-width: 599.98px) {
  .app-body { grid-template-columns: minmax(0, 1fr); }
  .app-side { display: none; }
}
@container demo-stage (max-width: 459.98px) {
  .app-main { padding: 1em; }
  .app-action { flex-wrap: wrap; }
  .app-buttons { inline-size: 100%; }
  .app-verify { flex: 1; justify-content: center; }
  .app-result { min-block-size: 5em; }
}

/* — The player: the controls (styled in /css/player.css), centred under
     the drawing, then the three steps as a timeline. The line from each step's dot to
     the next fills while that part plays. — */
.demo-player { display: grid; margin-block-start: var(--space-24); }
.demo-steps {
  list-style: none;
  counter-reset: demo-step;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-block-start: var(--space-32);
}
.demo-steps li {
  --reached: clamp(0, (var(--t) - var(--from)) * 1000, 1);
  --fill: clamp(0, (var(--t) - var(--from)) / (var(--to) - var(--from)), 1);
  counter-increment: demo-step;
  position: relative;
  display: grid;
  align-content: start;
  gap: var(--space-12);
  padding-inline-end: var(--space-24);
}
/* The number is drawn, so its colour change is never read as text mid-way. */
.demo-steps li::before {
  content: counter(demo-step);
  display: grid;
  place-items: center;
  inline-size: 1.75rem;
  block-size: 1.75rem;
  border: 1px solid color-mix(in srgb, var(--color-royal) calc(var(--reached) * 100%), var(--color-stone-20));
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-royal) calc(var(--reached) * 100%), var(--color-paper));
  color: color-mix(in srgb, var(--color-paper) calc(var(--reached) * 100%), var(--color-stone-60));
  font-size: var(--type-label-m);
  font-weight: 600;
}
.demo-steps li::after {
  content: "";
  position: absolute;
  inset-block-start: calc(0.875rem - 1px);
  inset-inline: calc(1.75rem + var(--space-8)) var(--space-8);
  block-size: 2px;
  border-radius: 2px;
  background: linear-gradient(var(--color-royal), var(--color-royal)) 0 0 / calc(var(--fill) * 100%) 100% no-repeat,
              var(--color-stone-20);
}
.demo-steps li:last-child::after { inset-inline-end: 0; }
.demo-steps p { font-weight: 600; line-height: var(--lh-body); color: var(--color-midnight); }

/* On a phone the timeline runs down: each dot beside its step, the line
   between them filling downward. */
@media (max-width: 639.98px) {
  .demo-steps { grid-template-columns: minmax(0, 1fr); }
  .demo-steps li {
    grid-template-columns: 1.75rem minmax(0, 1fr);
    align-items: center;
    padding-inline-end: 0;
    padding-block-end: var(--space-32);
  }
  .demo-steps li:last-child { padding-block-end: 0; }
  .demo-steps li::after {
    inset-block: calc(1.75rem + var(--space-4)) var(--space-4);
    inset-inline: calc(0.875rem - 1px) auto;
    inline-size: 2px;
    block-size: auto;
    background: linear-gradient(var(--color-royal), var(--color-royal)) 0 0 / 100% calc(var(--fill) * 100%) no-repeat,
                var(--color-stone-20);
  }
  .demo-steps li:last-child::after { display: none; }
}

/* ============================================================ */
/* EACH DEMO'S TIMELINE — the verification demo                   */
/* (src/partials/pv-demo.html) and the eligibility demo           */
/* (src/partials/ec-demo.html), on their pages and in the deck.   */
/* ============================================================ */
.demo.is-verify {
  --demo-length: 14;
  --demo-still: 10.5;
  --demo-skip: 8.9;      /* Skip to the answer: the finished answer */
  --t-click: 6.1;
  --t-send: 6.3;
  --t-check: 6.9;
  --t-answer: 7.9;
  --t-result: 8.5;
  --t-clear: 13.3;
}
.demo.is-eligibility {
  --demo-length: 19;
  --demo-still: 15;
  --demo-skip: 13;        /* Skip to the answer: the finished answer, every check ticked */
  --t-click: 8.9;
  --t-send: 9.1;
  --t-check: 9.7;
  --t-answer: 10.7;
  --t-result: 11.3;
  --t-clear: 17.6;
}
/* The page scrolls as a person moving down the form would, in up to four
   moves: to Provider details (phones only), to Billing details, on until
   both items show in full before Check Eligibility, and to the answer. It
   scrolls back as the form clears. The distances suit each layout. */
.is-eligibility .app-main {
  --d0: 0em;
  --d1: 8.2em;
  --d2: 5em;
  --d3: 24.4em;
  --s0: clamp(0, (var(--t) - 4.45) / 0.5, 1);
  --s1: clamp(0, (var(--t) - 6.15) / 0.6, 1);
  --s2: clamp(0, (var(--t) - 7.95) / 0.5, 1);
  --s3: clamp(0, (var(--t) - var(--t-result) + 0.1) / 0.6, 1);
  --s4: clamp(0, (var(--t) - var(--t-clear) - 0.4) / 0.6, 1);
  --scroll: calc((var(--d0) * var(--s0) * var(--s0) * (3 - 2 * var(--s0)) + var(--d1) * var(--s1) * var(--s1) * (3 - 2 * var(--s1)) + var(--d2) * var(--s2) * var(--s2) * (3 - 2 * var(--s2)) + var(--d3) * var(--s3) * var(--s3) * (3 - 2 * var(--s3))) * (1 - var(--s4) * var(--s4) * (3 - 2 * var(--s4))));
  transform: translateY(calc(-1 * var(--scroll)));
}
.is-eligibility .app-body { block-size: 41em; overflow: hidden; }

/* The item number clears as each item is added, as in the App: 104 at
   7.0 s, 58121 at 7.9 s. */
.is-eligibility .app-input.is-item .app-placeholder {
  opacity: calc(1 - (clamp(0, (var(--t) - 6.3) * 50, 1) - clamp(0, (var(--t) - 7.05) * 50, 1)) - (clamp(0, (var(--t) - 7.3) * 50, 1) - clamp(0, (var(--t) - 7.95) * 50, 1)));
}
.is-eligibility .app-segment.is-first .app-typed { opacity: calc(1 - clamp(0, (var(--t) - 7.05) * 50, 1)); }
.is-eligibility .app-segment.is-second .app-typed { opacity: calc(1 - clamp(0, (var(--t) - 7.95) * 50, 1)); }
.is-eligibility .app-add {
  --press: max(clamp(0, (var(--t) - 7) / 0.2, 1) * (1 - clamp(0, (var(--t) - 7.2) / 0.2, 1)), clamp(0, (var(--t) - 7.9) / 0.2, 1) * (1 - clamp(0, (var(--t) - 8.1) / 0.2, 1)));
  position: relative;
  background: color-mix(in srgb, var(--color-mist) calc(var(--press) * 100%), transparent);
}
.is-eligibility .app-add > .app-cursor { inset-inline-start: 40%; font-size: 1em; }
.is-eligibility .app-field.is-switch { align-self: end; padding-block-end: 0.5em; }
/* Below 880px the App reflows and runs its full length, so it neither
   holds a fixed height nor scrolls. */
@container demo-stage (max-width: 879.98px) {
  .is-eligibility .app-body { block-size: auto; overflow: visible; }
  .is-eligibility .app-main { transform: none; }
}
/* On a phone the form is one column and long, so the window holds its
   height again and scrolls, with distances measured at 390px. */
@container demo-stage (max-width: 599.98px) {
  .is-eligibility .app-body { block-size: 45em; overflow: hidden; }
  .is-eligibility .app-main { --d0: 9.5em; --d1: 34.5em; --d2: 0em; --d3: 23.4em; transform: translateY(calc(-1 * var(--scroll))); }
}

@media (prefers-reduced-motion: reduce) {
  .demo { animation: none; --t: var(--demo-still); }
  .demo-steps li { --reached: 1; --fill: 1; }
}
