/* ai-assistant.css — styling for the AI assistant: component library
   (product cards, quick replies, cart/recipe/promotion/stall cards) plus
   the full-screen chrome (templates/public/ai_assistant.html). Reuses the
   shared design tokens/button classes from styles.css (--color-forest,
   --color-pine, .btn-pill) so it visually matches the rest of the site
   without inheriting its layout (no navbar/footer — see ai_assistant.html). */

.ai-product-carousel {
  display: flex;
  gap: .75rem;
  overflow-x: auto;
  padding: .5rem 0;
}

.ai-product-card {
  flex: 0 0 auto;
  /* 202 = 200px image + 1px border each side (image is 1:1, so 200x200) */
  width: 202px;
  border: 1px solid #e0e0e0;
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
}

/* Image wrapper: square (1:1) and the positioning context for the
   AddToCartStepper overlay — same layout as parada.html's featured cards
   (.pr-img in parada_ranking.css). */
.ai-product-card-imgwrap {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  background: #f2f2f2;
  overflow: hidden;
}

.ai-product-card-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Same overlay placement as parada_ranking.css's stepper wrapper (that file
   isn't loaded on the assistant page). The stepper's own visuals (.add-btn,
   quantity controls) come from cart.css, loaded globally via the base. */
.ai-product-card .product-action-stepper-wrapper {
  position: absolute;
  right: 5px;
  bottom: 5px;
  z-index: 999;
  pointer-events: auto;
  display: inline-block;
  background: transparent;
  box-shadow: 0 0 0 0.5px rgba(255, 255, 255, 0.95);
  border-radius: calc(var(--stepper-height, var(--stepper-height-default, 34px)) / 2 + 2px);
}

/* Free-parada products: the stepper renders nothing — hide the empty
   wrapper so its box-shadow ring doesn't show as a stray dot. */
.ai-product-card .product-action-stepper-wrapper:empty {
  display: none;
}

.ai-product-card-body {
  padding: .5rem;
}

.ai-product-card-name {
  font-weight: 600;
  font-size: .9rem;
  margin-bottom: .2rem;
}

.ai-product-card-price {
  font-size: .85rem;
  color: #333;
  margin-bottom: .2rem;
}

/* Unit-weight label next to the name and per-weight/unit info next to the
   price — same roles as .product-qty/.pr-per/.pr-unit on parada.html's
   featured cards (parada_ranking.css), scaled to this card's typography. */
.ai-product-card-name .product-qty {
  color: var(--muted-text, #6a7a72);
  font-weight: 400;
  font-size: .8rem;
  margin-left: 6px;
}

.ai-product-card-per,
.ai-product-card-unit {
  color: var(--muted-text, #6a7a72);
  font-weight: 400;
  font-size: .8rem;
  margin-left: 6px;
}

.ai-product-card-parada {
  font-size: .75rem;
  color: #777;
  margin-bottom: .35rem;
}

.ai-quick-replies {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin: .5rem 0;
}

.ai-quick-reply-btn {
  border: 1px solid transparent;
  background: var(--Color-pine, var(--color-pine, #2a7a5f));
  color: #fff;
  border-radius: 999px;
  padding: .35rem .9rem;
  font-size: .85rem;
  cursor: pointer;
}

.ai-quick-reply-btn:hover {
  background: color-mix(in srgb, var(--Color-pine, var(--color-pine, #2a7a5f)) 85%, #000);
}

.ai-cart-summary {
  border: 1px solid #e0e0e0;
  border-radius: 12px;
  padding: .75rem;
  margin: .5rem 0;
  background: #fafafa;
}

.ai-cart-summary-list {
  list-style: none;
  margin: 0 0 .5rem;
  padding: 0;
  font-size: .9rem;
}

.ai-cart-summary-total {
  font-weight: 600;
  font-size: .9rem;
}

.ai-promotion-list,
.ai-stall-list {
  display: flex;
  gap: .75rem;
  overflow-x: auto;
  padding: .5rem 0;
}

/* Promotion and stall cards reuse .ai-product-card-* wholesale
   (AIPromotionCard.js / AIStallCard.js build the same DOM as
   AIProductCard.js), so no card styles of their own here. */

.ai-recipe-card {
  border: 1px solid #e0e0e0;
  border-radius: 12px;
  padding: .75rem;
  margin: .5rem 0;
  background: #fafafa;
}

.ai-recipe-card-title {
  font-weight: 700;
  font-size: 1rem;
  margin-bottom: .4rem;
}

.ai-recipe-card-total {
  font-weight: 600;
  font-size: .9rem;
  margin-top: .4rem;
}

/* -----------------------------------------------------------------------
   Full-screen chrome (templates/public/ai_assistant.html)
   ----------------------------------------------------------------------- */

/* The page extends public/base.html (Bootstrap, fixed navbar, cart mounts)
   like every other public page — typography and body background come from
   there. The chat scrolls with the DOCUMENT, like every other page: that
   is what lets iOS Safari collapse its bottom toolbar on scroll so the
   conversation slides under it and the home indicator. The composer and
   the action bar are position:fixed over the flow (an earlier design used
   an inner overflow scroller with the page pinned to 100dvh; that kept
   Safari's toolbar permanently expanded, leaving a dead band at the bottom
   of the screen that the chat could never reach). The iOS keyboard —
   which the pinned design existed to tame — is handled in
   ai_assistant.html via the visualViewport API, which feeds the
   --ai-kb-overlap var used below. */

/* Bootstrap's min-vh-100 pins the body's minimum height to 100vh — on iOS
   Safari with the toolbar expanded that's TALLER than the visible viewport
   (100dvh). The invisible slack makes the document scrollable before there
   is any real content to scroll, and since the assistant auto-scrolls to
   the bottom of the document on load / on new messages, that slack parked
   the start of the conversation under the fixed navbar. Cap the minimum at
   the dynamic viewport instead: the document only outgrows the visible
   height when the conversation itself does. (!important to beat
   min-vh-100; the vh line is the fallback for browsers without dvh.) */
body.ai-page {
  min-height: 100vh !important;
  min-height: 100dvh !important;
}

main.ai-main {
  min-height: 100vh; /* fallback for browsers without dvh */
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  /* Total height of the floating composer (input + its vertical padding);
     the action bar and the messages' bottom padding offset against it. */
  --ai-composer-h: calc(var(--btn-pill-height, 48px) + .5rem + 12px + env(safe-area-inset-bottom, 0px));
  /* Side gutter of the whole page: messages, composer, action bar, and the
     full-bleed card scrollers (which cancel it) all read this. */
  --ai-gutter: 12px;
  /* styles.css reserves --cart-safe-bottom on every <main> for the fixed
     cart pill; the pill is hidden here (below) and the composer owns the
     bottom edge, so drop that clearance. */
  padding-bottom: 0;
}

/* The fixed cart pill would sit on top of the composer; the chat has its
   own cart affordances (get_cart summaries, add_to_cart intents). */
body.ai-page #cart-simple-root {
  display: none;
}

/* .ai-messages grows with the conversation and the document scrolls
   (no inner scroller — see the header comment). The flex chain
   main > .ai-messages > .ai-messages-inner exists so short conversations
   still fill the first viewport and .ai-welcome can center itself with
   margin:auto. The ResizeObserver in ai_assistant.html re-scrolls the
   window whenever .ai-messages-inner's size changes — text streaming,
   cards appearing, images finishing loading asynchronously. */
.ai-messages {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  /* Extra bottom padding: the fixed composer and "Esborra la conversa"
     button float over the bottom of the screen, so when fully scrolled
     the last message clears them instead of resting underneath.
     --ai-kb-overlap is the on-screen-keyboard height (set from JS via
     visualViewport, 0 when closed): the floating controls lift by it,
     so the clearance grows with them. */
  padding: 1rem var(--ai-gutter, 12px) calc(var(--ai-composer-h, 68px) + 3.25rem + var(--ai-kb-overlap, 0px));
}

.ai-messages-inner {
  display: flex;
  flex-direction: column;
  gap: .25rem;
  flex: 1 1 auto;
}

/* Horizontal card scrollers go full-bleed inside the chat: cards slide over
   .ai-messages' side gutter all the way to both screen edges — same
   pattern as parada.html's "productes destacats" scroller
   (parada_ranking.css): negative side margins cancel the container gutter,
   the start gutter is re-created INSIDE the scrollable area (so it scrolls
   away with the content) and an ::after flex spacer plays that role at the
   end. Scrollbar hidden to match that scroller too. */
.ai-messages .ai-product-carousel,
.ai-messages .ai-promotion-list,
.ai-messages .ai-stall-list {
  margin-inline: calc(-1 * var(--ai-gutter, 12px));
  padding-inline: var(--ai-gutter, 12px) 0;
  scroll-padding-inline: var(--ai-gutter, 12px);
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.ai-messages .ai-product-carousel::-webkit-scrollbar,
.ai-messages .ai-promotion-list::-webkit-scrollbar,
.ai-messages .ai-stall-list::-webkit-scrollbar {
  display: none;
}

.ai-messages .ai-product-carousel::after,
.ai-messages .ai-promotion-list::after,
.ai-messages .ai-stall-list::after {
  content: '';
  flex: 0 0 var(--ai-gutter, 12px);
}

.ai-messages-inner > * {
  flex-shrink: 0;
}

.ai-welcome {
  margin: auto 0;
  text-align: center;
  padding: 1rem;
}

.ai-welcome h1 {
  font-size: 1.3rem;
  color: var(--color-evergreen, #304040);
  margin-bottom: .5rem;
}

.ai-welcome p {
  color: var(--color-pine, #5B7065);
  font-size: .9rem;
  margin-bottom: 1rem;
}

/* Bubbles render a small markdown subset (see AIMessage.js): paragraphs,
   <br> line breaks, bullet lists and <strong>. No pre-wrap — line breaks
   are explicit markup now. */
.ai-message {
  max-width: 80%;
  padding: .6rem .9rem;
  border-radius: 16px;
  margin-bottom: .6rem;
}

.ai-message p {
  margin: 0;
}

.ai-message ul {
  margin: 0;
  padding-left: 1.25rem;
}

.ai-message li {
  margin: .2rem 0;
}

.ai-message p + p,
.ai-message p + ul,
.ai-message ul + p {
  margin-top: .5rem;
}

.ai-message-user {
  align-self: flex-end;
  background: var(--color-pine, #5B7065);
  color: #fff;
  border-bottom-right-radius: 4px;
}

.ai-message-assistant {
  align-self: flex-start;
  background: #fff;
  color: #222;
  border-bottom-left-radius: 4px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .06);
}

.ai-typing-indicator {
  align-self: flex-start;
  display: flex;
  align-items: center; /* keeps the dots vertically centered next to the taller status label */
  gap: .3rem;
  padding: .7rem .9rem;
  background: #fff;
  border-radius: 16px;
  border-bottom-left-radius: 4px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .06);
  margin-bottom: .6rem;
}

.ai-typing-indicator span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-pine, #5B7065);
  opacity: .4;
  animation: ai-typing-bounce 1s infinite ease-in-out;
}

.ai-typing-indicator span:nth-child(2) { animation-delay: .15s; }
.ai-typing-indicator span:nth-child(3) { animation-delay: .3s; }

@keyframes ai-typing-bounce {
  0%, 80%, 100% { opacity: .4; transform: translateY(0); }
  40% { opacity: 1; transform: translateY(-3px); }
}

/* Activity label next to the dots ("Buscant al mercat…") */
.ai-typing-label {
  font-style: normal;
  font-size: .85rem;
  color: #5B7065;
  margin-left: .2rem;
  white-space: nowrap;
}

/* #action-bar-slot is just the mount point in the markup; the bar itself
   is fixed to the viewport, floating just above the fixed composer, and
   the chat scrolls behind it. (It stays a DOM child of <main>, so it
   still inherits --ai-composer-h / --ai-gutter.) */
.ai-action-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(var(--ai-composer-h, 68px) + .5rem + var(--ai-kb-overlap, 0px));
  z-index: 5;
  display: flex;
  justify-content: center;
  padding: 0 var(--ai-gutter, 12px);
  /* Only the button itself should catch taps/scroll, not the full-width bar. */
  pointer-events: none;
}

/* Chip-sized (same box as .ai-quick-reply-btn), with the glass treatment
   of the hero's secondary button — .btn-glass-dark, the light-background
   variant of index.html's "Com funciona" (.btn-glass). */
.ai-action-bar-btn {
  pointer-events: auto;
  padding: .35rem .9rem;
  font-size: .85rem;
  border-radius: 999px;
  cursor: pointer;
  background: rgba(91, 112, 101, 0.08);
  border: 1px solid rgba(91, 112, 101, 0.35);
  color: var(--color-pine, #5B7065);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.ai-action-bar-btn:hover,
.ai-action-bar-btn:focus {
  background: rgba(91, 112, 101, 0.16);
  color: var(--color-pine, #5B7065);
}

/* Composer: just the white input pill over the page background (no white
   bar behind it), 12px off the bottom of the window (plus the device
   safe-area inset), spanning the full available width. The send button
   floats inside the field's right end and is only shown while there is
   text to send (toggled from ai_assistant.html on the input's events). */
.ai-composer {
  /* Fixed over the document: the chat scrolls behind it. Only the input
     pill (and the send button inside it) catches pointer events; the
     transparent padding gutters let taps/scroll through. --ai-kb-overlap
     lifts it above the iOS on-screen keyboard, which shrinks only the
     visual viewport and would otherwise cover a fixed bottom element
     (0 while the keyboard is closed — see ai_assistant.html). */
  position: fixed;
  left: 0;
  right: 0;
  bottom: var(--ai-kb-overlap, 0px);
  z-index: 5;
  padding: .5rem var(--ai-gutter, 12px) calc(12px + env(safe-area-inset-bottom, 0px));
  pointer-events: none;
}

.ai-composer input[type=text],
.ai-composer .ai-composer-send {
  pointer-events: auto;
}

.ai-composer input[type=text] {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid #ccc;
  border-radius: 999px;
  /* right padding reserves room for the send icon inside the field */
  padding: 0 52px 0 1rem;
  /* 16px floor: iOS Safari auto-zooms the page when focusing any input
     with a smaller font-size. */
  font-size: max(16px, 1rem);
  height: var(--btn-pill-height, 48px);
  background: #fff;
}

.ai-composer input[type=text]:focus {
  outline: none;
  border-color: var(--color-pine, #5B7065);
}

/* "Still working" cue while the input is disabled awaiting the assistant's
   reply (composer.classList toggled in ai_assistant.html alongside
   composerInput.disabled). A "barber pole" of hard-edged forest/evergreen
   stripes marches around the pill's border — sharp, high-contrast bands
   read as obvious motion where a soft single-color sweep didn't — plus a
   glow that never fully fades, only breathes between two visible
   intensities, so there's no dead point in the loop where the cue is
   momentarily invisible. Two-layer background trick (dual gradient, inner
   one padding-box, outer one border-box) paints the stripes in the border
   area only, without needing an extra wrapper element. */
.ai-composer input[type=text].is-thinking {
  border: 3px solid transparent;
  background:
    linear-gradient(#fff, #fff) padding-box,
    repeating-linear-gradient(90deg,
      var(--color-forest, #04202C) 0%, var(--color-forest, #04202C) 12.5%,
      var(--color-evergreen, #304040) 12.5%, var(--color-evergreen, #304040) 25%) border-box;
  background-size: 100% 100%, 200% 100%;
  animation:
    ai-thinking-march 0.9s linear infinite,
    ai-thinking-pulse 1.1s ease-in-out infinite;
}

@keyframes ai-thinking-march {
  from { background-position: 0 0, 0% 0; }
  to   { background-position: 0 0, -200% 0; }
}

@keyframes ai-thinking-pulse {
  0%, 100% { box-shadow: 0 0 8px 2px rgba(4, 32, 44, .5); }
  50%      { box-shadow: 0 0 22px 6px rgba(48, 64, 64, .85); }
}

@media (prefers-reduced-motion: reduce) {
  .ai-composer input[type=text].is-thinking {
    animation: none;
    border-color: var(--color-evergreen, #304040);
    background: #fff;
    box-shadow: 0 0 10px 2px rgba(48, 64, 64, .5);
  }
}

.ai-composer-send {
  position: absolute;
  /* centered vertically inside the 48px input: bottom padding + (48-36)/2 */
  right: calc(var(--ai-gutter, 12px) + 6px);
  bottom: calc(12px + env(safe-area-inset-bottom, 0px) + (var(--btn-pill-height, 48px) - 36px) / 2);
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--color-pine, #5B7065);
  color: #fff;
  font-size: 1rem;
  cursor: pointer;
}

.ai-composer-send:hover {
  background: var(--color-evergreen, #304040);
}

.ai-composer-send[hidden] {
  display: none;
}
