/* LynxOffice — product demos
 *
 * Each demo is a small looping reconstruction of ONE real interaction in the
 * app, drawn in HTML and CSS: no video and no JavaScript, so the page stays as
 * it was — static, and complete without scripts.
 *
 * What keeps them honest (the README's first rule applies to motion too):
 *  - Every label, control and result on screen exists in the shipped build,
 *    read out of the app's source. A demo may leave controls OUT to fit; it
 *    never adds one, and it never shows a result the app does not produce.
 *  - Colours are the app's own (--demo-* in styles.css), not the page's.
 *  - Motion demonstrates the operation and nothing else: no bounce, no
 *    parallax, no decoration. State changes take 120–200 ms like the app's;
 *    only the pointer moves at the pace of a hand.
 *  - prefers-reduced-motion gets one still frame of the result instead.
 *
 * Sizing: a demo is drawn on an em grid where 1em is 10 pt of the real UI, so
 * sizes read straight off the SwiftUI source (a 24 pt button is 2.4em). The
 * grid is --dw em wide, and 1em = container width / --dw, so a demo scales as
 * one piece from a 300 px card to a 560 px hero.
 */

/* ---------- the window ---------- */

.demo { margin: 0; }
.demo__stage { container-type: inline-size; }

.demo__win {
  --dw: 48;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  position: relative;
  font-size: 10px;                          /* fallback without container units */
  font-size: calc(100cqw / var(--dw));
  aspect-ratio: var(--ratio, 16 / 10);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 1em;
  border: 1px solid var(--demo-frame);
  background: var(--demo-ribbon);
  color: var(--demo-text);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, system-ui, sans-serif;
  line-height: 1.25;
  text-align: left;
  box-shadow: 0 1.8em 3.6em -1.6em rgba(0, 12, 28, 0.55), 0 0.2em 0.6em rgba(0, 12, 28, 0.12);
  -webkit-user-select: none;
  user-select: none;
  cursor: default;
}

/* Every size inside is in the grid's em; text sizes live on the text only. */
.demo__win * { box-sizing: border-box; }

.demo__bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 1em;
  height: 2.8em;
  padding: 0 1.2em;
  background: var(--demo-chrome);
  border-bottom: 1px solid var(--demo-line);
}
.demo__dots { display: flex; gap: 0.6em; flex: none; }
.demo__dots i { width: 1.1em; height: 1.1em; border-radius: 50%; background: #FF5F57; }
.demo__dots i:nth-child(2) { background: #FEBC2E; }
.demo__dots i:nth-child(3) { background: #28C840; }
.demo__doc { font-size: 1.2em; font-weight: 600; white-space: nowrap; color: var(--demo-text); }
.demo__dirty {
  display: inline-block;
  width: 0.5em; height: 0.5em;
  margin-left: 0.45em;
  vertical-align: 0.15em;
  border-radius: 50%;
  background: currentColor;
  opacity: 0;
}

.demo__ribbon {
  flex: none;
  display: flex;
  align-items: center;
  gap: 0.8em;
  padding: 0.7em 1.4em;
  background: var(--demo-ribbon);
  border-bottom: 1px solid var(--demo-line);
}

.demo__status {
  flex: none;
  display: flex;
  align-items: center;
  gap: 1em;
  height: 2.8em;
  padding: 0 1.4em;
  background: var(--demo-chrome);
  border-top: 1px solid var(--demo-line);
  color: var(--demo-text-2);
}
.demo__status .t { font: 500 1.1em/1 ui-monospace, "SF Mono", Menlo, monospace; white-space: nowrap; }
.demo__status .sep { color: var(--demo-text-3); }

/* ---------- controls ---------- */

.demo__cap {                                /* a ribbon group caption: 9 pt bold, uppercase */
  font-size: 0.9em;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--demo-text-2);
  white-space: nowrap;
}
.demo__lbl { display: block; font-size: 0.8em; font-weight: 500; color: var(--demo-text-2); white-space: nowrap; }

.demo__btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 2.4em;
  padding: 0 1.2em;
  border-radius: 0.6em;
  white-space: nowrap;
  background: var(--demo-control);
  color: var(--demo-text);
  box-shadow: inset 0 0 0 1px var(--demo-line);
}
.demo__btn > span { font-size: 1.3em; }
.demo__btn--prominent { background: var(--demo-accent); color: var(--demo-accent-ink); box-shadow: none; }

/* A slider as the app draws a mini one: a thin track, the value filled in the
 * accent, a round knob. The knob and fill are positioned by transform only. */
.demo__slider { position: relative; display: block; height: 1.4em; }
.demo__track {
  position: absolute; left: 0; right: 0; top: 50%;
  height: 0.35em; margin-top: -0.175em;
  border-radius: 0.2em;
  background: var(--demo-line);
  overflow: hidden;
}
.demo__fill {
  position: absolute; left: 0; top: 0; bottom: 0; width: 100%;
  background: var(--demo-accent);
  transform-origin: left center;
  transform: scaleX(var(--v, 0.5));
}
.demo__knob {
  position: absolute; top: 50%; left: 0;
  width: 1.3em; height: 1.3em; margin: -0.65em 0 0 -0.65em;
  border-radius: 50%;
  background: #FFFFFF;
  box-shadow: 0 0.05em 0.3em rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(0, 0, 0, 0.06);
}

.demo__badge {                               /* the status bar's "Modified" capsule */
  margin-left: auto;
  padding: 0.3em 0.8em;
  border-radius: 1em;
  background: rgba(255, 149, 0, 0.18);
  color: var(--demo-text);
  opacity: 0;
}
.demo__badge span { font-size: 1.1em; font-weight: 700; }

/* ---------- the pointer ---------- */

.demo__ptr {
  position: absolute;
  left: 0; top: 0;
  z-index: 9;
  width: 1.5em; height: 2.2em;
  pointer-events: none;
  filter: drop-shadow(0 0.08em 0.14em rgba(0, 0, 0, 0.35));
  will-change: transform;
}

/* ---------- reduced motion: one still frame of the result ---------- */

@media (prefers-reduced-motion: reduce) {
  .demo *, .demo *::before, .demo *::after { animation: none !important; }
  .demo__ptr { display: none; }
}

/* ===================================================================== */
/* Images — adjust brightness, then Apply (the Images page's hero)        */
/* ===================================================================== */
/* Source: ImageEditorView.swift. The Edit tab's ADJUST group at its narrowest
 * one-line layout: four sliders at their 64 pt minimum, Reset, Apply. Moving a
 * slider enables Reset and Apply and previews live; Apply bakes the change,
 * marks the document modified, and returns the sliders to centre. */

.demo-img .demo__win { --dw: 49; --ratio: 760 / 446; --t: 9s; }

.demo-img__ribbon { height: 5.2em; }
.demo-img__col { width: 6.4em; flex: none; }
.demo-img__col .demo__lbl { margin-bottom: 0.1em; }
.demo-img__pair { display: flex; gap: 0.8em; }

.demo-img__canvas {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--demo-image-ground);
  overflow: hidden;
}
.demo-img__poster { width: 18.6em; height: auto; display: block; }

/* Brightness slider: knob and fill travel together (value 0.5 → 0.74). */
.demo-img__b .demo__knob { left: 50%; animation: img-knob var(--t) infinite; }
.demo-img__b .demo__fill { animation: img-fill var(--t) infinite; }
.demo-img__col:not(.demo-img__b) .demo__knob { left: 50%; }

@keyframes img-knob {
  0%, 14%   { transform: translateX(0); }
  30%, 45%  { transform: translateX(1.55em); animation-timing-function: var(--ease); }
  47%, 100% { transform: translateX(0); }
}
@keyframes img-fill {
  0%, 14%   { transform: scaleX(0.5); }
  30%, 45%  { transform: scaleX(0.742); animation-timing-function: var(--ease); }
  47%, 100% { transform: scaleX(0.5); }
}

/* The live preview, then the committed bitmap. */
.demo-img__poster { animation: img-bright var(--t) infinite; }
@keyframes img-bright {
  0%, 14%   { filter: brightness(1); }
  30%, 92%  { filter: brightness(1.32); }
  100%      { filter: brightness(1); }
}

/* Reset and Apply: disabled at identity, enabled while a slider is off centre. */
.demo-img__reset, .demo-img__apply { animation: img-enable var(--t) infinite; }
@keyframes img-enable {
  0%, 15%   { opacity: 0.42; }
  17%, 45%  { opacity: 1; }
  47%, 100% { opacity: 0.42; }
}
.demo-img__apply { background: var(--demo-control); color: var(--demo-text-2); box-shadow: inset 0 0 0 1px var(--demo-line); }
.demo-img__apply::before {                   /* the prominent fill, faded in with the enabled state */
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  background: var(--demo-accent);
  opacity: 0;
  animation: img-apply-fill var(--t) infinite;
}
.demo-img__apply > span { position: relative; animation: img-apply-ink var(--t) infinite; }
@keyframes img-apply-fill {
  0%, 15%   { opacity: 0; }
  17%, 42%  { opacity: 1; filter: brightness(1); }
  43%, 44%  { opacity: 1; filter: brightness(0.72); }   /* pressed */
  45%       { opacity: 1; }
  47%, 100% { opacity: 0; }
}
@keyframes img-apply-ink {
  0%, 15%   { color: var(--demo-text-2); }
  17%, 45%  { color: var(--demo-accent-ink); }
  47%, 100% { color: var(--demo-text-2); }
}

/* After Apply: the status bar says Modified, the tab gets its dot. */
.demo-img .demo__badge, .demo-img .demo__dirty { animation: img-modified var(--t) infinite; }
@keyframes img-modified {
  0%, 45%   { opacity: 0; }
  47%, 92%  { opacity: 1; }
  96%, 100% { opacity: 0; }
}

/* The pointer: in, onto the Brightness knob, drag, to Apply, click, out. */
.demo-img .demo__ptr {
  /* the arrow's tip is 0.15em in from its box; targets measured on the grid */
  --p-knob: translate(9.32em, 5.84em);
  --p-knob-end: translate(10.87em, 5.84em);
  --p-apply: translate(44.3em, 5.3em);
  animation: img-ptr var(--t) infinite;
}
@keyframes img-ptr {
  0%        { transform: translate(40em, 24em); opacity: 0; }
  4%        { opacity: 1; animation-timing-function: ease-in-out; }
  12%       { transform: var(--p-knob); }
  14%       { transform: var(--p-knob); animation-timing-function: var(--ease); }
  30%       { transform: var(--p-knob-end); animation-timing-function: ease-in-out; }
  40%       { transform: var(--p-apply); }
  43%       { transform: var(--p-apply) scale(0.9); }
  45%       { transform: var(--p-apply); animation-timing-function: ease-in-out; }
  58%, 88%  { transform: translate(40em, 24em); opacity: 1; }
  92%, 100% { transform: translate(40em, 24em); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .demo-img__b .demo__knob { transform: translateX(1.55em); }
  .demo-img__b .demo__fill { transform: scaleX(0.742); }
  .demo-img__poster { filter: brightness(1.32); }
  .demo-img__apply::before { opacity: 1; }
  .demo-img__apply > span { color: var(--demo-accent-ink); }
}

/* ---------- placements ---------- */

.hero__demo {                                /* beside the copy; below it when narrow */
  flex: 1 1 400px;
  max-width: 560px;
  align-self: center;
}
@media (max-width: 900px) { .hero__demo { max-width: 540px; margin-inline: auto; } }
.flow--demo .flow__text { display: grid; gap: 8px; align-content: start; }
.flow__demo { max-width: 560px; }
@media (min-width: 860px) {
  .flow--demo { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); align-items: center; }
}

/* ---------- more shared controls ---------- */

.demo__ico { width: 1.6em; height: 1.6em; flex: none; display: block; }

.demo__tabs { display: flex; align-items: center; gap: 1.4em; flex: none; }
.demo__tabs > span { position: relative; padding-bottom: 0.45em; font-size: 1.1em; font-weight: 500; color: var(--demo-text-2); }
.demo__tabs > .is-on { font-weight: 600; color: var(--demo-text); }
.demo__tabs > .is-on::after {                /* the 28 × 2 pt accent underline */
  content: "";
  position: absolute; left: 50%; bottom: 0;
  width: 2.55em; height: 0.18em; margin-left: -1.27em;
  border-radius: 1em;
  background: var(--demo-accent);
}

.demo__vr { flex: none; width: 1px; height: 3em; background: var(--demo-line); }
.demo__vr--thin { height: 2em; opacity: 0.8; }

.demo__ibtn, .demo__sbtn {                   /* .bordered, .controlSize(.small) */
  flex: none;
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5em;
  height: 2.2em;
  border-radius: 0.55em;
  background: var(--demo-control);
  box-shadow: inset 0 0 0 1px var(--demo-line);
  color: var(--demo-text);
}
.demo__ibtn { width: 2.8em; }
.demo__ibtn .demo__ico { width: 1.4em; height: 1.4em; }
.demo__sbtn { padding: 0 0.9em; }
.demo__sbtn .demo__ico { width: 1.3em; height: 1.3em; }
.demo__sbtn > span { font-size: 1em; font-weight: 500; white-space: nowrap; }

.demo__chip { flex: none; padding: 0.4em 0.8em; border-radius: 1em; background: rgba(89, 99, 109, 0.12); color: var(--demo-text-2); }
.demo__chip > span { font-size: 1.1em; font-weight: 500; white-space: nowrap; }
.demo__chip--orange { background: rgba(255, 149, 0, 0.14); color: #C45A00; }

.demo__toast {                               /* black 78 % capsule, 44 pt up, 2.2 s */
  position: absolute; left: 50%; bottom: 4.4em;
  z-index: 8;
  padding: 0.8em 1.4em;
  border-radius: 2em;
  background: rgba(0, 0, 0, 0.78);
  color: #FFFFFF;
  white-space: nowrap;
  transform: translateX(-50%);
  opacity: 0;
}
.demo__toast > span { font-size: 1.2em; font-weight: 500; }

.demo__caret { display: inline-block; width: 0.12em; height: 1.3em; margin-left: 0.1em; vertical-align: -0.2em; background: #111111; }

/* ===================================================================== */
/* PDF — select, Highlight, then a sticky note (the PDF page's hero)       */
/* ===================================================================== */
/* Source: PDFEditorView.swift. Markup tools are icon-only and disabled until
 * there is a text selection; Highlight marks the selection in systemYellow at
 * 40 % and says "Highlight added.". Sticky Note drops a note at the visible
 * centre and opens its popup (#FFFACC, blue border); clicking away commits it
 * with "Annotation updated.". The Saved chip turns to Modified. */

.demo-pdf .demo__win { --dw: 52; --ratio: 4 / 3; --t: 12s; }

.demo-pdf__head {
  flex: none;
  display: flex; align-items: center; gap: 1em;
  height: 5em;
  padding: 0 1.4em;
  background: var(--demo-ribbon);
}
.demo-pdf__tile {
  flex: none;
  display: grid; place-items: center;
  width: 3.2em; height: 3.2em;
  border-radius: 0.8em;
  background: #E5484D;
  color: #FFFFFF;
}
.demo-pdf__tile .demo__ico { width: 2em; height: 2em; stroke-width: 2; }
.demo-pdf__name { display: grid; gap: 0.15em; }
.demo-pdf__name b { font-size: 1.4em; font-weight: 700; }
.demo-pdf__name span { font-size: 1.1em; color: var(--demo-text-2); white-space: nowrap; }
.demo-pdf__chips { margin-left: auto; display: grid; justify-items: end; }
.demo-pdf__chips > * { grid-area: 1 / 1; }         /* Saved and Modified share one place */
.demo-pdf__modified { opacity: 0; animation: pdf-modified var(--t) infinite; }

.demo-pdf__ribbon { height: 4.6em; gap: 1em; }
.demo-pdf__markup { display: flex; gap: 0.6em; flex: none; }
.demo-pdf__markup .demo__ibtn { opacity: 0.4; animation: pdf-markup var(--t) infinite; }

.demo-pdf__canvas {
  position: relative;
  flex: 1 1 auto;
  overflow: hidden;
  background: var(--demo-canvas);
}
.demo-pdf__page {
  position: absolute; left: 3.2em; top: -1em;
  width: 64em; height: 40em;
  padding: 2.2em 3.4em;
  background: #FFFFFF;
  color: #1B2B36;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  box-shadow: 0 0.1em 0.6em rgba(0, 0, 0, 0.18);
}
.demo-pdf__page p { margin: 0; white-space: nowrap; }
.demo-pdf__title { font-size: 2.2em; font-weight: 700; color: #1E3448; letter-spacing: -0.01em; }
.demo-pdf__sub { margin-top: 0.3em !important; font-size: 1.1em; color: #3E4C57; }
.demo-pdf__h { margin-top: 0.9em !important; font-size: 1.5em; font-weight: 700; color: #1E3448; }
.demo-pdf__p { margin-top: 0.5em !important; font-size: 1.15em; line-height: 1.6; }
.demo-pdf__s1 { position: relative; }
.demo-pdf__sel, .demo-pdf__mark { position: absolute; left: -0.1em; right: -0.1em; top: -0.05em; bottom: -0.05em; }
.demo-pdf__sel {                              /* the text selection, drawn by the drag */
  background: rgba(0, 110, 255, 0.24);
  transform-origin: left center;
  transform: scaleX(0);
  animation: pdf-sel var(--t) infinite;
}
.demo-pdf__mark { background: rgba(255, 204, 0, 0.4); opacity: 0; animation: pdf-mark var(--t) infinite; }
.demo-pdf__table {
  display: grid; grid-template-columns: 10em 10em 9em 7em;
  margin-top: 1.2em;
  padding: 0.6em 0.8em;
  background: #E6F2EA;
  font-size: 1em; font-weight: 700;
}

.demo-pdf__pin {                              /* the note, dropped at the visible centre */
  position: absolute; left: 21.1em; top: 12.2em;
  display: grid; place-items: center;
  width: 3.2em; height: 3.2em;
  border-radius: 0.4em;
  background: #FFD60A;
  color: #3A2E00;
  opacity: 0;
  animation: pdf-pin var(--t) infinite;
}
.demo-pdf__pin .demo__ico { width: 2.2em; height: 2.2em; }
.demo-pdf__pop {                              /* 230 × 130 pt popup, right of the note */
  position: absolute; left: 24.7em; top: 11.2em;
  width: 23em; height: 13em;
  padding: 0.8em 1em;
  background: #FFFACC;
  border: 0.15em solid #0A84FF;
  border-radius: 0.3em;
  color: #000000;
  opacity: 0;
  animation: pdf-pop var(--t) infinite;
}
.demo-pdf__typed { display: inline-block; clip-path: inset(0 100% 0 0); animation: pdf-type var(--t) infinite; }
.demo-pdf__typed > span { font-size: 1.2em; white-space: nowrap; }
.demo-pdf__pop .demo__caret { opacity: 0; animation: pdf-caret var(--t) infinite; }

.demo-pdf__t1 { animation: pdf-t1 var(--t) infinite; }
.demo-pdf__t2 { animation: pdf-t2 var(--t) infinite; }
.demo-pdf__t3 { animation: pdf-t3 var(--t) infinite; }
.demo-pdf__saved { animation: pdf-saved var(--t) infinite; }
.demo-pdf .demo__dirty { animation: pdf-dirty var(--t) infinite; }

@keyframes pdf-sel {
  0%, 12%    { transform: scaleX(0); opacity: 1; }
  22%, 30.5% { transform: scaleX(1); opacity: 1; }
  31.5%, 100% { transform: scaleX(1); opacity: 0; }
}
@keyframes pdf-markup {                       /* enabled while there is a selection */
  0%, 12.5%  { opacity: 0.4; }
  13.5%, 31% { opacity: 1; }
  32%, 100%  { opacity: 0.4; }
}
@keyframes pdf-mark {
  0%, 31%    { opacity: 0; }
  32%, 95%   { opacity: 1; }
  99%, 100%  { opacity: 0; }
}
@keyframes pdf-t1 { 0%, 31.5% { opacity: 0; } 33%, 44% { opacity: 1; } 45.5%, 100% { opacity: 0; } }
@keyframes pdf-t2 { 0%, 47.5% { opacity: 0; } 49%, 62% { opacity: 1; } 63.5%, 100% { opacity: 0; } }
@keyframes pdf-t3 { 0%, 72.5% { opacity: 0; } 74%, 86% { opacity: 1; } 87.5%, 100% { opacity: 0; } }
@keyframes pdf-pin { 0%, 47% { opacity: 0; } 48%, 95% { opacity: 1; } 99%, 100% { opacity: 0; } }
@keyframes pdf-pop { 0%, 47% { opacity: 0; } 48%, 72% { opacity: 1; } 73%, 100% { opacity: 0; } }
@keyframes pdf-type {
  0%, 50%    { clip-path: inset(0 100% 0 0); animation-timing-function: steps(33, end); }
  63%, 100%  { clip-path: inset(0 0 0 0); }
}
@keyframes pdf-caret { 0%, 63% { opacity: 0; } 64%, 67% { opacity: 1; } 68%, 69% { opacity: 0; } 70%, 72% { opacity: 1; } 73%, 100% { opacity: 0; } }
@keyframes pdf-saved {                        /* the chip text swaps Saved → Modified */
  0%, 31%   { opacity: 1; }
  32%, 96%  { opacity: 0; }
  100%      { opacity: 1; }
}
@keyframes pdf-dirty { 0%, 31% { opacity: 0; } 32%, 96% { opacity: 1; } 100% { opacity: 0; } }
@keyframes pdf-modified { 0%, 31% { opacity: 0; } 32%, 96% { opacity: 1; } 100% { opacity: 0; } }

.demo-pdf .demo__ptr {
  --p-sel0: translate(6.65em, 22.65em);
  --p-sel1: translate(48.05em, 22.65em);
  --p-hl: translate(17.8em, 10em);
  --p-note: translate(31.05em, 10em);
  --p-rest: translate(33em, 34.4em);
  --p-out: translate(11.85em, 34.35em);
  animation: pdf-ptr var(--t) infinite;
}
@keyframes pdf-ptr {
  0%          { transform: translate(56em, 36em); opacity: 0; }
  5%          { opacity: 1; animation-timing-function: ease-in-out; }
  10%         { transform: var(--p-sel0); }
  12%         { transform: var(--p-sel0); animation-timing-function: linear; }
  22%         { transform: var(--p-sel1); animation-timing-function: ease-in-out; }
  29%         { transform: var(--p-hl); }
  30.5%       { transform: var(--p-hl) scale(0.9); }
  31.5%       { transform: var(--p-hl); animation-timing-function: ease-in-out; }
  45%         { transform: var(--p-note); }
  46.5%       { transform: var(--p-note) scale(0.9); }
  47.5%       { transform: var(--p-note); animation-timing-function: ease-in-out; }
  52%, 64%    { transform: var(--p-rest); animation-timing-function: ease-in-out; }
  70%         { transform: var(--p-out); }
  71.5%       { transform: var(--p-out) scale(0.9); }
  72.5%       { transform: var(--p-out); animation-timing-function: ease-in-out; }
  84%, 95%    { transform: translate(56em, 36em); opacity: 1; }
  99%, 100%   { transform: translate(56em, 36em); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .demo-pdf__mark, .demo-pdf__pin, .demo-pdf__pop { opacity: 1; }
  .demo-pdf__typed { clip-path: none; }
  .demo-pdf__saved { opacity: 0; }
  .demo-pdf__modified { opacity: 1; }
  .demo-pdf .demo__dirty { opacity: 1; }
}

/* ---------- the document editors' band (Word, Markdown, sheet, deck) ---------- */

.demo-ed__qa {                               /* quick access: 20 pt buttons, 14 pt inset */
  flex: none;
  display: flex; align-items: center; gap: 0.6em;
  height: 2.8em;
  padding: 0 1.4em;
  background: var(--demo-band);
}
.demo-ed__qb { flex: none; display: grid; place-items: center; width: 2em; height: 2em; color: var(--demo-text); }
.demo-ed__qb .demo__ico { width: 1.35em; height: 1.35em; stroke-width: 2; }
.demo-ed__save { opacity: 0.35; }            /* disabled until there is something to save */
.demo-ed__qdiv { flex: none; width: 1px; height: 1.8em; background: var(--demo-line); }
.demo-ed__name { display: flex; align-items: center; gap: 0.45em; min-width: 0; color: var(--demo-text-2); }
.demo-ed__name .demo__ico { width: 1.3em; height: 1.3em; }
.demo-ed__name b { font-size: 1.2em; font-weight: 600; white-space: nowrap; color: var(--demo-text); }
.demo-ed__chip { margin-left: auto; display: grid; justify-items: end; }
.demo-ed__chip > span { grid-area: 1 / 1; display: flex; align-items: center; gap: 0.4em; white-space: nowrap; }
.demo-ed__chip > span > i { width: 0.6em; height: 0.6em; border-radius: 50%; background: #34C759; }
.demo-ed__chip > span > span { font-size: 1em; color: var(--demo-text-2); }
.demo-ed__modified { opacity: 0; }
.demo-ed__modified > i { background: #FF9500 !important; }
.demo-ed__modified > span { color: #C45A00 !important; }

.demo-ed__tabs {                             /* the tabs share the row's width */
  flex: none;
  display: flex; align-items: stretch;
  height: 2.9em;
  padding: 0 0.8em;
  background: var(--demo-band);
  border-bottom: 1px solid var(--demo-line);
}
.demo-ed__tabs > span { position: relative; flex: 1 1 0; display: grid; place-items: center; color: var(--demo-text); white-space: nowrap; }
.demo-ed__tabs > span > span { font-size: 1.2em; }
.demo-ed__tabs > .is-on { color: var(--demo-accent); font-weight: 600; }
.demo-ed__tabs > .is-on::after { content: ""; position: absolute; left: 0.4em; right: 0.4em; bottom: 0; height: 0.2em; background: var(--demo-accent); }
.demo-ed__tabs > .demo-ed__collapse { flex: 0 0 2.4em; color: var(--demo-text-2); }
.demo-ed__collapse .demo__ico { width: 1.3em; height: 1.3em; }

.demo-ed__ribbon {                           /* groups: controls, caption below */
  flex: none;
  display: flex; align-items: flex-start; gap: 0.5em;
  height: 6em;
  padding: 0.5em 1em 0;
  background: var(--demo-ribbon);
  border-bottom: 1px solid var(--demo-line);
}
.demo-ed__grp { flex: none; display: flex; flex-direction: column; align-items: center; }
.demo-ed__ctl { display: flex; align-items: center; gap: 0.4em; height: 4.2em; padding: 0 0.5em; }
.demo-ed__cap { font-size: 0.8em; font-weight: 500; color: var(--demo-text-3); white-space: nowrap; }
.demo-ed__div { flex: none; width: 1px; height: 3.6em; margin-top: 0.3em; background: var(--demo-line); }
.demo-ed__tile {                             /* a 44 × 40 pt tile: icon over label */
  flex: none;
  display: grid; justify-items: center; align-content: center; gap: 0.2em;
  width: 4.4em; height: 4em;
  border-radius: 0.5em;
  color: var(--demo-text);
}
.demo-ed__tile .demo__ico { width: 1.9em; height: 1.9em; }
.demo-ed__tile > span { font-size: 1em; }
.demo-ed__stack { display: grid; gap: 0.2em; }
.demo-ed__cb {                               /* a compact 28 × 24 pt button, 13 pt symbol */
  flex: none;
  display: grid; place-items: center;
  width: 2.8em; height: 2.4em;
  border-radius: 0.4em;
  color: var(--demo-text);
}
.demo-ed__cb .demo__ico { width: 1.5em; height: 1.5em; }
.demo-ed__glyph { font-size: 1.45em; line-height: 1; font-style: normal; text-decoration: none; }
.demo-ed__glyph--i { font-style: italic; font-family: Georgia, "Times New Roman", serif; font-weight: 500; }
b.demo-ed__glyph { font-weight: 800; }
u.demo-ed__glyph { text-decoration: underline; text-underline-offset: 0.12em; text-decoration-thickness: 0.07em; }
s.demo-ed__glyph { text-decoration: line-through; text-decoration-thickness: 0.07em; }
.demo-ed__menu { flex: none; display: flex; align-items: center; color: var(--demo-text); }
.demo-ed__cg { display: grid; justify-items: center; align-content: center; width: 2.8em; height: 2.4em; }  /* ColorGlyphLabel */
.demo-ed__cg > b { font-size: 1.3em; font-weight: 700; line-height: 1; }
.demo-ed__cg > i { display: block; width: 1.8em; height: 0.3em; margin-top: 0.12em; }
.demo-ed__cg .demo-ed__hlico { width: 1.35em; height: 1.35em; }
.demo-ed__chev { width: 1em; height: 1em; margin-left: -0.3em; color: var(--demo-text-2); }

.demo__status--sans .t { font-family: inherit; font-weight: 400; }
.demo__rule { flex: none; width: 1px; height: 1.4em; background: var(--demo-line); }
.demo__status-r { margin-left: auto; }
.demo__status-r .t { font-family: ui-monospace, "SF Mono", Menlo, monospace; }

/* A pull-down menu as macOS draws one: system material, 13 pt items, the
 * item under the pointer in the accent colour. */
.demo-menu {
  position: absolute; z-index: 7;
  display: grid;
  min-width: 15em;
  padding: 0.5em;
  border-radius: 0.9em;
  background: var(--demo-menu);
  box-shadow: 0 0.1em 0.2em rgba(0, 0, 0, 0.12), 0 1em 2.6em rgba(0, 0, 0, 0.24), inset 0 0 0 1px rgba(0, 0, 0, 0.08);
  color: var(--demo-text);
  opacity: 0;
}
.demo-menu__it { position: relative; display: flex; align-items: center; gap: 0.6em; height: 2.2em; padding: 0 0.9em; border-radius: 0.5em; }
.demo-menu__it > i { flex: none; width: 1.4em; height: 1.4em; border-radius: 0.4em; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25); }
.demo-menu__it > span { font-size: 1.3em; white-space: nowrap; }
.demo-menu__it--plain { padding-left: 3em; }
.demo-menu__sep { display: block; height: 1px; margin: 0.45em 0.9em; background: var(--demo-line); }
.demo-menu__it::before {                     /* the hover highlight, faded in on cue */
  content: ""; position: absolute; inset: 0; z-index: -1;
  border-radius: inherit;
  background: var(--demo-accent);
  opacity: 0;
}

/* ===================================================================== */
/* Word — select, Bold, Highlight, Save (the Word page's hero)             */
/* ===================================================================== */
/* Source: WordEditorView.swift (quick access, Home tab, status bar) and
 * WordStructuredEditor.swift / WordPageView.swift — the "Fidelity" canvas a
 * .docx opens in by default. Its selection is teal #0F8B8D at 25 % and its
 * caret a solid teal bar. Bold and Highlight act on the selection. On this
 * canvas the B button does NOT light up afterwards (only the legacy editor
 * reports formatting back), so here it stays unlit too. Highlight ▸ Yellow is
 * a #FFFF00 run fill. The chip reads Saved / Modified; Save is enabled only
 * while there is something to save. */

.demo-word .demo__win { --dw: 52; --ratio: 5 / 4; --t: 12s; background: var(--demo-band); }

.demo-word__canvas { position: relative; flex: 1 1 auto; overflow: hidden; background: var(--demo-canvas); }
.demo-word__page {
  position: absolute; left: 2.6em; right: 2.6em; top: 1em;
  height: 40em;
  padding: 1.9em 3.6em;
  background: #FFFFFF;
  color: #222222;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  box-shadow: 0 0.2em 0.6em rgba(0, 0, 0, 0.18);
}
.demo-word__page p { margin: 0; white-space: nowrap; }
.demo-word__title { font: 700 2.4em/1.12 Georgia, "Times New Roman", serif; color: #123C4A; letter-spacing: -0.005em; }
.demo-word__lead { margin-top: 0.35em !important; font-size: 1.2em; line-height: 1.3; color: #44585C; }
.demo-word__lead b { font-weight: 700; }
.demo-word__p { margin-top: 0.7em !important; font-size: 1.1em; line-height: 1.5; }
.demo-word__h { margin-top: 0.7em !important; font: 700 1.5em/1.2 Georgia, "Times New Roman", serif; color: #123C4A; }

.demo-word__s { position: relative; }
.demo-word__txt { position: relative; animation: word-bold var(--t) infinite; }
.demo-word__hl, .demo-word__sel { position: absolute; left: -0.05em; right: -0.05em; top: 0.05em; bottom: 0.02em; }
.demo-word__hl { background: #FFFF00; opacity: 0; animation: word-hl var(--t) infinite; }
.demo-word__sel {
  background: rgba(15, 139, 141, 0.25);
  transform-origin: left center;
  transform: scaleX(0);
  animation: word-sel var(--t) infinite;
}
.demo-word__caret {
  display: inline-block;
  width: 0.1em; height: 1.15em;
  margin-left: 0.08em;
  vertical-align: -0.2em;
  background: #0F8B8D;
  opacity: 0;
  animation: word-caret var(--t) infinite;
}
.demo-word__hlbar { background: #FFCC00; animation: word-hlbar var(--t) infinite; }  /* systemYellow until a pick */

.demo-word__menu { top: 12.7em; left: 27.6em; animation: word-menu var(--t) infinite; }
.demo-word__yellow::before { animation: word-item var(--t) infinite; }
.demo-word__yellow > span { animation: word-item-ink var(--t) infinite; }

.demo-word .demo-ed__save { animation: word-save var(--t) infinite; }
.demo-word .demo-ed__saved { animation: word-saved var(--t) infinite; }
.demo-word .demo-ed__modified { animation: word-modified var(--t) infinite; }
.demo-word .demo__dirty { animation: word-modified var(--t) infinite; }

@keyframes word-sel {
  0%, 9%      { transform: scaleX(0); opacity: 1; }
  17%, 46.5%  { transform: scaleX(1); opacity: 1; }
  47%, 100%   { transform: scaleX(1); opacity: 0; }
}
@keyframes word-bold {
  0%, 25.4%   { font-weight: 400; }
  25.5%, 98.9% { font-weight: 700; }
  99%, 100%   { font-weight: 400; }
}
@keyframes word-hl {
  0%, 39.4%   { opacity: 0; }
  39.5%, 96%  { opacity: 1; }
  99%, 100%   { opacity: 0; }
}
@keyframes word-hlbar {
  0%, 39.4%   { background: #FFCC00; }
  39.5%, 96%  { background: #FFFF00; }
  99%, 100%   { background: #FFCC00; }
}
@keyframes word-menu {
  0%, 31.9%   { opacity: 0; transform: translateY(-0.3em); }
  33%, 38.9%  { opacity: 1; transform: none; }
  40%, 100%   { opacity: 0; transform: none; }
}
@keyframes word-item { 0%, 35.9% { opacity: 0; } 36%, 39.4% { opacity: 1; } 39.5%, 100% { opacity: 0; } }
@keyframes word-item-ink { 0%, 35.9% { color: inherit; } 36%, 39.4% { color: var(--demo-accent-ink); } 39.5%, 100% { color: inherit; } }
@keyframes word-caret { 0%, 46.9% { opacity: 0; } 47%, 95% { opacity: 1; } 96%, 100% { opacity: 0; } }
@keyframes word-save {                       /* enabled while Modified */
  0%, 25.4%   { opacity: 0.35; }
  25.5%, 56.4% { opacity: 1; }
  56.5%, 100% { opacity: 0.35; }
}
@keyframes word-modified { 0%, 25.4% { opacity: 0; } 25.5%, 56.4% { opacity: 1; } 56.5%, 100% { opacity: 0; } }
@keyframes word-saved    { 0%, 25.4% { opacity: 1; } 25.5%, 56.4% { opacity: 0; } 56.5%, 100% { opacity: 1; } }

.demo-word .demo__ptr {
  /* the arrow's tip is 0.15em in from its box; targets measured on the grid */
  --p-s0: translate(12.15em, 32.73em);
  --p-s1: translate(26.8em, 32.73em);
  --p-b: translate(12.55em, 11.05em);
  --p-hl: translate(29.24em, 11.05em);
  --p-y: translate(29.45em, 13.96em);
  --p-end: translate(39.35em, 32.75em);
  --p-save: translate(2.36em, 4.16em);
  --p-away: translate(44em, 36em);
  animation: word-ptr var(--t) infinite;
}
@keyframes word-ptr {
  0%          { transform: var(--p-away); opacity: 0; }
  3%          { opacity: 1; animation-timing-function: ease-in-out; }
  8%          { transform: var(--p-s0); }
  9%          { transform: var(--p-s0) scale(0.92); animation-timing-function: linear; }
  17%         { transform: var(--p-s1) scale(0.92); }
  17.5%       { transform: var(--p-s1); animation-timing-function: ease-in-out; }
  24%         { transform: var(--p-b); }
  25%         { transform: var(--p-b) scale(0.9); }
  25.5%       { transform: var(--p-b); animation-timing-function: ease-in-out; }
  31%         { transform: var(--p-hl); }
  32%         { transform: var(--p-hl) scale(0.9); }
  32.5%       { transform: var(--p-hl); animation-timing-function: ease-in-out; }
  36%         { transform: var(--p-y); }
  38.5%       { transform: var(--p-y) scale(0.9); }
  39.5%       { transform: var(--p-y); animation-timing-function: ease-in-out; }
  46%         { transform: var(--p-end); }
  46.5%       { transform: var(--p-end) scale(0.9); }
  47%         { transform: var(--p-end); animation-timing-function: ease-in-out; }
  55%         { transform: var(--p-save); }
  56%         { transform: var(--p-save) scale(0.9); }
  56.5%       { transform: var(--p-save); animation-timing-function: ease-in-out; }
  70%, 88%    { transform: var(--p-away); opacity: 1; }
  92%, 100%   { transform: var(--p-away); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .demo-word__txt { font-weight: 700; }
  .demo-word__hl { opacity: 1; }
  .demo-word__hlbar { background: #FFFF00; }
}

/* ===================================================================== */
/* Spreadsheet — a live total (the Spreadsheets page's hero)               */
/* ===================================================================== */
/* Source: ArchiveEditorsView.swift / XLSXRibbonView.swift. Selecting the total
 * shows its formula in the formula bar with a purple "Formula" capsule and
 * "Result:" in the status bar. A double-click opens the inline editor seeded
 * with the raw value (6030, not 6,030); ⌘A and typing replace it; Return
 * commits and the selection stays put. The total B6 is a live =SUM(B2:B5),
 * so it re-evaluates at once. The grid is drawn light in either appearance,
 * as the app forces it, and numbers sit left because the file sets no
 * alignment. Values replayed through TruePathCore; see demos.py. */

.demo-xl .demo__win { --dw: 56; --ratio: 4 / 3; --t: 11s; background: var(--demo-band); }
.demo-xl__ribbon { height: 4.6em; }
.demo-xl__ribbon .demo-ed__ctl { height: 3em; }
.demo-xl__ribbon .demo-ed__cap { font-size: 0.9em; }
.demo-xl__ribbon .demo-ed__div { height: 3.4em; margin-top: 0.2em; }
.demo-xl__numfmt {
  display: flex; align-items: center; gap: 0.5em;
  height: 2.4em; padding: 0 0.6em 0 1em;
  border-radius: 0.6em;
  background: var(--demo-control);
  color: var(--demo-text);
}
.demo-xl__numfmt > span { font-size: 1.2em; }
.demo-xl__numfmt .demo-ed__chev { margin-left: 0; }

/* States: .v1 A1 · .v2 B6 before · .v3 B5 editing · .v4 B5 after · .v5 B6 after.
 * Each readout stacks its variants in one grid cell and shows one at a time. */
.demo-xl__fbar {
  flex: none;
  display: flex; align-items: center; gap: 0.8em;
  height: 3.6em;
  padding: 0 1.4em;
  background: var(--demo-panel);
  border-bottom: 1px solid var(--demo-line);
}
.demo-xl__name, .demo-xl__field, .demo-xl__kind, .demo-xl__sumv { display: grid; }
.demo-xl__name > *, .demo-xl__field > *, .demo-xl__kind > *, .demo-xl__sumv > * { grid-area: 1 / 1; }
.demo-xl__name {                              /* 60 pt minimum, 12 pt semibold mono */
  min-width: 6em;
  padding: 0.4em 0.6em;
  border-radius: 0.4em;
  background: var(--demo-control);
  font: 600 1.2em/1 ui-monospace, "SF Mono", Menlo, monospace;
}
.demo-xl__name { min-width: 5em; }            /* the em above is 12 pt text: 60 pt */
.demo-xl__fx { flex: none; width: 1.7em; font: 700 1.2em/1 ui-rounded, -apple-system, system-ui, sans-serif; color: var(--demo-accent); text-align: center; }
.demo-xl__field {                             /* .roundedBorder text field */
  flex: 1 1 auto;
  align-items: center;
  height: 2.2em;
  padding: 0 0.7em;
  border-radius: 0.5em;
  background: var(--demo-paper);
  box-shadow: inset 0 0 0 1px var(--demo-line);
  color: var(--demo-text);
}
.demo-xl__field > span { font-size: 1.3em; white-space: nowrap; }
.demo-xl__kind > span {                       /* 10 pt semibold capsule, colour at 15 % */
  justify-self: end;
  padding: 0.3em 0.6em;
  border-radius: 1em;
  font-size: 1em; font-weight: 600;
  white-space: nowrap;
}
.demo-xl__k-text { color: var(--demo-text-2); background: rgba(128, 128, 128, 0.15); }
.demo-xl__k-formula { color: #AF52DE; background: rgba(175, 82, 222, 0.15); }
.demo-xl__k-number { color: #0A84FF; background: rgba(10, 132, 255, 0.15); }

.demo-xl__grid {                              /* forced light, as the app draws it */
  position: relative;
  flex: none;
  height: 19.2em;                             /* the header row and rows 1-6 */
  overflow: hidden;
  background: #FFFFFF;
  color: #2B3A3E;
}
.demo-xl__row { display: flex; height: 2.8em; }
.demo-xl__row--head { height: 2.4em; }
.demo-xl__row > span {
  position: relative;
  flex: none;
  display: flex; align-items: center;
  padding: 0 0.6em;
  box-shadow: inset -1px -1px 0 rgba(128, 128, 128, 0.18);
  white-space: nowrap;
}
.demo-xl__row > span > span { font-size: 1.1em; }
.demo-xl__corner, .demo-xl__rn, .demo-xl__ch { justify-content: center; background: #F2F2F5; color: #252C33; font-weight: 600; }
.demo-xl__corner { width: 4em; color: #59636D; }
.demo-xl__corner b { font-size: 1em; font-weight: 600; }
.demo-xl__rn { width: 4em; }
.demo-xl__ch { width: 9.6em; }
.demo-xl__ch--a { width: 11.7em; }
.demo-xl__c { width: 9.6em; }
.demo-xl__c[data-ref^="A"] { width: 11.7em; }
.demo-xl__hd { background: #176B78; color: #FFFFFF; font-weight: 700; }
.demo-xl__tot { background: #E3F1F0; color: #123C4A; font-weight: 700; box-shadow: inset 0 1px 0 #176B78, inset -1px -1px 0 rgba(128, 128, 128, 0.18); }

/* header tints for the selection (accent at 12 %) */
.demo-xl__ch--a::after, .demo-xl__ch--b::after, .demo-xl__rn1::after, .demo-xl__rn5::after, .demo-xl__rn6::after {
  content: ""; position: absolute; inset: 0; background: rgba(0, 32, 63, 0.12); opacity: 0;
}
.demo-xl__ch--a::after, .demo-xl__rn1::after { animation: xl-s1 var(--t) infinite; }
.demo-xl__ch--b::after { animation: xl-s2345 var(--t) infinite; }
.demo-xl__rn6::after { animation: xl-s25 var(--t) infinite; }
.demo-xl__rn5::after { animation: xl-s34 var(--t) infinite; }

/* the active cell: 2 pt accent (half of it clipped by the cell), 7 pt handle */
.demo-xl__sel {
  position: absolute; left: 4em; top: 2.4em;
  width: 11.7em; height: 2.8em;
  box-shadow: inset 0 0 0 0.13em #00203F;
  pointer-events: none;
  animation: xl-sel var(--t) infinite;
}
.demo-xl__handle { position: absolute; right: 0; bottom: 0; width: 0.7em; height: 0.7em; background: #00203F; animation: xl-handle var(--t) infinite; }
@keyframes xl-sel {
  0%, 10.4%    { transform: none; width: 11.7em; }
  10.5%, 25.4% { transform: translate(11.7em, 14em); width: 9.6em; }
  25.5%, 50.4% { transform: translate(11.7em, 11.2em); width: 9.6em; }
  50.5%, 95.9% { transform: translate(11.7em, 14em); width: 9.6em; }
  96%, 100%    { transform: none; width: 11.7em; }
}
@keyframes xl-handle { 0%, 26.9% { opacity: 1; } 27%, 42.9% { opacity: 0; } 43%, 100% { opacity: 1; } }

/* B5 and B6 */
.demo-xl__c[data-ref="B5"], .demo-xl__c[data-ref="B6"] { display: grid; align-items: center; justify-items: start; }
.demo-xl__c[data-ref="B5"] > *, .demo-xl__c[data-ref="B6"] > * { grid-area: 1 / 1; }
.demo-xl__c[data-ref="B5"] .demo-xl__old { animation: xl-b5-old var(--t) infinite; }
.demo-xl__c[data-ref="B6"] .demo-xl__old { animation: xl-old var(--t) infinite; }
.demo-xl__new { opacity: 0; animation: xl-new var(--t) infinite; }
@keyframes xl-b5-old { 0%, 26.9% { opacity: 1; } 27%, 95.9% { opacity: 0; } 96%, 100% { opacity: 1; } }
@keyframes xl-old { 0%, 42.9% { opacity: 1; } 43%, 95.9% { opacity: 0; } 96%, 100% { opacity: 1; } }
@keyframes xl-new { 0%, 42.9% { opacity: 0; } 43%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0; } }

.demo-xl__ed {                                /* InlineCellEditor: plain 12 pt field */
  display: flex; align-items: center;
  opacity: 0;
  color: #111111;
  animation: xl-ed var(--t) infinite;
}
.demo-xl__ed1, .demo-xl__typed { display: inline-block; overflow: hidden; white-space: nowrap; font-size: 1.2em; font-variant-numeric: tabular-nums; }
.demo-xl__ed1 { max-width: 4ch; animation: xl-ed1 var(--t) infinite; }
.demo-xl__typed { max-width: 0; animation: xl-type var(--t) infinite; }
.demo-xl__caret { flex: none; width: 0.1em; height: 1.4em; margin-left: 0.05em; background: #111111; }
.demo-xl__edsel { display: none; }
@keyframes xl-ed { 0%, 26.9% { opacity: 0; } 27%, 42.9% { opacity: 1; } 43%, 100% { opacity: 0; } }
@keyframes xl-ed1 {                           /* the seed, then ⌘A selects it, then typing replaces it */
  0%, 29.9%  { max-width: 4ch; background: transparent; }
  30%, 31.9% { max-width: 4ch; background: rgba(0, 32, 63, 0.2); }
  32%, 100%  { max-width: 0; background: transparent; }
}
@keyframes xl-type {
  0%, 32%    { max-width: 0; animation-timing-function: steps(4, end); }
  40%, 100%  { max-width: 4ch; }
}

/* the readouts */
.demo-xl__v1 { animation: xl-s1 var(--t) infinite; }
.demo-xl__name .demo-xl__v2, .demo-xl__field .demo-xl__v2, .demo-xl__kind .demo-xl__v2 { animation: xl-s25 var(--t) infinite; }
.demo-xl__name .demo-xl__v3, .demo-xl__kind .demo-xl__v3 { animation: xl-s34 var(--t) infinite; }
.demo-xl__field .demo-xl__v3, .demo-xl__sumv .demo-xl__v3 { animation: xl-s3 var(--t) infinite; }
.demo-xl__field .demo-xl__v4, .demo-xl__sumv .demo-xl__v4 { animation: xl-s4 var(--t) infinite; }
.demo-xl__sumv .demo-xl__v2 { animation: xl-s2 var(--t) infinite; }
.demo-xl__sumv .demo-xl__v5 { animation: xl-s5 var(--t) infinite; }
.demo-xl__name > *, .demo-xl__field > *, .demo-xl__kind > *, .demo-xl__sumv > * { opacity: 0; }

@keyframes xl-s1    { 0%, 10.4% { opacity: 1; } 10.5%, 95.9% { opacity: 0; } 96%, 100% { opacity: 1; } }
@keyframes xl-s2    { 0%, 10.4% { opacity: 0; } 10.5%, 25.4% { opacity: 1; } 25.5%, 100% { opacity: 0; } }
@keyframes xl-s25   { 0%, 10.4% { opacity: 0; } 10.5%, 25.4% { opacity: 1; } 25.5%, 50.4% { opacity: 0; } 50.5%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0; } }
@keyframes xl-s34   { 0%, 25.4% { opacity: 0; } 25.5%, 50.4% { opacity: 1; } 50.5%, 100% { opacity: 0; } }
@keyframes xl-s3    { 0%, 25.4% { opacity: 0; } 25.5%, 42.9% { opacity: 1; } 43%, 100% { opacity: 0; } }
@keyframes xl-s4    { 0%, 42.9% { opacity: 0; } 43%, 50.4% { opacity: 1; } 50.5%, 100% { opacity: 0; } }
@keyframes xl-s5    { 0%, 50.4% { opacity: 0; } 50.5%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0; } }
@keyframes xl-s2345 { 0%, 10.4% { opacity: 0; } 10.5%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0; } }

.demo-xl__sheets {
  flex: 1 1 auto;
  display: flex; align-items: center; gap: 0.4em;
  padding: 0 1.2em;
  background: var(--demo-chrome);
  border-top: 1px solid var(--demo-line);
}
.demo-xl__sheets > span { padding: 0.45em 1.1em; border-radius: 0.4em; background: var(--demo-control); font-size: 1.1em; white-space: nowrap; }
.demo-xl__sheets > .is-on { background: color-mix(in srgb, var(--demo-accent) 18%, transparent); font-weight: 700; }
.demo-xl__sheets > .demo-xl__plus { background: none; padding: 0 0.4em; font-size: 1.2em; color: var(--demo-text-2); }

.demo-xl__status { gap: 0; }
.demo-xl__status .t { padding: 0 0.6em; }
.demo-xl__status > .t:first-child { padding-left: 0; }
.demo-xl__sum { display: flex; align-items: center; overflow: hidden; max-width: 0; animation: xl-sumw var(--t) infinite; }
@keyframes xl-sumw { 0%, 10.4% { max-width: 0; } 10.5%, 95.9% { max-width: 16em; } 96%, 100% { max-width: 0; } }

.demo-xl .demo-ed__save { animation: xl-dirty-on var(--t) infinite; }
.demo-xl .demo-ed__saved { animation: xl-saved var(--t) infinite; }
.demo-xl .demo-ed__modified, .demo-xl .demo__dirty { animation: xl-modified var(--t) infinite; }
@keyframes xl-dirty-on { 0%, 42.9% { opacity: 0.35; } 43%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0.35; } }
@keyframes xl-saved    { 0%, 42.9% { opacity: 1; } 43%, 95.9% { opacity: 0; } 96%, 100% { opacity: 1; } }
@keyframes xl-modified { 0%, 42.9% { opacity: 0; } 43%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0; } }

.demo-xl .demo__ptr {
  --p-b6: translate(20.46em, 34.45em);        /* tip 0.15em in; cell centres measured */
  --p-b5: translate(20.46em, 31.65em);
  --p-away: translate(50em, 38em);
  animation: xl-ptr var(--t) infinite;
}
@keyframes xl-ptr {
  0%          { transform: var(--p-away); opacity: 0; }
  3%          { opacity: 1; animation-timing-function: ease-in-out; }
  9.5%        { transform: var(--p-b6); }
  10.2%       { transform: var(--p-b6) scale(0.9); }
  10.8%       { transform: var(--p-b6); }
  20%         { transform: var(--p-b6); animation-timing-function: ease-in-out; }
  24.8%       { transform: var(--p-b5); }
  25.3%       { transform: var(--p-b5) scale(0.9); }
  25.9%       { transform: var(--p-b5); }
  26.4%       { transform: var(--p-b5) scale(0.9); }
  27%         { transform: var(--p-b5); }
  42.4%       { transform: var(--p-b5); animation-timing-function: ease-in-out; }
  49.5%       { transform: var(--p-b6); }
  50.2%       { transform: var(--p-b6) scale(0.9); }
  50.8%       { transform: var(--p-b6); animation-timing-function: ease-in-out; }
  64%, 86%    { transform: var(--p-away); opacity: 1; }
  90%, 100%   { transform: var(--p-away); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  /* the result: B6 selected after the edit */
  .demo-xl__sel { transform: translate(11.7em, 14em); width: 9.6em; }
  .demo-xl__c[data-ref="B5"] .demo-xl__old, .demo-xl__c[data-ref="B6"] .demo-xl__old { opacity: 0; }
  .demo-xl__new { opacity: 1; }
  .demo-xl__ch--b::after, .demo-xl__rn6::after { opacity: 1; }
  .demo-xl__name .demo-xl__v2, .demo-xl__field .demo-xl__v2, .demo-xl__kind .demo-xl__v2, .demo-xl__sumv .demo-xl__v5 { opacity: 1; }
  .demo-xl__sum { max-width: 16em; }
}

/* ===================================================================== */
/* Presentation — select a shape, edit the title in place                  */
/* ===================================================================== */
/* Source: ArchiveEditorsView.swift (PPTX editor) and SlideSceneView.swift /
 * ShapeTextEditor.swift. In the default "Real layout" view a click selects a
 * shape: a 1.5 pt teal (#0F8B8D) ring with four 9 pt corner handles, and a
 * floating style bar (Fill, Border, Duplicate, Delete) above the canvas's
 * bottom edge. A double-click on a text shape edits it in place with the
 * caret at the END of the text; the handles and style bar go away while
 * editing. Clicking the slide background commits the edit: only then does
 * the slide's thumbnail re-render and the deck turn Modified. The Font group
 * is enabled only while a text shape is selected or being edited. */

.demo-deck .demo__win { --dw: 64; --ratio: 4 / 3; --t: 12s; background: var(--demo-band); }
.demo-deck__ribbon { height: 4.8em; }
.demo-deck__ribbon .demo-ed__ctl { height: 3.2em; }
.demo-deck__ribbon .demo-ed__cap { font-size: 0.9em; }
.demo-deck__ribbon .demo-ed__div { height: 3.4em; margin-top: 0.3em; }
.demo-deck__font { display: flex; align-items: center; gap: 0.4em; opacity: 0.45; animation: deck-font var(--t) infinite; }
.demo-deck__bb {                              /* .bordered, .controlSize(.small) */
  flex: none;
  display: inline-flex; align-items: center;
  height: 2.2em; padding: 0 0.9em;
  border-radius: 0.55em;
  background: var(--demo-control);
  box-shadow: inset 0 0 0 1px var(--demo-line);
  font-size: 1.15em; white-space: nowrap;
}
.demo-deck__ribbon .demo-ed__ctl { gap: 0.6em; }
.demo-deck__lay { margin: 0 0.2em 0 -0.4em; }

.demo-deck__main { flex: 1 1 auto; min-height: 0; display: flex; }
.demo-deck__list {                            /* 180 pt, 8 pt padding, rows 6 pt apart */
  flex: none;
  width: 18em;
  display: flex; flex-direction: column; gap: 0.6em;
  padding: 0.8em;
  overflow: hidden;
  background: var(--demo-panel);
  border-right: 1px solid var(--demo-line);
}
.demo-deck__row { display: flex; align-items: center; gap: 0.8em; }
.demo-deck__num { flex: none; width: 1.8em; text-align: center; font: 700 1em/1 ui-monospace, "SF Mono", Menlo, monospace; color: var(--demo-text-3); }
.demo-deck__thumb {                           /* 70 pt tall, 16:9 */
  position: relative; flex: none;
  width: 12.44em; height: 7em;
  border-radius: 0.3em;
  background: #FFFFFF;
  box-shadow: 0 0 0 0.05em rgba(128, 128, 128, 0.3);
  overflow: hidden;
}
.demo-deck__row.is-on .demo-deck__thumb { box-shadow: 0 0 0 0.2em var(--demo-accent); }
/* A thumbnail is the same slide drawn at stage size and scaled down, so its
 * tiny type is never clamped by the browser's minimum font size. */
.demo-deck__thumb .dk-slide {
  --in: calc(41.3em / 13.333);
  inset: auto; left: 0; top: 0;
  width: 41.3em; height: 23.23em;
  transform: scale(0.3012);
  transform-origin: 0 0;
}

.demo-deck__right { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.demo-deck__canvas { position: relative; flex: 1 1 auto; overflow: hidden; background: var(--demo-canvas); }
.demo-deck__stage {                           /* 90 % of the canvas width, 16:9 */
  --in: calc(41.3em / 13.333);
  position: absolute; left: 50%; top: 50%;
  width: 41.3em; height: 23.23em;
  margin: -11.615em 0 0 -20.65em;
  border-radius: 0.4em;
  background: #FFFFFF;
  box-shadow: 0 0.4em 0.8em rgba(0, 0, 0, 0.3);
}

/* the slide itself, in inches (--in) and points (--in / 72) */
.dk-slide { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; color: #0B1A1F; }
.dk-sp { position: absolute; display: flex; flex-direction: column; justify-content: center; padding: 0 calc(0.15 * var(--in)); }
.dk-sp p { margin: 0; line-height: 1.2; white-space: nowrap; }
.dk-body p { white-space: normal; }
.dk-raw { padding: 0; }
.dk-b { position: relative; margin-bottom: calc(6 * var(--in) / 72) !important; }
.dk-b i { display: inline-block; width: calc(0.35 * var(--in)); margin-left: calc(-0.35 * var(--in)); font-style: normal; }
.dk-tbl { position: absolute; display: grid; grid-template-columns: 30fr 18fr 18fr 17fr 17fr; grid-auto-rows: 1fr; row-gap: calc(var(--in) / 72); }
.dk-tbl > span { display: flex; align-items: center; padding: 0 calc(0.1 * var(--in)); font-size: calc(12 * var(--in) / 72); white-space: nowrap; overflow: hidden; background: #F4F8F8; }
.dk-tbl > .dk-th { background: #123C4A; color: #FFFFFF; font-weight: 700; }

/* the in-place edit: typed text, then the caret after it */
.demo-deck__typed { position: relative; }
.demo-deck__tclip { clip-path: inset(0 100% 0 0); animation: deck-type var(--t) infinite; }
.demo-deck__caret {
  position: absolute; top: 0.1em; bottom: 0.05em; left: 0;
  width: 0.07em;
  background: #000000;
  opacity: 0;
  animation: deck-caret var(--t) infinite, deck-caret-x var(--t) infinite;
}
.demo-deck__ttyped { opacity: 0; animation: deck-committed var(--t) infinite; }

.demo-deck__ring {                            /* 1.5 pt teal, 9 pt handles inside the corners */
  position: absolute;
  border: 0.15em solid #0F8B8D; border-radius: 0.2em;
  opacity: 0;
  pointer-events: none;
}
.demo-deck__ring i { position: absolute; width: 0.9em; height: 0.9em; background: #FFFFFF; border: 0.12em solid #0F8B8D; border-radius: 0.15em; }
.demo-deck__ring i:nth-child(1) { left: 0; top: 0; }
.demo-deck__ring i:nth-child(2) { right: 0; top: 0; }
.demo-deck__ring i:nth-child(3) { left: 0; bottom: 0; }
.demo-deck__ring i:nth-child(4) { right: 0; bottom: 0; }
.demo-deck__ring--card { left: calc(8 * var(--in)); top: calc(1.9 * var(--in)); width: calc(4.4 * var(--in)); height: calc(1.7 * var(--in)); animation: deck-ring-card var(--t) infinite; }
.demo-deck__ring--title { left: calc(0.9 * var(--in)); top: calc(0.7 * var(--in)); width: calc(11.533 * var(--in)); height: calc(0.9 * var(--in)); animation: deck-ring-title var(--t) infinite; }
.demo-deck__ring--title i { animation: deck-handles var(--t) infinite; }

.demo-deck__bar {                             /* material capsule, 14 pt above the canvas bottom */
  position: absolute; left: 50%; bottom: 1.4em;
  display: flex; align-items: center; gap: 0.8em;
  padding: 0.7em 1.2em;
  border-radius: 2em;
  background: var(--demo-menu);
  box-shadow: inset 0 0 0 1px rgba(128, 128, 128, 0.24), 0 0.3em 0.8em rgba(0, 0, 0, 0.18);
  color: var(--demo-text);
  transform: translateX(-50%);
  opacity: 0;
  animation: deck-bar var(--t) infinite;
}
.demo-deck__bar .demo__ico { width: 1.35em; height: 1.35em; }
.demo-deck__bar .demo-ed__chev { margin-left: -0.5em; }
.demo-deck__sw { width: 1.4em; height: 1.4em; border-radius: 0.2em; box-shadow: inset 0 0 0 1px rgba(128, 128, 128, 0.4); margin-left: -0.4em; }
.demo-deck__ln { width: 1.4em; height: 0.3em; background: #2F528F; margin-left: -0.4em; }
.demo-deck__bdiv { width: 1px; height: 1.6em; background: var(--demo-line); }

.demo-deck__notes {                           /* collapsed: header + the notes' first line */
  position: relative; flex: none;
  display: flex; align-items: center;
  height: 3em;
  padding: 0.5em 1.6em 0;
  background: var(--demo-panel);
  border-top: 1px solid var(--demo-line);
  color: var(--demo-text-2);
}
.demo-deck__grab { position: absolute; top: 0.3em; left: 50%; width: 3em; height: 0.3em; margin-left: -1.5em; border-radius: 0.2em; background: rgba(128, 128, 128, 0.4); }
.demo-deck__nh { display: flex; align-items: center; gap: 0.5em; min-width: 0; white-space: nowrap; }
.demo-deck__nchev { width: 1em; height: 1em; stroke-width: 2.6; }
.demo-deck__nh b { font-size: 1em; font-weight: 600; }
.demo-deck__nh > span { overflow: hidden; text-overflow: ellipsis; font-size: 1em; color: var(--demo-text-3); }

.demo-deck__switch { flex: none; position: relative; width: 2.6em; height: 1.5em; margin-left: -0.3em; border-radius: 1em; background: var(--demo-accent); }
.demo-deck__switch::after { content: ""; position: absolute; right: 0.15em; top: 0.15em; width: 1.2em; height: 1.2em; border-radius: 50%; background: #FFFFFF; box-shadow: 0 0.05em 0.15em rgba(0, 0, 0, 0.3); }
.demo-deck__status .demo__status-r { display: flex; align-items: center; gap: 1em; }
.demo-deck__play { width: 1.4em; height: 1.4em; color: var(--demo-text-2); }

/* timeline: select the card (10 %), double-click the title (28 / 29.5 %),
 * type (31–43 %), click the background to commit (48.5 %) */
@keyframes deck-font      { 0%, 9.9% { opacity: 0.45; } 10%, 48.4% { opacity: 1; } 48.5%, 100% { opacity: 0.45; } }
@keyframes deck-ring-card { 0%, 9.9% { opacity: 0; } 10%, 27.9% { opacity: 1; } 28%, 100% { opacity: 0; } }
@keyframes deck-bar       { 0%, 9.9% { opacity: 0; } 10%, 27.9% { opacity: 1; } 28%, 100% { opacity: 0; } }
@keyframes deck-ring-title { 0%, 27.9% { opacity: 0; } 28%, 48.4% { opacity: 1; } 48.5%, 100% { opacity: 0; } }
@keyframes deck-handles   { 0%, 29.4% { opacity: 1; } 29.5%, 100% { opacity: 0; } }
@keyframes deck-caret     { 0%, 29.4% { opacity: 0; } 29.5%, 48.4% { opacity: 1; } 48.5%, 100% { opacity: 0; } }
@keyframes deck-type {
  0%, 31%    { clip-path: inset(0 100% 0 0); animation-timing-function: steps(12, end); }
  43%, 96%   { clip-path: inset(0 0 0 0); }
  99%, 100%  { clip-path: inset(0 100% 0 0); }
}
@keyframes deck-caret-x {
  0%, 31%    { left: 0; animation-timing-function: steps(12, end); }
  43%, 100%  { left: 100%; }
}
@keyframes deck-committed { 0%, 48.4% { opacity: 0; } 48.5%, 96% { opacity: 1; } 99%, 100% { opacity: 0; } }

.demo-deck .demo-ed__save { animation: deck-save var(--t) infinite; }
.demo-deck .demo-ed__saved { animation: deck-saved var(--t) infinite; }
.demo-deck .demo-ed__modified, .demo-deck .demo__dirty { animation: deck-modified var(--t) infinite; }
.demo-deck .demo-ed__qb:nth-child(3) { animation: deck-undo var(--t) infinite; }
.demo-deck .demo-ed__qb:nth-child(4) { animation: deck-redo var(--t) infinite; }
@keyframes deck-save     { 0%, 48.4% { opacity: 0.35; } 48.5%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0.35; } }
@keyframes deck-saved    { 0%, 48.4% { opacity: 1; } 48.5%, 95.9% { opacity: 0; } 96%, 100% { opacity: 1; } }
@keyframes deck-modified { 0%, 48.4% { opacity: 0; } 48.5%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0; } }
@keyframes deck-undo     { 0%, 29.4% { opacity: 0.35; } 29.5%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0.35; } }
@keyframes deck-redo     { 0%, 29.4% { opacity: 0.35; } 29.5%, 48.4% { opacity: 1; } 48.5%, 100% { opacity: 0.35; } }

.demo-deck .demo__ptr {
  --p-card: translate(50.35em, 24.15em);       /* tip 0.15em in; measured on the grid */
  --p-title: translate(39.85em, 19.55em);
  --p-bg: translate(53.85em, 36.35em);
  --p-away: translate(58em, 44em);
  animation: deck-ptr var(--t) infinite;
}
@keyframes deck-ptr {
  0%          { transform: var(--p-away); opacity: 0; }
  3%          { opacity: 1; animation-timing-function: ease-in-out; }
  9%          { transform: var(--p-card); }
  9.5%        { transform: var(--p-card) scale(0.9); }
  10%         { transform: var(--p-card); }
  20%         { transform: var(--p-card); animation-timing-function: ease-in-out; }
  27%         { transform: var(--p-title); }
  27.5%       { transform: var(--p-title) scale(0.9); }
  28.2%       { transform: var(--p-title); }
  28.8%       { transform: var(--p-title) scale(0.9); }
  29.5%       { transform: var(--p-title); }
  43%         { transform: var(--p-title); animation-timing-function: ease-in-out; }
  47.5%       { transform: var(--p-bg); }
  48%         { transform: var(--p-bg) scale(0.9); }
  48.5%       { transform: var(--p-bg); animation-timing-function: ease-in-out; }
  62%, 86%    { transform: var(--p-away); opacity: 1; }
  90%, 100%   { transform: var(--p-away); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .demo-deck__tclip { clip-path: none; }
  .demo-deck__ttyped { opacity: 1; }
}

/* ===================================================================== */
/* Workflow: review a contract (hub)                                      */
/* ===================================================================== */
/* Source: WordEditorView.swift (Review tab, comments panel) and
 * WordDocumentScene.trackedChanges. Each <w:ins> / <w:del> is one change, so a
 * replaced word is two. Accept resolves the FIRST pending change in document
 * order, Accept All the rest; at zero the four buttons and the orange count
 * leave the ribbon. The canvas marks a deletion struck through and an
 * insertion underlined, both in the text's own colour — the app draws no
 * redline colours, change bars or balloons. Resolve tints the card green and
 * swaps in "Resolved" and "Reopen". */

.demo-rv .demo__win { --dw: 60; --ratio: 4 / 3; --t: 12s; background: var(--demo-band); }
.demo-rv__ribbon .demo-ed__ctl { gap: 0.6em; }
.demo-rv__tile {                              /* 44 × 36 pt: 14 pt symbol over an 8 pt label */
  flex: none;
  display: grid; justify-items: center; align-content: center; gap: 0.2em;
  width: 4.4em; height: 3.6em;
  border-radius: 0.5em;
  background: var(--demo-control);
  color: var(--demo-text);
}
.demo-rv__tile .demo__ico { width: 1.6em; height: 1.6em; }
.demo-rv__tile > span { font-size: 0.8em; font-weight: 500; }
.demo-rv__show {                              /* on while the panel is open */
  display: flex; align-items: center; gap: 0.3em;
  padding: 0.4em 0.6em;
  border-radius: 0.5em;
  background: color-mix(in srgb, var(--demo-accent) 18%, transparent);
  color: var(--demo-accent);
}
.demo-rv__show .demo__ico { width: 1.2em; height: 1.2em; }
.demo-rv__show > span { font-size: 1em; font-weight: 500; }
.demo-rv__cap { display: grid; padding: 0.2em 0.6em; border-radius: 1em; color: #FFFFFF; font: 700 1em/1.2 ui-monospace, "SF Mono", Menlo, monospace; }
.demo-rv__cap > * { grid-area: 1 / 1; }
.demo-rv__cap--blue { background: #007AFF; }
.demo-rv__cap--orange { background: #FF9500; }
.demo-rv__acts { display: flex; align-items: center; gap: 0.6em; overflow: hidden; max-width: 40em; animation: rv-acts var(--t) infinite; }
.demo-rv__acts .demo-deck__bb { font-size: 1.1em; }
.demo-rv__n3 { opacity: 0; animation: rv-n3 var(--t) infinite; }
.demo-rv__n4 { animation: rv-n4 var(--t) infinite; }

.demo-rv__main { flex: 1 1 auto; min-height: 0; display: flex; }
.demo-rv__canvas { position: relative; flex: 1 1 auto; overflow: hidden; background: var(--demo-canvas); }
.demo-rv__page {
  position: absolute; left: 1.8em; right: 1.8em; top: -0.6em;
  padding: 2.4em 2.8em;
  background: #FFFFFF;
  color: #2B3A3E;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  box-shadow: 0 0.2em 0.6em rgba(0, 0, 0, 0.18);
}
.demo-rv__page p { margin: 0; }
.demo-rv__h { margin-top: 1em !important; font-size: 1.55em; font-weight: 700; color: #123C4A; }
.demo-rv__h:first-child { margin-top: 0 !important; }
.demo-rv__p { margin-top: 0.4em !important; font-size: 1.25em; line-height: 1.56; }
.demo-rv__del s { text-decoration: line-through; text-decoration-thickness: 0.07em; }
.demo-rv__del { animation: rv-del var(--t) infinite; }
.demo-rv__del.demo-rv__c1 { animation: rv-del1 var(--t) infinite; }
.demo-rv__ins { text-decoration: underline; text-decoration-thickness: 0.07em; text-underline-offset: 0.12em; animation: rv-ins var(--t) infinite; }

.demo-rv__panel {                             /* 200-240 pt, controlBg */
  flex: none;
  display: flex; flex-direction: column; gap: 0.8em;
  width: 22em;
  padding: 1.2em;
  background: var(--demo-control);
  border-left: 1px solid var(--demo-line);
  overflow: hidden;
}
.demo-rv__ph { display: flex; align-items: center; justify-content: space-between; padding-bottom: 0.8em; border-bottom: 1px solid var(--demo-line); }
.demo-rv__ph b { font-size: 1.2em; font-weight: 600; }
.demo-rv__x { width: 1.1em; height: 1.1em; stroke-width: 2.2; color: var(--demo-text-2); }
.demo-rv__card {
  display: grid; gap: 0.4em;
  padding: 0.8em;
  border-radius: 0.6em;
  background: var(--demo-card);
  box-shadow: inset 0 0 0 1px rgba(128, 128, 128, 0.3);
}
.demo-rv__card1 { animation: rv-card var(--t) infinite; }
.demo-rv__who { display: flex; align-items: center; gap: 0.4em; color: var(--demo-text); }
.demo-rv__av { width: 1.3em; height: 1.3em; color: var(--demo-text-3); stroke: none; }
.demo-rv__who b { font-size: 1em; font-weight: 600; }
.demo-rv__who > span { margin-left: auto; font-size: 0.9em; color: var(--demo-text-3); }
.demo-rv__text { display: flex; align-items: flex-start; gap: 0.4em; }
.demo-rv__text > span { flex: 1 1 auto; font-size: 1.1em; line-height: 1.3; color: var(--demo-text); }
.demo-rv__card1 .demo-rv__text > span { animation: rv-text var(--t) infinite; }
.demo-rv__mini { flex: none; width: 1em; height: 1em; margin-top: 0.15em; color: var(--demo-text-2); }
.demo-rv__red { color: #FF3B30; }
.demo-rv__acts2 { display: flex; align-items: center; }
.demo-rv__state { display: grid; }
.demo-rv__state > * { grid-area: 1 / 1; }
.demo-rv__resolve, .demo-rv__reply, .demo-rv__resolved { font-size: 0.9em; white-space: nowrap; }
.demo-rv__resolve { color: #34C759; }
.demo-rv__resolved { display: flex; gap: 0.8em; opacity: 0; }
.demo-rv__resolved b { font-weight: 600; color: #34C759; }
.demo-rv__resolved span { color: var(--demo-text-2); }
.demo-rv__card1 .demo-rv__resolve { animation: rv-unresolved var(--t) infinite; }
.demo-rv__card1 .demo-rv__resolved { animation: rv-resolved var(--t) infinite; }
.demo-rv__reply { margin-left: auto; color: var(--demo-accent); }
.demo-rv__sc { display: inline-flex; align-items: center; gap: 0.3em; }
.demo-rv__sc .demo__ico { width: 1.2em; height: 1.2em; }

/* Accept at 10.5 %, Accept All at 20.5 %, Resolve at 32 % */
@keyframes rv-del1 { 0%, 10.4% { font-size: 1em; } 10.5%, 95.9% { font-size: 0; } 96%, 100% { font-size: 1em; } }
@keyframes rv-del  { 0%, 20.4% { font-size: 1em; } 20.5%, 95.9% { font-size: 0; } 96%, 100% { font-size: 1em; } }
@keyframes rv-ins  { 0%, 20.4% { text-decoration-color: currentColor; } 20.5%, 95.9% { text-decoration-color: transparent; } 96%, 100% { text-decoration-color: currentColor; } }
@keyframes rv-n4   { 0%, 10.4% { opacity: 1; } 10.5%, 95.9% { opacity: 0; } 96%, 100% { opacity: 1; } }
@keyframes rv-n3   { 0%, 10.4% { opacity: 0; } 10.5%, 20.4% { opacity: 1; } 20.5%, 100% { opacity: 0; } }
@keyframes rv-acts { 0%, 20.4% { max-width: 40em; } 20.5%, 95.9% { max-width: 0; } 96%, 100% { max-width: 40em; } }
@keyframes rv-card {
  0%, 31.9%  { background: var(--demo-card); box-shadow: inset 0 0 0 1px rgba(128, 128, 128, 0.3); }
  32%, 95.9% { background: rgba(52, 199, 89, 0.06); box-shadow: inset 0 0 0 1px rgba(52, 199, 89, 0.2); }
  96%, 100%  { background: var(--demo-card); box-shadow: inset 0 0 0 1px rgba(128, 128, 128, 0.3); }
}
@keyframes rv-text       { 0%, 31.9% { color: var(--demo-text); } 32%, 95.9% { color: var(--demo-text-2); } 96%, 100% { color: var(--demo-text); } }
@keyframes rv-unresolved { 0%, 31.9% { opacity: 1; } 32%, 95.9% { opacity: 0; } 96%, 100% { opacity: 1; } }
@keyframes rv-resolved   { 0%, 31.9% { opacity: 0; } 32%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0; } }

.demo-rv .demo-ed__save { animation: rv-save var(--t) infinite; }
.demo-rv .demo-ed__saved { animation: rv-saved var(--t) infinite; }
.demo-rv .demo-ed__modified, .demo-rv .demo__dirty { animation: rv-modified var(--t) infinite; }
@keyframes rv-save     { 0%, 10.4% { opacity: 0.35; } 10.5%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0.35; } }
@keyframes rv-saved    { 0%, 10.4% { opacity: 1; } 10.5%, 95.9% { opacity: 0; } 96%, 100% { opacity: 1; } }
@keyframes rv-modified { 0%, 10.4% { opacity: 0; } 10.5%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0; } }

.demo-rv .demo__ptr {
  --p-accept: translate(24.29em, 11.07em);    /* tip 0.15em in; measured on the grid */
  --p-all: translate(37.44em, 11.07em);
  --p-resolve: translate(41.45em, 25.21em);
  --p-away: translate(52em, 40em);
  animation: rv-ptr var(--t) infinite;
}
@keyframes rv-ptr {
  0%          { transform: var(--p-away); opacity: 0; }
  3%          { opacity: 1; animation-timing-function: ease-in-out; }
  9.5%        { transform: var(--p-accept); }
  10%         { transform: var(--p-accept) scale(0.9); }
  10.6%       { transform: var(--p-accept); animation-timing-function: ease-in-out; }
  19.5%       { transform: var(--p-all); }
  20%         { transform: var(--p-all) scale(0.9); }
  20.6%       { transform: var(--p-all); animation-timing-function: ease-in-out; }
  31%         { transform: var(--p-resolve); }
  31.5%       { transform: var(--p-resolve) scale(0.9); }
  32.1%       { transform: var(--p-resolve); animation-timing-function: ease-in-out; }
  46%, 86%    { transform: var(--p-away); opacity: 1; }
  90%, 100%   { transform: var(--p-away); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .demo-rv__del, .demo-rv__del.demo-rv__c1 { font-size: 0; }
  .demo-rv__ins { text-decoration-color: transparent; }
  .demo-rv__acts { max-width: 0; }
  .demo-rv__card1 .demo-rv__resolve { opacity: 0; }
  .demo-rv__card1 .demo-rv__resolved { opacity: 1; }
}

/* ===================================================================== */
/* Markdown — formatted by default, source in one click                    */
/* ===================================================================== */
/* Source: WordEditorView.swift (a .md opens in the Word editor with only Home
 * and View, and the rendered page showing), MarkdownPreviewView.swift, and a
 * live capture of the build for the source view: a Print Layout page with a
 * dashed Header guide and the file's text in Helvetica 12. The Markdown group's
 * one button names the view it switches TO — "Source" (tinted) over the
 * rendered page, "Preview" over the source — and editing happens in the
 * source. The page count differs between the two views (1 of 1, 1 of 2). */

.demo-md .demo__win { --dw: 56; --ratio: 5 / 4; --t: 13s; background: var(--demo-band); }
.demo-md__toggle { display: grid; width: 5.2em; height: 3.6em; }
.demo-md__src, .demo-md__pre {
  grid-area: 1 / 1;
  display: grid; justify-items: center; align-content: center; gap: 0.15em;
  border-radius: 0.5em;
}
.demo-md__src { background: color-mix(in srgb, var(--demo-accent) 18%, transparent); color: var(--demo-accent); animation: md-rendered var(--t) infinite; }
.demo-md__pre { background: var(--demo-control); color: var(--demo-text); opacity: 0; animation: md-source var(--t) infinite; }
.demo-md__braces { font: 500 1.45em/1 ui-monospace, "SF Mono", Menlo, monospace; letter-spacing: -0.05em; }
.demo-md__pre .demo__ico { width: 1.6em; height: 1.6em; }
.demo-md__src > span, .demo-md__pre > span { font-size: 0.8em; font-weight: 500; }
.demo-md__note { align-self: flex-start; margin-top: 1.9em; font-size: 1.1em; color: var(--demo-text-2); white-space: nowrap; }

.demo-md__ruler { flex: none; position: relative; height: 2.3em; background: var(--demo-band); border-bottom: 1px solid var(--demo-line); overflow: hidden; }
.demo-md__ticks { position: absolute; left: 5.4em; top: 0.4em; display: flex; gap: 0; }
.demo-md__ticks > span {
  width: 5.4em; padding-top: 0.6em;
  font-size: 0.75em; color: var(--demo-text-3);
  background: linear-gradient(var(--demo-text-3), var(--demo-text-3)) 0 0 / 1px 0.5em no-repeat;
}

.demo-md__center { position: relative; flex: 1 1 auto; overflow: hidden; }
.demo-md__rendered, .demo-md__source { position: absolute; inset: 0; }
.demo-md__rendered { background: var(--demo-textbg); color: var(--demo-label); animation: md-rendered var(--t) infinite; }
.demo-md__col { max-width: 68em; padding: 4em 4.8em; }
.demo-md__col p { margin: 0; }
.demo-md__h1 { font-size: 2.6em; font-weight: 700; line-height: 1.2; color: var(--demo-mdink); }
.demo-md__p { margin-top: 1.14em !important; font-size: 1.4em; line-height: 1.55; }
.demo-md__h2 { margin-top: 1.14em !important; font-size: 2.1em; font-weight: 700; line-height: 1.2; color: var(--demo-mdink); }
.demo-md__li { margin-top: 1.14em !important; font-size: 1.4em; line-height: 1.55; }
.demo-md__li i { display: inline-block; min-width: 1.3em; font-style: normal; font-weight: 700; color: var(--demo-accent); }
.demo-md__new { font-size: 0; animation: md-newpara var(--t) infinite; }

.demo-md__source { background: var(--demo-canvas); opacity: 0; animation: md-source var(--t) infinite; }
.demo-md__page {                              /* 640 pt wide: wider than this view, as on a small window */
  position: absolute; left: 2em; top: 1.8em;
  width: 64em; height: 90em;
  border-radius: 0.8em;
  background: #FFFFFF;
  box-shadow: 0 0 0 1px #D5D8DC, 0 0 0 0.35em #C4D6F1;
  color: #000000;
}
.demo-md__hdr { position: absolute; left: 3.1em; top: 2em; font: 600 1.1em/1 -apple-system, system-ui, sans-serif; color: #7F8080; }
.demo-md__dash { position: absolute; left: 3.1em; right: 3.1em; top: 3.8em; border-top: 1px dashed #DDDDDF; }
.demo-md__text { position: absolute; left: 3.1em; top: 7.7em; font-family: Helvetica, Arial, sans-serif; }
.demo-md__text p { margin: 0; height: 1.19em; font-size: 1.2em; line-height: 1.19; white-space: pre; }
.demo-md__ins { overflow: hidden; max-height: 0; animation: md-returns var(--t) infinite; }
.demo-md__c1, .demo-md__c1b, .demo-md__c2 {
  display: inline-block; width: 0.08em; height: 1.05em; vertical-align: -0.18em; background: #000000; opacity: 0;
}
.demo-md__c1 { margin-left: 0.05em; animation: md-c1 var(--t) infinite; }
.demo-md__c1b { animation: md-c1b var(--t) infinite; }
.demo-md__typed { position: relative; display: inline-block; }
.demo-md__tclip { display: inline-block; clip-path: inset(0 100% 0 0); animation: md-type var(--t) infinite; }
.demo-md__c2 { position: absolute; left: 0; top: 0.12em; animation: md-c2 var(--t) infinite, md-c2x var(--t) infinite; }

.demo-md__pg { display: grid; }
.demo-md__pg > * { grid-area: 1 / 1; }
.demo-md__pg1 { animation: md-rendered var(--t) infinite; }
.demo-md__pg2 { opacity: 0; animation: md-source var(--t) infinite; }

/* Source at 10 %, caret 18 %, Return 19 / 20 %, typing 21.5–35 %, Preview at 43 % */
@keyframes md-rendered { 0%, 9.9% { opacity: 1; } 10%, 42.9% { opacity: 0; } 43%, 100% { opacity: 1; } }
@keyframes md-source   { 0%, 9.9% { opacity: 0; } 10%, 42.9% { opacity: 1; } 43%, 100% { opacity: 0; } }
@keyframes md-c1       { 0%, 17.9% { opacity: 0; } 18%, 18.9% { opacity: 1; } 19%, 100% { opacity: 0; } }
@keyframes md-c1b      { 0%, 18.9% { opacity: 0; } 19%, 19.9% { opacity: 1; } 20%, 100% { opacity: 0; } }
@keyframes md-c2       { 0%, 19.9% { opacity: 0; } 20%, 42.9% { opacity: 1; } 43%, 100% { opacity: 0; } }
@keyframes md-returns  { 0%, 18.9% { max-height: 0; } 19%, 19.9% { max-height: 1.43em; } 20%, 95.9% { max-height: 2.86em; } 96%, 100% { max-height: 0; } }
@keyframes md-type {
  0%, 21.5%  { clip-path: inset(0 100% 0 0); animation-timing-function: steps(37, end); }
  35%, 95.9% { clip-path: inset(0 0 0 0); }
  96%, 100%  { clip-path: inset(0 100% 0 0); }
}
@keyframes md-c2x {
  0%, 21.5%  { left: 0; animation-timing-function: steps(37, end); }
  35%, 100%  { left: 100%; }
}
@keyframes md-newpara { 0%, 42.9% { font-size: 0; } 43%, 95.9% { font-size: 1.4em; } 96%, 100% { font-size: 0; } }

.demo-md .demo-ed__save { animation: md-save var(--t) infinite; }
.demo-md .demo-ed__saved { animation: md-saved var(--t) infinite; }
.demo-md .demo-ed__modified, .demo-md .demo__dirty { animation: md-modified var(--t) infinite; }
@keyframes md-save     { 0%, 18.9% { opacity: 0.35; } 19%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0.35; } }
@keyframes md-saved    { 0%, 18.9% { opacity: 1; } 19%, 95.9% { opacity: 0; } 96%, 100% { opacity: 1; } }
@keyframes md-modified { 0%, 18.9% { opacity: 0; } 19%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0; } }

.demo-md .demo__ptr {
  --p-toggle: translate(13.77em, 11.06em);    /* tip 0.15em in; measured on the grid */
  --p-eol: translate(50.35em, 31.28em);
  --p-away: translate(48em, 40em);
  animation: md-ptr var(--t) infinite;
}
@keyframes md-ptr {
  0%          { transform: var(--p-away); opacity: 0; }
  3%          { opacity: 1; animation-timing-function: ease-in-out; }
  9%          { transform: var(--p-toggle); }
  9.5%        { transform: var(--p-toggle) scale(0.9); }
  10%         { transform: var(--p-toggle); animation-timing-function: ease-in-out; }
  17%         { transform: var(--p-eol); }
  17.5%       { transform: var(--p-eol) scale(0.9); }
  18%         { transform: var(--p-eol); }
  35%         { transform: var(--p-eol); animation-timing-function: ease-in-out; }
  42%         { transform: var(--p-toggle); }
  42.5%       { transform: var(--p-toggle) scale(0.9); }
  43%         { transform: var(--p-toggle); animation-timing-function: ease-in-out; }
  58%, 86%    { transform: var(--p-away); opacity: 1; }
  90%, 100%   { transform: var(--p-away); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .demo-md__new { font-size: 1.4em; }
}

/* ---------- the Home screen (AgentToolsSection.swift) ---------- */

.demo-home .demo__win { --dw: 60; --ratio: 6 / 5; --t: 13s; background: var(--demo-ground); }
.demo-home__tabs {                            /* the document tab strip, Home in front */
  flex: none;
  display: flex; align-items: center; gap: 1.8em;
  height: 3.4em;
  padding: 0 1em;
  background: var(--demo-chrome);
  border-bottom: 1px solid var(--demo-line);
}
.demo-home__house { display: grid; place-items: center; width: 3.4em; height: 2.6em; border-radius: 0.6em; background: color-mix(in srgb, var(--demo-text) 7%, transparent); color: var(--demo-accent); }
.demo-home__house .demo__ico { width: 1.5em; height: 1.5em; }
.demo-home__tab { display: flex; align-items: center; gap: 0.6em; color: var(--demo-text-2); white-space: nowrap; }
.demo-home__tab .demo__ico { width: 1.3em; height: 1.3em; }
.demo-home__tab > span { font-size: 1.2em; }
.demo-home__tab .demo-home__x { width: 1em; height: 1em; stroke-width: 2.2; }
.demo-home__scroll { position: relative; flex: 1 1 auto; overflow: hidden; padding: 0 2.4em; }
.demo-home__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4em; margin-top: -12.4em; }  /* scrolled: row 2 mostly above */
.demo-home__card {                            /* 12 pt radius, 14 pt padding, 150 pt tall */
  display: flex; flex-direction: column; gap: 0.6em;
  min-height: 15em;
  padding: 1.4em;
  border-radius: 1.2em;
  background: var(--demo-elevated);
  box-shadow: inset 0 0 0 1px var(--demo-line);
  color: var(--demo-text);
}
.demo-home__glyph { display: block; height: 1.9em; color: var(--demo-emph); }
.demo-home__glyph .demo__ico { width: 1.9em; height: 1.9em; stroke-width: 2; }
.demo-home__card > b { font-size: 1.5em; font-weight: 600; line-height: 1.2; }
.demo-home__sub { font-size: 1.2em; line-height: 1.3; color: var(--demo-text-2); }
.demo-home__eq {
  margin-top: auto; padding-top: 0.4em;
  font: 1.1em/1.3 ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--demo-text-3);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.demo-home__fx { font: italic 600 1.55em/1 "Times New Roman", Georgia, serif; letter-spacing: -0.02em; }
.demo-home__glyph .demo-home__fx { font-size: 1.6em; }

.demo-home__panel {
  display: flex; flex-direction: column;
  margin-top: 1.4em;
  padding: 1.4em;
  border-radius: 1.2em;
  background: var(--demo-elevated);
  box-shadow: inset 0 0 0 1px var(--demo-line);
  color: var(--demo-text);
}
.demo-home__panel > * + * { margin-top: 0.8em; }
.demo-home__ph { display: flex; align-items: center; gap: 0.8em; }
.demo-home__ph b { font-size: 1.4em; font-weight: 600; }
.demo-home__ph .demo-home__fx { color: var(--demo-accent); font-size: 1.35em; }
.demo-home__btn { display: inline-flex; align-items: center; padding: 0.35em 0.9em; border-radius: 0.5em; background: color-mix(in srgb, var(--demo-text) 9%, transparent); font-size: 1.3em; white-space: nowrap; }
.demo-home__prominent { display: inline-flex; padding: 0.35em 0.9em; border-radius: 0.5em; background: var(--demo-accent); color: var(--demo-accent-ink); font-size: 1.3em; white-space: nowrap; }
.demo-home__popup { display: inline-flex; align-items: center; justify-content: space-between; min-width: 13em; padding: 0.3em 0.5em 0.3em 0.8em; border-radius: 0.45em; background: color-mix(in srgb, var(--demo-text) 7%, transparent); }
.demo-home__popup .demo__ico { width: 1.1em; height: 1.1em; stroke-width: 2.2; }
.demo-home__picker { overflow: hidden; }
.demo-home__pk {                              /* the in-app picker, a card of its own */
  display: grid; gap: 0.6em;
  padding: 1.4em;
  border-radius: 1.2em;
  background: var(--demo-elevated);
  box-shadow: inset 0 0 0 1px var(--demo-line);
}
.demo-home__pkh { font-size: 1.3em; font-weight: 600; color: var(--demo-text-2); }
.demo-home__row { display: flex; align-items: center; gap: 0.8em; }
.demo-home__row .demo__ico { width: 1.4em; height: 1.4em; }
.demo-home__row > span { font-size: 1.3em; }

/* ===================================================================== */
/* Workflow: verify a formula (hub)                                        */
/* ===================================================================== */
/* Source: AgentToolsSection.swift formulaPanel, replayed in the build over AX:
 * the card opens a panel under the grid; "Pick a workbook…" opens the in-app
 * picker (never a Finder panel); picking preselects the first sheet and
 * drops the "No workbook picked" note; Evaluate is the only trigger. The
 * result for =SUM(C4:C11) on the sample is 585. */

.demo-home__card--go { animation: home-card var(--t) infinite; }
@keyframes home-card {
  0%, 8.4%   { background: var(--demo-elevated); box-shadow: inset 0 0 0 1px var(--demo-line); }
  8.5%, 95.9% { background: var(--demo-focus-soft); box-shadow: inset 0 0 0 0.15em var(--demo-focus); }
  96%, 100%  { background: var(--demo-elevated); box-shadow: inset 0 0 0 1px var(--demo-line); }
}
.demo-fx__panel { opacity: 0; animation: home-panel var(--t) infinite; }
@keyframes home-panel { 0%, 8.4% { opacity: 0; } 8.5%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0; } }

.demo-fx__pickrow { display: flex; align-items: center; gap: 0.8em; }
.demo-fx__p1 { font-size: 1em; animation: fx-p1 var(--t) infinite; }
.demo-fx__p2 { font-size: 0; animation: fx-p2 var(--t) infinite; }
.demo-fx__sheet { display: flex; align-items: center; gap: 0.8em; max-width: 0; overflow: hidden; white-space: nowrap; animation: fx-sheet var(--t) infinite; }
.demo-fx__sheet > span:first-child { font-size: 1.3em; }
.demo-fx__sheet .demo-home__popup > span { font-size: 1.3em; }
.demo-home__picker { max-height: 0; margin-top: 0 !important; animation: fx-picker var(--t) infinite; }
.demo-home__picker > .demo-home__pk { margin-top: 0.8em; }
.demo-fx__field {
  position: relative;
  display: flex; align-items: center;
  max-width: 52em; height: 2.4em;
  padding: 0 0.7em;
  border-radius: 0.5em;
  background: var(--demo-paper);
  box-shadow: inset 0 0 0 1px var(--demo-line);
  animation: fx-focus var(--t) infinite;
}
.demo-fx__ph, .demo-fx__typed { font: 1.2em/1 ui-monospace, "SF Mono", Menlo, monospace; white-space: nowrap; }
.demo-fx__ph { position: absolute; left: 0.58em; color: #A9AEB4; animation: fx-ph var(--t) infinite; }
.demo-fx__typed { position: relative; color: #111111; }
.demo-fx__clip { display: inline-block; clip-path: inset(0 100% 0 0); animation: fx-type var(--t) infinite; }
.demo-fx__caret { position: absolute; left: 0; top: -0.1em; width: 0.08em; height: 1.2em; background: #111111; opacity: 0; animation: fx-caret var(--t) infinite, fx-caret-x var(--t) infinite; }
.demo-fx__run { display: flex; align-items: center; gap: 0.8em; }
.demo-fx__result { font: 600 1.2em/1 ui-monospace, "SF Mono", Menlo, monospace; color: var(--demo-text); opacity: 0; animation: fx-result var(--t) infinite; }
.demo-fx__note { max-height: 2.4em; overflow: hidden; animation: fx-note var(--t) infinite; }
.demo-fx__note > span { display: block; font-size: 1.1em; color: var(--demo-text-3); }

/* card 8.5 %, picker 16.5 %, pick 24.5 %, field 30.5 %, type 32-42 %, Evaluate 46.5 % */
@keyframes fx-picker { 0%, 16.4% { max-height: 0; } 16.5%, 24.4% { max-height: 12em; } 24.5%, 100% { max-height: 0; } }
@keyframes fx-p1     { 0%, 24.4% { font-size: 1em; } 24.5%, 95.9% { font-size: 0; } 96%, 100% { font-size: 1em; } }
@keyframes fx-p2     { 0%, 24.4% { font-size: 0; } 24.5%, 95.9% { font-size: 1em; } 96%, 100% { font-size: 0; } }
@keyframes fx-sheet  { 0%, 24.4% { max-width: 0; } 24.5%, 95.9% { max-width: 40em; } 96%, 100% { max-width: 0; } }
@keyframes fx-note   { 0%, 24.4% { max-height: 2.4em; } 24.5%, 95.9% { max-height: 0; } 96%, 100% { max-height: 2.4em; } }
@keyframes fx-focus {
  0%, 30.4%  { box-shadow: inset 0 0 0 1px var(--demo-line); }
  30.5%, 95.9% { box-shadow: inset 0 0 0 1px var(--demo-line), 0 0 0 0.25em rgba(122, 125, 141, 0.85); }
  96%, 100%  { box-shadow: inset 0 0 0 1px var(--demo-line); }
}
@keyframes fx-ph     { 0%, 31.9% { opacity: 1; } 32%, 95.9% { opacity: 0; } 96%, 100% { opacity: 1; } }
@keyframes fx-type {
  0%, 32%    { clip-path: inset(0 100% 0 0); animation-timing-function: steps(12, end); }
  42%, 95.9% { clip-path: inset(0 0 0 0); }
  96%, 100%  { clip-path: inset(0 100% 0 0); }
}
@keyframes fx-caret   { 0%, 30.4% { opacity: 0; } 30.5%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0; } }
@keyframes fx-caret-x { 0%, 32% { left: 0; animation-timing-function: steps(12, end); } 42%, 100% { left: 100%; } }
@keyframes fx-result  { 0%, 46.4% { opacity: 0; } 46.5%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0; } }

.demo-fx .demo__ptr {
  --p-card: translate(11.85em, 14.95em);      /* tip 0.15em in; measured on the grid */
  --p-pick: translate(10.56em, 31.78em);
  --p-row: translate(11.85em, 38.28em);
  --p-field: translate(14.85em, 35.05em);
  --p-run: translate(7.58em, 38.31em);
  --p-away: translate(50em, 46em);
  animation: fx-ptr var(--t) infinite;
}
@keyframes fx-ptr {
  0%          { transform: var(--p-away); opacity: 0; }
  3%          { opacity: 1; animation-timing-function: ease-in-out; }
  7.5%        { transform: var(--p-card); }
  8%          { transform: var(--p-card) scale(0.9); }
  8.6%        { transform: var(--p-card); animation-timing-function: ease-in-out; }
  15.5%       { transform: var(--p-pick); }
  16%         { transform: var(--p-pick) scale(0.9); }
  16.6%       { transform: var(--p-pick); animation-timing-function: ease-in-out; }
  23.5%       { transform: var(--p-row); }
  24%         { transform: var(--p-row) scale(0.9); }
  24.6%       { transform: var(--p-row); animation-timing-function: ease-in-out; }
  29.5%       { transform: var(--p-field); }
  30%         { transform: var(--p-field) scale(0.9); }
  30.6%       { transform: var(--p-field); }
  42%         { transform: var(--p-field); animation-timing-function: ease-in-out; }
  45.5%       { transform: var(--p-run); }
  46%         { transform: var(--p-run) scale(0.9); }
  46.6%       { transform: var(--p-run); animation-timing-function: ease-in-out; }
  60%, 86%    { transform: var(--p-away); opacity: 1; }
  90%, 100%   { transform: var(--p-away); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .demo-home__card--go { background: var(--demo-focus-soft); box-shadow: inset 0 0 0 0.15em var(--demo-focus); }
  .demo-fx__panel, .demo-fx__result { opacity: 1; }
  .demo-fx__p1 { font-size: 0; }
  .demo-fx__p2 { font-size: 1em; }
  .demo-fx__sheet { max-width: 40em; }
  .demo-fx__note { max-height: 0; }
  .demo-fx__ph { opacity: 0; }
  .demo-fx__clip { clip-path: none; }
}

/* ===================================================================== */
/* Workflow: make a scan searchable (hub)                                  */
/* ===================================================================== */
/* Source: AgentToolsSection.swift ocrPanel and OCRService.swift, replayed in
 * the build over AX on an image-only scan (see demos.py for the numbers).
 * The card shows the in-app picker; picking a PDF reports the pages without
 * a text layer; the save panel opens beside the original with the
 * "(searchable)" name; while Vision runs the button is disabled and Cancel,
 * a spinner and "n / N" follow it; the result is one line in a grey box. */

.demo-ocr .demo__win { --t: 14s; }
.demo-ocr__picker { animation: ocr-picker var(--t) infinite; }
.demo-ocr__panel { max-height: 0; overflow: hidden; padding-top: 0; padding-bottom: 0; margin-top: 0; opacity: 0; animation: ocr-panel var(--t) infinite; }
.demo-ocr__panel > * + * { margin-top: 0.8em; }
.demo-ocr__file { display: flex; align-items: center; gap: 0.8em; }
.demo-ocr__file .demo__ico { width: 1.4em; height: 1.4em; }
.demo-ocr__file b { font-size: 1.3em; font-weight: 600; }
.demo-ocr__chip { padding: 0.2em 0.7em; border-radius: 1em; background: color-mix(in srgb, var(--demo-accent) 8%, transparent); color: var(--demo-accent); font: 500 1em/1.2 ui-monospace, "SF Mono", Menlo, monospace; font-style: normal; }
.demo-ocr__pages { font-size: 1.2em; font-weight: 500; color: var(--demo-text-2); }
.demo-ocr__run { display: flex; align-items: center; gap: 0.8em; }
.demo-ocr__go { animation: ocr-go var(--t) infinite; }
.demo-ocr__busy { display: flex; align-items: center; gap: 0.8em; max-width: 0; overflow: hidden; animation: ocr-busy var(--t) infinite; }
.demo-ocr__spin {
  flex: none; width: 1.5em; height: 1.5em;
  border-radius: 50%;
  border: 0.2em solid color-mix(in srgb, var(--demo-text) 18%, transparent);
  border-top-color: color-mix(in srgb, var(--demo-text) 70%, transparent);
  animation: ocr-spin 0.9s linear infinite;
}
.demo-ocr__n { display: grid; }
.demo-ocr__n > span { grid-area: 1 / 1; font-size: 1.2em; color: var(--demo-text-2); opacity: 0; white-space: nowrap; }
.demo-ocr__n1 { animation: ocr-n1 var(--t) infinite; }
.demo-ocr__n2 { animation: ocr-n2 var(--t) infinite; }
.demo-ocr__n3 { animation: ocr-n3 var(--t) infinite; }
.demo-ocr__done { max-height: 0; overflow: hidden; animation: ocr-done var(--t) infinite; }
.demo-ocr__done > span {                      /* 12 pt medium, 10 pt padding, primary at 5 % */
  display: block;
  padding: 1em;
  border-radius: 0.8em;
  background: color-mix(in srgb, var(--demo-text) 5%, transparent);
  font-size: 1.2em; font-weight: 500;
}
.demo-ocr__done > span { font-size: 1.2em; }

.demo-save {                                  /* NSSavePanel, compact: 370 × 204 pt */
  position: absolute; z-index: 8;
  left: 50%; top: 14em;
  width: 37em; margin-left: -18.5em;
  display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 0.9em 1em;
  padding: 1.6em 2em 1.8em;
  border-radius: 1.2em;
  background: var(--demo-menu);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1), 0 1.2em 3em rgba(0, 0, 0, 0.3);
  color: var(--demo-text);
  opacity: 0;
  animation: ocr-save var(--t) infinite;
}
.demo-save__t { grid-column: 1 / -1; font-size: 1.3em; font-weight: 700; color: var(--demo-text-2); margin-bottom: 0.3em; }
.demo-save__l { justify-self: end; font-size: 1.3em; color: var(--demo-text-2); }
.demo-save__f { display: flex; align-items: center; height: 2.6em; padding: 0 0.6em; border-radius: 0.6em; background: var(--demo-paper); box-shadow: inset 0 0 0 1px var(--demo-line); }
.demo-save__name { box-shadow: inset 0 0 0 1px var(--demo-line), 0 0 0 0.25em rgba(122, 125, 141, 0.85); }
.demo-save__name > span { padding: 0 0.1em; border-radius: 0.15em; background: rgba(0, 32, 63, 0.2); font-size: 1.3em; color: #111111; white-space: nowrap; }
.demo-save__where { display: flex; align-items: center; gap: 0.6em; }
.demo-save__pop { flex: 1 1 auto; display: flex; align-items: center; gap: 0.5em; height: 2.4em; padding: 0 0.6em; border-radius: 0.6em; background: color-mix(in srgb, var(--demo-text) 7%, transparent); }
.demo-save__pop > span { flex: 1 1 auto; font-size: 1.3em; }
.demo-save__pop .demo__ico { width: 1.2em; height: 1.2em; stroke-width: 2.2; }
.demo-save__pop .demo-save__folder { width: 1.6em; height: 1.6em; stroke-width: 1; }
.demo-save__more { display: grid; place-items: center; width: 2.4em; height: 2.4em; border-radius: 0.6em; background: color-mix(in srgb, var(--demo-text) 7%, transparent); }
.demo-save__more .demo__ico { width: 1.3em; height: 1.3em; stroke-width: 2.2; }
.demo-save__btns { grid-column: 1 / -1; justify-self: end; display: flex; gap: 0.8em; margin-top: 0.6em; }
.demo-save__b { padding: 0.45em 1.4em; border-radius: 0.6em; background: color-mix(in srgb, var(--demo-text) 9%, transparent); font-size: 1.3em; }
.demo-save__ok { background: var(--demo-accent); color: var(--demo-accent-ink); }

/* card 7.5 %, picker until 14.5 %, panel 14.5 %, save panel 21.5-29.5 %,
 * pages done at 33 / 36 / 39 %, result 41 % */
@keyframes ocr-picker { 0%, 7.4% { max-height: 0; } 7.5%, 14.4% { max-height: 14em; } 14.5%, 100% { max-height: 0; } }
@keyframes ocr-panel {
  0%, 14.4%   { max-height: 0; opacity: 0; padding-top: 0; padding-bottom: 0; margin-top: 0; }
  14.5%, 95.9% { max-height: 20em; opacity: 1; padding-top: 1.4em; padding-bottom: 1.4em; margin-top: 1.4em; }
  96%, 100%   { max-height: 0; opacity: 0; padding-top: 0; padding-bottom: 0; margin-top: 0; }
}
@keyframes ocr-save  { 0%, 21.4% { opacity: 0; transform: translateY(-0.4em); } 21.5%, 29.4% { opacity: 1; transform: none; } 29.5%, 100% { opacity: 0; } }
@keyframes ocr-go    { 0%, 29.4% { opacity: 1; } 29.5%, 40.9% { opacity: 0.45; } 41%, 100% { opacity: 1; } }
@keyframes ocr-busy  { 0%, 29.4% { max-width: 0; } 29.5%, 40.9% { max-width: 20em; } 41%, 100% { max-width: 0; } }
@keyframes ocr-n1    { 0%, 32.9% { opacity: 0; } 33%, 35.9% { opacity: 1; } 36%, 100% { opacity: 0; } }
@keyframes ocr-n2    { 0%, 35.9% { opacity: 0; } 36%, 38.9% { opacity: 1; } 39%, 100% { opacity: 0; } }
@keyframes ocr-n3    { 0%, 38.9% { opacity: 0; } 39%, 40.9% { opacity: 1; } 41%, 100% { opacity: 0; } }
@keyframes ocr-done  { 0%, 40.9% { max-height: 0; } 41%, 95.9% { max-height: 6em; } 96%, 100% { max-height: 0; } }
@keyframes ocr-spin  { to { transform: rotate(360deg); } }

.demo-ocr .demo__ptr {
  --p-card: translate(39.85em, 14.97em);      /* tip 0.15em in; measured in each state */
  --p-row: translate(10.85em, 30.4em);
  --p-go: translate(12.28em, 34.12em);
  --p-save: translate(43.04em, 30.77em);
  --p-away: translate(50em, 46em);
  animation: ocr-ptr var(--t) infinite;
}
@keyframes ocr-ptr {
  0%          { transform: var(--p-away); opacity: 0; }
  3%          { opacity: 1; animation-timing-function: ease-in-out; }
  6.5%        { transform: var(--p-card); }
  7%          { transform: var(--p-card) scale(0.9); }
  7.6%        { transform: var(--p-card); animation-timing-function: ease-in-out; }
  13.5%       { transform: var(--p-row); }
  14%         { transform: var(--p-row) scale(0.9); }
  14.6%       { transform: var(--p-row); animation-timing-function: ease-in-out; }
  20.5%       { transform: var(--p-go); }
  21%         { transform: var(--p-go) scale(0.9); }
  21.6%       { transform: var(--p-go); animation-timing-function: ease-in-out; }
  28.5%       { transform: var(--p-save); }
  29%         { transform: var(--p-save) scale(0.9); }
  29.6%       { transform: var(--p-save); animation-timing-function: ease-in-out; }
  46%, 86%    { transform: var(--p-away); opacity: 1; }
  90%, 100%   { transform: var(--p-away); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .demo-home__card--go { background: var(--demo-focus-soft); box-shadow: inset 0 0 0 0.15em var(--demo-focus); }
  .demo-ocr__picker { max-height: 0; }
  .demo-ocr__panel { max-height: 20em; opacity: 1; padding-top: 1.4em; padding-bottom: 1.4em; margin-top: 1.4em; }
  .demo-ocr__done { max-height: 6em; }
  .demo-ocr__spin { animation: none; }
}

/* ===================================================================== */
/* AI — an assistant works on a contract through MCP (the AI page's hero)  */
/* ===================================================================== */
/* The tool results are the real replies of TruePathMCP (the server that
 * ships as lynxoffice-mcp), replayed over stdio on a real .docx; see
 * demos.py. The terminal is a generic MCP client drawn for this site, not
 * any vendor's interface. Afterwards the same file is shown open in
 * LynxOffice, as the build showed it: changes accepted, the reply under
 * Tom Hale's comment. Long JSON results are cut to two lines, as a terminal
 * client folds them. */

.demo-ai .demo__win { --dw: 60; --ratio: 4 / 3; --t: 18s; }
.demo__win--bare { background: transparent; border: 0; box-shadow: none; overflow: visible; }

.demo-ai__term, .demo-ai__app {
  position: absolute;
  display: flex; flex-direction: column;
  overflow: hidden;
  border-radius: 1em;
  border: 1px solid var(--demo-frame);
  box-shadow: 0 1.8em 3.6em -1.6em rgba(0, 12, 28, 0.55), 0 0.2em 0.6em rgba(0, 12, 28, 0.12);
}
.demo-ai__term { left: 0; top: 0; width: 44em; height: 30em; z-index: 2; background: #1C1C1E; }
.demo-ai__app { right: 0; bottom: 0; width: 50em; height: 40em; z-index: 3; opacity: 0; background: var(--demo-band); color: var(--demo-text); animation: ai-app var(--t) infinite; }
.demo-ai__tbar { flex: none; position: relative; display: flex; align-items: center; height: 2.6em; padding: 0 1.2em; background: #2C2C2E; border-bottom: 1px solid #000000; }
.demo-ai__ttl { position: absolute; left: 0; right: 0; text-align: center; font-size: 1.1em; font-weight: 600; color: #C7C7CC; }
.demo-ai__tbody {                             /* new output arrives at the bottom and pushes the rest up */
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 1em 1.3em;
  overflow: hidden;
  color: #E5E5EA;
  font: 1.1em/1.45 ui-monospace, "SF Mono", Menlo, monospace;
}
/* Top-anchored while it fits, bottom-anchored once it overflows, as a terminal scrolls. */
.demo-ai__flow { flex: none; min-height: 100%; }
.demo-ai__flow > div { overflow: hidden; }
.demo-ai__prompt b { color: #7FEFBE; font-weight: 600; }
.demo-ai__l1, .demo-ai__l2 { display: inline-block; vertical-align: bottom; overflow: hidden; white-space: pre; max-width: 0; }
.demo-ai__l1 { animation: ai-l1 var(--t) infinite; }
.demo-ai__l2 { animation: ai-l2 var(--t) infinite; }
.demo-ai__caret { display: inline-block; width: 0.55em; height: 1.15em; vertical-align: -0.2em; background: #E5E5EA; opacity: 0; }
.demo-ai__k1 { animation: ai-k1 var(--t) infinite; }
.demo-ai__k2 { animation: ai-k2 var(--t) infinite; }
.demo-ai__call, .demo-ai__res, .demo-ai__say { max-height: 0; }
.demo-ai__tool { display: block; margin-top: 0.55em; color: #8AB4F8; font-weight: 600; }
.demo-ai__args { display: block; padding-left: 1.6em; color: #98989D; }
.demo-ai__res { padding-left: 1.6em; color: #AEAEB2; }
.demo-ai__res > span {                        /* folded to two lines, as terminal clients fold long results */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  word-break: break-all;
  padding-left: 1.1em; text-indent: -1.1em;
}
.demo-ai__res > span::before { content: "⤷ "; color: #636366; }
.demo-ai__say { color: #F2F2F7; }
.demo-ai__say { padding-top: 0; }
.demo-ai__c1 { animation: ai-c1 var(--t) infinite; } .demo-ai__r1 { animation: ai-r1 var(--t) infinite; }
.demo-ai__c2 { animation: ai-c2 var(--t) infinite; } .demo-ai__r2 { animation: ai-r2 var(--t) infinite; }
.demo-ai__c3 { animation: ai-c3 var(--t) infinite; } .demo-ai__r3 { animation: ai-r3 var(--t) infinite; }
.demo-ai__c4 { animation: ai-c4 var(--t) infinite; } .demo-ai__r4 { animation: ai-r4 var(--t) infinite; }
.demo-ai__say { animation: ai-say var(--t) infinite; }

.demo-ai__term .demo__dots i { animation: ai-dots-term var(--t) infinite; }
.demo-ai__main { flex: 1 1 auto; }
.demo-ai__page { top: 1.4em; }
.demo-ai__panel { width: 24em; gap: 0.7em; }
.demo-ai__reply { margin-left: 1.4em; }       /* replies sit 14 pt in */

/* typing 2-13.5 %, then each call and its result; LynxOffice in front at 50 % */
@keyframes ai-l1 { 0%, 2% { max-width: 0; animation-timing-function: steps(56, end); } 10%, 94.9% { max-width: 56ch; } 95%, 100% { max-width: 0; } }
@keyframes ai-l2 { 0%, 10% { max-width: 0; animation-timing-function: steps(27, end); } 13.5%, 94.9% { max-width: 27ch; } 95%, 100% { max-width: 0; } }
@keyframes ai-k1 { 0%, 1% { opacity: 1; } 1.1%, 1.9% { opacity: 0; } 2%, 9.9% { opacity: 1; } 10%, 100% { opacity: 0; } }
@keyframes ai-k2 { 0%, 9.9% { opacity: 0; } 10%, 15% { opacity: 1; } 15.1%, 100% { opacity: 0; } }
@keyframes ai-c1 { 0%, 16.9% { max-height: 0; } 17%, 94.9% { max-height: 6em; } 95%, 100% { max-height: 0; } }
@keyframes ai-r1 { 0%, 19.4% { max-height: 0; } 19.5%, 94.9% { max-height: 4em; } 95%, 100% { max-height: 0; } }
@keyframes ai-c2 { 0%, 22.9% { max-height: 0; } 23%, 94.9% { max-height: 6em; } 95%, 100% { max-height: 0; } }
@keyframes ai-r2 { 0%, 25.4% { max-height: 0; } 25.5%, 94.9% { max-height: 4em; } 95%, 100% { max-height: 0; } }
@keyframes ai-c3 { 0%, 28.9% { max-height: 0; } 29%, 94.9% { max-height: 6em; } 95%, 100% { max-height: 0; } }
@keyframes ai-r3 { 0%, 31.4% { max-height: 0; } 31.5%, 94.9% { max-height: 4em; } 95%, 100% { max-height: 0; } }
@keyframes ai-c4 { 0%, 34.9% { max-height: 0; } 35%, 94.9% { max-height: 6em; } 95%, 100% { max-height: 0; } }
@keyframes ai-r4 { 0%, 37.4% { max-height: 0; } 37.5%, 94.9% { max-height: 4em; } 95%, 100% { max-height: 0; } }
@keyframes ai-say { 0%, 40.9% { max-height: 0; padding-top: 0; } 41%, 94.9% { max-height: 5em; padding-top: 0.6em; } 95%, 100% { max-height: 0; padding-top: 0; } }
/* the file is opened in LynxOffice once the assistant is done: a window opening, not a raise */
@keyframes ai-app {
  0%, 49.9%  { opacity: 0; transform: scale(0.97); }
  51%, 94.9% { opacity: 1; transform: none; }
  95%, 100%  { opacity: 0; transform: none; }
}
@keyframes ai-dots-term { 0%, 49.9% { background: var(--dot); } 50%, 94.9% { background: #58585D; } 95%, 100% { background: var(--dot); } }
.demo-ai .demo__dots i:nth-child(1) { --dot: #FF5F57; }
.demo-ai .demo__dots i:nth-child(2) { --dot: #FEBC2E; }
.demo-ai .demo__dots i:nth-child(3) { --dot: #28C840; }

@media (prefers-reduced-motion: reduce) {
  .demo-ai__app { opacity: 1; }
  .demo-ai__call, .demo-ai__res, .demo-ai__say { max-height: none; }
  .demo-ai__l1 { max-width: 56ch; }
  .demo-ai__l2 { max-width: 27ch; }
}

/* ===================================================================== */
/* Workflow: connect an AI (the /ai/ page)                                 */
/* ===================================================================== */
/* Source: AgentToolsSection.swift connectPanel and MCPConfigComposer,
 * replayed in the build over AX (see demos.py). The panel opens under the
 * whole grid, so the Home screen is scrolled to it, as a person would. Picking
 * Claude Code swaps the JSON for the one-line command and the panel shrinks;
 * Copy configuration reads "Copied" for 0.8 s, then its own label again. */

.demo-cx .demo__win { --t: 14s; }
.demo-cx__content { --cx-s: -47.9em; padding-top: 1.8em; animation: cx-scroll var(--t) infinite; }
.demo-cx__title { display: block; margin-bottom: 1.4em; font-size: 3em; font-weight: 700; line-height: 1.2; color: var(--demo-text); }
.demo-cx__grid { margin-top: 0; }             /* the other Home demos start scrolled into the grid */
.demo-cx__panel { opacity: 0; animation: home-panel var(--t) infinite; }
.demo-cx__panel .demo-home__ph .demo__ico { width: 1.4em; height: 1.4em; stroke-width: 2; color: var(--demo-accent); }
.demo-cx__hint { font-size: 1.1em; color: var(--demo-text-2); }
.demo-cx__radios { display: grid; gap: 0.5em; justify-items: start; }
.demo-cx__radio { display: flex; align-items: center; gap: 0.6em; }
.demo-cx__radio > span { font-size: 1.1em; }
.demo-cx__radio i {                           /* a small radio button: accent when on */
  --cx-off: color-mix(in srgb, var(--demo-text) 10%, var(--demo-elevated));
  position: relative; flex: none;
  width: 1.3em; height: 1.3em; border-radius: 50%;
  background: var(--cx-off);
}
.demo-cx__radio i::after { content: ""; position: absolute; inset: 0.42em; border-radius: 50%; background: var(--demo-accent-ink); opacity: 0; }
.demo-cx__r1 i { background: var(--demo-accent); animation: cx-r1 var(--t) infinite; }
.demo-cx__r1 i::after { opacity: 1; animation: cx-dot1 var(--t) infinite; }
.demo-cx__r2 i { animation: cx-r2 var(--t) infinite; }
.demo-cx__r2 i::after { animation: cx-dot2 var(--t) infinite; }
.demo-cx__path {
  display: flex; align-items: center;
  max-width: 52em; height: 2.2em;
  padding: 0 0.6em;
  border-radius: 0.5em;
  background: var(--demo-textbg);
  box-shadow: inset 0 0 0 1px var(--demo-line);
}
.demo-cx__path > span { font: 1.2em/1 ui-monospace, "SF Mono", Menlo, monospace; color: var(--demo-text); white-space: nowrap; }
.demo-cx__snip > span { display: block; overflow: hidden; font: 1.1em/1.3 ui-monospace, "SF Mono", Menlo, monospace; color: var(--demo-text-2); white-space: pre; }
.demo-cx__json { max-height: 10.4em; animation: cx-json var(--t) infinite; }
.demo-cx__cmd { max-height: 0; animation: cx-cmd var(--t) infinite; }
.demo-cx__copy { display: flex; }
.demo-cx__c1 { font-size: 1em; animation: cx-c1 var(--t) infinite; }
.demo-cx__c2 { font-size: 0; animation: cx-c2 var(--t) infinite; }
.demo-cx__headless { display: block; margin-top: 1.4em; font-size: 1.2em; font-weight: 500; line-height: 1.35; color: var(--demo-text-3); }
.demo-cx__recent { margin-top: 0.6em; }

/* card 8.5 %, scroll 11-19 %, Claude Code 28 %, Copied 39.5-45.2 % (0.8 s of 14 s) */
@keyframes cx-scroll {
  0%, 11%    { transform: none; animation-timing-function: ease-in-out; }
  19%, 95.9% { transform: translateY(var(--cx-s)); }
  96%, 100%  { transform: none; }
}
@keyframes cx-r1   { 0%, 27.9% { background: var(--demo-accent); } 28%, 95.9% { background: var(--cx-off); } 96%, 100% { background: var(--demo-accent); } }
@keyframes cx-dot1 { 0%, 27.9% { opacity: 1; } 28%, 95.9% { opacity: 0; } 96%, 100% { opacity: 1; } }
@keyframes cx-r2   { 0%, 27.9% { background: var(--cx-off); } 28%, 95.9% { background: var(--demo-accent); } 96%, 100% { background: var(--cx-off); } }
@keyframes cx-dot2 { 0%, 27.9% { opacity: 0; } 28%, 95.9% { opacity: 1; } 96%, 100% { opacity: 0; } }
@keyframes cx-json { 0%, 27.9% { max-height: 10.4em; } 28%, 95.9% { max-height: 0; } 96%, 100% { max-height: 10.4em; } }
@keyframes cx-cmd  { 0%, 27.9% { max-height: 0; } 28%, 95.9% { max-height: 1.3em; } 96%, 100% { max-height: 0; } }
@keyframes cx-c1   { 0%, 39.4% { font-size: 1em; } 39.5%, 45.1% { font-size: 0; } 45.2%, 100% { font-size: 1em; } }
@keyframes cx-c2   { 0%, 39.4% { font-size: 0; } 39.5%, 45.1% { font-size: 1em; } 45.2%, 100% { font-size: 0; } }

.demo-cx .demo__ptr {
  --p-card: translate(11.85em, 20.85em);          /* tip 0.15em in; measured on the grid */
  --p-code: translate(4.42em, 25.83em);
  --p-copy: translate(10.88em, 35.68em);
  --p-away: translate(50em, 46em);
  animation: cx-ptr var(--t) infinite;
}
@keyframes cx-ptr {
  0%          { transform: var(--p-away); opacity: 0; }
  3%          { opacity: 1; animation-timing-function: ease-in-out; }
  7.5%        { transform: var(--p-card); }
  8%          { transform: var(--p-card) scale(0.9); }
  8.6%        { transform: var(--p-card); }
  21%         { transform: var(--p-card); animation-timing-function: ease-in-out; }
  27%         { transform: var(--p-code); }
  27.5%       { transform: var(--p-code) scale(0.9); }
  28.1%       { transform: var(--p-code); }
  33%         { transform: var(--p-code); animation-timing-function: ease-in-out; }
  38.5%       { transform: var(--p-copy); }
  39%         { transform: var(--p-copy) scale(0.9); }
  39.6%       { transform: var(--p-copy); animation-timing-function: ease-in-out; }
  55%, 86%    { transform: var(--p-away); opacity: 1; }
  90%, 100%   { transform: var(--p-away); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .demo-cx .demo-home__card--go { background: var(--demo-focus-soft); box-shadow: inset 0 0 0 0.15em var(--demo-focus); }
  .demo-cx__content { transform: translateY(var(--cx-s)); }
  .demo-cx__panel { opacity: 1; }
  .demo-cx__r1 i { background: var(--cx-off); }
  .demo-cx__r1 i::after { opacity: 0; }
  .demo-cx__r2 i { background: var(--demo-accent); }
  .demo-cx__r2 i::after { opacity: 1; }
  .demo-cx__json { max-height: 0; }
  .demo-cx__cmd { max-height: 1.3em; }
}

/* ===================================================================== */
/* The command line (the /cli/ page)                                       */
/* ===================================================================== */
/* Source: the command-line tool run in zsh on the sample files; every
 * output line is its own (CLI_SESSION in demos.py, which also asserts the
 * steps() counts below against the commands' lengths). A generic terminal
 * drawn for this site, not any vendor's. A command types at a steady pace,
 * then its output lands, as a terminal prints it. */

.demo-cli .demo__win { --dw: 60; --ratio: 16 / 9; --t: 15s; }
.demo-cli__term {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
  border-radius: 1em;
  border: 1px solid var(--demo-frame);
  box-shadow: 0 1.8em 3.6em -1.6em rgba(0, 12, 28, 0.55), 0 0.2em 0.6em rgba(0, 12, 28, 0.12);
  background: #1C1C1E;
}
.demo-cli__tbar { flex: none; position: relative; display: flex; align-items: center; height: 2.6em; padding: 0 1.2em; background: #2C2C2E; border-bottom: 1px solid #000000; }
.demo-cli__ttl { position: absolute; left: 0; right: 0; text-align: center; font-size: 1.1em; font-weight: 600; color: #C7C7CC; }
.demo-cli__tbody {
  flex: 1 1 auto; min-height: 0;
  padding: 1em 1.3em;
  overflow: hidden;
  color: #E5E5EA;
  font: 1.15em/1.45 ui-monospace, "SF Mono", Menlo, monospace;   /* the longest line, 78 characters, fits with room */
  white-space: pre;
}
.demo-cli__line, .demo-cli__out { overflow: hidden; }
.demo-cli__line b { color: #7FEFBE; font-weight: 600; }
.demo-cli__out { color: #C7C7CC; }
.demo-cli__cmd { display: inline-block; vertical-align: bottom; overflow: hidden; max-width: 0; }
.demo-cli__caret { display: inline-block; width: 0.55em; height: 1.15em; vertical-align: -0.2em; background: #E5E5EA; opacity: 0; }
.demo-cli__p2, .demo-cli__p3, .demo-cli__p4, .demo-cli__out { max-height: 0; }
.demo-cli__k1 { animation: cli-k1 var(--t) infinite; }
.demo-cli__k2 { animation: cli-k2 var(--t) infinite; }
.demo-cli__k3 { animation: cli-k3 var(--t) infinite; }
.demo-cli__c1 { animation: cli-c1 var(--t) infinite; }
.demo-cli__c2 { animation: cli-c2 var(--t) infinite; }
.demo-cli__c3 { animation: cli-c3 var(--t) infinite; }
.demo-cli__c4 { animation: cli-c4 var(--t) infinite; }
.demo-cli__p2 { animation: cli-p2 var(--t) infinite; }
.demo-cli__p3 { animation: cli-p3 var(--t) infinite; }
.demo-cli__p4 { animation: cli-p4 var(--t) infinite; }
.demo-cli__o1 { animation: cli-o1 var(--t) infinite; }
.demo-cli__o2 { animation: cli-o2 var(--t) infinite; }
.demo-cli__o3a { animation: cli-o3a var(--t) infinite; }
.demo-cli__o3b { animation: cli-o3b var(--t) infinite; }
.demo-cli__o3c { animation: cli-o3c var(--t) infinite; }

/* type 3-12 %, 20-32 %, 40-51 %; output at 14, 34, 53.5/57/59.5 %; last prompt 61 % */
@keyframes cli-k1 { 0%, 3%  { max-width: 0; animation-timing-function: steps(56, end); } 12%, 94.9% { max-width: 56ch; } 95%, 100% { max-width: 0; } }
@keyframes cli-k2 { 0%, 20% { max-width: 0; animation-timing-function: steps(76, end); } 32%, 94.9% { max-width: 76ch; } 95%, 100% { max-width: 0; } }
@keyframes cli-k3 { 0%, 40% { max-width: 0; animation-timing-function: steps(47, end); } 51%, 94.9% { max-width: 47ch; } 95%, 100% { max-width: 0; } }
@keyframes cli-c1 { 0%, 13.9% { opacity: 1; } 14%, 94.9% { opacity: 0; } 95%, 100% { opacity: 1; } }
@keyframes cli-c2 { 0%, 17.9% { opacity: 0; } 18%, 33.9% { opacity: 1; } 34%, 100% { opacity: 0; } }
@keyframes cli-c3 { 0%, 37.9% { opacity: 0; } 38%, 53.4% { opacity: 1; } 53.5%, 100% { opacity: 0; } }
@keyframes cli-c4 { 0%, 60.9% { opacity: 0; } 61%, 94.9% { opacity: 1; } 95%, 100% { opacity: 0; } }
@keyframes cli-p2 { 0%, 17.9% { max-height: 0; } 18%, 94.9% { max-height: 2em; } 95%, 100% { max-height: 0; } }
@keyframes cli-p3 { 0%, 37.9% { max-height: 0; } 38%, 94.9% { max-height: 2em; } 95%, 100% { max-height: 0; } }
@keyframes cli-p4 { 0%, 60.9% { max-height: 0; } 61%, 94.9% { max-height: 2em; } 95%, 100% { max-height: 0; } }
@keyframes cli-o1 { 0%, 13.9% { max-height: 0; } 14%, 94.9% { max-height: 7em; } 95%, 100% { max-height: 0; } }
@keyframes cli-o2 { 0%, 33.9% { max-height: 0; } 34%, 94.9% { max-height: 2em; } 95%, 100% { max-height: 0; } }
@keyframes cli-o3a { 0%, 53.4% { max-height: 0; } 53.5%, 94.9% { max-height: 2em; } 95%, 100% { max-height: 0; } }
@keyframes cli-o3b { 0%, 56.9% { max-height: 0; } 57%, 94.9% { max-height: 2em; } 95%, 100% { max-height: 0; } }
@keyframes cli-o3c { 0%, 59.4% { max-height: 0; } 59.5%, 94.9% { max-height: 2em; } 95%, 100% { max-height: 0; } }

@media (prefers-reduced-motion: reduce) {
  .demo-cli__cmd { max-width: none; }
  .demo-cli__p2, .demo-cli__p3, .demo-cli__p4, .demo-cli__out { max-height: none; }
  .demo-cli__c4 { opacity: 1; }
}

/* Reduced motion: the still frames above show an edited document, so they
 * also show it unsaved — Modified, Save enabled, the tab's dot. (Word's still
 * is after its Save, so it stays Saved.) */
@media (prefers-reduced-motion: reduce) {
  .demo-xl .demo-ed__saved, .demo-deck .demo-ed__saved, .demo-rv .demo-ed__saved, .demo-md .demo-ed__saved { opacity: 0; }
  .demo-xl .demo-ed__modified, .demo-deck .demo-ed__modified, .demo-rv .demo-ed__modified, .demo-md .demo-ed__modified,
  .demo-xl .demo__dirty, .demo-deck .demo__dirty, .demo-rv .demo__dirty, .demo-md .demo__dirty,
  .demo-xl .demo-ed__save, .demo-deck .demo-ed__save, .demo-rv .demo-ed__save, .demo-md .demo-ed__save { opacity: 1; }
}
