/*
  The demo dialog, on the site's own material.

  The panel is the glass face the cookie card and the playbook cards share
  (pryor-tokens.css --glass-face-*), with the lime kiss the nav glass carries in
  its corner. The close button, eyebrow and copy sizes come from the consent
  card in site-chrome.css; the fields are the hero's scan input; the submit is
  the page's .button, unchanged, so it lifts and its arrow turns lime exactly
  like every other call to action here.

  Two open states have to look the same. With JavaScript the dialog is opened
  with showModal() and lives in the top layer with its ::backdrop. Without it
  the founder link is a plain #book-demo anchor and :target is the only signal,
  so the panel is positioned and scrimmed by hand. The :target rule outranks
  the UA's dialog:not([open]) { display: none }, which is what makes the
  fallback work at all.
*/

.demo-dialog {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  overflow: visible;
}

.demo-dialog::backdrop {
  background: rgba(var(--ink-rgb), .38);
  -webkit-backdrop-filter: blur(6px) saturate(120%);
  backdrop-filter: blur(6px) saturate(120%);
}

.demo-dialog[open] {
  max-width: min(440px, calc(100vw - 32px));
  max-height: calc(100dvh - 48px);
  overflow-y: auto;
  overscroll-behavior: contain;
  animation: demo-dialog-in var(--dur-micro, .22s) var(--ease, ease) both;
}

@keyframes demo-dialog-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* No-JavaScript fallback: the anchor navigates, :target opens.

   Gated on the root class the script sets, so the two mechanisms can never both
   apply. Once the script runs, [open] is the only thing that shows the dialog;
   a #book-demo left in the URL by a back button or a restored page then paints
   nothing, where :target alone would have dropped a full-screen scrim over a
   page with no dialog on it. */
:root:not(.demo-dialog-js) .demo-dialog:target:not([open]) {
  display: block;
  position: fixed;
  z-index: 90;
  inset: 0;
  width: 100%;
  max-width: none;
  max-height: none;
  overflow-y: auto;
  background: rgba(var(--ink-rgb), .38);
}

:root:not(.demo-dialog-js) .demo-dialog:target:not([open]) .demo-dialog__panel {
  max-width: min(440px, calc(100vw - 32px));
  margin: max(24px, 8vh) auto;
}

.demo-dialog__panel {
  position: relative;
  overflow: hidden;
  /* Right padding leaves a lane for the close button, as on the cookie card. */
  padding: 26px 28px 24px;
  border: 1px solid var(--glass-face-border);
  border-radius: 20px;
  background: var(--glass-face-bg);
  -webkit-backdrop-filter: var(--glass-face-blur);
  backdrop-filter: var(--glass-face-blur);
  box-shadow: var(--glass-face-shadow);
  text-align: left;
}

/* The lime kiss the nav glass wears in its corner. */
.demo-dialog__panel::before {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 260px 130px at 4% -8%, rgba(var(--lime-rgb), .18), rgba(var(--lime-rgb), .05) 46%, transparent 74%),
    radial-gradient(ellipse 140px 40px at 8% 0, rgba(255, 255, 255, .8), transparent 72%);
  pointer-events: none;
  content: "";
}

.demo-dialog__panel > * { position: relative; }

/* Without backdrop-filter the glass would read as a pale smear over the page. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .demo-dialog__panel { background: rgba(var(--paper-rgb), .97); }
}

.demo-dialog__close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  appearance: none;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font: 20px/1 var(--sans);
  cursor: pointer;
  transition: background var(--dur-micro) var(--ease), color var(--dur-micro) var(--ease);
}

.demo-dialog__close:hover { background: rgba(var(--ink-rgb), .08); color: var(--ink); }

.demo-dialog__eyebrow {
  margin: 0 0 8px;
  font: 600 11px/1.3 var(--mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}

.demo-dialog__title {
  margin: 0 0 8px;
  max-width: 20ch;
  font-family: var(--sans);
  font-size: clamp(22px, 2.6vw, 27px);
  font-weight: 760;
  line-height: 1.1;
  letter-spacing: -.03em;
  color: var(--ink);
}

.demo-dialog__lede {
  margin: 0 0 20px;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--muted);
}

.demo-dialog__form {
  display: grid;
  gap: 13px;
}

/* Present to a bot, absent to everyone else. Never display:none — some
   form fillers skip hidden fields, and this one has to look fillable. */
.demo-dialog__honey {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  border: 0;
  opacity: 0;
  pointer-events: none;
  left: -9999px;
}

.demo-dialog__field {
  display: grid;
  gap: 6px;
}

.demo-dialog__label {
  font: 600 11px/1.3 var(--mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}

.demo-dialog__label i {
  font-style: normal;
  font-weight: 500;
  text-transform: none;
  letter-spacing: .02em;
  color: rgba(var(--ink-rgb), .45);
}

/* The hero's scan input, widened to the panel. */
.demo-dialog__field input,
.demo-dialog__field textarea {
  width: 100%;
  min-height: 48px;
  padding: 12px 14px;
  border: 1px solid var(--c-hairline-strong, rgba(var(--ink-rgb), .16));
  border-radius: var(--r-sm, 3px);
  outline: 0;
  background: var(--c-field-fill, rgba(255, 255, 255, .78));
  color: var(--ink);
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.4;
  letter-spacing: .015em;
  transition: border-color .2s ease, background-color .2s ease, box-shadow .2s ease;
}

.demo-dialog__field textarea {
  min-height: 78px;
  resize: vertical;
}

/* Lighter than --c-text-low, which is body-copy grey: at that weight a
   placeholder reads as a value the visitor already typed. */
.demo-dialog__field input::placeholder,
.demo-dialog__field textarea::placeholder {
  color: rgba(var(--ink-rgb), .38);
  opacity: 1;
}

.demo-dialog__field input:focus,
.demo-dialog__field textarea:focus {
  border-color: var(--c-accent, var(--accent));
  background: var(--c-field-fill-focus, #fff);
  box-shadow: 0 0 0 3px rgba(var(--c-accent-rgb, 93, 106, 8), .18);
}

.demo-dialog__field input:user-invalid {
  border-color: var(--c-form-error, #b8324e);
}

/* The page's .button, full width. The dialog sits outside the hero's .m-light
   chapter, so the full-lime arrow that chapter gives the button is restated. */
.demo-dialog .demo-dialog__submit {
  position: relative;
  width: 100%;
  margin-top: 4px;
}

.demo-dialog .demo-dialog__submit span:last-child { color: var(--lime-on-dark); }

.demo-dialog .demo-dialog__submit:disabled {
  cursor: default;
  transform: none;
}

/* While sending, the arrow gives way to a spinner in the same slot, and the
   label stays put so the button does not change size under the pointer. */
.demo-dialog .demo-dialog__submit[aria-busy="true"] span:last-child { visibility: hidden; }

.demo-dialog .demo-dialog__submit[aria-busy="true"]::after {
  position: absolute;
  top: 50%;
  left: calc(50% + 3.2em);
  width: 14px;
  height: 14px;
  margin-top: -7px;
  border: 2px solid rgba(255, 255, 255, .22);
  border-top-color: var(--lime-on-dark);
  border-radius: 50%;
  animation: demo-dialog-spin .7s linear infinite;
  content: "";
}

@keyframes demo-dialog-spin { to { transform: rotate(360deg); } }

.demo-dialog__msg {
  margin: 0;
  min-height: 15px;
  font: 11px/1.35 var(--mono);
  letter-spacing: .005em;
  color: var(--muted);
}

.demo-dialog__msg[data-err] { color: var(--c-form-error, #b8324e); }
.demo-dialog__msg[data-ok] { color: var(--accent); }

.demo-dialog :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The sent state replaces the form, so the panel does not sit there inviting
   a second submission. The panel keeps its height (set inline on send) and the
   reply takes the room the form had. */
.demo-dialog__panel[data-done] {
  display: flex;
  flex-direction: column;
}

.demo-dialog__panel[data-done] .demo-dialog__form,
.demo-dialog__panel[data-done] .demo-dialog__lede {
  display: none;
}

.demo-dialog__sent {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 12px 0 8px;
}

.demo-dialog__sent[hidden] { display: none; }

/* The reply arrives in two beats. First Jakub is typing: his chip, small, with
   three dots breathing in it, the avatar already on its corner. Then the chip
   gives way to the message, which springs in where the dots were. */
.demo-dialog__typing {
  display: flex;
  align-items: center;
  gap: 5px;
  width: max-content;
  margin-left: auto;
  padding: 13px 16px;
  border-radius: 18px 18px 6px 18px;
  background: var(--m-ink-chip);
  box-shadow: 0 10px 26px rgba(var(--ink-rgb), .22), inset 0 1px 0 rgba(255, 255, 255, .1);
  animation: demo-dialog-bubble .4s var(--spring) both;
}

.demo-dialog__typing i {
  display: block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--paper);
  opacity: .35;
  animation: demo-dialog-typing 1.1s ease-in-out infinite;
}

.demo-dialog__typing i:nth-child(2) { animation-delay: .16s; }
.demo-dialog__typing i:nth-child(3) { animation-delay: .32s; }

@keyframes demo-dialog-typing {
  0%, 60%, 100% { opacity: .35; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}

.demo-dialog__sent[data-stage="typing"] .demo-dialog__bubble { display: none; }
.demo-dialog__sent[data-stage="replied"] .demo-dialog__typing { display: none; }

/* The avatar is already there while the dots breathe, so when the message
   lands only the chip changes; the avatar does not enter a second time. */
.demo-dialog__sent[data-stage="replied"] .demo-dialog__bubble-avatar { animation: none; }

/* The bubble and the avatar move as one: the avatar sits on the bubble's
   tail corner, whatever the bubble's height turns out to be. */
.demo-dialog__reply {
  position: relative;
  width: min(100%, 340px);
  padding: 0 22px 14px 0;
}

/* A message from Jakub: the brand's dark chip, the way the light chapters
   carry lime, with a tail-side corner pulled in like a chat bubble. */
.demo-dialog__bubble {
  position: relative;
  width: 100%;
  padding: 20px 22px 30px;
  border-radius: 18px 18px 6px 18px;
  background: var(--m-ink-chip);
  color: var(--paper);
  box-shadow: 0 10px 26px rgba(var(--ink-rgb), .22), inset 0 1px 0 rgba(255, 255, 255, .1);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.45;
  letter-spacing: -.01em;
  outline: 0;
  animation: demo-dialog-bubble .55s var(--spring) both;
}

.demo-dialog__bubble p { margin: 0; }
.demo-dialog__bubble p + p { margin-top: 12px; }
.demo-dialog__bubble p:last-of-type { font-weight: 700; }

/* Kept clear of the avatar, which sits on the tail corner. */
.demo-dialog__bubble-time {
  position: absolute;
  right: 46px;
  bottom: 11px;
  font: 10.5px/1 var(--mono);
  letter-spacing: .02em;
  color: rgba(250, 251, 252, .5);
}

.demo-dialog__bubble-avatar {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 46px;
  height: 46px;
  border: 2px solid var(--paper);
  border-radius: 50%;
  object-fit: cover;
  object-position: center;
  box-shadow: var(--c-shadow-rest, 0 2px 8px rgba(28, 38, 64, .08));
  animation: demo-dialog-avatar .5s var(--spring) .14s both;
}

@keyframes demo-dialog-bubble {
  from { opacity: 0; transform: translateY(8px) scale(.96); transform-origin: 20% 100%; }
  to { opacity: 1; transform: none; }
}

@keyframes demo-dialog-avatar {
  from { opacity: 0; transform: scale(.6); }
  to { opacity: 1; transform: none; }
}

@media (max-width: 640px) {
  .demo-dialog__panel {
    padding: 22px 20px 20px;
    border-radius: 16px;
  }
  .demo-dialog__title { max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
  .demo-dialog[open],
  .demo-dialog__bubble,
  .demo-dialog__typing,
  .demo-dialog__typing i,
  .demo-dialog__bubble-avatar { animation: none; }
  .demo-dialog__close { transition: none; }
  /* A still ring still says "working"; the motion is the only thing dropped. */
  .demo-dialog .demo-dialog__submit[aria-busy="true"]::after { animation: none; border-top-color: rgba(255, 255, 255, .22); border-color: var(--lime-on-dark); }
}
