@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

/* GluX AI widget — premium green chat */
#glux-ai-root {
  /* One accent, set by the tenant, and everything else derived from it. The old file hard-
     coded a violet in eleven places, so a shop that changed its colour got a violet send
     button next to a blue bubble. */
  --glux-ai-accent: #0f6fff;
  --glux-ai-accent-strong: #0a58cc;
  --glux-ai-accent-soft: rgba(15, 111, 255, 0.08);
  --glux-ai-accent-ring: rgba(15, 111, 255, 0.22);
  --glux-ai-send: var(--glux-ai-accent-ink, var(--glux-ai-accent));

  /* The accent, twice more, for the two jobs it cannot do at full strength.
     #0f6fff against white is 4.43:1 — under AA by a hair, and every "accent on white" and
     "white on accent" pairing in this file inherited that. These two are the same colour
     darkened by exactly as much as the ratio needs and no more: applyTheme() recomputes both
     from whatever accent the shop sets, so a brand that already passes is left alone, and one
     that does not is corrected invisibly instead of being shipped illegible.
     The values here are the defaults for #0f6fff, and the fallbacks if the script never runs. */
  --glux-ai-accent-text: #0267ff;
  --glux-ai-accent-ink: #0d6bf7;

  /* Csak a három csatorna, alfa nélkül — hogy bármelyik szabály írhasson
     rgba(var(--glux-ai-accent-rgb), .12)-t a saját átlátszóságával.
     Enélkül minden árnyalathoz külön token kellett volna, és a fájl ezt eddig úgy
     kerülte meg, hogy hat szabályba beégette egy RÉGI accent három csatornáját.
     Azt a színt két teszt kitiltja innen — de a hex írásmódot keresik, ezért az
     rgba() alak átcsúszott rajtuk. Ez a token az, ami miatt nem kell újra. */
  --glux-ai-accent-rgb: 15, 111, 255;

  --glux-ai-surface: #ffffff;
  --glux-ai-canvas: #f7f9fc;
  --glux-ai-bubble-in: #eff2f7;
  --glux-ai-bubble-in-text: #1b2733;

  --glux-ai-user-bg: var(--glux-ai-accent-ink, var(--glux-ai-accent));
  --glux-ai-user-text: #ffffff;
  --glux-ai-text: #1b2733;
  /* Was #8a95a5 — 3.03:1 on white, and this token dresses ten different labels: the progress
     line, the header status, the system turn, the day separator, the link-card URL, the quick-
     actions label. One value under AA meant ten places under AA. #636f81 is the same grey,
     dark enough to clear 4.5:1 on every surface it lands on (white 5.10, canvas 4.83,
     assistant bubble 4.54). */
  --glux-ai-muted: #636f81;
  --glux-ai-border: #e6eaf0;
  --glux-ai-hairline: #eef1f6;

  --glux-ai-radius-panel: 24px;
  --glux-ai-radius-bubble: 20px;
  --glux-ai-radius-card: 14px;

  --glux-ai-shadow-panel: 0 32px 80px rgba(16, 32, 64, 0.18), 0 8px 24px rgba(16, 32, 64, 0.08);
  --glux-ai-shadow-card: 0 1px 2px rgba(16, 32, 64, 0.06);

  /* One easing for the whole widget. Decelerating, never bouncing: a chat panel that
     overshoots reads as a toy. */
  --glux-ai-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --glux-ai-fast: 160ms;
  --glux-ai-base: 260ms;

  font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: var(--glux-ai-text);
  -webkit-font-smoothing: antialiased;
}

#glux-ai-root * {
  box-sizing: border-box;
}

#glux-ai-root .glux-ai-launcher {
  position: fixed;
  bottom: 24px;
  right: 20px;
  z-index: 2147483000;
  width: 58px;
  height: 58px;
  border: none;
  /* A rounded square, not a circle: it reads as an app icon, which is what a launcher is. */
  border-radius: 19px;
  background: var(--glux-ai-accent-ink, var(--glux-ai-accent));
  color: #fff;
  cursor: pointer;
  box-shadow: 0 12px 30px rgba(15, 111, 255, 0.34), 0 2px 6px rgba(16, 32, 64, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform var(--glux-ai-base) var(--glux-ai-ease),
    box-shadow var(--glux-ai-base) var(--glux-ai-ease);
}

#glux-ai-root .glux-ai-launcher:hover {
  transform: translateY(-2px);
  box-shadow: 0 18px 38px rgba(15, 111, 255, 0.42), 0 3px 8px rgba(16, 32, 64, 0.14);
}

#glux-ai-root .glux-ai-launcher svg {
  width: 26px;
  height: 26px;
}

#glux-ai-root .glux-ai-launcher[hidden] {
  display: none;
}

#glux-ai-root .glux-ai-panel {
  position: fixed;
  bottom: 24px;
  /* 20px from the RIGHT EDGE THE CUSTOMER CAN SEE. 100vw is the layout viewport, and on a
     page with horizontal overflow that edge is off-screen; the difference between the two
     is added back here. With no visualViewport the whole expression collapses to 20px. */
  right: calc(100vw - var(--glux-ai-vv-left, 0px) - var(--glux-ai-vv-width, 100vw) + 20px);
  z-index: 2147483001;
  width: min(400px, calc(100dvh * 0.5));
  /* --glux-ai-vv-width is the VISIBLE width, measured from window.visualViewport in JS.
     100vw is the layout viewport, which the browser widens to hold anything on the page
     that overflows it — one too-wide element on the storefront and this clamp stops
     clamping. Falls back to 100vw where visualViewport does not exist. */
  max-width: calc(var(--glux-ai-vv-width, 100vw) - 40px);
  height: min(800px, 92dvh);
  max-height: min(800px, 92dvh);
  background: var(--glux-ai-surface);
  border: 1px solid var(--glux-ai-border);
  border-radius: var(--glux-ai-radius-panel);
  box-shadow: var(--glux-ai-shadow-panel);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
  /* Grows from the launcher's corner rather than fading in place. */
  transform-origin: 100% 100%;
  transform: translateY(16px) scale(0.94);
  transition: opacity var(--glux-ai-base) var(--glux-ai-ease),
    transform var(--glux-ai-base) var(--glux-ai-ease),
    visibility var(--glux-ai-base);
}

#glux-ai-root .glux-ai-panel.is-open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0) scale(1);
}

#glux-ai-root .glux-ai-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 64px;
  padding: 0 16px 0 18px;
  border-bottom: 1px solid var(--glux-ai-hairline);
  background: var(--glux-ai-header-bg, var(--glux-ai-surface));
  color: var(--glux-ai-header-text, inherit);
}

#glux-ai-root .glux-ai-header .glux-ai-header-title {
  color: var(--glux-ai-header-text, inherit);
}

/* A photo replaces the glyph rather than sitting behind it. If the URL never loads, the
   class is still applied but the SVG stays visible underneath — a missing avatar should
   look like the default, not like a hole. */
#glux-ai-root .glux-ai-avatar.has-photo svg {
  display: none;
}

#glux-ai-root .glux-ai-avatar.has-photo {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.16);
}

/* The header carries the shop's face, or nothing --------------------------------
   A 44px block of flat accent next to the title is not a brand mark, it is a hole
   where a photo should be. When the tenant has configured one it earns its place;
   when they have not, the title stands alone and the header reads as the reference
   design does. */

#glux-ai-root .glux-ai-avatar:not(.has-photo) {
  display: none;
}

#glux-ai-root .glux-ai-header-main {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

#glux-ai-root .glux-ai-avatar,
#glux-ai-root .glux-ai-msg-avatar {
  width: 44px;
  height: 44px;
  border-radius: 14px;
  background: var(--glux-ai-accent-ink, var(--glux-ai-accent));
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 2px 8px rgba(var(--glux-ai-accent-rgb), 0.22);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* --- Jump to latest ----------------------------------------------------------
   Shown only once the customer has scrolled away from the bottom. It is the other
   half of not yanking the view: stop following, and give them the way back rather
   than deciding for them.

   Positioned against the panel, not the log, so it does not scroll with the
   content it is offering to scroll to.                                        */
#glux-ai-root .glux-ai-jump {
  position: absolute;
  left: 50%;
  bottom: 92px;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: inherit;
  font-size: 12px;
  line-height: 1;
  padding: 8px 14px 8px 11px;
  border: 1px solid rgba(0, 0, 0, 0.06);
  border-radius: 999px;
  background: #fff;
  color: #3b3b46;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(15, 15, 40, 0.16);
  animation: glux-ai-jump-in 0.18s ease;
  z-index: 3;
}

/* A class with `display` outranks the user agent's `[hidden] { display: none }`, so the
   pill stayed on screen after it was hidden in JS. Caught in the browser, not the diff. */
#glux-ai-root .glux-ai-jump[hidden] {
  display: none;
}

#glux-ai-root .glux-ai-jump svg {
  width: 14px;
  height: 14px;
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
}

#glux-ai-root .glux-ai-jump:hover,
#glux-ai-root .glux-ai-jump:focus-visible {
  background: #fafafc;
  box-shadow: 0 8px 24px rgba(15, 15, 40, 0.2);
}

@keyframes glux-ai-jump-in {
  from { opacity: 0; transform: translate(-50%, 6px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

/* The streaming tail is plain text in its own node so the settled lines above it are
   never re-parsed. It must inherit everything, or the last line would look different
   from the ones before it for as long as it is being written. */
#glux-ai-root .glux-ai-stream-settled,
#glux-ai-root .glux-ai-stream-tail {
  font: inherit;
  color: inherit;
  white-space: pre-wrap;
}

@media (prefers-reduced-motion: reduce) {
  #glux-ai-root .glux-ai-jump { animation: none; }
}

/* Motion, switched off for anyone who asked ------------------------------------
   Every entrance in this file is decoration: the panel opening, a turn arriving, a
   control lifting under the pointer. None of them carries information, so all of
   them go. The orb is handled separately and deliberately keeps its signal — see
   the block below it. */

@media (prefers-reduced-motion: reduce) {
  #glux-ai-root .glux-ai-panel,
  #glux-ai-root .glux-ai-turn,
  #glux-ai-root .glux-ai-daysep,
  #glux-ai-root .glux-ai-launcher,
  #glux-ai-root .glux-ai-send,
  #glux-ai-root .glux-ai-pill,
  #glux-ai-root .glux-ai-input-wrap,
  #glux-ai-root .glux-ai-close,
  .glux-ai-action-row,
  .glux-ai-product-card {
    animation: none;
    transition: none;
  }
  /* Opening still has to change something, or the panel never appears. */
  #glux-ai-root .glux-ai-panel {
    transform: none;
  }
  #glux-ai-root .glux-ai-launcher:hover,
  #glux-ai-root .glux-ai-pill--outline:hover,
  #glux-ai-root .glux-ai-pill--starter:hover,
  .glux-ai-action-row:hover {
    transform: none;
  }
}

/* --- The orb -----------------------------------------------------------------
   The mark beside an assistant message is a small sphere rather than a squircle
   with a glyph in it, and it is alive only when the assistant actually is.

   That distinction is the whole design. An avatar that animates constantly is
   decoration and stops being read after the second message; one that stirs while
   the answer is being written is telling the customer something they otherwise
   have no way to know. The chat's own numbers made the case: first token measured
   at 3.7s against production, and until now the customer watched nothing at all
   for those seconds.

   So the orb breathes almost imperceptibly at rest — a 7s cycle, a fraction of a
   pixel — and wakes while the turn is streaming. Pure CSS: this widget has no
   build step, ships to every storefront page, and one canvas or shader per message
   is not a trade worth making for an ornament.

   The header avatar is deliberately untouched: it carries the shop's photo at
   44px, where a face reads. Repeating that face at 26px on every message would
   fight the conversation instead of marking it.                              */
#glux-ai-root .glux-ai-msg-avatar {
  position: relative;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  margin-bottom: 18px;
  overflow: visible;
  background:
    radial-gradient(circle at 34% 30%, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0) 46%),
    radial-gradient(circle at 72% 78%, rgba(0, 0, 0, 0.22), rgba(0, 0, 0, 0) 58%),
    var(--glux-ai-accent);
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.35),
    inset 0 -2px 5px rgba(0, 0, 0, 0.18),
    0 1px 4px rgba(var(--glux-ai-accent-rgb), 0.3);
  animation: glux-ai-orb-breathe 7s ease-in-out infinite;
}

/* The specular highlight, as its own layer so it can drift without repainting the
   gradient stack — a moving background-position on a radial gradient stutters. */
#glux-ai-root .glux-ai-msg-avatar::after {
  content: "";
  position: absolute;
  top: 17%;
  left: 24%;
  width: 34%;
  height: 26%;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.75);
  filter: blur(1.5px);
  animation: glux-ai-orb-drift 7s ease-in-out infinite;
}

/* The aura. Zero opacity at rest: at rest there is nothing to say. */
#glux-ai-root .glux-ai-msg-avatar::before {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--glux-ai-accent) 0%, transparent 68%);
  opacity: 0;
  transition: opacity 0.35s ease;
  pointer-events: none;
}

@keyframes glux-ai-orb-breathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.045); }
}

@keyframes glux-ai-orb-drift {
  0%, 100% { transform: translate(0, 0); opacity: 0.75; }
  50% { transform: translate(1.5px, 1px); opacity: 0.95; }
}

/* Awake: the turn is being written right now. Faster, brighter, and the aura
   appears — this is also the typing indicator the widget never had. */
#glux-ai-root .glux-ai-msg-avatar.is-thinking {
  animation-duration: 1.9s;
}

#glux-ai-root .glux-ai-msg-avatar.is-thinking::after {
  animation-duration: 1.9s;
}

#glux-ai-root .glux-ai-msg-avatar.is-thinking::before {
  opacity: 0.28;
  animation: glux-ai-orb-aura 1.9s ease-in-out infinite;
}

/* What the agent is doing, beside the pulsing orb. Secondary weight and size on purpose:
   it is a status line, not the answer, and it is replaced in place rather than stacking —
   a log of six steps is more alarming than one line that keeps changing.

   aria-live="polite" is on the element, so a screen reader hears each step once the current
   utterance finishes, instead of being interrupted three times in two seconds. */
#glux-ai-root .glux-ai-progress {
  margin: 0;
  padding-top: 5px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--glux-ai-muted, #6b7280);
  /* Empty until the first status frame, and an empty <p> with padding would nudge the orb. */
}

#glux-ai-root .glux-ai-progress:empty {
  display: none;
}

@media (prefers-reduced-motion: no-preference) {
  #glux-ai-root .glux-ai-progress {
    animation: glux-ai-progress-in 260ms ease-out;
  }
}

@keyframes glux-ai-progress-in {
  from { opacity: 0; transform: translateY(2px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes glux-ai-orb-aura {
  0%, 100% { opacity: 0.18; transform: scale(0.94); }
  50% { opacity: 0.34; transform: scale(1.06); }
}

/* The shop's own photo wins over the sphere, the same way it does in the header —
   but the aura still wakes, so a branded avatar does not lose the one signal the
   orb was added to give. */
#glux-ai-root .glux-ai-msg-avatar.has-photo {
  background-size: cover;
  background-position: center;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
}

#glux-ai-root .glux-ai-msg-avatar.has-photo::after {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  #glux-ai-root .glux-ai-msg-avatar,
  #glux-ai-root .glux-ai-msg-avatar::after,
  #glux-ai-root .glux-ai-msg-avatar.is-thinking,
  #glux-ai-root .glux-ai-msg-avatar.is-thinking::after,
  #glux-ai-root .glux-ai-msg-avatar.is-thinking::before {
    animation: none;
  }
  /* Thinking must still be visible without motion: the aura stays, it just holds
     still. A customer who asked not to be moved still needs to know we are working. */
  #glux-ai-root .glux-ai-msg-avatar.is-thinking::before {
    opacity: 0.3;
  }
}

#glux-ai-root .glux-ai-avatar svg,
#glux-ai-root .glux-ai-msg-avatar svg {
  width: 20px;
  height: 20px;
}

/* No glyph inside the orb. A sparkle drawn on a sphere reads as a sticker on a
   bead; the sphere is the mark on its own. */
#glux-ai-root .glux-ai-msg-avatar svg {
  display: none;
}

#glux-ai-root .glux-ai-header-title {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.2;
  color: var(--glux-ai-header-text, var(--glux-ai-accent-text, var(--glux-ai-accent)));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#glux-ai-root .glux-ai-header-status {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
  font-size: 12px;
  color: var(--glux-ai-muted);
}

#glux-ai-root .glux-ai-close {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  /* Takes the header's own text colour instead of pinning its own. A white disc with a grey
     glyph is right on a white header and a bright blob on a dark one, and the shop's header
     colour is configurable — so the control has to follow it rather than assume it. The
     border is a neutral grey at low alpha, which reads against both. */
  border: 1px solid rgba(127, 137, 153, 0.32);
  border-radius: 50%;
  background: transparent;
  color: inherit;
  opacity: 0.72;
  cursor: pointer;
  transition: opacity var(--glux-ai-fast) var(--glux-ai-ease),
    border-color var(--glux-ai-fast) var(--glux-ai-ease),
    background var(--glux-ai-fast) var(--glux-ai-ease);
}

#glux-ai-root .glux-ai-close:hover {
  opacity: 1;
  border-color: rgba(127, 137, 153, 0.6);
  background: rgba(127, 137, 153, 0.14);
}

#glux-ai-root .glux-ai-close svg {
  width: 18px;
  height: 18px;
}

#glux-ai-root .glux-ai-messages {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 18px 16px 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* The ground the assistant bubble sits on. The admin publishes it (--glux-ai-messages-bg) and
     the widget used to ignore it, which is how a published WHITE bubble ended up on a white
     scroller with nothing between them. */
  background: var(--glux-ai-messages-bg, var(--glux-ai-surface));
  scrollbar-width: thin;
  scrollbar-color: #d7dde6 transparent;
}

#glux-ai-root .glux-ai-turn {
  display: flex;
  flex-direction: column;
  max-width: 100%;
  animation: glux-ai-turn-in var(--glux-ai-base) var(--glux-ai-ease) both;
}

@keyframes glux-ai-turn-in {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

#glux-ai-root .glux-ai-turn--user {
  align-items: flex-end;
  padding-left: 56px;
}

#glux-ai-root .glux-ai-turn--system {
  align-items: center;
  font-size: 12px;
  color: var(--glux-ai-muted);
  text-align: center;
}

/* The avatar belongs beside the MESSAGE, and it used to align to the bottom of the
   whole column — which includes the feedback control and, once one is open, the
   reasons panel. So the avatar sank to the middle of the turn and sat next to a list
   of complaint buttons. It drifted before this too, on any long answer; the taller
   panel only made it impossible to miss. Aligned to the top, with the avatar nudged
   down to meet the bubble's first line. */
#glux-ai-root .glux-ai-assistant-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  max-width: 88%;
}

#glux-ai-root .glux-ai-assistant-row > .glux-ai-msg-avatar {
  margin-top: 2px;
}

#glux-ai-root .glux-ai-assistant-col {
  min-width: 0;
  flex: 1;
}

#glux-ai-root .glux-ai-bubble {
  max-width: 84%;
  padding: 11px 15px;
  border-radius: var(--glux-ai-radius-bubble);
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

#glux-ai-root .glux-ai-bubble--user {
  align-self: flex-end;
  background: var(--glux-ai-user-bg);
  color: var(--glux-ai-user-text);
  /* The one squared corner is what makes a rounded rectangle read as speech. */
  border-bottom-right-radius: 7px;
  box-shadow: 0 2px 10px rgba(15, 111, 255, 0.22);
}

#glux-ai-root .glux-ai-bubble--assistant {
  align-self: flex-start;
  background: var(--glux-ai-bubble-in);
  color: var(--glux-ai-bubble-in-text);
  border-bottom-left-radius: 7px;
}

#glux-ai-root .glux-ai-user-meta {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  margin-top: 4px;
  padding-right: 2px;
  font-size: 11px;
  color: var(--glux-ai-muted);
}

#glux-ai-root .glux-ai-user-meta svg {
  width: 12px;
  height: 12px;
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
}

#glux-ai-root .glux-ai-msg-text {
  line-height: 1.45;
}

#glux-ai-root .glux-ai-link {
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  text-decoration: underline;
  text-underline-offset: 2px;
}

#glux-ai-root .glux-ai-bubble--user .glux-ai-link {
  /* On a solid accent bubble an accent-coloured link is invisible. */
  color: #ffffff;
  text-decoration: underline;
  text-underline-offset: 2px;
}

#glux-ai-root .glux-ai-link-cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
}

#glux-ai-root .glux-ai-link-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 10px 10px 12px;
  border-radius: var(--glux-ai-radius-card);
  border: 1px solid var(--glux-ai-border);
  background: var(--glux-ai-surface);
  box-shadow: var(--glux-ai-shadow-card);
  text-decoration: none;
  color: var(--glux-ai-text);
  transition: border-color var(--glux-ai-fast) var(--glux-ai-ease),
    box-shadow var(--glux-ai-fast) var(--glux-ai-ease),
    transform var(--glux-ai-fast) var(--glux-ai-ease);
}

/* A card carrying a product photo sits on the panel's own canvas so the picture, not the
   container, is the thing with edges. */
#glux-ai-root .glux-ai-link-card--product {
  padding-left: 10px;
}

#glux-ai-root .glux-ai-link-card:hover {
  border-color: var(--glux-ai-accent-ring);
  box-shadow: 0 4px 14px rgba(16, 32, 64, 0.1);
  transform: translateY(-1px);
}

#glux-ai-root .glux-ai-link-card:active {
  transform: translateY(0);
}

/* The shop's own photo, at the size a thumbnail is actually read.
   `contain` on a white ground, not `cover`: these are product shots on white, and cropping
   a sensor to fill a square cuts the thing the customer is trying to recognise. */
#glux-ai-root .glux-ai-link-card-thumb {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--glux-ai-canvas);
  border: 1px solid var(--glux-ai-hairline);
  display: flex;
  align-items: center;
  justify-content: center;
}

#glux-ai-root .glux-ai-link-card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* Affordance, not decoration: the card is a link and nothing else on it says so. */
#glux-ai-root .glux-ai-link-card-go {
  flex-shrink: 0;
  margin-left: auto;
  width: 20px;
  height: 20px;
  color: var(--glux-ai-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color var(--glux-ai-fast) var(--glux-ai-ease),
    transform var(--glux-ai-fast) var(--glux-ai-ease);
}

#glux-ai-root .glux-ai-link-card-go svg {
  width: 16px;
  height: 16px;
}

#glux-ai-root .glux-ai-link-card:hover .glux-ai-link-card-go {
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  transform: translateX(2px);
}

#glux-ai-root .glux-ai-link-card-icon {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #e5e7eb;
  color: #4b5563;
}

#glux-ai-root .glux-ai-link-card-icon svg {
  width: 18px;
  height: 18px;
}

#glux-ai-root .glux-ai-link-card--facebook .glux-ai-link-card-icon {
  background: #1877f2;
  color: #fff;
}

#glux-ai-root .glux-ai-link-card-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

/* One line, ellipsis past it. A card heading is a name, and a name that wraps over four
   lines in a 260px panel is a wall — which is exactly how a bare URL used to render here. */
#glux-ai-root .glux-ai-link-card-title {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#glux-ai-root .glux-ai-link-card--product .glux-ai-link-card-url {
  font-weight: 600;
  color: var(--glux-ai-text);
}

#glux-ai-root .glux-ai-link-card-url {
  font-size: 11.5px;
  color: var(--glux-ai-muted);
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#glux-ai-root .glux-ai-quick--orders {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  margin-top: 4px;
}

#glux-ai-root .glux-ai-msg-text .glux-ai-order-pick {
  display: block;
  width: fit-content;
  max-width: 100%;
  margin-top: 8px;
  text-align: left;
  pointer-events: auto;
  cursor: pointer;
}

#glux-ai-root .glux-ai-pill {
  border: 1px solid var(--glux-ai-border);
  background: var(--glux-ai-surface);
  color: var(--glux-ai-text);
  border-radius: 999px;
  padding: 9px 14px;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.2;
  cursor: pointer;
  transition: border-color var(--glux-ai-fast) var(--glux-ai-ease),
    background var(--glux-ai-fast) var(--glux-ai-ease),
    color var(--glux-ai-fast) var(--glux-ai-ease),
    transform var(--glux-ai-fast) var(--glux-ai-ease);
}

#glux-ai-root .glux-ai-pill--fill {
  background: var(--glux-ai-accent-ink, var(--glux-ai-accent));
  border-color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  color: #fff;
}

#glux-ai-root .glux-ai-pill--outline:hover,
#glux-ai-root .glux-ai-pill--starter:hover {
  border-color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  background: var(--glux-ai-accent-soft);
  transform: translateY(-1px);
}

#glux-ai-root .glux-ai-handoff-row {
  margin-bottom: 8px;
}

#glux-ai-root .glux-ai-handoff-btn {
  width: 100%;
  border: 1px solid var(--glux-ai-accent);
  background: #fff;
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  border-radius: 10px;
  padding: 8px 12px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

#glux-ai-root .glux-ai-handoff-btn:hover {
  background: rgba(var(--glux-ai-accent-rgb), 0.06);
}

/* --- "Segítséget kérek" ---------------------------------------------------------
   A quieter button than the handoff one on purpose: handoff is the loud escalation
   ("someone will answer now"), this is the calm one that always works. Same shape so the
   footer reads as one control strip when both are showing. */
#glux-ai-root .glux-ai-help-row {
  margin-bottom: 8px;
}

#glux-ai-root .glux-ai-help-btn {
  width: 100%;
  border: 1px solid #e2e6ee;
  background: #fff;
  color: #334155;
  border-radius: 10px;
  padding: 8px 12px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.16s ease, background 0.16s ease;
}

#glux-ai-root .glux-ai-help-btn:hover {
  border-color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  background: rgba(var(--glux-ai-accent-rgb), 0.04);
}

#glux-ai-root .glux-ai-help-form {
  display: grid;
  gap: 6px;
  margin-bottom: 8px;
  padding: 12px;
  border: 1px solid #e2e6ee;
  border-radius: 12px;
  background: #f8f9fb;
}

#glux-ai-root .glux-ai-help-form[hidden] {
  display: none;
}

#glux-ai-root .glux-ai-help-intro {
  margin: 0 0 2px;
  font-size: 13px;
  color: #475569;
  line-height: 1.45;
}

#glux-ai-root .glux-ai-help-label {
  font-size: 12px;
  font-weight: 600;
  color: #475569;
}

#glux-ai-root .glux-ai-help-input {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid #d5dbe5;
  border-radius: 8px;
  padding: 8px 10px;
  font: inherit;
  font-size: 14px;
  color: #0f172a;
  background: #fff;
}

#glux-ai-root .glux-ai-help-input:focus {
  outline: none;
  border-color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  box-shadow: 0 0 0 3px rgba(var(--glux-ai-accent-rgb), 0.12);
}

#glux-ai-root .glux-ai-help-textarea {
  resize: vertical;
  min-height: 62px;
}

/* The error sits where the eye already is — under the field it belongs to would need a
   third element per field; one line above the actions is enough for two fields. */
#glux-ai-root .glux-ai-help-error {
  margin: 2px 0 0;
  font-size: 13px;
  color: #b42318;
}

#glux-ai-root .glux-ai-help-error[hidden] {
  display: none;
}

#glux-ai-root .glux-ai-help-privacy {
  margin: 2px 0 0;
  font-size: 11.5px;
  color: var(--glux-ai-muted);
  line-height: 1.4;
}

#glux-ai-root .glux-ai-help-privacy a {
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
}

#glux-ai-root .glux-ai-help-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 4px;
}

#glux-ai-root .glux-ai-help-cancel,
#glux-ai-root .glux-ai-help-submit {
  border-radius: 8px;
  padding: 8px 14px;
  font: inherit;
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
}

#glux-ai-root .glux-ai-help-cancel {
  border: 1px solid #d5dbe5;
  background: #fff;
  color: #475569;
}

#glux-ai-root .glux-ai-help-submit {
  border: none;
  background: var(--glux-ai-accent-ink, var(--glux-ai-accent));
  color: #fff;
}

#glux-ai-root .glux-ai-help-submit:disabled {
  opacity: 0.65;
  cursor: default;
}

#glux-ai-root .glux-ai-footer {
  padding: 10px 14px 12px;
  border-top: 1px solid var(--glux-ai-hairline);
  background: var(--glux-ai-surface);
}

#glux-ai-root .glux-ai-quick-actions-label {
  font-size: 11px;
  font-weight: 500;
  color: var(--glux-ai-muted);
  margin-bottom: 8px;
}

#glux-ai-root .glux-ai-quick--starters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}

#glux-ai-root .glux-ai-pill--starter {
  height: 36px;
  padding: 0 12px;
  font-size: 12px;
}

#glux-ai-root .glux-ai-input-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--glux-ai-canvas);
  border: 1px solid transparent;
  border-radius: 16px;
  padding: 4px 4px 4px 8px;
  min-height: 52px;
  transition: border-color var(--glux-ai-fast) var(--glux-ai-ease),
    background var(--glux-ai-fast) var(--glux-ai-ease),
    box-shadow var(--glux-ai-fast) var(--glux-ai-ease);
}

/* The one place this stylesheet overrides the host by force, and it is a reset rather than
   a look.

   The widget is injected into whatever theme the shop runs, and a theme that styles `input`
   with a background, a border and a radius draws a SECOND box inside our field: the
   customer sees a rounded white cell inside a rounded grey one, which is what "dupla
   körvonal" was. Id specificity is not enough against a theme rule carrying !important,
   and there is no arrangement of our own selectors that wins that. Reported from the
   storefront on v1.6.2. */
#glux-ai-root .glux-ai-input {
  flex: 1;
  padding: 8px 6px;
  font: inherit;
  color: var(--glux-ai-text);
  min-width: 0;
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  outline: none !important;
  /* Themes set these on inputs too, and either one re-introduces a visible edge. */
  min-height: 0 !important;
  height: auto !important;
}

#glux-ai-root .glux-ai-input::placeholder {
  color: var(--glux-ai-muted);
}

#glux-ai-root .glux-ai-send {
  width: 42px;
  height: 42px;
  border: none;
  border-radius: 50%;
  /* Grey until there is something to send. The button used to sit fully lit above an empty
     field, which is an invitation to press a control that does nothing.
     The glyph is grey too, and that is the fix: a WHITE arrow on this grey was 1.39:1, an icon
     you could not see on a button that was not disabled. Quiet is a colour pair, not an
     invisible one — armed flips both back. */
  background: #d5dbe4;
  color: var(--glux-ai-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background var(--glux-ai-fast) var(--glux-ai-ease),
    transform var(--glux-ai-fast) var(--glux-ai-ease),
    opacity var(--glux-ai-fast) var(--glux-ai-ease);
}

/* Focus and arm --------------------------------------------------------------
   The composer reacts to being used: the field lifts when focused, and the send
   button lights only once there is something to send. */

/* One ring, not two. A 1px border AND a 4px halo is two concentric outlines around one
   control; the field now states its focus with a single accent edge. */
#glux-ai-root .glux-ai-input-wrap:focus-within {
  background: var(--glux-ai-surface);
  border-color: var(--glux-ai-accent-ring);
}

#glux-ai-root .glux-ai-send.is-armed {
  background: var(--glux-ai-send, var(--glux-ai-accent));
  color: #fff;
}

#glux-ai-root .glux-ai-send.is-armed:not(:disabled):hover {
  background: var(--glux-ai-accent-strong);
}

#glux-ai-root .glux-ai-send:not(:disabled):active {
  transform: scale(0.94);
}

/* Day separator --------------------------------------------------------------
   A centred, quiet line marking when the conversation happened. Written once at the
   top and again after a real gap, never between two messages a minute apart. */

#glux-ai-root .glux-ai-daysep {
  align-self: center;
  margin: 2px 0;
  padding: 2px 10px;
  font-size: 11px;
  color: var(--glux-ai-muted);
  letter-spacing: 0.01em;
  animation: glux-ai-turn-in var(--glux-ai-base) var(--glux-ai-ease) both;
}

#glux-ai-root .glux-ai-send:not(:disabled):hover {
  transform: scale(1.04);
}

#glux-ai-root .glux-ai-send:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

#glux-ai-root .glux-ai-send svg {
  width: 18px;
  height: 18px;
}

#glux-ai-root .glux-ai-disclaimer {
  margin: 8px 0 0;
  text-align: center;
  font-size: 10px;
  color: var(--glux-ai-muted);
  line-height: 1.35;
}

/* Findable, not noisy: it rides on the line that is already there, so it costs no height. */
#glux-ai-root .glux-ai-version {
  color: var(--glux-ai-muted);
  font-variant-numeric: tabular-nums;
}

/* Phone: a sheet, not a takeover.
   ------------------------------------------------------------------------------
   This used to be inset:0, 100dvh, no radius, no border — the chat replaced the
   shop. A customer mid-purchase lost every reference point they had, and closing
   it was the only way back to the product they were asking about.

   It now sits above the page with a strip of the shop still visible over it, the
   same rounded card it is on a desktop. dvh rather than vh so the iOS keyboard
   shrinks the sheet instead of pushing its composer under the keyboard, and the
   bottom inset respects the home indicator. */
@media (max-width: 640px) {
  #glux-ai-root.glux-ai-mobile-open .glux-ai-panel {
    top: auto;
    /* Pinned to the visible window, not the layout viewport: --glux-ai-vv-left is how far
       that window has been pushed sideways by a horizontally scrolled or pinched page.
       Both default to the old behaviour when visualViewport is missing. */
    left: calc(var(--glux-ai-vv-left, 0px) + 10px);
    right: auto;
    width: calc(var(--glux-ai-vv-width, 100vw) - 20px);
    /* --glux-ai-kb is how much of the layout viewport the on-screen keyboard is
       covering, measured in JS from window.visualViewport (see syncKeyboardInset).
       dvh alone cannot do this: on Android Chrome the keyboard is drawn OVER a
       layout viewport that never shrinks, so a fixed sheet stays put and the
       composer ends up underneath it. Default 0px, so a browser without
       visualViewport gets exactly the previous behaviour. */
    bottom: calc(10px + var(--glux-ai-kb, 0px) + env(safe-area-inset-bottom, 0px));
    max-width: none;
    height: 86dvh;
    /* Never taller than the visible viewport minus a strip of the shop — and the
       keyboard's share is taken off here as well as added to `bottom`, so the sheet
       shrinks upward from the composer instead of sliding off the top of the screen. */
    max-height: calc(100dvh - 56px - var(--glux-ai-kb, 0px) - env(safe-area-inset-bottom, 0px));
    /* The height change follows the keyboard's own animation rather than snapping a
       frame ahead of it. */
    transition: bottom 0.18s ease, max-height 0.18s ease;
    border-radius: 22px;
    transform: none;
  }

  /* The launcher still goes: it would sit on top of the sheet, and the header
     already carries the close control. */
  #glux-ai-root.glux-ai-mobile-open .glux-ai-launcher {
    display: none;
  }

  #glux-ai-root .glux-ai-turn--user {
    padding-left: 24px;
  }

  #glux-ai-root .glux-ai-assistant-row {
    max-width: 92%;
  }
}

.glux-ai-product-cards {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 6px;
}

.glux-ai-product-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  min-height: 48px;
  border: 1px solid var(--glux-ai-border);
  border-radius: var(--glux-ai-radius-card);
  background: var(--glux-ai-surface);
  box-shadow: var(--glux-ai-shadow-card);
  transition: border-color var(--glux-ai-fast) var(--glux-ai-ease),
    box-shadow var(--glux-ai-fast) var(--glux-ai-ease);
}

.glux-ai-product-img {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 8px;
  flex-shrink: 0;
}

.glux-ai-product-body {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.glux-ai-product-title {
  display: block;
  font-weight: 600;
  font-size: 12px;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}

.glux-ai-product-price {
  display: block;
  font-size: 12px;
  font-weight: 700;
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  flex-shrink: 0;
  white-space: nowrap;
}

.glux-ai-product-view {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  margin-left: 0;
  border: 1px solid var(--glux-ai-border);
  border-radius: 8px;
  background: #fff;
  color: var(--glux-ai-muted);
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.glux-ai-product-view:hover {
  border-color: var(--glux-ai-accent-ring);
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  background: var(--glux-ai-accent-soft);
}

/* --- Action rows -------------------------------------------------------------
   The link the answer is about. The prose is told not to repeat a raw URL because
   "the client renders verified products and actions as structured cards" — so when
   this did not exist, the customer read a description of a link and had nothing to
   click. Full width and clearly tappable: it is usually the point of the turn. */

.glux-ai-action-rows {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 6px;
}

.glux-ai-action-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 44px;
  padding: 11px 16px;
  border: 1px solid var(--glux-ai-accent-ring);
  border-radius: var(--glux-ai-radius-card);
  background: var(--glux-ai-accent-soft);
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: border-color var(--glux-ai-fast) var(--glux-ai-ease),
    background var(--glux-ai-fast) var(--glux-ai-ease),
    transform var(--glux-ai-fast) var(--glux-ai-ease);
}

.glux-ai-action-row:hover,
.glux-ai-action-row:focus-visible {
  border-color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  background: rgba(15, 111, 255, 0.14);
  transform: translateY(-1px);
  text-decoration: none;
}

/* --- Message feedback -------------------------------------------------------
   Small by intent: the control is for the rare bad answer, not a rating prompt on
   every message. A 14px outlined glyph inside a 44px touch target — the visual
   weight is the 14px, the tappable area is the 44px, and on a phone those must
   not be the same number.

   Always visible, on every device. It used to fade in on hover, which meant a
   customer had to discover it by accident and a touch user got a different
   product from a mouse user. An outline at low contrast is quiet enough without
   being invisible.

   The wrapper is a COLUMN. It was a row, and the reasons panel was appended into
   it as a third item, so the four choices sat beside the thumb instead of under
   it — offered choices that looked like scattered ones.                        */
#glux-ai-root .glux-ai-feedback {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  margin: 6px 0 0 2px;
}

/* The answer and its thumb, side by side: the thumb level with the bubble's last line,
   on its right. The bubble keeps its own max-width inside the line. */
#glux-ai-root .glux-ai-bubble-line {
  display: flex;
  align-items: flex-end;
  gap: 4px;
}

#glux-ai-root .glux-ai-bubble-line > .glux-ai-bubble {
  min-width: 0;
}

#glux-ai-root .glux-ai-bubble-line > .glux-ai-flag {
  flex: none;
  margin: 0 0 1px 0;
}

/* `display: flex` above would otherwise override the hidden attribute. */
#glux-ai-root .glux-ai-feedback[hidden] {
  display: none;
}

#glux-ai-root .glux-ai-feedback-row {
  display: flex;
  align-items: center;
  gap: 10px;
  /* Was 28px while the control inside it was 44px, so the button overflowed its
     own row and was pulled back into place with negative margins on all sides.
     The row is now as tall as what it holds. */
  min-height: 34px;
}

/* The visual is 34px; the tap target is still 44px, via the overlay below.
   Those were the same box before, held apart by -8px/-12px margins — which is
   what made it look squeezed against the edge of the bubble. */
#glux-ai-root .glux-ai-flag {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin-left: -4px;
  padding: 0;
  border: 1px solid transparent;
  background: none;
  color: var(--glux-ai-muted);
  cursor: pointer;
  border-radius: 11px;
  transition: color var(--glux-ai-fast) var(--glux-ai-ease),
    background var(--glux-ai-fast) var(--glux-ai-ease),
    border-color var(--glux-ai-fast) var(--glux-ai-ease),
    transform var(--glux-ai-fast) var(--glux-ai-ease);
}

/* 34 + 5px on each side = 44. Invisible, unpositioned in the layout, and the
   reason the button can be small without being hard to hit on a phone. */
#glux-ai-root .glux-ai-flag::before {
  content: "";
  position: absolute;
  inset: -5px;
}

#glux-ai-root .glux-ai-flag svg {
  width: 17px;
  height: 17px;
}

#glux-ai-root .glux-ai-flag:hover,
#glux-ai-root .glux-ai-flag:focus-visible {
  color: #6b6b76;
  background: rgba(15, 23, 42, 0.05);
  border-color: var(--glux-ai-hairline);
}

#glux-ai-root .glux-ai-flag:active {
  transform: scale(0.92);
}

#glux-ai-root .glux-ai-flag.is-on,
#glux-ai-root .glux-ai-flag.is-on:hover {
  color: #c0392b;
  background: rgba(192, 57, 43, 0.08);
  border-color: rgba(192, 57, 43, 0.22);
}

#glux-ai-root .glux-ai-feedback-note {
  font-size: 11px;
  color: var(--glux-ai-muted);
}

/* Withdrawing was "press the same thumb again", which nothing on screen said. */
#glux-ai-root .glux-ai-undo {
  font: inherit;
  font-size: 11px;
  line-height: 1;
  padding: 4px 6px;
  border: none;
  background: none;
  color: var(--glux-ai-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  border-radius: 6px;
}

#glux-ai-root .glux-ai-undo:hover,
#glux-ai-root .glux-ai-undo:focus-visible {
  color: #55555f;
  background: rgba(0, 0, 0, 0.04);
}

/* A panel, not four loose pills. It is a question being asked, so it gets the
   frame of one: its own surface, its own label, and choices that share an edge
   so the eye reads them as a set rather than as debris.                        */
#glux-ai-root .glux-ai-reasons {
  align-self: stretch;
  box-sizing: border-box;
  max-width: 320px;
  padding: 10px;
  border: 1px solid #ececf2;
  border-radius: 12px;
  background: #fafafc;
  animation: glux-ai-reasons-in 0.16s ease;
}

@keyframes glux-ai-reasons-in {
  from { opacity: 0; transform: translateY(-3px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  #glux-ai-root .glux-ai-reasons { animation: none; }
  #glux-ai-root .glux-ai-flag,
  #glux-ai-root .glux-ai-reason { transition: none; }
  /* The press-scale is motion too. Turning off only the transition would leave it
     as an instant jump, which is the same signal with the smoothing removed. */
  #glux-ai-root .glux-ai-flag:active { transform: none; }
  /* The sheet still MOVES with the keyboard — it has to, or the composer goes back
     under it. What is removed is the easing, so it arrives in one step. */
  #glux-ai-root.glux-ai-mobile-open .glux-ai-panel { transition: none; }
  #glux-ai-root .glux-ai-review-star,
  #glux-ai-root .glux-ai-review-btn { transition: none; }
  #glux-ai-root .glux-ai-review-btn:active { transform: none; }
}

#glux-ai-root .glux-ai-reasons-label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--glux-ai-muted);
  margin: 0 2px 8px;
}

/* Full width rather than shrink-to-fit: ragged right edges are most of what made
   the old version look thrown together, and a chip sized to its text turns the
   longest reason into the biggest target. */
#glux-ai-root .glux-ai-reasons-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

#glux-ai-root .glux-ai-reason {
  display: block;
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  font-size: 12px;
  line-height: 1.3;
  text-align: left;
  padding: 9px 12px;
  min-height: 36px;
  border: 1px solid #e3e3ea;
  border-radius: 9px;
  background: #fff;
  color: #4a4a55;
  cursor: pointer;
  transition: border-color 0.14s ease, background 0.14s ease, color 0.14s ease;
}

#glux-ai-root .glux-ai-reason:hover,
#glux-ai-root .glux-ai-reason:focus-visible {
  border-color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  background: var(--glux-ai-surface);
  color: var(--glux-ai-text);
}

#glux-ai-root .glux-ai-reason:active {
  background: var(--glux-ai-accent-soft);
}


/* ---------------------------------------------------------------------------
   The review card.

   It sits IN the message column, not in the footer, because it is the reply to a
   thank-you rather than a fallback control — see offerReview() in glux-ai.js. So it
   is styled as a card in the conversation: the shop's own card radius, a hairline
   edge, and the same widths the bubbles use.
   --------------------------------------------------------------------------- */

#glux-ai-root .glux-ai-turn--review {
  display: flex;
  justify-content: center;
  padding: 4px 0;
}

#glux-ai-root .glux-ai-review {
  box-sizing: border-box;
  width: 100%;
  max-width: 340px;
  padding: 14px 15px 13px;
  border: 1px solid var(--glux-ai-border);
  border-radius: var(--glux-ai-radius-card);
  background: var(--glux-ai-surface);
  box-shadow: var(--glux-ai-shadow-card);
  color: var(--glux-ai-text);
  font-size: 13px;
  line-height: 1.45;
}

#glux-ai-root .glux-ai-review-intro {
  margin: 0 0 8px;
}

#glux-ai-root .glux-ai-review-question {
  margin: 0 0 11px;
  font-weight: 600;
}

#glux-ai-root .glux-ai-review-actions {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}

#glux-ai-root .glux-ai-review-btn {
  flex: 1 1 auto;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  /* 40px, not the 44px a bare tap target would take: these sit inside a card that is
     itself inside a scrolling column, so the surrounding padding is part of the
     target and a taller pair of buttons crowds the card. */
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid var(--glux-ai-border);
  border-radius: 10px;
  background: var(--glux-ai-surface);
  color: var(--glux-ai-text);
  cursor: pointer;
  transition: border-color 0.14s ease, background 0.14s ease, transform 0.1s ease;
}

#glux-ai-root .glux-ai-review-btn:hover,
#glux-ai-root .glux-ai-review-btn:focus-visible {
  border-color: var(--glux-ai-accent-text, var(--glux-ai-accent));
}

#glux-ai-root .glux-ai-review-btn:active {
  transform: scale(0.97);
}

#glux-ai-root .glux-ai-review-btn--primary {
  background: var(--glux-ai-accent-ink, var(--glux-ai-accent));
  border-color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  color: #fff;
}

#glux-ai-root .glux-ai-review-btn--primary:hover,
#glux-ai-root .glux-ai-review-btn--primary:focus-visible {
  background: var(--glux-ai-accent-strong);
  border-color: var(--glux-ai-accent-strong);
}

#glux-ai-root .glux-ai-review-btn[disabled] {
  opacity: 0.6;
  cursor: default;
}

#glux-ai-root .glux-ai-review-stars {
  display: flex;
  gap: 2px;
  margin: 2px 0 12px;
}

#glux-ai-root .glux-ai-review-star {
  /* 40px square: this is the control the whole flow turns on, and a 24px star is a
     miss on a phone. The gap is small so the five read as one row, not five buttons. */
  width: 40px;
  height: 40px;
  padding: 0;
  font-size: 26px;
  line-height: 1;
  border: 0;
  background: none;
  cursor: pointer;
  /* Unfilled stars are grey, not invisible: an outline the customer cannot see is a
     control they do not know is there. */
  color: #d3d8e0;
  transition: color 0.12s ease, transform 0.1s ease;
}

#glux-ai-root .glux-ai-review-star.is-on {
  color: #f5a524;
}

#glux-ai-root .glux-ai-review-star:active {
  transform: scale(0.9);
}

#glux-ai-root .glux-ai-review-label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  color: var(--glux-ai-muted);
  margin: 0 2px 5px;
}

/* Same !important reset as the composer, for the same reason: this markup is injected
   into an unknown Shopify theme, and a theme rule for `input`/`textarea` puts its own
   box, border and radius inside ours. Id specificity does not beat a theme's
   !important — see the note on .glux-ai-input. */
#glux-ai-root .glux-ai-review-input {
  box-sizing: border-box !important;
  display: block !important;
  width: 100% !important;
  font: inherit !important;
  font-size: 13px !important;
  color: var(--glux-ai-text) !important;
  padding: 9px 11px !important;
  margin: 0 0 10px !important;
  border: 1px solid var(--glux-ai-border) !important;
  border-radius: 10px !important;
  background: var(--glux-ai-surface) !important;
  box-shadow: none !important;
  outline: none !important;
}

#glux-ai-root .glux-ai-review-input:focus {
  border-color: var(--glux-ai-accent) !important;
}

#glux-ai-root .glux-ai-review-textarea {
  resize: vertical !important;
  min-height: 68px !important;
}

#glux-ai-root .glux-ai-review-error {
  margin: 0 0 8px;
  font-size: 12px;
  color: #b42318;
}

#glux-ai-root .glux-ai-review-privacy {
  margin: 8px 0 0;
  font-size: 11px;
  line-height: 1.4;
  color: var(--glux-ai-muted);
}

#glux-ai-root .glux-ai-coupon {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}

#glux-ai-root .glux-ai-coupon-code {
  flex: 1 1 auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 10px 12px;
  border: 1px dashed var(--glux-ai-accent);
  border-radius: 10px;
  background: var(--glux-ai-accent-soft);
  color: var(--glux-ai-text);
  /* Selectable by hand, always. The copy button is a convenience; a clipboard API that
     is blocked or absent must not be the only way to get the code off the screen. */
  user-select: all;
  word-break: break-all;
}

#glux-ai-root .glux-ai-coupon-copy {
  flex: 0 0 auto;
}

/* ============================================================================
   Keyboard visibility, and the dark palette the server has always published.
   Appended at the end on purpose: several tests slice this file BETWEEN two
   selectors, so a new rule inserted in the middle silently changes what they
   read. Order at the end of a stylesheet costs nothing and breaks nothing.
   ============================================================================ */

/* The three controls a keyboard actually lands on had no visible focus state at
   all — the launcher, the close button and the send button. A focus ring that
   only shows for :focus-visible keeps it off mouse clicks, which is why the
   rings were left out in the first place. */
#glux-ai-root .glux-ai-launcher:focus-visible,
#glux-ai-root .glux-ai-send:focus-visible {
  outline: 2px solid var(--glux-ai-accent-ink, var(--glux-ai-accent));
  outline-offset: 2px;
}

/* The close button is the one control that cannot take the accent ring, for the two reasons
   its own rule above already gives: it sits at `opacity: 0.72`, which composites the outline
   too and would render a 2px ring at 72% alpha, and it deliberately inherits `color` from a
   header the shop colours itself — a fixed accent ring there is the same mistake as a fixed
   background, which widgetRedesign.test.mjs:170 already forbids on this selector. */
#glux-ai-root .glux-ai-close:focus-visible {
  opacity: 1;
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* The launcher sits on the shop's own page, whose background this widget does not
   control. A white halo under the ring keeps it visible on a dark hero image. */
#glux-ai-root .glux-ai-launcher:focus-visible {
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.9),
    0 12px 30px rgba(15, 111, 255, 0.34);
}

/* Dark mode.
   The heavy lifting is not here: /config publishes a complete `cssVarsDark` — 28
   values including panel, header, bubbles and border — and applyPublishedAppearance
   sets them inline and adds this class. What the server does NOT send is the eight
   below, so without them a dark panel kept light text colours and a light hairline,
   which is the half-dark result that looks like a bug rather than a theme.
   Every value here clears AA on the server's own dark surfaces: the muted grey
   measures 7.11:1 on #111827, 5.88:1 on the assistant bubble #1f2937. */
#glux-ai-root.glux-ai-dark {
  --glux-ai-surface: #111827;
  --glux-ai-canvas: #0d131f;
  --glux-ai-text: #f3f4f6;
  --glux-ai-muted: #9aa5b4;
  --glux-ai-border: rgba(255, 255, 255, 0.12);
  --glux-ai-hairline: rgba(255, 255, 255, 0.08);
  --glux-ai-bubble-in: #1f2937;
  --glux-ai-bubble-in-text: #f3f4f6;
  --glux-ai-shadow-panel: 0 32px 80px rgba(0, 0, 0, 0.62), 0 8px 24px rgba(0, 0, 0, 0.4);
  --glux-ai-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.5);
}

/* The two greys that are literals rather than tokens, because they carry a state
   the token cannot: the resting send button, and the grey it wears until there is
   something to send. */
#glux-ai-root.glux-ai-dark .glux-ai-send:not(.is-armed) {
  background: #2b3442;
}

/* The bubble that would otherwise not be there.
   Toggled from applyPublishedAppearance when the assistant bubble's fill is within 1.12:1 of the
   ground behind it — the ratio the widget's own grey-on-white bubble shipped with. The shop keeps
   the colour it chose; the hairline is what makes the shape exist, and it is what the approved
   mockup draws around its own cards. */
#glux-ai-root.glux-ai-outline-bubbles .glux-ai-bubble--assistant {
  border: 1px solid var(--glux-ai-border);
}

/* ============================================================================
   A termékkártya és a linkkártya egy kártya.
   ============================================================================
   Nem "három kártyanyelv" volt, ahogy a terv írta: a kettő kerete (szegély,
   rádiusz, háttér, árnyék) már ma bájtra azonos, és csak olyan számokban tért
   el, amiket senki nem választott — 10 vs 12px rés, 8px 10px vs
   10px 10px 10px 12px belső tér, 12 vs 13,5px cím. A kupon viszont NEM a
   harmadik kártya: az egy chip egy kártyán belül, és mindhárom eltérése
   jelentést hordoz (a szaggatott szegély az egyetlen a fájlban), ezért békén
   marad.

   A blokk a fájl VÉGÉN van, mert több teszt két szelektor KÖZÉ szeletel, és egy
   középre beszúrt szabály csendben átírja, mit olvasnak.

   A specificitás sem kozmetika: a .glux-ai-product-card szabály (0,1,0)-n áll,
   miközben a fájl minden más kártyája (1,1,0)-n. Egy Shopify-téma (0,1,0)
   szabálya később a forrásban legyőzi — pont az a hibaosztály, ami a beviteli
   mezőnkbe egyszer már saját dobozt és két fókuszgyűrűt rajzolt.
   ============================================================================ */

#glux-ai-root .glux-ai-product-cards {
  gap: 8px;
  margin-top: 10px;
}

#glux-ai-root .glux-ai-product-card {
  gap: 12px;
  padding: 10px 10px 10px 12px;
  border: 1px solid var(--glux-ai-border);
  border-radius: var(--glux-ai-radius-card);
  background: var(--glux-ai-surface);
  box-shadow: var(--glux-ai-shadow-card);
  transition: border-color var(--glux-ai-fast) var(--glux-ai-ease),
    box-shadow var(--glux-ai-fast) var(--glux-ai-ease);
}

/* A kártya eddig deklarált egy box-shadow-átmenetet, amit sosem használt: nem
   volt hover szabálya. Most van, és ugyanaz, mint a linkkártyáé. */
#glux-ai-root .glux-ai-product-card:hover {
  border-color: var(--glux-ai-accent-ring);
  box-shadow: 0 4px 14px rgba(16, 32, 64, 0.1);
}

/* A kép: ugyanaz a keret és ugyanaz az illesztés, mint a linkkártya bélyegképén.
   A linkkártya kommentje meg is indokolja, miért `contain`: "ezek termékfotók
   fehéren, és egy szenzort négyzetre vágni pont azt vágja le, amit a vásárló
   felismerni próbál". A termékkártya ugyanazokat a fotókat `cover`-rel mutatta —
   vagyis ugyanaz a szenzorfotó egy hasábban egyszer levágva, egyszer teljesen.
   Ez nem két jelentés volt, hanem egy ellentmondás. */
#glux-ai-root .glux-ai-product-img {
  width: 44px;
  height: 44px;
  object-fit: contain;
  border-radius: 10px;
  background: var(--glux-ai-canvas);
  border: 1px solid var(--glux-ai-hairline);
  padding: 2px;
}

#glux-ai-root .glux-ai-product-title {
  font-size: 13.5px;
}

/* Két élő hiba egy szabályban.
   A szegélye egy RÉGI accent három csatornáját égette be alfával — ugyanazt a
   színt, amit két teszt kitilt ebből a stíluslapból. Mindkettő a hex írásmódot
   keresi a fájl szövegében, ezért az rgba() alak átcsúszott rajtuk, hat
   szabályban. Mind a hat most a --glux-ai-accent-rgb tokenből jön, amit az
   applyTheme a bolt színéből ír. (A tiltott értéket ez a komment sem írja le:
   a tesztek a nyers fájlt grepelik, és egy magyarázó komment is kibuktatja őket
   — ez a commit egyszer pontosan így hasalt el.)
   A háttere pedig `#fff`
   literál volt, ami a sötét blokkban fehéret fest #111827-re.
   És 32x32 volt, miközben ez a fájl a lobogónál és a csillagnál 44px-es
   érintőfelületet követel meg tesztben. */
#glux-ai-root .glux-ai-product-view {
  width: 44px;
  height: 44px;
  border: 1px solid var(--glux-ai-border);
  border-radius: 10px;
  background: var(--glux-ai-surface);
}

/* KÖTELEZŐ társblokk, nem opcionális.
   A fenti szabályok (1,1,0)-n állnak, a 269. sor csökkentett-mozgás blokkja
   viszont (0,1,0)-n listázza a .glux-ai-product-card-ot — és egy media query nem
   ad specificitást. A fenti `transition` tehát csendben visszakapcsolná a mozgást
   annak, aki kikapcsolta. Itt kapcsol vissza ki.
   A .glux-ai-link-card:hover eltolása eddig SEM volt a listán: az a hiány most
   szűnik meg, nem most keletkezik. */
@media (prefers-reduced-motion: reduce) {
  #glux-ai-root .glux-ai-product-card,
  #glux-ai-root .glux-ai-product-view,
  #glux-ai-root .glux-ai-link-card {
    transition: none;
  }
  #glux-ai-root .glux-ai-link-card:hover,
  #glux-ai-root .glux-ai-link-card:active,
  #glux-ai-root .glux-ai-product-card:hover {
    transform: none;
  }
}

/* ============================================================================
   Fejléc: arc, név, és az info gomb.
   ============================================================================
   A vásárló a panel megnyitásakor a felső 64 pixelt olvassa el először, és azok
   eddig annyit mondtak, hogy „AI Asszisztens", semmi mellett — az avatar
   display:none volt fotó nélkül, a fejlécben pedig egyetlen gomb állt.

   Ez a felület a widget legnézettebb és legkevésbé védett része: a 12 tesztfájl
   közül EGYIK SEM köti a .glux-ai-avatar, .glux-ai-header, .glux-ai-header-title,
   .glux-ai-header-main vagy .glux-ai-header-copy elemet. Ezért itt a legnagyobb a
   látható nyereség a legkisebb kockázattal — és ezért kap mindegyik saját
   őrtesztet ebben a commitban.
   ============================================================================ */

#glux-ai-root .glux-ai-header-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

/* Az info gomb ugyanazt a kabátot viseli, mint a bezárás: ugyanaz a méret, ugyanaz
   a hajszálszegély, ugyanaz az áttetszőség — mert a kettő egy pár, és két különböző
   gomb egymás mellett a fejlécben azt üzeni, hogy az egyik fontosabb. */
#glux-ai-root .glux-ai-info {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid rgba(127, 137, 153, 0.32);
  border-radius: 50%;
  background: transparent;
  color: inherit;
  opacity: 0.72;
  cursor: pointer;
  transition: opacity var(--glux-ai-fast) var(--glux-ai-ease),
    border-color var(--glux-ai-fast) var(--glux-ai-ease),
    background var(--glux-ai-fast) var(--glux-ai-ease);
}

#glux-ai-root .glux-ai-info:hover {
  opacity: 1;
  border-color: rgba(127, 137, 153, 0.6);
  background: rgba(127, 137, 153, 0.14);
}

/* Ugyanaz az indoklás, mint a bezárás gombnál: 0,72-es áttetszőségen a gyűrű is
   0,72-re kompozitálódik, és a fejléc színét a bolt állítja. */
#glux-ai-root .glux-ai-info:focus-visible {
  opacity: 1;
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

#glux-ai-root .glux-ai-info svg {
  width: 18px;
  height: 18px;
}

/* A monogram: annak a boltnak, ami elnevezte az asszisztensét, de arcot nem adott
   neki. Fotó nélkül az avatar eddig display:none volt, tehát a cím a panel széléhez
   tapadt. */
#glux-ai-root .glux-ai-avatar.has-mono {
  display: grid;
  place-items: center;
  background: var(--glux-ai-accent-soft);
  box-shadow: inset 0 0 0 1px var(--glux-ai-accent-ring);
}

#glux-ai-root .glux-ai-avatar.has-mono svg {
  display: none;
}

#glux-ai-root .glux-ai-avatar-mono {
  font-weight: 700;
  font-size: 15px;
  line-height: 1;
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
}

/* ============================================================================
   Az info panel — a szálon belül, nem modalként.
   ============================================================================
   Telefonon a widget maga is egy sheet, és egy sheet a sheeten az a réteg, aminek
   nincs hova mennie: a klaviatúra letakarja, az Escape a kettő közül a rosszabbat
   zárja, és a vásárló elveszti mögötte a beszélgetést. Ez a panel a görgető ALATT
   csúszik fel, a beszélgetés a helyén marad, és az Escape előbb ezt zárja.
   ============================================================================ */

#glux-ai-root .glux-ai-info-panel {
  border-top: 1px solid var(--glux-ai-border);
  background: var(--glux-ai-surface);
  padding: 14px 16px 16px;
  max-height: 60%;
  overflow-y: auto;
  overscroll-behavior: contain;
  animation: glux-ai-info-in var(--glux-ai-base) var(--glux-ai-ease);
}

@keyframes glux-ai-info-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

#glux-ai-root .glux-ai-info-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

#glux-ai-root .glux-ai-info-title {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--glux-ai-text);
}

#glux-ai-root .glux-ai-info-close {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--glux-ai-border);
  border-radius: 50%;
  background: transparent;
  color: var(--glux-ai-muted);
  cursor: pointer;
}

#glux-ai-root .glux-ai-info-close:focus-visible {
  outline: 2px solid var(--glux-ai-accent-ink, var(--glux-ai-accent));
  outline-offset: 2px;
}

#glux-ai-root .glux-ai-info-close svg {
  width: 15px;
  height: 15px;
}

#glux-ai-root .glux-ai-info-row + .glux-ai-info-row {
  margin-top: 10px;
}

#glux-ai-root .glux-ai-info-row h3 {
  margin: 0 0 2px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--glux-ai-muted);
}

#glux-ai-root .glux-ai-info-row p {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--glux-ai-text);
}

#glux-ai-root .glux-ai-info-privacy {
  display: inline-block;
  margin-top: 12px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  text-decoration: underline;
  text-underline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  #glux-ai-root .glux-ai-info-panel {
    animation: none;
  }
  #glux-ai-root .glux-ai-info {
    transition: none;
  }
}

/* ------------------------------------------------------- beágyazott (inline) chat
   The same widget, sitting IN the page instead of over it.

   Asked for on the Kapcsolat page: a visitor who is one click away from writing an e-mail
   should be able to ask the question first, and a bubble in the corner is an invitation
   they have to notice. On a page that carries a mount point, this IS the widget — the
   launcher never appears, so there is no second chat to confuse it with.

   Everything here overrides the floating panel and nothing rewrites it: the base rules keep
   their exact values for every other page. The mobile sheet block needs no counterpart,
   because the class it keys off (`glux-ai-mobile-open`) is never set in embedded mode. */

#glux-ai-root.glux-ai-root--embedded {
  display: block;
  width: 100%;
}

#glux-ai-root.glux-ai-root--embedded .glux-ai-launcher {
  display: none;
}

#glux-ai-root.glux-ai-root--embedded .glux-ai-panel {
  /* relative, NOT static. `.glux-ai-jump` ("Új üzenet") is absolutely positioned against
     the panel; with a static panel it would escape to the theme's nearest positioned
     ancestor and land somewhere in the shop's own layout. */
  position: relative;
  inset: auto;
  z-index: auto;
  width: 100%;
  max-width: none;
  /* Tall enough for a question and its answer without scrolling, short enough that the
     e-mail address above it and the rest of the page below stay reachable by thumb. */
  height: clamp(420px, 58dvh, 580px);
  max-height: none;
  opacity: 1;
  visibility: visible;
  /* The floating panel grows out of the launcher's corner. There is no corner to grow from
     here, and an entrance animation on something that is simply part of the page reads as a
     glitch on load. */
  transform: none;
  transition: none;
  /* A drop shadow says "floating above". In the page the border carries the edge. */
  box-shadow: none;
}

/* ============================================================================
   Termékkártya a Kosárba gombbal (2.9.0).
   ============================================================================
   A bolt kérése, 2026-09-23: a termék-linknél legyen ott kicsiben a termék fő
   képe, a teljes neve, és egy kosárba tétel gomb. A kártya a buborék ALATT ül,
   nem benne: a szöveg a válasz végén még egyszer újrarajzolódik, és ami benne
   lenne, azt letörölné.

   Ugyanaz a keret, mint a link- és a termékkártyáé (szegély, rádiusz, felület,
   árnyék), hogy egy üzenetben ne legyen két kártyanyelv. Ami eltér, az a
   tartalom: a kép 64px (a bélyeg 44px-e egy színválasztó mellett felismerhetetlen),
   és a név NEM vágódik el — a kiszerelés (2 db, 10 db) a név végén áll, és egy
   „…" pont azt takarná el, amiben a vásárló dönt.

   A fájl végén áll, mert a tesztek szelektorok KÖZÉ szeletelnek.
   ============================================================================ */

#glux-ai-root .glux-ai-shop-cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 8px;
  max-width: 100%;
}

#glux-ai-root .glux-ai-shop-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px;
  border: 1px solid var(--glux-ai-border);
  border-radius: var(--glux-ai-radius-card);
  background: var(--glux-ai-surface);
  box-shadow: var(--glux-ai-shadow-card);
  color: var(--glux-ai-text);
  transition: border-color var(--glux-ai-fast) var(--glux-ai-ease),
    box-shadow var(--glux-ai-fast) var(--glux-ai-ease);
}

#glux-ai-root .glux-ai-shop-card:hover {
  border-color: var(--glux-ai-accent-ring);
  box-shadow: 0 4px 14px rgba(16, 32, 64, 0.1);
}

#glux-ai-root .glux-ai-shop-card-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

/* `contain` fehér alapon, ahogy a bélyegképnél: termékfotók fehéren, és egy
   tapaszt négyzetre vágni pont a formáját vágja le. */
#glux-ai-root .glux-ai-shop-card-media {
  flex-shrink: 0;
  width: 64px;
  height: 64px;
  border-radius: 10px;
  overflow: hidden;
  background: #ffffff;
  border: 1px solid var(--glux-ai-hairline);
  display: flex;
  align-items: center;
  justify-content: center;
}

#glux-ai-root .glux-ai-shop-card-media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

#glux-ai-root .glux-ai-shop-card-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  flex: 1 1 auto;
}

#glux-ai-root .glux-ai-shop-card-title {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.35;
  overflow-wrap: anywhere;
  text-wrap: pretty;
}

#glux-ai-root .glux-ai-shop-card-price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
  font-size: 13.5px;
  font-variant-numeric: tabular-nums;
}

#glux-ai-root .glux-ai-shop-card-now {
  font-weight: 700;
}

#glux-ai-root .glux-ai-shop-card-was,
#glux-ai-root .glux-ai-shop-card-stock {
  font-size: 12px;
  color: var(--glux-ai-muted);
}

#glux-ai-root .glux-ai-shop-card-stock {
  font-weight: 600;
}

/* A téma a saját select-stílusát hozná (a Wokiee-ben egy teljes szélességű, 50px
   magas mező); az azonosítós szelektor és a saját nyíl tartja a kártya méretén.
   A nyíl két gradient a currentColorból, nem egy beégetett SVG — így sötét
   módban is a szöveg színe. */
#glux-ai-root .glux-ai-shop-card-variant {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  min-height: 40px;
  margin: 0;
  padding: 6px 32px 6px 10px;
  border: 1px solid var(--glux-ai-border);
  border-radius: 10px;
  background-color: var(--glux-ai-surface);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 16px center, right 11px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  color: var(--glux-ai-text);
  font: inherit;
  font-size: 13px;
  line-height: 1.3;
  cursor: pointer;
}

/* Kosárba kitölti a sort, Megnézem a tartalmához méreteződik: az elsődleges
   cselekvés a nagyobb célpont. */
#glux-ai-root .glux-ai-shop-card-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

#glux-ai-root .glux-ai-shop-card-actions .glux-ai-shop-card-add {
  flex: 1 1 auto;
}

#glux-ai-root .glux-ai-shop-card-actions .glux-ai-shop-card-view {
  flex: 0 0 auto;
}

/* Az egyetlen kitöltött gomb a kártyán: ez a cselekvés. Az accent-ink a bolt
   színéből származik úgy, hogy a fehér rajta 4.5:1 fölött maradjon (applyTheme). */
#glux-ai-root .glux-ai-shop-card-add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 40px;
  padding: 0 16px;
  border: 0;
  border-radius: 999px;
  background: var(--glux-ai-accent-ink, var(--glux-ai-accent));
  color: #ffffff;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  transition: background var(--glux-ai-fast) var(--glux-ai-ease),
    transform var(--glux-ai-fast) var(--glux-ai-ease);
}

#glux-ai-root .glux-ai-shop-card-add:hover {
  background: var(--glux-ai-accent-strong, var(--glux-ai-accent-ink, var(--glux-ai-accent)));
}

#glux-ai-root .glux-ai-shop-card-add:active {
  transform: scale(0.98);
}

#glux-ai-root .glux-ai-shop-card-add svg {
  width: 15px;
  height: 15px;
}

#glux-ai-root .glux-ai-shop-card-add[aria-busy='true'] {
  cursor: progress;
  opacity: 0.8;
}

/* Elfogyott: nem kattintható, és nem is látszik annak. */
#glux-ai-root .glux-ai-shop-card-add:disabled {
  background: var(--glux-ai-hairline);
  color: var(--glux-ai-muted);
  cursor: not-allowed;
}

#glux-ai-root .glux-ai-shop-card-view {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid var(--glux-ai-border);
  border-radius: 999px;
  color: var(--glux-ai-text);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  transition: border-color var(--glux-ai-fast) var(--glux-ai-ease);
}

#glux-ai-root .glux-ai-shop-card-view:hover {
  border-color: var(--glux-ai-accent-ring);
  text-decoration: none;
}

#glux-ai-root .glux-ai-shop-card-add:focus-visible,
#glux-ai-root .glux-ai-shop-card-view:focus-visible,
#glux-ai-root .glux-ai-shop-card-variant:focus-visible,
#glux-ai-root .glux-ai-shop-card-cart:focus-visible {
  outline: 2px solid var(--glux-ai-accent-text, var(--glux-ai-accent));
  outline-offset: 2px;
}

#glux-ai-root .glux-ai-shop-card-note {
  font-size: 12px;
  line-height: 1.4;
  color: var(--glux-ai-muted);
}

#glux-ai-root .glux-ai-shop-card-note:empty {
  display: none;
}

#glux-ai-root .glux-ai-shop-card-note.is-error {
  color: var(--glux-ai-text);
}

#glux-ai-root .glux-ai-shop-card-cart {
  color: var(--glux-ai-accent-text, var(--glux-ai-accent));
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

#glux-ai-root .glux-ai-shop-card.is-sold-out .glux-ai-shop-card-media img {
  opacity: 0.55;
}

@media (prefers-reduced-motion: reduce) {
  #glux-ai-root .glux-ai-shop-card,
  #glux-ai-root .glux-ai-shop-card-add,
  #glux-ai-root .glux-ai-shop-card-view {
    transition: none;
  }
  #glux-ai-root .glux-ai-shop-card-add:active {
    transform: none;
  }
}
