/* ---------------------------------------------------------------------------
 * Live demos embedded in pattern cards.
 *
 * RULES THIS FILE FOLLOWS, and they are not optional:
 *  - Every selector is prefixed `.dmo` so a demo can never leak style into the
 *    dashboard around it. There is no iframe (adding one would mean loosening
 *    the page's `default-src 'none'` CSP to allow frame-src, and a CSP is
 *    worth more than isolation convenience here).
 *  - No inline styles anywhere. `style-src 'self'` blocks them, deliberately.
 *  - Every motion demo honours prefers-reduced-motion, because the library
 *    it is demonstrating says to. A motion demo that ignores the preference
 *    would be arguing against its own pattern.
 * ------------------------------------------------------------------------- */

.dmo {
  --dmo-fast: 0.01ms;
  --dmo-base: 0.01ms;
  --dmo-slow: 0.01ms;
  margin: 0.35rem 0 0;
  padding: 0.85rem;
  border: 1px solid var(--line, #2a3038);
  border-radius: 10px;
  background: var(--panel, #171b21);
}
@media (prefers-reduced-motion: no-preference) {
  .dmo { --dmo-fast: 120ms; --dmo-base: 240ms; --dmo-slow: 460ms; }
}

.dmo-hint {
  margin: 0 0 0.6rem;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--muted, #93a0ad);
}
.dmo-row { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }

.dmo-btn {
  font: inherit;
  font-size: 0.85rem;
  padding: 0.5rem 0.8rem;
  min-height: 40px;                 /* thumb-sized: these get tapped on a phone */
  border-radius: 8px;
  border: 1px solid var(--line, #2a3038);
  background: var(--chip, #1e242c);
  color: var(--fg, #e6edf3);
  cursor: pointer;
}
.dmo-btn:hover { border-color: var(--accent, #6ea8fe); }
.dmo-btn:focus-visible { outline: 2px solid var(--accent, #6ea8fe); outline-offset: 2px; }

/* --- 13 reduced-motion-gate: live readout of the real OS preference ------- */
.dmo-rm-state { font-weight: 600; }
.dmo-rm-on  { color: #7ee787; }
.dmo-rm-off { color: #ffa657; }

/* --- 14 native-dialog-modal ---------------------------------------------- */
.dmo-dialog {
  border: 1px solid var(--line, #2a3038);
  border-radius: 12px;
  background: var(--panel, #171b21);
  color: var(--fg, #e6edf3);
  padding: 1.1rem;
  max-inline-size: min(92vw, 26rem);
}
.dmo-dialog::backdrop { background: rgb(0 0 0 / 0.55); }
.dmo-dialog h4 { margin: 0 0 0.5rem; font-size: 1rem; }
.dmo-dialog p { margin: 0 0 0.9rem; font-size: 0.85rem; color: var(--muted, #93a0ad); }

/* --- 15 popover-menu ------------------------------------------------------ */
.dmo-anchor { position: relative; }
.dmo-popover {
  /* Tier 1 positioning: a plain wrapper, because CSS anchor positioning is
     not ready on Safari. This is the pattern's own headline gotcha, so the
     demo had better not cheat on it. */
  position: absolute;
  inset: auto auto auto 0;
  margin: 0;
  inset-block-start: 2.6rem;
  min-inline-size: 11rem;
  padding: 0.3rem;
  border: 1px solid var(--line, #2a3038);
  border-radius: 10px;
  background: var(--panel, #171b21);
  color: var(--fg, #e6edf3);
}
.dmo-popover button {
  display: block; inline-size: 100%; text-align: left;
  font: inherit; font-size: 0.85rem; min-height: 38px;
  padding: 0.4rem 0.6rem; border: 0; border-radius: 6px;
  background: none; color: inherit; cursor: pointer;
}
.dmo-popover button:hover { background: var(--chip, #1e242c); }

/* --- 16 enter-exit-animation --------------------------------------------- */
.dmo-panel {
  display: none;
  opacity: 0;
  translate: 0 -8px;
  margin-block-start: 0.5rem;
  padding: 0.7rem 0.85rem;
  border-radius: 8px;
  background: var(--chip, #1e242c);
  font-size: 0.85rem;
  transition: opacity var(--dmo-base) ease,
              translate var(--dmo-base) ease,
              display var(--dmo-base) allow-discrete;
}
.dmo-panel[data-open="true"] { display: block; opacity: 1; translate: 0 0; }
@starting-style {
  .dmo-panel[data-open="true"] { opacity: 0; translate: 0 -8px; }
}

/* --- 17 spring-easing ----------------------------------------------------- */
.dmo-track {
  position: relative; block-size: 34px; margin-block-start: 0.5rem;
  border-radius: 6px; background: var(--chip, #1e242c);
}
.dmo-track + .dmo-track { margin-block-start: 0.35rem; }
.dmo-ball {
  position: absolute; inset-block-start: 5px; inset-inline-start: 5px;
  inline-size: 24px; block-size: 24px; border-radius: 50%;
  background: var(--accent, #6ea8fe);
  translate: 0 0;
  transition: translate var(--dmo-slow);
}
.dmo-track[data-run="true"] .dmo-ball { translate: calc(100cqw - 34px) 0; }
.dmo-track { container-type: inline-size; }
.dmo-ease-linear  .dmo-ball { transition-timing-function: cubic-bezier(.4,0,.2,1); }
.dmo-ease-spring  .dmo-ball {
  transition-timing-function: cubic-bezier(.2,1.2,.3,1);
  transition-timing-function: linear(0,.29 6%,.86 15%,1.04 20%,1.06 24%,1 32%,.99 40%,1);
}
.dmo-ease-bounce  .dmo-ball {
  transition-timing-function: cubic-bezier(.2,1.6,.3,1);
  transition-timing-function: linear(0,.24 6%,.83 15%,1.14 21%,1.03 30%,.98 38%,1.01 47%,1);
}
.dmo-lbl { font-size: 0.72rem; color: var(--muted, #93a0ad); }

/* --- 18/19 scroll-driven: one scrollable box each ------------------------- */
.dmo-scroller {
  block-size: 150px; overflow: auto; position: relative;
  border-radius: 8px; background: var(--chip, #1e242c);
  padding: 0.6rem;
}
.dmo-scroller p { margin: 0 0 0.55rem; font-size: 0.82rem; }
.dmo-item {
  margin: 0 0 0.5rem; padding: 0.55rem 0.7rem; border-radius: 6px;
  background: var(--panel, #171b21); font-size: 0.82rem;
  opacity: 1; translate: none;      /* FAIL-VISIBLE base state -- see pattern 18 */
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .dmo-item {
      animation: dmo-reveal linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 35%;
    }
  }
}
@keyframes dmo-reveal {
  from { opacity: 0; translate: 0 14px; }
  to   { opacity: 1; translate: 0 0; }
}

.dmo-progress {
  position: sticky; inset-block-start: 0; z-index: 2;
  block-size: 4px; border-radius: 3px;
  background: var(--accent, #6ea8fe);
  transform-origin: left center;
  scale: 0 1;                        /* FAIL-INVISIBLE base state -- pattern 19 */
}
@supports (animation-timeline: scroll()) {
  .dmo-progress {
    scale: 1 1;
    animation: dmo-grow linear;
    animation-timeline: scroll(nearest);
  }
}
@keyframes dmo-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* Honest about non-support, in pure CSS. */
.dmo-unsupported { display: none; }
@supports not (animation-timeline: view()) {
  .dmo-unsupported { display: block; color: #ffa657; }
}

/* --- 21 css-3d-card ------------------------------------------------------- */
.dmo-flip { perspective: 800px; block-size: 120px; max-inline-size: 15rem; }
.dmo-flip-inner {
  position: relative; inline-size: 100%; block-size: 100%;
  transform-style: preserve-3d;
  transition: transform var(--dmo-slow) cubic-bezier(.2,.9,.3,1);
}
.dmo-flip-inner[data-flipped="true"] { transform: rotateY(180deg); }
.dmo-face {
  position: absolute; inset: 0;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  display: flex; flex-direction: column; gap: 0.4rem;
  align-items: center; justify-content: center;
  border-radius: 12px; background: var(--chip, #1e242c);
  font-size: 0.85rem; text-align: center; padding: 0.6rem;
}
.dmo-face--back { transform: rotateY(180deg); }
@media (prefers-reduced-motion: reduce) {
  /* Cross-fade instead of rotating -- rotation in depth is exactly the
     vestibular trigger the preference exists to suppress. Pattern 21 says so. */
  .dmo-flip { perspective: none; }
  .dmo-flip-inner { transform-style: flat; transition: none; }
  .dmo-face { backface-visibility: visible; transition: opacity 0.01ms; }
  .dmo-face--back { transform: none; opacity: 0; }
  .dmo-flip-inner[data-flipped="true"] { transform: none; }
  .dmo-flip-inner[data-flipped="true"] .dmo-face--front { opacity: 0; }
  .dmo-flip-inner[data-flipped="true"] .dmo-face--back  { opacity: 1; }
}

/* --- shared widgets for the data/behaviour demos -------------------------- */
.dmo-input {
  font: inherit; font-size: 0.85rem; min-height: 40px; flex: 1 1 12rem;
  padding: 0.45rem 0.6rem; border-radius: 8px;
  border: 1px solid var(--line, #2a3038);
  background: var(--bg, #0f1216); color: var(--fg, #e6edf3);
}
.dmo-input:focus-visible { outline: 2px solid var(--accent, #6ea8fe); outline-offset: 1px; }
.dmo-check { font-size: 0.82rem; gap: 0.45rem; }
.dmo-out {
  margin: 0.55rem 0 0; padding: 0.6rem 0.7rem;
  border-radius: 8px; background: var(--bg, #0f1216);
  font-size: 0.75rem; line-height: 1.5;
  white-space: pre-wrap; word-break: break-word;
  max-block-size: 15rem; overflow: auto;
}
.dmo-out-tall { max-block-size: 20rem; }

/* --- toast demo ----------------------------------------------------------- */
.dmo-toasts {
  display: flex; flex-direction: column; gap: 0.4rem; margin-block-start: 0.6rem;
}
.dmo-toast {
  position: relative;
  padding: 0.55rem 2rem 0.55rem 0.75rem;
  border-radius: 8px; background: var(--chip, #1e242c);
  border: 1px solid var(--line, #2a3038);
  font-size: 0.82rem;
  opacity: 0; translate: 0 6px;
  animation: dmo-toast-in var(--dmo-base) ease forwards;
}
@keyframes dmo-toast-in { to { opacity: 1; translate: 0 0; } }
.dmo-toast-x {
  position: absolute; inset-block-start: 50%; inset-inline-end: 0.35rem;
  translate: 0 -50%;
  min-inline-size: 28px; min-block-size: 28px;
  border: 0; border-radius: 6px; background: none;
  color: var(--muted, #93a0ad); font-size: 1rem; cursor: pointer;
}
.dmo-toast-x:hover { color: var(--fg, #e6edf3); }

/* The pairing card links out to the two-device demo. An <a> with .dmo-btn
   needs these two lines to sit like the buttons beside it. */
a.dmo-btn { display: inline-block; text-decoration: none; }
