/* Fahad AI Shopping Assistant Widget */

:root {
	--chatbot-accent:      #2563eb;
	--chatbot-accent-dark: #1d4ed8;
	/* Foreground for text/icons on accent backgrounds. JS overrides this with the
	   higher-contrast of black/white for the configured accent (>=4.5:1 across the
	   whole gamut); the literal here is the fallback for the default accent. */
	--chatbot-accent-fg:   #ffffff;
	--chatbot-bg:          #ffffff;
	--chatbot-border:      #e5e7eb;
	--chatbot-text:        #111827;
	/* #646b76 = 4.88:1 on the bot bubble (#f3f4f6) so muted text clears AA 4.5:1
	   for normal text; was #6b7280 (4.39:1, just under). */
	--chatbot-muted:       #646b76;
	--chatbot-bot-bubble:  #f3f4f6;
	--chatbot-user-bubble: var(--chatbot-accent);
	--chatbot-user-text:   var(--chatbot-accent-fg);
	--chatbot-radius:      16px;
	--chatbot-z:           9999;
}

/* ── Toggle button ── */
#chatbot-toggle {
	position:      fixed;
	bottom:        24px;
	right:         24px;
	width:         56px;
	height:        56px;
	border-radius: 50%;
	background:    var(--chatbot-accent);
	color:         var(--chatbot-accent-fg);
	border:        none;
	cursor:        pointer;
	display:       flex;
	align-items:   center;
	justify-content: center;
	box-shadow:    0 4px 14px rgba(0, 0, 0, .22);
	z-index:       var(--chatbot-z);
}

#chatbot-toggle:hover {
	background: var(--chatbot-accent-dark);
}

/* High-contrast, accent-independent focus ring: a dark ring plus a white offset
   so it is visible on any accent/background (WCAG 2.4.7 / 2.4.11). */
#chatbot-toggle:focus-visible {
	outline:        2px solid #1a1a1a;
	outline-offset: 2px;
	box-shadow:     0 4px 14px rgba(0, 0, 0, .22), 0 0 0 4px #ffffff, 0 0 0 6px #1a1a1a;
}

@media (prefers-reduced-motion: no-preference) {
	#chatbot-toggle        { transition: background .2s, transform .2s; }
	#chatbot-toggle:hover  { transform: scale(1.06); }
}

/* ── Panel ── */
#chatbot-panel {
	position:       fixed;
	bottom:         92px;
	right:          24px;
	width:          360px;
	height:         520px;
	/* Never taller than the viewport (e.g. a landscape phone or a short desktop
	   window), which would push the header + close button off the top of the screen
	   and make the chat impossible to close. Cap to the visible height minus the
	   bottom offset and a little top breathing room. dvh tracks the mobile URL bar;
	   the vh line is the fallback. The fullscreen mobile rule resets this. (#126) */
	max-height:     calc(100vh - 112px);
	max-height:     calc(100dvh - 112px);
	background:     var(--chatbot-bg);
	border:         1px solid var(--chatbot-border);
	border-radius:  var(--chatbot-radius);
	box-shadow:     0 8px 32px rgba(0, 0, 0, .15);
	display:        flex;
	flex-direction: column;
	z-index:        var(--chatbot-z);
	overflow:       hidden;
}

@media (prefers-reduced-motion: no-preference) {
	#chatbot-panel { transition: opacity .2s, transform .2s; }
}

/* The closed panel is also given the `inert` attribute in JS, which removes it
   and its controls from the keyboard tab order and from assistive tech, so focus
   cannot land on the hidden input (WCAG 2.4.3 / 4.1.2). Using `inert` rather than
   `visibility:hidden` keeps the open animation while not delaying focusability of
   the controls when the panel is revealed. */
#chatbot-panel.chatbot-hidden {
	opacity:        0;
	pointer-events: none;
	transform:      translateY(12px);
}

/* Defensive: a stale/un-inert-ed hidden panel (e.g. inert unsupported) must still
   not capture clicks. inert handles keyboard/AT; this covers pointer. */
#chatbot-panel[inert] {
	pointer-events: none;
}

/* ── Header ── */
#chatbot-header {
	background:      var(--chatbot-accent);
	color:           var(--chatbot-accent-fg);
	padding:         14px 16px;
	display:         flex;
	align-items:     center;
	justify-content: space-between;
	flex-shrink:     0;
}

#chatbot-header-left {
	display:     flex;
	align-items: center;
	gap:         10px;
}

#chatbot-status-dot {
	width:         8px;
	height:        8px;
	background:    #4ade80;
	border-radius: 50%;
	flex-shrink:   0;
}

#chatbot-bot-name {
	font-weight: 600;
	font-size:   15px;
	line-height: 1;
}

/* Full-opacity accent-fg (no alpha dimming) so the glyph keeps maximum contrast
   on the accent background. Hover uses a subtle translucent backdrop instead. */
#chatbot-close {
	background:    none;
	border:        none;
	color:         var(--chatbot-accent-fg);
	cursor:        pointer;
	font-size:     18px;
	line-height:   1;
	padding:       4px;
	margin:        -4px;
	border-radius: 6px;
	display:       flex;
	align-items:   center;
}

#chatbot-close:hover {
	background: rgba(127, 127, 127, .25);
}

#chatbot-close:focus-visible {
	outline:        2px solid var(--chatbot-accent-fg);
	outline-offset: 1px;
}

/* ── Messages ── */
#chatbot-messages {
	flex:           1;
	overflow-y:     auto;
	padding:        16px;
	display:        flex;
	flex-direction: column;
	gap:            10px;
}

@media (prefers-reduced-motion: no-preference) {
	#chatbot-messages { scroll-behavior: smooth; }
}

/* Column layout so anything appended after the bubble, the reply-feedback 👍/👎
   toolbar (#50), in particular, stacks BELOW it instead of being squeezed into a
   flex row to the right of the bubble. align-items keeps each message's content on
   its own side (bot left, user right). (#127) */
.chatbot-msg {
	display:        flex;
	flex-direction: column;
	max-width:      82%;
}

.chatbot-msg.bot  { align-self: flex-start; align-items: flex-start; }
.chatbot-msg.user { align-self: flex-end;   align-items: flex-end;   }

.chatbot-bubble {
	padding:     10px 14px;
	border-radius: 14px;
	font-size:   14px;
	line-height: 1.55;
	word-break:  break-word;
	white-space: pre-wrap;
}

.chatbot-msg.bot  .chatbot-bubble {
	background:             var(--chatbot-bot-bubble);
	color:                  var(--chatbot-text);
	border-bottom-left-radius: 4px;
}

.chatbot-msg.user .chatbot-bubble {
	background:              var(--chatbot-user-bubble);
	color:                   var(--chatbot-user-text);
	border-bottom-right-radius: 4px;
}

/* ── Typing indicator ── */
.chatbot-typing {
	display:     flex;
	align-items: center;
	gap:         5px;
	padding:     12px 14px;
}

.chatbot-typing span {
	width:         7px;
	height:        7px;
	background:    #6b7280;
	border-radius: 50%;
}

/* Animate the typing dots only when motion is allowed; under reduced-motion the
   three dots remain as a static "typing" affordance (WCAG 2.3.3). */
@media (prefers-reduced-motion: no-preference) {
	.chatbot-typing span {
		animation: chatbot-bounce 1.2s infinite ease-in-out;
	}

	.chatbot-typing span:nth-child(2) { animation-delay: .2s; }
	.chatbot-typing span:nth-child(3) { animation-delay: .4s; }

	@keyframes chatbot-bounce {
		0%, 60%, 100% { transform: translateY(0); }
		30%           { transform: translateY(-6px); }
	}
}

/* ── Input area ── */
#chatbot-input-area {
	padding:      10px 12px;
	border-top:   1px solid var(--chatbot-border);
	display:      flex;
	gap:          8px;
	align-items:  center;
	flex-shrink:  0;
}

#chatbot-input {
	flex:          1;
	padding:       9px 13px;
	border:        1px solid var(--chatbot-border);
	border-radius: 8px;
	/* 16px (not 14px): iOS Safari auto-zooms the page when a focused input is under
	   16px and never zooms back, leaving the widget oversized/misaligned. (#128) */
	font-size:     16px;
	font-family:   inherit;
	outline:       none;
	background:    var(--chatbot-bg);
	color:         var(--chatbot-text);
}

@media (prefers-reduced-motion: no-preference) {
	#chatbot-input { transition: border-color .15s, box-shadow .15s; }
}

/* Visible focus indicator that does not depend on the (configurable) accent
   meeting contrast: a dark ring is always perceivable (WCAG 2.4.7). */
#chatbot-input:focus-visible {
	border-color: var(--chatbot-accent);
	box-shadow:   0 0 0 2px #ffffff, 0 0 0 4px #1a1a1a;
}

#chatbot-send {
	width:         38px;
	height:        38px;
	flex-shrink:   0;
	background:    var(--chatbot-accent);
	color:         var(--chatbot-accent-fg);
	border:        none;
	border-radius: 8px;
	cursor:        pointer;
	display:       flex;
	align-items:   center;
	justify-content: center;
}

@media (prefers-reduced-motion: no-preference) {
	#chatbot-send { transition: background .15s; }
}

#chatbot-send:hover  { background: var(--chatbot-accent-dark); }

#chatbot-send:focus-visible {
	outline:        2px solid #1a1a1a;
	outline-offset: 2px;
	box-shadow:     0 0 0 4px #ffffff, 0 0 0 6px #1a1a1a;
}

#chatbot-send:disabled {
	opacity: .5;
	cursor:  not-allowed;
}

/* ── Tool status indicator (shown mid-stream while a tool runs) ── */
.chatbot-bubble.chatbot-tool-status {
	color:       var(--chatbot-muted);
	font-style:  italic;
	font-size:   13px;
}

/* ── Mobile ── */
@media (max-width: 480px) {
	#chatbot-panel {
		right:         0;
		bottom:        0;
		width:         100%;
		/* dvh tracks the dynamic mobile URL bar so the input is never pushed below
		   the visible area; vh is the fallback. max-height:none overrides the
		   floating-panel cap, fullscreen owns the full height here. (#129) */
		height:        100vh;
		height:        100dvh;
		max-height:    none;
		border-radius: 0;
		border:        none;
	}

	/* Keep the header clear of the status bar / notch and the input clear of the
	   home indicator on notched phones (iOS safe areas; needs viewport-fit=cover,
	   which the plugin sets via the theme's viewport meta). (#129) */
	#chatbot-header {
		padding-top: calc(14px + env(safe-area-inset-top));
	}

	#chatbot-input-area {
		padding-bottom: calc(10px + env(safe-area-inset-bottom));
	}

	#chatbot-toggle {
		bottom: calc(16px + env(safe-area-inset-bottom));
		right:  16px;
	}
}

/* ── In-chat links ────────────────────────────────────────────────────────── */
.chatbot-bubble .chatbot-link {
	color:           var(--chatbot-accent);
	text-decoration: underline;
	text-underline-offset: 2px;
	font-weight:     500;
	word-break:      break-word;
}

.chatbot-bubble .chatbot-link:hover {
	opacity: 0.8;
}

/* ── Product cards ─────────────────────────────────────────────────────────── */
.chatbot-cards-msg {
	max-width: 100%;
	width:     100%;
}

.chatbot-products {
	display:        flex;
	flex-direction: column;
	gap:            8px;
	width:          100%;
}

.chatbot-card {
	display:       flex;
	gap:           10px;
	padding:       10px;
	border:        1px solid var(--chatbot-border);
	border-radius: 12px;
	background:    #fff;
}

.chatbot-card-img {
	width:         64px;
	height:        64px;
	flex-shrink:   0;
	border-radius: 8px;
	object-fit:    cover;
	background:    var(--chatbot-bot-bubble);
}

.chatbot-card-body {
	flex:           1;
	min-width:      0;
	display:        flex;
	flex-direction: column;
	gap:            3px;
}

.chatbot-card-title {
	font-weight:     600;
	font-size:       14px;
	line-height:     1.3;
	color:           var(--chatbot-text);
	text-decoration: none;
	word-break:      break-word;
}

a.chatbot-card-title:hover {
	color: var(--chatbot-accent);
}

.chatbot-card-price {
	font-size:   13px;
	font-weight: 600;
	color:       var(--chatbot-text);
}

.chatbot-card-price .was {
	margin-right:    6px;
	font-weight:     400;
	color:           var(--chatbot-muted);
	text-decoration: line-through;
}

/* ── Star rating (issue #11) ──────────────────────────────────────────────────
   ★avg (count), shown only when the product has reviews (the element is omitted
   in JS otherwise). The filled overlay is clipped to (avg/5)*100% over a grey
   base so fractional ratings render precisely with just the ★ glyph. */
.chatbot-card-rating {
	display:     flex;
	align-items: center;
	gap:         5px;
	font-size:   12px;
	line-height: 1;
}

.chatbot-card-stars {
	position:       relative;
	display:        inline-block;
	white-space:    nowrap;
	font-size:      13px;
	line-height:    1;
	/* Empty (base) stars colour. */
	color:          #d1d5db;
}

.chatbot-card-stars-empty {
	display: block;
}

.chatbot-card-stars-filled {
	position:    absolute;
	top:         0;
	left:        0;
	overflow:    hidden;
	white-space: nowrap;
	/* #b45309 (amber-700) = 4.8:1 on the white card so the filled stars are not a
	   colour-only signal failing contrast; the numeric "4.5 (24)" text and the
	   aria-label also convey the value (WCAG 1.4.1 / 1.4.11). */
	color:       #b45309;
}

.chatbot-card-rating-text {
	color:       var(--chatbot-muted);
	font-weight: 600;
}

.chatbot-card-stock {
	font-size: 11px;
	color:     #15803d;
}

.chatbot-card-stock.out {
	color: #b91c1c;
}

.chatbot-card-desc {
	font-size:           12px;
	line-height:         1.4;
	color:               var(--chatbot-muted);
	display:             -webkit-box;
	-webkit-line-clamp:  2;
	line-clamp:          2;
	-webkit-box-orient:  vertical;
	overflow:            hidden;
}

/* ── Variation selector (issue #12) ───────────────────────────────────────────
   A labelled <select> for variable products. The label is a real, associated
   <label> (for/id) so the control has an accessible name; the focus ring matches
   the card buttons' accent-independent dark ring on a white spacer (WCAG 2.4.7). */
.chatbot-card-var-label {
	display:     block;
	margin-top:  5px;
	font-size:   11px;
	font-weight: 600;
	color:       var(--chatbot-muted);
}

.chatbot-card-var-select {
	margin-top:    3px;
	width:         100%;
	max-width:     100%;
	box-sizing:    border-box;
	padding:       5px 8px;
	font-size:     12px;
	line-height:   1.4;
	color:         var(--chatbot-text);
	background:    #fff;
	border:        1px solid var(--chatbot-border);
	border-radius: 7px;
	cursor:        pointer;
}

.chatbot-card-var-select:focus-visible {
	outline:        2px solid #1a1a1a;
	outline-offset: 2px;
	box-shadow:     0 0 0 4px #ffffff;
}

.chatbot-card-actions {
	display:     flex;
	gap:         8px;
	margin-top:  5px;
}

.chatbot-card-view,
.chatbot-card-add {
	font-size:       12px;
	font-weight:     500;
	padding:         5px 12px;
	border-radius:   7px;
	cursor:          pointer;
	text-decoration: none;
	line-height:     1.4;
}

/* Shared visible focus indicator for the card controls, accent-independent dark
   ring on a white spacer so it is perceivable on any accent (WCAG 2.4.7). */
.chatbot-card-view:focus-visible,
.chatbot-card-add:focus-visible {
	outline:        2px solid #1a1a1a;
	outline-offset: 2px;
	box-shadow:     0 0 0 4px #ffffff;
}

.chatbot-card-view {
	color:      var(--chatbot-accent);
	background: transparent;
	border:     1px solid var(--chatbot-border);
}

.chatbot-card-view:hover {
	border-color: var(--chatbot-accent);
}

.chatbot-card-add {
	color:      var(--chatbot-accent-fg);
	background: var(--chatbot-accent);
	border:     1px solid var(--chatbot-accent);
}

.chatbot-card-add:hover {
	background: var(--chatbot-accent-dark);
}

.chatbot-card-stock-icon {
	font-weight: 700;
}

/* ── Comparison table (issue #13) ──────────────────────────────────────────────
   A real <table> rendered side-by-side. The scroll wrapper keeps a wide table from
   breaking the narrow chat panel: it scrolls horizontally on small screens and is a
   focusable, labelled region so it is keyboard-scrollable (WCAG 2.1.1 / 1.4.10). */
.chatbot-compare-scroll {
	width:           100%;
	max-width:       100%;
	overflow-x:      auto;
	-webkit-overflow-scrolling: touch;
	border:          1px solid var(--chatbot-border);
	border-radius:   12px;
	background:      #fff;
}

/* Accent-independent dark focus ring so the scrollable region's focus is always
   perceivable (WCAG 2.4.7), matching the card controls. */
.chatbot-compare-scroll:focus-visible {
	outline:        2px solid #1a1a1a;
	outline-offset: 2px;
	box-shadow:     0 0 0 4px #ffffff;
}

.chatbot-compare {
	border-collapse: collapse;
	width:           100%;
	/* Give each column room; the wrapper scrolls if the total exceeds the panel. */
	min-width:       max-content;
	font-size:       12px;
	line-height:     1.4;
	color:           var(--chatbot-text);
}

/* Caption conveys the table's purpose to AT; visually small and muted. */
.chatbot-compare-caption {
	caption-side:  top;
	text-align:    left;
	padding:       8px 10px 6px;
	font-size:     11px;
	font-weight:   600;
	color:         var(--chatbot-muted);
}

.chatbot-compare th,
.chatbot-compare td {
	padding:       7px 10px;
	text-align:    left;
	vertical-align: top;
	border-bottom: 1px solid var(--chatbot-border);
	/* Keep cells from collapsing too narrow while still allowing wrap on long values. */
	min-width:     84px;
}

/* Column headers (the products), emphasised, with a subtle fill. The row headers
   (attribute names) sit in the first column, also emphasised. */
.chatbot-compare thead th,
.chatbot-compare-corner {
	background:    var(--chatbot-bot-bubble);
	font-weight:   600;
}

.chatbot-compare-rowhead {
	background:    var(--chatbot-bot-bubble);
	font-weight:   600;
	white-space:   nowrap;
}

.chatbot-compare-name {
	color:           var(--chatbot-text);
	text-decoration: none;
	font-weight:     600;
	word-break:      break-word;
}

a.chatbot-compare-name {
	color: var(--chatbot-accent);
}

a.chatbot-compare-name:hover {
	text-decoration: underline;
}

.chatbot-compare-cell .was {
	margin-right:    6px;
	font-weight:     400;
	color:           var(--chatbot-muted);
	text-decoration: line-through;
}

/* Actions cell: stack the View / Add controls so they stay tappable in a narrow
   column. They reuse the card button styles (.chatbot-card-view / -add). */
.chatbot-compare-actions {
	white-space: normal;
}

.chatbot-compare-actions .chatbot-card-view,
.chatbot-compare-actions .chatbot-card-add {
	display:     inline-block;
	margin:      2px 4px 2px 0;
}

/* ── Reply feedback / thumbs (#50) ────────────────────────────────────────────
   A small toolbar appended under a finalized bot reply: a muted prompt + two real
   toggle buttons (👍/👎). The selected state is conveyed by border weight + a
   background tint AND the aria-pressed state AND which glyph was chosen, never by
   colour alone (WCAG 1.4.1). The muted prompt uses --chatbot-muted (>=4.5:1). */
.chatbot-feedback {
	display:     flex;
	align-items: center;
	gap:         6px;
	margin:      4px 0 2px 2px;
	flex-wrap:   wrap;
}

.chatbot-feedback-prompt,
.chatbot-feedback-status {
	font-size: 12px;
	color:     var(--chatbot-muted);
}

.chatbot-feedback-btn {
	display:         inline-flex;
	align-items:     center;
	justify-content: center;
	min-width:       32px;
	min-height:      32px;
	padding:         2px 6px;
	font-size:       14px;
	line-height:     1;
	background:      transparent;
	border:          1px solid var(--chatbot-border);
	border-radius:   7px;
	cursor:          pointer;
}

.chatbot-feedback-btn:hover:not([disabled]) {
	border-color: var(--chatbot-accent);
}

/* Accent-independent dark focus ring on a white spacer, perceivable on any accent
   (matches the card controls, WCAG 2.4.7). */
.chatbot-feedback-btn:focus-visible {
	outline:        2px solid #1a1a1a;
	outline-offset: 2px;
	box-shadow:     0 0 0 4px #ffffff;
}

/* Chosen rating: heavier accent border + tint. Not colour-alone, the disabled
   state, the aria-pressed value, and the picked glyph also signal the selection. */
.chatbot-feedback-btn.is-selected {
	border-color: var(--chatbot-accent);
	border-width: 2px;
	background:   var(--chatbot-bot-bubble);
}

.chatbot-feedback-btn[disabled] {
	cursor:  default;
	opacity: 1; /* keep contrast, don't grey out the chosen toggle */
}

/* The unpicked button fades once a choice is made so the selection reads clearly. */
.chatbot-feedback-btn[disabled]:not(.is-selected) {
	opacity: .45;
}

/* ── Proactive nudge (issue #65) ──────────────────────────────────────────────
   A small, dismissible card anchored just above the toggle. Shown ONLY when the
   server supplied a grounded value signal; the copy is honest (no urgency) and the
   controls are real, keyboard-operable buttons. */
#chatbot-nudge {
	position:       fixed;
	bottom:         92px;
	right:          24px;
	width:          300px;
	max-width:      calc(100vw - 48px);
	background:     var(--chatbot-bg);
	color:          var(--chatbot-text);
	border:         1px solid var(--chatbot-border);
	border-radius:  var(--chatbot-radius);
	box-shadow:     0 8px 32px rgba(0, 0, 0, .15);
	padding:        14px 16px;
	z-index:        var(--chatbot-z);
}

@media (prefers-reduced-motion: no-preference) {
	#chatbot-nudge {
		animation: chatbot-nudge-in .2s ease-out;
	}
}

@keyframes chatbot-nudge-in {
	from { opacity: 0; transform: translateY(8px); }
	to   { opacity: 1; transform: translateY(0); }
}

.chatbot-nudge-text {
	margin:      0 0 10px;
	font-size:   14px;
	line-height: 1.4;
}

.chatbot-nudge-actions {
	display:     flex;
	align-items: center;
	gap:         8px;
}

.chatbot-nudge-open {
	flex:          1 1 auto;
	background:    var(--chatbot-accent);
	color:         var(--chatbot-accent-fg);
	border:        none;
	border-radius: 8px;
	padding:       8px 12px;
	font-size:     13px;
	font-weight:   600;
	cursor:        pointer;
}

.chatbot-nudge-open:hover { background: var(--chatbot-accent-dark); }

.chatbot-nudge-dismiss {
	flex:          0 0 auto;
	background:    var(--chatbot-bot-bubble);
	color:         var(--chatbot-text);
	border:        1px solid var(--chatbot-border);
	border-radius: 8px;
	width:         32px;
	height:        32px;
	font-size:     14px;
	line-height:   1;
	cursor:        pointer;
}

/* High-contrast, accent-independent focus ring (matches the toggle/feedback
   controls, WCAG 2.4.7 / 2.4.11). */
.chatbot-nudge-open:focus-visible,
.chatbot-nudge-dismiss:focus-visible {
	outline:        2px solid #1a1a1a;
	outline-offset: 2px;
	box-shadow:     0 0 0 4px #ffffff;
}

@media (max-width: 480px) {
	#chatbot-nudge {
		right:  16px;
		bottom: 88px;
		width:  auto;
		left:   16px;
	}
}

/* ── Voice input/output (issue #64) ───────────────────────────────────────────
   The mic (speech-to-text) and speaker (text-to-speech) controls sit in the input
   row, next to Send. Built by JS only when the merchant enabled voice AND the
   browser supports the relevant Web Speech API, so an unsupported browser simply
   never renders them and text works unchanged. Styled to match Send: same size and
   the same accent-independent dark focus ring (WCAG 2.4.7). The active/recording
   state is conveyed by the accent fill AND the aria-pressed state (set in JS), never
   by colour alone (WCAG 1.4.1). */
#chatbot-mic,
#chatbot-speak {
	width:           38px;
	height:          38px;
	flex-shrink:     0;
	background:      transparent;
	color:           var(--chatbot-text);
	border:          1px solid var(--chatbot-border);
	border-radius:   8px;
	cursor:          pointer;
	display:         flex;
	align-items:     center;
	justify-content: center;
}

#chatbot-mic:hover,
#chatbot-speak:hover {
	border-color: var(--chatbot-accent);
}

#chatbot-mic:focus-visible,
#chatbot-speak:focus-visible {
	outline:        2px solid #1a1a1a;
	outline-offset: 2px;
	box-shadow:     0 0 0 4px #ffffff, 0 0 0 6px #1a1a1a;
}

#chatbot-mic:disabled,
#chatbot-speak:disabled {
	opacity: .5;
	cursor:  not-allowed;
}

/* Recording / active: accent fill so the on-state is obvious; the aria-pressed
   attribute carries the same meaning for assistive tech, so the cue is not
   colour-alone. */
#chatbot-mic.is-recording,
#chatbot-speak.is-active {
	background:   var(--chatbot-accent);
	color:        var(--chatbot-accent-fg);
	border-color: var(--chatbot-accent);
}

/* A gentle pulse while recording, purely decorative reinforcement of the on-state,
   and opt-in so it never plays for a reduced-motion user (the reduced-motion catch-all
   below also neutralises it for elements inside the widget root). */
@media (prefers-reduced-motion: no-preference) {
	#chatbot-mic.is-recording {
		animation: chatbot-mic-pulse 1.4s ease-in-out infinite;
	}
}

@keyframes chatbot-mic-pulse {
	0%, 100% { box-shadow: 0 0 0 0 rgba(37, 99, 235, .45); }
	50%      { box-shadow: 0 0 0 5px rgba(37, 99, 235, 0); }
}

/* Visually-hidden but screen-reader-available: the polite live region that announces
   voice status (listening / errors). Standard clip pattern. */
.chatbot-sr-only {
	position:    absolute;
	width:       1px;
	height:      1px;
	padding:     0;
	margin:      -1px;
	overflow:    hidden;
	clip:        rect(0, 0, 0, 0);
	white-space: nowrap;
	border:      0;
}

/* ── Reduced motion safety net ────────────────────────────────────────────────
   Non-essential transitions/animations are opt-in via the no-preference queries
   above; this scoped catch-all neutralises anything that slips through (e.g. a
   theme forcing a transition onto these elements) when the user asks to reduce
   motion (WCAG 2.3.3). */
@media (prefers-reduced-motion: reduce) {
	#fahad-ai-chatbot-root *,
	#chatbot-toggle,
	#chatbot-panel {
		animation-duration:        .001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration:       .001ms !important;
		scroll-behavior:           auto !important;
	}
}
