/* Tapping this still opens the device's real native date/time picker —
   nothing here replaces that. It only restyles the CLOSED-state field
   itself, which by default renders as an obviously "browser form field"
   look (boxy, small grey calendar icon, system font) that clashes with
   everything else in the app. */
.native-datetime-input {
  width: 100%;
  box-sizing: border-box;
  padding: 12px 14px;
  border: 1.5px solid var(--color-line);
  border-radius: 12px;
  background: #f9fbfc;
  font-size: 14px;
  font-family: inherit;
  font-weight: 700;
  color: var(--color-ink);
  /* Lets Chromium give the field's own icon a light-mode rendering that
     actually matches this light background, instead of guessing wrong
     based on the OS theme and drawing a dark, mismatched icon. */
  color-scheme: light;
}
.native-datetime-input::-webkit-calendar-picker-indicator {
  filter: invert(46%) sepia(78%) saturate(451%) hue-rotate(114deg) brightness(92%) contrast(101%);
  cursor: pointer;
  padding: 4px;
}

@keyframes spin { to { transform: rotate(360deg); } }
@keyframes recordPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@keyframes recordBar { 0%, 100% { transform: scaleY(0.4); } 50% { transform: scaleY(1); } }
.chat-recording-bar { transform-origin: center; }
#chat-recording-row.is-paused #chat-recording-dot,
#chat-recording-row.is-paused .chat-recording-bar { animation-play-state: paused; opacity: 0.4; }
/* height is the real hit area for drag-to-seek (WhatsApp-style) — the
   visible track itself is just the 3px fill/background centered inside
   it via top: 50%, so the tap/drag target is much bigger than what's
   actually drawn, which is what makes dragging with a finger reliable. */
.msg-swipe-reply-icon {
  /* Fixed to the viewport (like #msg-copy-menu) instead of absolute inside
     the bubble — chat-bubble-anim scrolls (overflow-y: auto), and per the
     CSS overflow spec, setting only one of overflow-x/overflow-y forces
     the other to 'auto' too, so an absolutely-positioned icon sticking out
     past a bubble flush against the container's edge was getting clipped
     almost entirely invisible. left/top are set inline, per-frame, from
     the bubble's real getBoundingClientRect() instead. */
  position: fixed;
  /* Scale rides along with the drag progress (set inline, per-frame, from
     JS) — the transition here only smooths opacity, since a transitioned
     scale would visibly lag half a frame behind the finger and feel
     mushy. Opacity doesn't need to track the finger that precisely, so
     smoothing it out looks better than the raw stepped values touchmove
     produces. */
  transform: translateY(-50%) scale(0.5);
  width: 36px;
  height: 36px;
  background: #ffffff;
  color: #009b61;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 10px rgba(0,0,0,0.15);
  opacity: 0;
  pointer-events: none;
  z-index: 30;
  transition: opacity 0.12s ease;
}
.msg-swipe-reply-icon svg {
  width: 20px;
  height: 20px;
}
/* Same fixed-to-viewport, drag-progress-driven hint as
   .msg-swipe-reply-icon above, for the edge-swipe-back gesture (see
   src/ui/edgeSwipeBack.js) — top/left set inline, per-frame, from JS. */
.audio-progress-track { position: relative; height: 16px; cursor: pointer; touch-action: none; }
.audio-progress-track::before {
  content: ''; position: absolute; top: 50%; left: 0; right: 0; height: 3px;
  transform: translateY(-50%); border-radius: 2px; background: rgba(0,0,0,0.08);
}
.audio-progress-fill {
  position: absolute; top: 50%; left: 0; height: 3px; width: 0%;
  transform: translateY(-50%); background: #009b61; border-radius: 2px;
}
.audio-progress-thumb {
  position: absolute; top: 50%; left: 0%; width: 11px; height: 11px;
  background: #009b61; border-radius: 50%; transform: translate(-50%, -50%);
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
}
.audio-speed-btn {
  flex-shrink: 0; border: none; background: rgba(0,0,0,0.06); color: #4a5b73;
  font-size: 11px; font-weight: 800; padding: 4px 8px; border-radius: 999px;
  cursor: pointer; font-family: inherit;
}
/* A soft pulse ring around the play button while a clip is actually
   playing — the only always-visible sign that audio is live besides the
   moving thumb, useful once the bubble scrolls partly off-screen. */
@keyframes audioPlayPulse {
  0% { box-shadow: 0 0 0 0 rgba(0,155,97,0.35); }
  100% { box-shadow: 0 0 0 8px rgba(0,155,97,0); }
}
.audio-bubble.is-playing .audio-play-btn { animation: audioPlayPulse 1.4s ease-out infinite; }
.pending-img-spinner {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 3px solid rgba(255,255,255,0.35);
  border-top-color: #fff;
  animation: spin 0.7s linear infinite;
}
.typing-dots {
  display: inline-flex;
  align-items: flex-end;
  gap: 2px;
  height: 10px;
}
.typing-dots span {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
  animation: typingBounce 1.1s infinite ease-in-out;
}
.typing-dots span:nth-child(2) { animation-delay: 0.15s; }
.typing-dots span:nth-child(3) { animation-delay: 0.3s; }
@keyframes typingBounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.5; }
  30% { transform: translateY(-3px); opacity: 1; }
}
.btn-spinner {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2.5px solid rgba(255,255,255,0.35);
  border-top-color: #fff;
  animation: spin 0.7s linear infinite;
}

/* The blinking caret at the end of Aivia's reply while it's still
   streaming in, token by token — the same visual cue as any text editor's
   own cursor, so it reads as "still writing" rather than "done". */
.ai-stream-cursor {
  display: inline-block;
  width: 2px;
  height: 14px;
  margin-left: 2px;
  vertical-align: -2px;
  background: #1a8b5c;
  animation: aiStreamBlink 0.9s step-end infinite;
}
@keyframes aiStreamBlink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

.top-header,
.home-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 70px;
}

.top-header h2 {
  margin: 0;
  font-size: 20px;
  font-weight: 800;
}

.brand-lockup {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 14px;
}

.brand-lockup img {
  width: 122px;
  height: auto;
  object-fit: contain;
}

.school-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  text-align: left;
}

.school-chip > span {
  display: grid;
  gap: 2px;
}

.school-chip strong {
  font-size: 14px;
}

.school-chip small {
  color: var(--color-muted);
  font-size: 12px;
}

.icon-button,
.plain-icon {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
}

.icon-button {
  background: #f5f7fa;
}

.icon-14 svg {
  width: 14px;
  height: 14px;
}

@keyframes barGrow {
  from { transform: scaleY(0); }
  to { transform: scaleY(1); }
}
.animated-bar {
  transform-origin: bottom;
  animation: barGrow 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

.day-bar-tooltip {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: #1a2a46;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  padding: 5px 9px;
  border-radius: 8px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
  z-index: 2;
}
.day-bar-col:hover .day-bar-tooltip,
.day-bar-tooltip.is-visible {
  opacity: 1;
}

.icon-16 svg {
  width: 16px;
  height: 16px;
}

.icon-18 svg {
  width: 18px;
  height: 18px;
}

.icon-20 svg {
  width: 20px;
  height: 20px;
}

.icon-32 svg {
  width: 32px;
  height: 32px;
}

.icon-40 svg {
  width: 40px;
  height: 40px;
}

.has-dot {
  position: relative;
}

.has-dot::after {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #64d99c;
  content: "";
}

.section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 12px 0 12px;
}

.section-head h2 {
  margin: 0;
  font-size: 19px;
  letter-spacing: 0;
}

.settings-section h2 {
  margin: 0 0 12px 4px;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: 0;
  color: var(--color-ink);
}

.section-head button {
  color: #0062a6;
  font-size: 13px;
  font-weight: 700;
}

.bottom-nav {
  position: relative;
  flex-shrink: 0;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  align-items: end;
  height: 78px;
  padding: 8px 12px 12px;
  border-top: 1px solid rgba(8, 20, 47, 0.08);
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(18px);
}

.nav-item {
  display: grid;
  justify-items: center;
  gap: 4px;
  min-width: 0;
  color: #3d475b;
  font-size: 11px;
  transition: color 0.3s cubic-bezier(0.4, 0.0, 0.2, 1), transform 0.2s ease;
}

.nav-item:active {
  transform: scale(0.95);
}

.nav-item span {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  transition: all 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
}

.nav-item small {
  font-size: 11px;
}

.nav-item.is-active {
  color: var(--color-mint);
}

.nav-item.is-active span svg {
  filter: drop-shadow(0 0 10px rgba(100, 217, 156, 0.8));
}

.nav-item.sell-action span {
  width: 54px;
  height: 54px;
  margin-top: -20px;
  border-radius: 50%;
  background: var(--color-navy);
  color: #fff;
  box-shadow: 0 10px 20px rgba(13, 26, 51, 0.2);
}

.nav-item.sell-action.is-active span {
  background: var(--color-navy);
}

.product-card {
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  background: #fff;
  box-shadow: 0 8px 20px rgba(8, 20, 47, 0.05);
  transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.product-card:active {
  transform: scale(0.96);
}

@media (hover: hover) {
  .product-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 12px 30px rgba(8, 20, 47, 0.12);
  }
}

.product-art {
  position: relative;
  height: 132px;
  overflow: hidden;
  background: #f4f6f8;
}

.product-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
}

@media (hover: hover) {
  .product-card:hover .product-art img {
    transform: scale(1.05);
  }
}

.heart {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  color: #4a5b73;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
  transition: transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.heart svg {
  width: 18px;
  height: 18px;
}

.photo-count-badge {
  position: absolute;
  top: 10px;
  left: 10px;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 5px 9px;
  border-radius: 999px;
  background: rgba(15, 23, 42, 0.65);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
}

.heart:active {
  transform: scale(0.8);
}

.heart-unfilled {
  display: block;
}

.heart-filled {
  display: none;
}

.liked .heart-unfilled {
  display: none;
}

.liked .heart-filled {
  display: block;
  color: #09834c;
  animation: heartPop 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

@keyframes heartPop {
  0% { transform: scale(0.5); opacity: 0.5; }
  50% { transform: scale(1.2); }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes slideUpFade {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}

.chat-bubble-anim > div {
  animation: slideUpFade 0.4s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
  opacity: 0;
}
.chat-bubble-anim > div:nth-child(1) { animation-delay: 0.05s; }
.chat-bubble-anim > div:nth-child(2) { animation-delay: 0.1s; }
.chat-bubble-anim > div:nth-child(3) { animation-delay: 0.15s; }
.chat-bubble-anim > div:nth-child(4) { animation-delay: 0.2s; }
.chat-bubble-anim > div:nth-child(5) { animation-delay: 0.25s; }
.chat-bubble-anim > div:nth-child(6) { animation-delay: 0.3s; }
.chat-bubble-anim > div:nth-child(7) { animation-delay: 0.35s; }

/* A single bubble appended live (new message arriving, or one I just
   sent) — no stagger, plays immediately regardless of its position in
   the list, since only that one bubble is actually new to the DOM. */
@keyframes msgBubbleIn {
  from { opacity: 0; transform: translateY(14px) scale(0.96); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
.chat-bubble-anim > div.msg-bubble-new {
  animation: msgBubbleIn 0.28s cubic-bezier(0.2, 0.8, 0.2, 1) both;
  animation-delay: 0s;
}

.draw-tool-btn.is-active {
  background: #009b61 !important;
}
.draw-color-dot {
  transform: scale(0.85);
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.draw-color-dot.is-active {
  transform: scale(1.05);
  border-color: #fff !important;
}

.badge {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 5px 9px;
  border-radius: 999px;
  background: #b8f3d5;
  color: var(--color-ink);
  font-size: 11px;
  font-weight: 700;
}

.product-copy {
  padding: 12px;
}

.product-copy h3,
.compact-row h3,
.order-card h3 {
  margin: 0 0 6px;
  font-size: 14px;
}

.product-copy strong,
.compact-row strong,
.order-card strong {
  color: #007d4d;
  font-size: 14px;
}

.product-copy p,
.compact-row p,
.order-card p,
.order-card small {
  margin: 5px 0 0;
  color: var(--color-muted);
  font-size: 12px;
}

/* tones removed */

.menu-card,
.privacy-card {
  overflow: hidden;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  background: #fff;
  box-shadow: 0 8px 22px rgba(8, 20, 47, 0.05);
}

.menu-card button,
.toggle-row {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 18px 16px;
  border-bottom: 1px solid var(--color-line);
  text-align: left;
  background: transparent;
  border-radius: 0;
  border-left: none;
  border-right: none;
  border-top: none;
}

.menu-card button:last-child,
.toggle-row:last-child {
  border-bottom: 0;
}

.menu-card button svg,
.toggle-row svg {
  width: 22px;
  height: 22px;
  color: var(--color-ink);
}

.menu-card button.danger {
  color: #d62a2a;
}

.menu-card button.danger svg {
  color: #d62a2a;
}

.menu-card button .chevron svg {
  color: #c4cdd5;
  width: 20px;
  height: 20px;
  margin-left: auto;
}

.menu-card span,
.toggle-row span {
  display: grid;
  gap: 3px;
  font-size: 14px;
  font-weight: 700;
  color: var(--color-ink);
}

.menu-card small,
.toggle-row small {
  color: var(--color-muted);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.35;
}

.primary-button {
  display: grid;
  place-items: center;
  width: 100%;
  min-height: 50px;
  border-radius: 12px;
  background: linear-gradient(180deg, #44c982, #17b464);
  color: #fff;
  font-weight: 800;
}

.primary-button.outline {
  border: 1px solid var(--color-mint);
  background: #fff;
  color: var(--color-mint-dark);
}

/* grid-template-rows 0fr -> 1fr instead of animating max-height: max-height
   forces the browser to recompute layout on every animation frame (cost
   scales with how much text is inside), which is what made long accordion
   items — like these Terms/Privacy clauses — visibly stutter on opening.
   This grid trick animates smoothly without that per-frame layout cost,
   and doesn't need JS to read scrollHeight (which was itself forcing a
   synchronous layout flush mid-way through the click handler). */
.accordion-content {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  transition: grid-template-rows 0.35s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.accordion-content.is-open {
  grid-template-rows: 1fr;
}

.accordion-content-inner {
  min-height: 0; /* lets a grid child actually shrink to the 0fr row */
  overflow: hidden;
  /* padding-bottom starts at 0, not 20px — a fixed bottom padding here
     would occupy real space even while the row above is collapsed to
     0fr, since padding isn't part of what min-height:0 can shrink away.
     That's what left one line of every clause peeking out below the
     accordion header instead of fully hiding it. Animating it in step
     with grid-template-rows keeps the open/close motion still feeling
     like one smooth movement. */
  padding: 0 20px 0;
  font-size: 14px;
  color: var(--color-muted);
  line-height: 1.6;
  transition: padding-bottom 0.35s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.accordion-content.is-open .accordion-content-inner {
  padding-bottom: 20px;
}

/* Global Modals & Bottom Sheets */
.modal-backdrop {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.4);
  z-index: 50;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 24px;
}

.bottom-sheet {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: #fff;
  border-radius: 24px 24px 0 0;
  z-index: 60;
  /* Without env(safe-area-inset-bottom), the last row of buttons sits
     right where iOS's home-indicator swipe bar overlaps fixed-to-bottom
     content — on a phone with no physical home button that reads as the
     sheet's own bottom edge getting visually "eaten" by the system bar
     instead of clearing it, the same way this same padding-bottom pattern
     already protects app.js's own scroll-lock math elsewhere. */
  padding: 24px 16px calc(32px + env(safe-area-inset-bottom, 0px));
  /* A little past 100% of its own height, not exactly 100% — Safari's own
     toolbar show/hide recalculates 100dvh (and this app's .screen-root
     height with it) on real phones far more aggressively than desktop
     Chrome ever does, and if that lands mid-transition while this closed
     transform is being computed, an exact 100% can leave a sliver of the
     sheet on-screen instead of fully hidden. This extra margin is a no-op
     visually either way, closed still just means "off-screen".  */
  transform: translateY(calc(100% + 60px));
  transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
  box-shadow: 0 -10px 40px rgba(0,0,0,0.1);
}

.centered-modal {
  background: #fff;
  border-radius: 24px;
  width: 100%;
  max-width: 360px;
  padding: 24px;
  transform: scale(0.95);
  opacity: 0;
  pointer-events: none;
  transition: all 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
  position: relative;
  text-align: center;
}

.modal-close-btn {
  position: absolute;
  top: 16px;
  right: 16px;
  padding: 4px;
  border: none;
  background: none;
  color: var(--color-ink);
  cursor: pointer;
}

.btn-solid, .btn-outline, .btn-danger {
  width: 100%;
  padding: 16px;
  border-radius: 12px;
  font-weight: 800;
  font-size: 15px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.btn-solid {
  border: none;
  background: #009b61;
  color: #fff;
}

.btn-outline {
  border: 1px solid #009b61;
  background: #fff;
  color: #009b61;
}

.btn-danger {
  border: 1px solid #d62a2a;
  background: #fff;
  color: #d62a2a;
}

.text-clamp {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

.text-clamp.is-expanded {
  -webkit-line-clamp: 99;
}

.read-more-btn span::before {
  content: 'Ver más';
}

.read-more-btn.is-active span::before {
  content: 'Ver menos';
}

.read-more-btn svg {
  transition: transform 0.3s ease;
}

.read-more-btn.is-active svg {
  transform: rotate(180deg);
}

/* Chat Actions Menu */
.chat-actions-menu {
  position: absolute;
  bottom: 64px;
  left: 16px;
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 8px 30px rgba(0,0,0,0.12);
  width: 280px;
  padding: 8px 0;
  display: flex;
  flex-direction: column;
  transform: scale(0.95);
  opacity: 0;
  pointer-events: none;
  transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  transform-origin: bottom left;
  z-index: 100;
}
.chat-actions-menu.is-open {
  transform: scale(1);
  opacity: 1;
  pointer-events: auto;
}
.order-tracker-dropdown {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 8px 30px rgba(0,0,0,0.12);
  width: 300px;
  padding: 16px;
  transform: scale(0.95) translateY(-6px);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.2s ease;
  transform-origin: top right;
  z-index: 20;
}
.order-tracker-dropdown.is-open {
  transform: scale(1) translateY(0);
  opacity: 1;
  pointer-events: auto;
}
.share-loc-center-pin {
  /* No longer flex column, relies on absolute positioning for the shadow */
}
/* Two different curves on purpose: lifting off (is-dragging applied) is
   quick and snappy, like the pin gets yanked up the instant a drag
   starts; settling back down (is-dragging removed, so THIS base rule's
   transition is what plays) uses the same bouncy overshoot curve as the
   chat's swipe-to-reply snap-back, so it reads as landing with a little
   weight instead of just stopping. */
.share-loc-center-pin-icon {
  transition: transform 0.32s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.share-loc-center-pin-shadow {
  width: 22px;
  height: 8px;
  border-radius: 50%;
  background: rgba(0,0,0,0.32);
  position: absolute;
  bottom: -4px;
  left: 50%;
  transform: translateX(-50%) scale(1);
  transition: transform 0.32s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.32s ease;
}
/* Lifts the pin (with a slight grow) and shrinks/fades its shadow while
   the map is being dragged underneath it — the same "picked up" feedback
   Uber/DiDi-style pickup pins give, so it reads as an active drag instead
   of a static icon. */
.share-loc-center-pin.is-dragging .share-loc-center-pin-icon {
  transform: translateY(-20px) scale(1.1);
  transition: transform 0.15s ease-out;
}
.share-loc-center-pin.is-dragging .share-loc-center-pin-shadow {
  transform: translateX(-50%) scale(0.5);
  opacity: 0.35;
  transition: transform 0.15s ease-out, opacity 0.15s ease-out;
}
.order-tracker-minitab {
  position: fixed;
  /* .screen-root itself establishes the containing block for every fixed
     element on the page (see its own transform: translateZ(0)) — this
     "right" only ever needs to dock to THAT box's own edge, not the true
     browser window. It used to compute an offset from 100vw (the real,
     un-clipped viewport) and apply it inside a box already capped at
     480px wide, which landed it floating out in the middle of the chat
     on any screen wider than 480px instead of docked to the edge. */
  right: 0;
  top: 50%;
  transform: translate(100%, -50%);
  background: #009b61;
  color: #fff;
  border: none;
  width: 28px;
  height: 48px;
  border-radius: 12px 0 0 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: -2px 0 10px rgba(0,0,0,0.12);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.25s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.25s ease;
  z-index: 20;
}
.order-tracker-mini.toggle.is-on::after {
  transform: translate(16px, -50%);
}

.custom-datetime-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  padding: 12px 16px;
  border: 1px solid var(--color-line);
  border-radius: 12px;
  background: #fff;
}

.native-datetime-input {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  box-sizing: border-box;
}

.native-datetime-input::-webkit-calendar-picker-indicator {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}
.order-tracker-minitab.is-open {
  transform: translate(0, -50%);
  opacity: 1;
  pointer-events: auto;
}
.order-tracker-dropdown::before {
  content: '';
  position: absolute;
  top: -6px;
  right: 20px;
  width: 12px;
  height: 12px;
  background: #fff;
  transform: rotate(45deg);
  box-shadow: -3px -3px 6px rgba(0,0,0,0.03);
}
.chat-action-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  cursor: pointer;
  transition: background 0.15s;
}
.chat-action-item:active {
  background: #f5f7fa;
}
.chat-action-icon {
  width: 40px;
  height: 40px;
  background: #f0fdf4;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.chat-action-icon svg {
  width: 20px;
  height: 20px;
}
.chat-action-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.chat-action-text strong {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-ink);
}
.chat-action-text small {
  font-size: 12px;
  color: var(--color-muted);
  line-height: 1.2;
}
.chat-action-item > svg {
  width: 16px;
  height: 16px;
  color: var(--color-muted);
}

/* ShinyText Animation (DesignPro) — the moving "shine" is the CONTRAST
   between the gradient's outer color and its middle stop, not the
   animation itself. #00d686 vs. --color-mint (#43c781) are two almost
   identical mid-tone greens, so the sweep was technically animating the
   whole time but read as "just static green" — no visible highlight band
   to actually catch the eye as it moved. A real pale near-white peak in
   the middle (matching how Stripe Link's own reference example does it)
   is what makes the sweep actually visible, moving across a green base
   instead of green sliding across slightly-different green. */
.shiny-text {
  background: linear-gradient(100deg, var(--color-mint) 20%, #eafff5 50%, var(--color-mint) 80%);
  background-size: 200% auto;
  color: transparent;
  -webkit-background-clip: text;
  background-clip: text;
  animation: shine 2.2s linear infinite;
}
@keyframes shine {
  to { background-position: -200% center; }
}

/* Liquid Glass Button (Vesper-inspired but Mint) */
.liquid-btn {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: linear-gradient(135deg, var(--color-mint) 0%, #007a4c 100%);
  color: #fff !important;
  box-shadow: 
    inset 0 1px 0 rgba(255,255,255,0.3),
    0 4px 14px rgba(0, 155, 97, 0.3) !important;
  transition: transform 0.3s, box-shadow 0.3s;
  border: none !important;
}
.liquid-btn::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
  transform: translateX(-100%);
  transition: transform 0.6s ease;
}
.liquid-btn:hover {
  transform: translateY(-2px);
  box-shadow: 
    inset 0 1px 0 rgba(255,255,255,0.4),
    0 6px 20px rgba(0, 155, 97, 0.4) !important;
}
.liquid-btn:hover::before {
  transform: translateX(100%);
}
