:root {
  color-scheme: light;
  --bg: #ffffff;
  --fg: #26272b;
  --muted: #656872;
  --line: #dddde0;
  --danger: #a3271f;
  --radius: 10px;

  /* The marketsite palette, for the page around the widget - neutral-900,
     neutral-800 and neutral-200 above, primary here. Copied as literals on
     purpose: this UI is a cross-origin iframe, so none of the theme's tokens
     or @font-face rules reach it. Source: theme.json presets. Fonts are the
     other half of matching the theme and are still outstanding. */
  --accent: #bee034;
  --accent-fg: #26272b;
  --accent-dark: #abca2f;
  --accent-tint: #f2f9da;
  --widget-h: 560px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* The widget keeps the Lime Connect palette: it is a picture of the
     product, not a themed part of this page. Its lime is the
     *product* green and deliberately not --accent above, which is the
     marketsite's: the two differ, and the widget has to look like the app it
     is a picture of rather than like the page it sits on. */
  --lime: #8dc63f;
  --lime-dark: #7cb336;
  --lime-tint: #eef6e1;
  --lime-soft: #a9cf72;
  --widget-bg: #ffffff;
  --widget-fg: #1d2129;
  --widget-line: #e6e9ed;
  --bubble-agent: #d9dee6;
  --bubble-visitor: #eaf3d9;
}

* { box-sizing: border-box; }

/* The `hidden` attribute is the switch the whole UI is built on, and a `display`
   rule outranks the UA stylesheet's [hidden] - so state it here and mean it. */
[hidden] { display: none !important; }

body {
  margin: 0;
  padding: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  color: var(--fg);
  /* No ground of its own: the frame is dropped onto whatever the embedding
     block paints, gradients included, and an opaque page would cut a white
     rectangle out of it. --bg stays the *component* surface - the URL pill,
     the tooltip, the banner note all still need something solid to sit on. */
  background: transparent;
}

/* Layout: the widget on the left, the flow on the right, from the first
   paint. Stacked below 860px, where the URL form leads until the agent is
   ready - see .ready below. */
.stage {
  display: grid;
  grid-template-columns: minmax(0, 400px) minmax(0, 1fr);
  align-items: start;
  gap: 24px;
  max-width: 1060px;
  margin: 0 auto;
  padding: 30px 20px 0;
}

/* Field and button read as one control: the pill is the row, and the button
   sits inside it. */
.row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 5px 5px 8px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 999px;
}

input[type="text"] {
  flex: 1 1 240px;
  min-width: 0;
  padding: 8px 10px;
  font: inherit;
  color: var(--fg);
  background: transparent;
  border: none;
  border-radius: 999px;
}

/* The pill takes the focus ring for the field inside it, so focus shows as
   one ring rather than a ring around a ring. */
.row:focus-within { border-color: var(--accent-dark); box-shadow: 0 0 0 1px var(--accent-dark); }
.row input[type="text"]:focus-visible { outline: none; }

button:focus-visible,
a.cta:focus-visible {
  outline: 2px solid var(--accent-dark);
  outline-offset: 2px;
}

/* Everything else that takes text: one ring, drawn over its own border. */
input[type="text"]:focus-visible {
  outline: 2px solid var(--accent-dark);
  outline-offset: -1px;
}

/* The marketsite's button: a pill with a 2px border of its own colour, dark
   ink on the lime rather than white - #bee034 is far too light to carry white
   text. Padding is 11/17 against the 2px border so the box matches the 12/14
   plus 1px of the input it sits beside. */
button,
a.cta {
  padding: 11px 17px;
  font: inherit;
  font-weight: 600;
  border: 2px solid transparent;
  border-radius: 999px;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
}

#url-submit,
.cta.primary {
  color: var(--accent-fg);
  background: var(--accent);
  border-color: var(--accent);
}

#url-submit:hover:not(:disabled),
.cta.primary:hover {
  background: var(--accent-dark);
  border-color: var(--accent-dark);
}

/* The theme's secondary: white pill, accent border, tinted on hover. Labels
   stay ink - the accent as text on white is 1.6:1. */
.cta.secondary {
  color: var(--fg);
  background: var(--bg);
  border-color: var(--accent);
}

.cta.secondary:hover {
  background: var(--accent-tint);
}

button:disabled { opacity: 0.5; cursor: default; }

.note,
.label {
  margin: 10px 0 0;
  font-size: 0.82rem;
  color: var(--muted);
}

.label {
  max-width: 1060px;
  margin: 20px auto 0;
  padding: 12px 20px 16px;
  text-align: center;
  border-top: 1px solid var(--line);
}

/* Smaller than the note it replaced under the field: it is a condition of
   use, not something the visitor has to read to get started. */
.note.consent { font-size: 0.76rem; }

.error { color: var(--danger); font-size: 0.9rem; margin: 10px 0 0; }
.error.big { font-size: 1rem; margin-bottom: 16px; }

.turnstile:empty { display: none; }
.turnstile { margin-top: 12px; }

/* The idle panel is the only one that gets a ground of its own: it is what
   the visitor lands on, and the column is otherwise empty beside a widget
   560px tall. The gradient runs the full height of that widget while the
   content sits centred within it, so the colour carries on above the
   headline instead of starting at it. Low alphas throughout - the frame is
   transparent now, so whatever the embedding block paints still reads
   through this. */
#panel-idle {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: var(--widget-h);
  /* Centred in the box, but the box is bottom-heavy - which lands the
     headline around 40% down rather than halfway, as in the design. */
  padding: 40px 36px 130px;
  border-radius: 16px;
  /* One glow, centred on the field rather than the box - the field is what
     the panel is for. closest-side sizes the ellipse to the nearest edge, so
     the fade completes inside the element whatever its proportions; the last
     stop lands at 92% of that, leaving a clear band all round rather than
     running up against the widget beside it. */
  background: radial-gradient(
    closest-side at 42% 42%,
    rgba(190, 224, 52, 0.32),
    rgba(190, 224, 52, 0.12) 55%,
    rgba(190, 224, 52, 0) 92%
  );
}

/* crawl */
.crawl { padding: 8px 0 4px; }
.crawl-found { margin: 0; font-size: 1.35rem; line-height: 1.25; min-height: 1.25em; }
.crawl-progress { margin: 4px 0 14px; font-size: 0.85rem; color: var(--muted); min-height: 1.5em; }
.crawl-note { margin: 12px 0 0; font-size: 0.8rem; color: var(--muted); }

.crawl-pages { list-style: none; margin: 14px 0 0; padding: 0; }

.crawl-pages li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 9px 0;
  border-top: 1px solid var(--line);
}
.crawl-pages li:last-child { border-bottom: 1px solid var(--line); }

.crawl-no { flex: none; font-size: 0.85rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.crawl-body { min-width: 0; }
.crawl-title { display: block; font-size: 0.9rem; }

.crawl-path {
  display: block;
  font-size: 0.78rem;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bar { height: 4px; background: var(--line); border-radius: 999px; overflow: hidden; }
.bar-fill { height: 100%; width: 0; background: var(--accent); transition: width 0.4s ease; }

/* ---------------------------------------------------------------- widget --
   A copy of the Lime Connect chat widget: green header with the assistant's
   identity, scrolling body, pill composer. Fixed height so it reads as a
   widget rather than as a page section that grows with the conversation. */

.widget {
  display: flex;
  flex-direction: column;
  height: var(--widget-h);
  color: var(--widget-fg);
  background: var(--widget-bg);
  border-radius: 14px;
  box-shadow: 0 2px 6px rgba(20, 24, 31, 0.08), 0 12px 32px rgba(20, 24, 31, 0.14);
  overflow: hidden;
}

.widget-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  color: #ffffff;
  background: var(--lime);
}

.widget-id { display: flex; flex-direction: column; min-width: 0; margin-right: auto; }
.widget-id strong {
  font-size: 1.05rem;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.widget-id span { font-size: 0.8rem; opacity: 0.95; }

.head-actions { display: flex; align-items: center; gap: 6px; }
.icon-btn { display: block; width: 22px; height: 22px; opacity: 0.95; }
.icon-btn svg { width: 100%; height: 100%; display: block; }

/* The product's own avatar, at 80px for a 40px box - it carries its ring and
   its halo with it, so the span is nothing but the size. Cloned into every
   agent message by avatar(), which the browser serves from cache. */
.orb {
  flex: none;
  width: 40px;
  height: 40px;
}
.orb img { display: block; width: 100%; height: 100%; }
.orb.small { width: 30px; height: 30px; }

.widget-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 16px 14px;
  overflow-y: auto;
}

.messages { display: flex; flex-direction: column; gap: 12px; }

.msg { display: flex; flex-direction: column; align-items: flex-start; }
.msg.visitor { align-items: flex-end; }
/* Avatar sits at the bubble's baseline, the timestamp below it - as in the
   widget, where the time hangs under the message and not beside the avatar. */
.msg-line { display: flex; align-items: flex-end; gap: 8px; max-width: 78%; }
.msg.agent .msg-time { margin-left: 38px; }

.bubble {
  padding: 12px 14px;
  font-size: 0.95rem;
  line-height: 1.45;
  white-space: pre-wrap;
  border-radius: 6px;
}
.msg.agent .bubble { background: var(--bubble-agent); }
.msg.visitor .bubble { background: var(--bubble-visitor); }

.msg-time { margin: 4px 2px 0; font-size: 0.72rem; color: #8b939d; }

/* Three-dot "typing" bubble, shown until the first token arrives. */
.bubble.typing { display: flex; gap: 4px; padding: 14px; }
.bubble.typing i {
  width: 6px;
  height: 6px;
  background: #6f7883;
  border-radius: 50%;
  animation: blink 1.2s infinite ease-in-out;
}
.bubble.typing i:nth-child(2) { animation-delay: 0.2s; }
.bubble.typing i:nth-child(3) { animation-delay: 0.4s; }

@keyframes blink {
  0%, 60%, 100% { opacity: 0.25; }
  30% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .bubble.typing i { animation: none; opacity: 0.5; }
}

/* The example questions live in the widget, pinned under the conversation. */
.starters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: auto;
  padding-top: 16px;
}
.starters:empty { padding-top: 0; }

.chip {
  padding: 8px 12px;
  font-size: 0.85rem;
  font-weight: 500;
  line-height: 1.25;
  color: var(--widget-fg);
  background: var(--widget-bg);
  border: 1px solid var(--lime);
  border-radius: 999px;
  text-align: left;
}
.chip:hover { background: #f4f9ea; }

.widget-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px 12px;
  background: var(--widget-bg);
  border-top: 1px solid var(--widget-line);
}

.plus {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  color: #4b535d;
  background: #f0f2f4;
  border-radius: 50%;
}
.plus svg { width: 20px; height: 20px; }

/* The pill is the field *and* the send button: the border belongs to this
   box, and the button is inset inside it. */
.chat-field {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  padding: 2px;
  background: var(--widget-bg);
  border: 1px solid #d5dae0;
  border-radius: 999px;
}

/* The pill carries the focus ring for the field inside it - one ring, not a
   ring around a ring. */
.chat-field:focus-within {
  border-color: var(--lime);
  box-shadow: 0 0 0 1px var(--lime);
}
.chat-field #chat-input:focus-visible { outline: none; }

#chat-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 9px 4px 9px 14px;
  font-size: 0.95rem;
  color: var(--widget-fg);
  background: transparent;
  border: none;
  border-radius: 999px;
}
#chat-input::placeholder { color: #9aa2ac; }

/* Off: mid-answer, or waiting for a website. Either way there is nothing to
   type here, and a flat ground says so without going grey-on-grey. */
.chat-field.off { background: #f4f6f8; }
/* Readonly rather than disabled means waiting: the click is the point. */
#chat-input[readonly] { cursor: pointer; }

#chat-submit {
  flex: none;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  color: #ffffff;
  background: var(--lime);
  border: none;
  border-radius: 50%;
}
#chat-submit svg { width: 20px; height: 20px; }
#chat-submit:hover:not(:disabled) { background: var(--lime-dark); }

/* Spent, the button becomes a tint of itself rather than the solid at half
   strength - the faded solid left the white icon almost invisible on it. */
#chat-submit:disabled {
  opacity: 1;
  color: var(--lime-soft);
  background: var(--lime-tint);
}

/* --------------------------------------------------------------- sources -- */

.sources { padding-top: 4px; }
.sources h3 {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: 1.05rem;
}

/* The note about what we read and how long we keep it, folded into the
   heading it belongs to. Hover or focus opens it; it is a button rather than
   a span so the keyboard reaches it. */
.info {
  position: relative;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  padding: 0;
  color: var(--muted);
  background: none;
  border: none;
}
.info:hover { color: var(--fg); }
.info svg { width: 16px; height: 16px; }

.tip {
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  z-index: 2;
  width: max-content;
  max-width: 18rem;
  padding: 8px 10px;
  font-size: 0.78rem;
  font-weight: 400;
  line-height: 1.4;
  text-align: left;
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
  transform: translateX(-50%);
  opacity: 0;
  visibility: hidden;
}
.info:hover .tip,
.info:focus .tip { opacity: 1; visibility: visible; }
.sources-meta { margin: 4px 0 0; font-size: 0.85rem; color: var(--muted); }
.sources-note { margin: 12px 0 0; font-size: 0.8rem; color: var(--muted); }

.sources-list { list-style: none; margin: 14px 0 0; padding: 0; }

.sources-list li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 0;
  border-top: 1px solid var(--line);
}
.sources-list li:last-child { border-bottom: 1px solid var(--line); }

/* Dot filled = the page the last answer cited. */
.sources-list li::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  margin-top: 7px;
  background: transparent;
  border: 1.5px solid var(--line);
  border-radius: 50%;
}
.sources-list li.used::before { background: var(--accent); border-color: var(--accent); }

.source-body { min-width: 0; }
.source-title { font-size: 0.9rem; }
.source-title a { color: inherit; text-decoration: none; }
.source-title a:hover { text-decoration: underline; }
.sources-list li.used .source-title { font-weight: 600; }

.source-path {
  display: block;
  font-size: 0.78rem;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.used-badge {
  margin-left: 8px;
  padding: 1px 7px;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--accent-fg);
  background: var(--accent);
  border-radius: 999px;
  white-space: nowrap;
}

/* ---------------------------------------------------------------- banner --
   Fills the column beside the widget and centres on both axes, so the two
   read as one composition rather than a page with a notice stuck to it. */

.banner {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: var(--widget-h);
  padding: 32px 28px 24px;
  text-align: center;
  /* Blue at the top-left running to lavender and then pink at the bottom -
     the one place in the frame that is allowed to advertise. Opaque, unlike
     every other surface here, because the gradient *is* the design and a
     host page reading through it would muddy every stop. */
  background: linear-gradient(158deg, #cfe1f7 0%, #e6e7fb 36%, #e1d8f4 64%, #f0d9ea 100%);
  border-radius: 14px;
  /* The arcs below run past the corners. */
  overflow: hidden;
}

/* Rings rising from a point below the panel, fading out before they reach
   the copy. Painted on their own layer so the mask that fades them does not
   take the gradient with it. */
.banner::before {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-radial-gradient(
    circle at 50% 118%,
    rgba(255, 255, 255, 0) 0 96px,
    rgba(255, 255, 255, 0.55) 96px 98px
  );
  -webkit-mask-image: linear-gradient(to top, #000 10%, transparent 62%);
  mask-image: linear-gradient(to top, #000 10%, transparent 62%);
  pointer-events: none;
}

/* Above the ::before layer, which would otherwise cover the copy. */
.banner > * { position: relative; }

.banner-body { max-width: 30rem; margin: auto 0; }

.banner h3 {
  margin: 0 0 14px;
  font-size: 1.5rem;
  line-height: 1.3;
  /* The headline is two sentences on two lines - the break is part of it. */
  white-space: pre-line;
}
.banner p { margin: 0 0 20px; font-size: 0.95rem; color: var(--muted); }
.banner .ctas { justify-content: center; }

.banner .banner-foot { margin: 24px 0 0; }

.banner-close {
  position: absolute;
  top: 10px;
  right: 10px;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  color: var(--muted);
  background: transparent;
  border: none;
  border-radius: 50%;
}
.banner-close:hover { background: rgba(127, 140, 155, 0.18); }
.banner-close svg { width: 18px; height: 18px; }

/* "Try another URL" is the quiet way out of a failure, next to two CTAs. */
.linky {
  padding: 0;
  font: inherit;
  font-weight: 500;
  color: var(--muted);
  background: none;
  border: none;
  text-decoration: underline;
}
.linky:hover { color: var(--fg); }

.ctas { display: flex; flex-wrap: wrap; gap: 8px; }

/* The banner's single CTA points onward, so it carries an arrow. */
.cta.primary { display: inline-flex; align-items: center; gap: 8px; }
.cta.primary svg { width: 18px; height: 18px; }

@media (max-width: 860px) {
  :root { --widget-h: 520px; }

  .stage { grid-template-columns: minmax(0, 1fr); gap: 4px; }

  /* Stacked, a column is as wide as the viewport, and the widget stretched
     to 768px reads as a page section rather than as a chat widget. Only the
     widget takes a cap - the form and the flow beside it are page-width
     content and read fine at any width. */
  .lane {
    width: 100%;
    max-width: 400px;
    margin-inline: auto;
  }

  /* Stacked, the column is only as tall as the form, so a 520px ground with
     the content floating in the middle of it would be all gradient. */
  #panel-idle {
    min-height: 0;
    padding: 24px 20px;
  }

  /* Stacked, the two columns need a seam: a hairline and room on both sides
     of it, or the widget's green header butts straight into the form. The
     line goes on whichever column ends up second - see .ready. */
  body:not(.ready) .lane,
  body.ready .side {
    margin-top: 24px;
    padding-top: 28px;
    border-top: 1px solid var(--line);
  }
  /* Stacked, the banner only needs to hold its own content. */
  .banner { min-height: 0; padding: 28px 20px 20px; }
  /* Until the agent answers, the form is the point of the page. */
  body:not(.ready) .side { order: -1; }
}

@media (max-width: 480px) {
  /* Too narrow for the field and the button side by side, so the pill comes
     apart into the two controls it is made of. */
  .row {
    flex-direction: column;
    align-items: stretch;
    padding: 0;
    background: none;
    border: none;
  }
  .row:focus-within { box-shadow: none; }
  /* flex-basis follows the main axis, so the 240px basis above would become
     the field's *height* once the row stacks. */
  .row input[type="text"] {
    flex: 0 0 auto;
    width: 100%;
    padding: 12px 14px;
    background: var(--bg);
    border: 1px solid var(--line);
  }
  .ctas .cta { flex: 1 1 100%; text-align: center; justify-content: center; }
  .msg-stack { max-width: 85%; }
}
