/* =========================================================================
   GRAVITAS+, ASK GRAVITAS
   A floating assistant, on every page. Built on the same tokens as everything
   else, so it inherits both themes without a single hard-coded colour.

   Two deliberate departures from the usual e-commerce widget:
   it does not open itself, and it does not nag. A bubble that pops up
   unasked on a reading site interrupts the one thing the site is for.
   ========================================================================= */

.gchat {
  position: fixed; right: clamp(1rem, 3vw, 1.75rem); bottom: clamp(1rem, 3vw, 1.75rem);
  z-index: var(--g-z-overlay);
  font-family: var(--g-font); line-height: 0;
}

/* ---- Launcher -----------------------------------------------------------
   One control, one job: open. It used to morph into an X while the panel was
   also showing a close button in its header, two ways to shut the same thing,
   six inches apart, which makes a reader stop and choose. Now the launcher
   simply gets out of the way, and the panel's own close is the only close.
   It stays in the layout while hidden, because the panel is anchored to it. */
.gchat__btn {
  display: inline-flex; align-items: center; gap: 0.55rem;
  height: 3.25rem; padding: 0 1.25rem 0 1.1rem;
  border-radius: var(--g-radius-pill);
  border: 1px solid var(--g-solid-bg);
  background: var(--g-solid-bg); color: var(--g-solid-fg);
  font-size: var(--g-fs-small); font-weight: var(--g-w-semibold); line-height: 1;
  cursor: pointer; box-shadow: var(--g-shadow), var(--g-glow-md);
  transform-origin: 100% 100%;
  transition: transform var(--g-dur) var(--g-ease-orbit),
              opacity 160ms var(--g-ease-orbit),
              box-shadow var(--g-dur) var(--g-ease-orbit),
              visibility 0s linear 0s;
}
.gchat__btn:hover { transform: translateY(-2px); }
.gchat__btn .gchat__spark { width: 1.3rem; height: 1.3rem; flex: none; }
/* visibility has to be named in the transition list, not just given a delay in
   `transition-delay`, a delay on a property that isn't being transitioned is
   ignored, and the button would snap out of existence mid-fade. */
.gchat.is-open .gchat__btn {
  opacity: 0; transform: scale(0.85); visibility: hidden;
  transition: transform 160ms var(--g-ease-orbit),
              opacity 160ms var(--g-ease-orbit),
              visibility 0s linear 160ms;
}
@media (max-width: 560px) {
  /* On a phone the label costs a third of the thumb zone for no information -
     the mark already reads as "the assistant". */
  .gchat__btn { width: 3.25rem; padding: 0; justify-content: center; }
  .gchat__btn span { display: none; }
}

/* ---- Panel --------------------------------------------------------------
   Absolutely positioned above the launcher rather than stacked with it, so
   the panel can animate on both edges. `display: none` was why closing had no
   animation at all: it is not an animatable property, so the panel vanished on
   the frame the class came off. Visibility is, if you delay it past the fade. */
.gchat__panel {
  /* Anchored to the bottom of the widget, not above the launcher. Sitting it
     above left the launcher's own height as a band of nothing under the panel -
     and since the launcher hides while the panel is open, that band was empty.
     The panel simply takes the space instead. */
  position: absolute; right: 0; bottom: 0;
  display: flex; flex-direction: column; line-height: var(--g-lh-body);
  width: min(23.5rem, calc(100vw - 2rem));
  height: min(32rem, calc(100vh - 4rem));
  height: min(32rem, calc(100dvh - 4rem));
  background: var(--g-surface-raised);
  border: 1px solid var(--g-border);
  border-radius: var(--g-radius-lg);
  box-shadow: var(--g-shadow), var(--g-glow-lg);
  overflow: hidden;

  /* Closed state. The origin is the launcher's corner, so it grows out of the
     button it came from and collapses back into it. */
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(8px) scale(0.96);
  transform-origin: 100% 100%;
  transition: opacity 170ms var(--g-ease-orbit),
              transform 220ms var(--g-ease-orbit),
              visibility 0s linear 220ms;
}
.gchat.is-open .gchat__panel {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: none;
  transition: opacity 200ms var(--g-ease-orbit),
              transform 280ms var(--g-ease-orbit),
              visibility 0s linear 0s;
}

/* ---- Panel header -------------------------------------------------------
   Was: a bordered circle holding the mark like a profile picture, a title, and
   a mono uppercase strapline reading "FIND YOUR WAY AROUND", which said the
   same thing as the note at the foot of the panel, one line below the name and
   in the loudest treatment in the widget. A logo does not need a container to
   be a logo, and the honesty line only needs saying once. What is left is a
   lockup and a close. */
.gchat__head {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.85rem var(--g-space-md);
  border-bottom: 1px solid var(--g-hairline);
  background: var(--g-surface);
  flex: none;
}
.gchat__brand { display: inline-flex; align-items: center; gap: 0.55rem; min-width: 0; }
.gchat__brand .gchat__mark { width: 1.15rem; height: 1.15rem; flex: none; }
.gchat__title {
  font-size: var(--g-fs-body); font-weight: var(--g-w-semibold);
  letter-spacing: -0.01em; line-height: 1.2; color: var(--g-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* The + is part of the name, and the brand sets it apart everywhere else. */
.gchat__plus { color: var(--g-accent); }
.gchat__close {
  margin-left: auto; flex: none;
  width: 1.9rem; height: 1.9rem; border-radius: 50%;
  display: grid; place-items: center;
  background: none; border: 1px solid transparent; cursor: pointer;
  color: var(--g-text-subtle);
  transition: color var(--g-dur) var(--g-ease-orbit),
              background-color var(--g-dur) var(--g-ease-orbit),
              border-color var(--g-dur) var(--g-ease-orbit);
}
.gchat__close:hover {
  color: var(--g-text); border-color: var(--g-border);
  background: rgb(var(--g-tint) / 0.08);
}
.gchat__close svg { width: 1rem; height: 1rem; display: block; }

.gchat__log {
  flex: 1; overflow-y: auto; overscroll-behavior: contain;
  padding: var(--g-space-md);
  display: flex; flex-direction: column; gap: var(--g-space-sm);
  scrollbar-width: thin;
}

.gchat__msg { max-width: 92%; font-size: var(--g-fs-small); line-height: 1.55; }
.gchat__msg p { margin: 0 0 .5rem; }
.gchat__msg p:last-child { margin-bottom: 0; }
.gchat__msg--bot {
  align-self: flex-start; color: var(--g-text-muted);
  background: var(--g-surface-sunken);
  border: 1px solid var(--g-hairline);
  border-radius: var(--g-radius) var(--g-radius) var(--g-radius) var(--g-radius-sm);
  padding: .65rem .85rem;
}
.gchat__msg--me {
  align-self: flex-end; color: var(--g-solid-fg);
  background: var(--g-solid-bg);
  border-radius: var(--g-radius) var(--g-radius) var(--g-radius-sm) var(--g-radius);
  padding: .65rem .85rem;
}
.gchat__msg a { color: var(--g-text); text-decoration-color: var(--g-accent); }

/* Links the assistant offers are destinations, so they look like the site's
   own controls rather than blue text inside a chat bubble. */
.gchat__links { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .6rem; }
.gchat__link {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: var(--g-fs-caption); font-weight: var(--g-w-medium);
  color: var(--g-text); text-decoration: none;
  border: 1px solid var(--g-border); border-radius: var(--g-radius-pill);
  padding: .25rem .7rem;
  transition: border-color var(--g-dur) var(--g-ease-orbit),
              background-color var(--g-dur) var(--g-ease-orbit);
}
.gchat__link:hover { border-color: var(--g-border-strong); background: rgb(var(--g-tint) / .08); }

.gchat__typing { display: flex; gap: .25rem; padding: .8rem .85rem; }
.gchat__typing i {
  width: .38rem; height: .38rem; border-radius: 50%;
  background: var(--g-text-subtle); animation: gchat-blink 1.1s infinite;
}
.gchat__typing i:nth-child(2) { animation-delay: .18s; }
.gchat__typing i:nth-child(3) { animation-delay: .36s; }
@keyframes gchat-blink { 0%, 60%, 100% { opacity: .25; } 30% { opacity: 1; } }

/* ---- Suggested openers --------------------------------------------------
   A blank chat box is a small exam. Three concrete questions show what the
   thing is for and cost one tap instead of a sentence. */
.gchat__chips {
  display: flex; flex-wrap: wrap; gap: .35rem; flex: none;
  padding: 0 var(--g-space-md) var(--g-space-sm);
}
.gchat__chip {
  font: inherit; font-size: var(--g-fs-caption); color: var(--g-text-muted);
  background: transparent; border: 1px dashed var(--g-border);
  border-radius: var(--g-radius-pill); padding: .28rem .7rem; cursor: pointer;
  transition: color var(--g-dur) var(--g-ease-orbit), border-color var(--g-dur) var(--g-ease-orbit);
}
.gchat__chip:hover { color: var(--g-text); border-color: var(--g-border-strong); }

.gchat__form {
  display: flex; gap: .4rem; align-items: flex-end; flex: none;
  padding: var(--g-space-sm) var(--g-space-md) .55rem;
  border-top: 1px solid var(--g-hairline);
  background: var(--g-surface);
}
.gchat__input {
  flex: 1; font: inherit; font-size: var(--g-fs-small);
  color: var(--g-text); background: var(--g-surface-sunken);
  border: 1px solid var(--g-border); border-radius: var(--g-radius);
  padding: .55rem .7rem; resize: none; max-height: 6rem; line-height: 1.45;
}
.gchat__input::placeholder { color: var(--g-text-subtle); }
.gchat__input:focus-visible {
  outline: none; border-color: var(--g-accent);
  box-shadow: 0 0 0 3px rgb(var(--g-tint) / .18);
}
.gchat__send {
  flex: none; width: 2.3rem; height: 2.3rem; border-radius: var(--g-radius);
  border: 1px solid var(--g-solid-bg); background: var(--g-solid-bg);
  color: var(--g-solid-fg); cursor: pointer; display: grid; place-items: center;
}
.gchat__send svg { width: 1rem; height: 1rem; }
.gchat__send[disabled] { opacity: .4; cursor: default; }

/* The only place the widget explains itself, now the header does not. It sits
   under the input rather than over the conversation, where it is available
   without being read twice. */
.gchat__foot {
  margin: 0; flex: none;
  padding: 0 var(--g-space-md) .8rem;
  font-family: var(--g-font-mono); font-size: .65rem; letter-spacing: .06em;
  line-height: 1.5; color: var(--g-text-subtle); background: var(--g-surface);
}

/* The hero's orbit is a drag target on touch and the launcher is fixed over
   the page. They never overlap on desktop, but on a short phone in landscape
   the button can land on the canvas, so it gets out of the way while a drag
   is in progress. */
.gchat.is-dragging-hero { opacity: .25; pointer-events: none; }
