/* ============================================================================
   MY35 PHARMACY — AI ASSISTANT  ·  PRODUCTION STYLESHEET  (single self-contained)
   ----------------------------------------------------------------------------
   Concatenation, in this exact cascade order, of:
     1) design-system.css   (tokens, primitives, @font-face, ambient keyframes)
     2) widget.css          (component geometry — FAB, panel, bubbles, cards…)
     3) motion.css          (loads AFTER widget.css → equal-specificity wins)
     4) responsive.css      (loads LAST → mobile / safe-area / a11y wins ties)

   FONTS: @font-face src paths are RELATIVE (url('fonts/advent-pro-*.woff2')).
   CSS url() resolves relative to THIS file, so when this stylesheet lives in the
   plugin's assets/ dir next to a fonts/ subdir, the Advent Pro woff2 load works
   with no rewrite needed.

   COMPATIBILITY: the live widget renders the `.my35w-*` namespace. The OLD theme
   CSS may still target `.my35-ai-*` (launcher/input/root). Those legacy selectors
   do not collide here — every rule below is scoped to `.my35w` / `.my35w-*`, so
   the new styles always win for the actual rendered elements. The launcher also
   carries `.my35-ai-launcher` and the field `.my35-ai-input` (compatibility
   aliases set by the JS), but their VISUAL styling comes from `.my35w-fab` /
   `.my35w-field` below — never from a legacy `.my35-ai-*` rule.
   ============================================================================ */


/* ===== design-system.css ===== */
/* ============================================================================
   MY35 PHARMACY — AI ASSISTANT DESIGN SYSTEM
   ----------------------------------------------------------------------------
   VISUAL DIRECTION
   "Warm clinical glass." A modern AI-assistant surface built on layered
   glassmorphism — frosted translucent panels, soft luminous gradients, real
   depth via stacked shadows — but emotionally warmed by the MY35 sunflower
   yellow (#FFC700). It should feel like a premium 2026 AI product (the polish
   of Linear / Arc / Apple Intelligence) yet unmistakably a trusted Greek
   neighbourhood pharmacy since 1982: confident, calm, human.

   Three emotional registers, all driven from these tokens:
     1. CONVERSATION  — light, airy glass, warm yellow accents, friendly depth.
     2. COMMERCE      — clean product surfaces, gentle elevation, clear price ink.
     3. SAFETY        — deliberately NON-glass: solid calm, serious, no sparkle,
                        prominent phone / ΕΚΑΒ. Trust over delight.

   ARCHITECTURE
   This file ships ONLY tokens + base primitives:
     · color / brand ramps        · gradient tokens
     · glass surface tokens        · radius scale
     · spacing scale               · typography scale (Advent Pro + DM Sans)
     · elevation / shadow scale     · z-index scale
     · easing + duration tokens     · light/dark surface vars
     · a thin layer of reusable primitive classes (.ds-glass, .ds-pill …)
   Component LAYOUT (FAB geometry, panel grid, bubble structure) is B2's job.
   Engineers compose these tokens; they do not redefine them.
   ============================================================================ */

/* DM Sans (body) stays from Google Fonts via index.html <link> as a safe fallback. */
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600;9..40,700&display=swap');

/* ----------------------------------------------------------------------------
   0. SELF-HOSTED ADVENT PRO  (the brand display face — variable 100..900)
   Self-hosted woff2 (same subsets/ranges as the production WoodMart-replacement
   theme) so the panel title / eyebrows / welcome render in Advent Pro instead of
   silently falling back to system-ui. font-display:swap keeps first paint fast;
   the Google Fonts Advent Pro is intentionally NOT loaded (self-host is canonical).
   document.fonts.check('600 16px "Advent Pro"') must return true once loaded.
   ---------------------------------------------------------------------------- */
@font-face {
  font-family: 'Advent Pro';
  font-style: normal;
  font-weight: 100 900;          /* variable — covers 400/500/600/700 used in §5 */
  font-display: swap;
  src: url('https://my35pharmacy.gr/wp-content/themes/my35-ultralight/assets/fonts/advent-pro-greek-1.woff2') format('woff2');
  unicode-range: U+0370-03FF, U+1F00-1FFF;   /* Greek + Greek Extended */
}
@font-face {
  font-family: 'Advent Pro';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('https://my35pharmacy.gr/wp-content/themes/my35-ultralight/assets/fonts/advent-pro-latinext-1.woff2') format('woff2');
  unicode-range: U+0100-024F, U+1E00-1EFF;   /* Latin Extended */
}
@font-face {
  font-family: 'Advent Pro';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('https://my35pharmacy.gr/wp-content/themes/my35-ultralight/assets/fonts/advent-pro-latin-1.woff2') format('woff2');
  unicode-range: U+0000-00FF;                /* Basic Latin + Latin-1 */
}

/* ----------------------------------------------------------------------------
   1. ROOT TOKENS  (light-mode defaults; dark overrides in §11)
   ---------------------------------------------------------------------------- */
:root {

  /* === 1.1 BRAND CORE ===================================================== */
  --my35-yellow:            #FFC700;   /* primary brand — sunflower          */
  --my35-yellow-accent:     #FFC225;   /* warmer secondary accent            */
  --my35-yellow-deep:       #E8A800;   /* pressed / strong-contrast yellow   */
  --my35-yellow-tint:       #FFF6D6;   /* lightest wash for fills/glows      */
  --my35-ink:               #2D3436;   /* primary text / dark surface base   */
  --my35-ink-soft:          #4A5358;   /* secondary ink                      */
  --my35-white:             #FFFFFF;
  --my35-bg-light:          #F7F7F7;   /* page light bg                      */

  /* Yellow ramp (for borders, glows, hovers, gradients) */
  --my35-yellow-50:         #FFFBEA;
  --my35-yellow-100:        #FFF3C4;
  --my35-yellow-200:        #FFE793;
  --my35-yellow-300:        #FFD659;
  --my35-yellow-400:        #FFC700;
  --my35-yellow-500:        #F2B500;
  --my35-yellow-600:        #CB9400;
  --my35-yellow-700:        #9A6F00;

  /* Neutral / slate ramp (text, dividers, muted surfaces) */
  --my35-slate-50:          #F8F9FA;
  --my35-slate-100:         #EEF1F2;
  --my35-slate-200:         #E0E4E6;
  --my35-slate-300:         #C7CDD0;
  --my35-slate-400:         #98A1A6;
  --my35-slate-500:         #6B747A;
  --my35-slate-600:         #4A5358;
  --my35-slate-700:         #353C40;
  --my35-slate-800:         #2D3436;
  --my35-slate-900:         #1C2123;

  /* === 1.2 SEMANTIC COLOR ================================================= */
  --ds-text-primary:        var(--my35-ink);
  --ds-text-secondary:      var(--my35-slate-500);   /* #6B747A — AA 4.77:1 on white */
  --ds-text-tertiary:       #6F787D;                 /* AA 4.51:1 on white (was slate-400 #98A1A6 2.63) */
  --ds-text-on-yellow:      #4A3500;     /* dark-amber ink on yellow fills    */
  --ds-text-on-dark:        #FFFFFF;
  --ds-text-inverse:        #FFFFFF;
  --ds-text-link:           #8A6200;     /* warm on-brand link, ≥4.5:1 on glass */
  --ds-text-placeholder:    #5F686D;     /* input placeholder — AA 5.22:1 on surface-3 well (was #6B7479 4.38) */

  --ds-price-ink:           var(--my35-ink);
  --ds-price-strike:        var(--my35-slate-400);
  --ds-save-fg:             #1D7A4D;     /* "Κερδίζεις" green                  */
  --ds-save-bg:             #E4F6EC;
  --ds-discount-fg:         #C4322E;     /* "-X%" red                         */
  --ds-discount-bg:         #FDEBEA;

  /* Status / feedback */
  --ds-success:             #1D9E75;
  --ds-success-bg:          #E1F5EE;
  --ds-info:                #21689E;     /* AA 5.18:1 on info-bg (was #2E83C9 3.52) */
  --ds-info-bg:             #E6F1FB;
  --ds-warning:             #8A5408;     /* safety-head ink — AA 5.55:1 on warning-bg (was #BA7515 3.30) */
  --ds-warning-bg:          #FBF0DC;
  --ds-danger:             #B62F2B;     /* AA 5.31:1 on danger-bg (was #D33A36 4.11) */
  --ds-danger-bg:           #FCEBEA;

  /* Stock pills */
  --ds-stock-in-fg:         #15795A;
  --ds-stock-in-bg:         #E1F5EE;
  --ds-stock-out-fg:        #855A0E;   /* AA 5.37:1 on stock-out-bg (was #9A6A12 4.18) */
  --ds-stock-out-bg:        #FBF0DC;

  /* === 1.3 SURFACE BASE (opaque fallbacks) =============================== */
  --ds-surface-page:        var(--my35-bg-light);
  --ds-surface-1:           #FFFFFF;      /* base card                        */
  --ds-surface-2:           #FBFBFC;      /* raised inner surface             */
  --ds-surface-3:           #F4F5F7;      /* recessed / input wells           */
  --ds-surface-ink:         var(--my35-ink);   /* dark inverse surface        */

  /* === 1.4 GLASS TOKENS =================================================== */
  /* Translucent fills — sit over the page; pair with --ds-blur-*.           */
  --ds-glass-fill:          rgba(255, 255, 255, 0.96);
  --ds-glass-fill-strong:   rgba(255, 255, 255, 0.98);
  --ds-glass-fill-faint:    rgba(255, 255, 255, 0.92);
  --ds-glass-fill-warm:     rgba(255, 251, 234, 0.97);   /* yellow-tinted    */
  --ds-glass-fill-tint:     rgba(255, 199, 0, 0.10);     /* assistant bubble  */
  --ds-glass-fill-ink:      rgba(45, 52, 54, 0.62);      /* dark glass        */

  --ds-glass-border:        rgba(255, 255, 255, 0.65);   /* top-light edge   */
  --ds-glass-border-soft:   rgba(45, 52, 54, 0.08);      /* hairline divider  */
  --ds-glass-border-warm:   rgba(255, 199, 0, 0.42);     /* branded edge      */
  --ds-glass-highlight:     rgba(255, 255, 255, 0.85);   /* inner top sheen  */

  --ds-blur-sm:             8px;
  --ds-blur-md:             16px;
  --ds-blur-lg:             28px;
  --ds-blur-xl:             40px;
  --ds-glass-saturate:      135%;

  /* Composable backdrop-filter helpers */
  --ds-backdrop-panel:      blur(var(--ds-blur-lg)) saturate(var(--ds-glass-saturate));
  --ds-backdrop-bubble:     blur(var(--ds-blur-sm)) saturate(120%);
  --ds-backdrop-bar:        blur(var(--ds-blur-md)) saturate(130%);

  /* === 1.5 GRADIENT TOKENS =============================================== */
  /* WARM LIGHT SOURCE — all branded warm gradients share ONE angle (145deg)
     so header, FAB, user bubble and CTA read as lit from the same direction. */
  /* Hero / FAB / CTA / user bubble — warm sunflower core */
  --ds-grad-brand:          linear-gradient(145deg, #FFD659 0%, #FFC700 48%, #F2B500 100%);
  --ds-grad-brand-soft:     linear-gradient(145deg, #FFF3C4 0%, #FFE793 100%);
  /* Panel header — warm-to-cream wash that reads premium, not loud */
  --ds-grad-header:         linear-gradient(145deg, #FFD45A 0%, #FFC225 42%, #FFB800 100%);
  /* Glass body backdrop — barely-there cool/warm sheen behind frosted fill */
  --ds-grad-glass:          linear-gradient(160deg, rgba(255,251,234,0.55) 0%, rgba(255,255,255,0.30) 55%, rgba(247,247,247,0.40) 100%);
  /* Dark inverse hero (e.g. AI promo) */
  --ds-grad-ink:            linear-gradient(150deg, #353C40 0%, #2D3436 55%, #20262A 100%);
  /* Aurora accent sweep for subtle motion sheen on glass */
  --ds-grad-aurora:         linear-gradient(115deg, rgba(255,199,0,0.00) 0%, rgba(255,214,89,0.28) 40%, rgba(255,255,255,0.00) 75%);
  /* CTA shimmer (animated translateX on ::before) */
  --ds-grad-shimmer:        linear-gradient(100deg, transparent 0%, rgba(255,255,255,0.55) 50%, transparent 100%);
  /* Safety surface — calm, solid, NON-glass */
  --ds-grad-safety:         linear-gradient(160deg, #FFFDF7 0%, #FFF8E8 100%);
  /* Focus / online glow ring */
  --ds-grad-glow:           radial-gradient(circle, rgba(255,199,0,0.55) 0%, rgba(255,199,0,0.00) 70%);

  /* === 1.6 RADIUS SCALE ================================================== */
  --ds-radius-xs:           6px;
  --ds-radius-sm:           10px;
  --ds-radius-md:           14px;    /* default control / chip               */
  --ds-radius-lg:           18px;    /* cards, bubbles                       */
  --ds-radius-xl:           24px;    /* panel corners                        */
  --ds-radius-2xl:          30px;
  --ds-radius-pill:         999px;
  --ds-radius-fab:          50%;

  /* === 1.7 SPACING SCALE  (4px base) ===================================== */
  --ds-space-0:             0;
  --ds-space-1:             4px;
  --ds-space-2:             8px;
  --ds-space-3:             12px;
  --ds-space-4:             16px;
  --ds-space-5:             20px;
  --ds-space-6:             24px;
  --ds-space-7:             32px;
  --ds-space-8:             40px;
  --ds-space-9:             48px;
  --ds-space-10:            64px;

  /* === 1.8 TYPOGRAPHY ==================================================== */
  --ds-font-display:        'Advent Pro', 'DM Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --ds-font-body:           'DM Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --ds-font-mono:           ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;

  /* Type scale (px values; pair with line-heights below)                    */
  --ds-text-2xs:            11px;
  --ds-text-xs:             12px;
  --ds-text-sm:             13px;
  --ds-text-base:           14px;   /* body default in compact chat surface  */
  --ds-text-md:             15px;
  --ds-text-lg:             17px;
  --ds-text-xl:             20px;
  --ds-text-2xl:            24px;
  --ds-text-display:        28px;   /* panel title / Advent Pro              */

  --ds-leading-tight:       1.25;
  --ds-leading-snug:        1.4;
  --ds-leading-normal:      1.55;
  --ds-leading-relaxed:     1.7;

  --ds-weight-regular:      400;
  --ds-weight-medium:       500;
  --ds-weight-semibold:     600;
  --ds-weight-bold:         700;

  --ds-tracking-tight:      -0.01em;
  --ds-tracking-normal:     0;
  --ds-tracking-wide:       0.04em;
  --ds-tracking-caps:       0.08em;   /* eyebrow / ALL-CAPS labels           */

  /* === 1.9 ELEVATION / SHADOW SCALE ===================================== */
  /* Layered, soft, neutral-cool — the glass-product look.                   */
  --ds-shadow-xs:           0 1px 2px rgba(28, 33, 35, 0.06);
  --ds-shadow-sm:           0 2px 6px rgba(28, 33, 35, 0.07),
                            0 1px 2px rgba(28, 33, 35, 0.05);
  --ds-shadow-md:           0 8px 20px -6px rgba(28, 33, 35, 0.14),
                            0 2px 6px rgba(28, 33, 35, 0.06);
  --ds-shadow-lg:           0 20px 44px -12px rgba(28, 33, 35, 0.20),
                            0 6px 14px -6px rgba(28, 33, 35, 0.10);
  /* Panel — the big floating surface */
  --ds-shadow-panel:        0 40px 90px -24px rgba(28, 33, 35, 0.32),
                            0 16px 40px -16px rgba(28, 33, 35, 0.18),
                            0 2px 8px rgba(28, 33, 35, 0.06);
  /* FAB — grounded but lively, warm-tinted ambient */
  --ds-shadow-fab:          0 14px 30px -8px rgba(203, 148, 0, 0.42),
                            0 6px 14px -6px rgba(28, 33, 35, 0.24),
                            0 1px 3px rgba(28, 33, 35, 0.18);
  --ds-shadow-fab-hover:    0 20px 42px -10px rgba(203, 148, 0, 0.52),
                            0 8px 18px -6px rgba(28, 33, 35, 0.28);
  /* Inner sheen for glass tops (use as inset) */
  --ds-shadow-glass-inset:  inset 0 1px 0 var(--ds-glass-highlight),
                            inset 0 0 0 0.5px rgba(255, 255, 255, 0.30);
  /* Warm focus ring */
  --ds-ring-focus:          0 0 0 3px rgba(255, 199, 0, 0.45);
  --ds-ring-focus-ink:      0 0 0 3px rgba(45, 52, 54, 0.18);
  /* Online / glow pulse */
  --ds-glow-yellow:         0 0 0 0 rgba(255, 199, 0, 0.55);

  /* === 1.10 Z-INDEX SCALE =============================================== */
  --ds-z-base:              1;
  --ds-z-cards:             10;
  --ds-z-sticky-input:      20;
  --ds-z-panel-header:      30;
  --ds-z-quickreplies:      40;
  --ds-z-fab:               2147483000;   /* above site chrome, below modal  */
  --ds-z-panel:             2147483200;
  --ds-z-toast:             2147483400;
  --ds-z-overlay:           2147483600;
  --ds-z-max:               2147483647;

  /* === 1.11 MOTION ====================================================== */
  --ds-dur-instant:         90ms;
  --ds-dur-fast:            160ms;
  --ds-dur-base:            240ms;
  --ds-dur-slow:            380ms;
  --ds-dur-slower:          600ms;
  --ds-dur-ambient:         3200ms;   /* breathing FAB / online pulse        */

  --ds-ease-out:            cubic-bezier(0.22, 1, 0.36, 1);   /* settle       */
  --ds-ease-in-out:         cubic-bezier(0.65, 0, 0.35, 1);
  --ds-ease-spring:         cubic-bezier(0.34, 1.56, 0.64, 1); /* playful pop */
  --ds-ease-emphasis:       cubic-bezier(0.2, 0.9, 0.1, 1);

  /* === 1.12 SIZING HINTS (advisory — B2 owns final geometry) ============ */
  --ds-fab-size:            64px;
  --ds-fab-size-mobile:     56px;
  --ds-panel-width:         400px;
  --ds-panel-max-height:    760px;
  --ds-avatar-size:         34px;
  --ds-control-height:      44px;
  --ds-hairline:            0.5px;
}

/* ----------------------------------------------------------------------------
   2. BASE PRIMITIVE — surface reset for the widget root
   (B2 attaches geometry; these set font + smoothing + token inheritance)
   ---------------------------------------------------------------------------- */
.ds-root,
.ds-scope {
  font-family: var(--ds-font-body);
  font-size: var(--ds-text-base);
  line-height: var(--ds-leading-normal);
  color: var(--ds-text-primary);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-feature-settings: 'kern' 1, 'liga' 1;
}

/* ----------------------------------------------------------------------------
   3. GLASS SURFACE PRIMITIVES
   ---------------------------------------------------------------------------- */
.ds-glass {
  background: var(--ds-glass-fill);
  -webkit-backdrop-filter: var(--ds-backdrop-panel);
  backdrop-filter: var(--ds-backdrop-panel);
  border: var(--ds-hairline) solid var(--ds-glass-border);
  box-shadow: var(--ds-shadow-glass-inset);
}
.ds-glass-strong {
  background: var(--ds-glass-fill-strong);
  -webkit-backdrop-filter: var(--ds-backdrop-bar);
  backdrop-filter: var(--ds-backdrop-bar);
  border: var(--ds-hairline) solid var(--ds-glass-border);
}
.ds-glass-warm {
  background: var(--ds-glass-fill-warm);
  -webkit-backdrop-filter: var(--ds-backdrop-bubble);
  backdrop-filter: var(--ds-backdrop-bubble);
  border: var(--ds-hairline) solid var(--ds-glass-border-warm);
}
/* Graceful fallback where backdrop-filter is unsupported */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .ds-glass        { background: var(--ds-surface-1); }
  .ds-glass-strong { background: var(--ds-surface-1); }
  .ds-glass-warm   { background: var(--my35-yellow-50); }
}

/* ----------------------------------------------------------------------------
   4. ELEVATION PRIMITIVES
   ---------------------------------------------------------------------------- */
.ds-elev-sm     { box-shadow: var(--ds-shadow-sm); }
.ds-elev-md     { box-shadow: var(--ds-shadow-md); }
.ds-elev-lg     { box-shadow: var(--ds-shadow-lg); }
.ds-elev-panel  { box-shadow: var(--ds-shadow-panel); }
.ds-elev-fab    { box-shadow: var(--ds-shadow-fab); }

/* ----------------------------------------------------------------------------
   5. TEXT PRIMITIVES
   ---------------------------------------------------------------------------- */
.ds-display {
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-semibold);
  letter-spacing: var(--ds-tracking-tight);
  line-height: var(--ds-leading-tight);
}
.ds-eyebrow {
  font-family: var(--ds-font-body);
  font-size: var(--ds-text-2xs);
  font-weight: var(--ds-weight-semibold);
  letter-spacing: var(--ds-tracking-caps);
  text-transform: uppercase;
  color: var(--ds-text-secondary);
}
.ds-muted    { color: var(--ds-text-secondary); }
.ds-faint    { color: var(--ds-text-tertiary); }

/* ----------------------------------------------------------------------------
   6. PILL / CHIP / BADGE PRIMITIVES
   ---------------------------------------------------------------------------- */
.ds-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-1);
  border-radius: var(--ds-radius-pill);
  font-family: var(--ds-font-body);
  font-size: var(--ds-text-xs);
  font-weight: var(--ds-weight-medium);
  line-height: 1;
  padding: var(--ds-space-1) var(--ds-space-3);
  white-space: nowrap;
}
.ds-pill-save     { background: var(--ds-save-bg);     color: var(--ds-save-fg); }
.ds-pill-discount { background: var(--ds-discount-bg); color: var(--ds-discount-fg);     font-weight: var(--ds-weight-semibold); }
.ds-pill-stock    { background: var(--ds-stock-in-bg); color: var(--ds-stock-in-fg); }
.ds-pill-warm     { background: var(--my35-yellow-tint); color: var(--ds-text-on-yellow); }

/* ----------------------------------------------------------------------------
   7. FOCUS PRIMITIVE  (accessible, on-brand)
   ---------------------------------------------------------------------------- */
.ds-focusable:focus-visible {
  outline: none;
  box-shadow: var(--ds-ring-focus);
  border-radius: var(--ds-radius-sm);
}

/* ----------------------------------------------------------------------------
   8. AMBIENT MOTION KEYFRAMES  (FAB breathing, online dot, shimmer, typing)
   B2 opts in via animation shorthands referencing these names + dur tokens.
   ---------------------------------------------------------------------------- */
@keyframes ds-fab-breathe {
  0%, 100% { transform: scale(1); }
  18%      { transform: scale(1.06); }
  50%      { transform: scale(1.03); }
}
@keyframes ds-fab-sonar {
  0%   { box-shadow: 0 0 0 0 rgba(255, 199, 0, 0.45); }
  70%  { box-shadow: 0 0 0 16px rgba(255, 199, 0, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 199, 0, 0); }
}
@keyframes ds-online-pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.6; transform: scale(0.82); }
}
@keyframes ds-shimmer-sweep {
  0%   { transform: translateX(-120%); }
  100% { transform: translateX(120%); }
}
@keyframes ds-bubble-in {
  0%   { opacity: 0; transform: translateY(8px) scale(0.98); }
  100% { opacity: 1; transform: translateY(0)   scale(1); }
}
@keyframes ds-typing-bounce {
  0%, 60%, 100% { transform: translateY(0);   opacity: 0.5; }
  30%           { transform: translateY(-4px); opacity: 1; }
}
@keyframes ds-aurora-drift {
  0%   { transform: translateX(-30%); opacity: 0; }
  40%  { opacity: 1; }
  100% { transform: translateX(60%);  opacity: 0; }
}

.ds-anim-bubble-in {
  animation: ds-bubble-in var(--ds-dur-base) var(--ds-ease-out) both;
}

/* ----------------------------------------------------------------------------
   9. SCROLLBAR PRIMITIVE  (slim, warm, unobtrusive)
   ---------------------------------------------------------------------------- */
.ds-scroll {
  scrollbar-width: thin;
  scrollbar-color: var(--my35-slate-300) transparent;
}
.ds-scroll::-webkit-scrollbar { width: 8px; height: 8px; }
.ds-scroll::-webkit-scrollbar-thumb {
  background: var(--my35-slate-300);
  border-radius: var(--ds-radius-pill);
  border: 2px solid transparent;
  background-clip: padding-box;
}
.ds-scroll::-webkit-scrollbar-thumb:hover { background: var(--my35-slate-400); }
.ds-scroll::-webkit-scrollbar-track { background: transparent; }

/* ----------------------------------------------------------------------------
   10. DIVIDER PRIMITIVE
   ---------------------------------------------------------------------------- */
.ds-divider {
  height: var(--ds-hairline);
  background: var(--ds-glass-border-soft);
  border: 0;
}

/* ----------------------------------------------------------------------------
   11. DARK-MODE-AWARE SURFACE OVERRIDES
   Activates on .ds-dark scope OR system preference. Glass stays glass; the
   substrate goes ink-deep, the warm yellow stays the soul.
   ---------------------------------------------------------------------------- */
.ds-dark,
:root.ds-dark {
  --ds-text-primary:        #F4F5F6;
  --ds-text-secondary:      #AEB6BA;
  --ds-text-tertiary:       #8B949A;   /* AA 4.78:1 on dark surface-1 (was #7C858A 3.92) */
  --ds-text-on-dark:        #FFFFFF;
  --ds-text-link:           #FFD659;

  --ds-price-ink:           #F4F5F6;
  --ds-price-strike:        #7C858A;
  --ds-save-fg:             #6FD9A6;
  --ds-save-bg:             rgba(29, 158, 117, 0.18);
  --ds-discount-fg:         #F4938F;
  --ds-discount-bg:         rgba(211, 58, 54, 0.18);

  --ds-stock-in-fg:         #6FD9A6;
  --ds-stock-in-bg:         rgba(29, 158, 117, 0.18);
  --ds-stock-out-fg:        #E7B968;
  --ds-stock-out-bg:        rgba(186, 117, 21, 0.20);

  --ds-surface-page:        #181D1F;
  --ds-surface-1:           #23292B;
  --ds-surface-2:           #283032;
  --ds-surface-3:           #1E2426;
  --ds-surface-ink:         #14181A;

  --ds-glass-fill:          rgba(33, 39, 42, 0.975);
  --ds-glass-fill-strong:   rgba(46, 53, 57, 0.985);
  --ds-glass-fill-faint:    rgba(40, 47, 50, 0.48);
  --ds-glass-fill-warm:     rgba(48, 44, 30, 0.97);
  --ds-glass-fill-tint:     rgba(255, 199, 0, 0.14);
  --ds-glass-fill-ink:      rgba(20, 24, 26, 0.96);

  --ds-glass-border:        rgba(255, 255, 255, 0.12);
  --ds-glass-border-soft:   rgba(255, 255, 255, 0.08);
  --ds-glass-border-warm:   rgba(255, 199, 0, 0.38);
  --ds-glass-highlight:     rgba(255, 255, 255, 0.10);

  --ds-grad-glass:          linear-gradient(160deg, rgba(60,52,24,0.30) 0%, rgba(40,47,50,0.20) 55%, rgba(24,29,31,0.30) 100%);
  --ds-grad-safety:         linear-gradient(160deg, #25292B 0%, #2C2A22 100%);

  --ds-shadow-glass-inset:  inset 0 1px 0 rgba(255, 255, 255, 0.08),
                            inset 0 0 0 0.5px rgba(255, 255, 255, 0.05);
  --ds-shadow-panel:        0 40px 90px -24px rgba(0, 0, 0, 0.62),
                            0 16px 40px -16px rgba(0, 0, 0, 0.42),
                            0 2px 8px rgba(0, 0, 0, 0.30);
  --ds-ring-focus:          0 0 0 3px rgba(255, 199, 0, 0.50);
}
@media (prefers-color-scheme: dark) {
  :root:not(.ds-light) {
    --ds-text-primary:        #F4F5F6;
    --ds-text-secondary:      #AEB6BA;
    --ds-text-tertiary:       #8B949A;   /* AA 4.78:1 on dark surface-1 (was #7C858A 3.92) */
    --ds-text-link:           #FFD659;
    --ds-price-ink:           #F4F5F6;
    --ds-price-strike:        #7C858A;
    --ds-save-fg:             #6FD9A6;
    --ds-save-bg:             rgba(29, 158, 117, 0.18);
    --ds-discount-fg:         #F4938F;
    --ds-discount-bg:         rgba(211, 58, 54, 0.18);
    --ds-stock-in-fg:         #6FD9A6;
    --ds-stock-in-bg:         rgba(29, 158, 117, 0.18);
    --ds-stock-out-fg:        #E7B968;
    --ds-stock-out-bg:        rgba(186, 117, 21, 0.20);
    --ds-surface-page:        #181D1F;
    --ds-surface-1:           #23292B;
    --ds-surface-2:           #283032;
    --ds-surface-3:           #1E2426;
    --ds-surface-ink:         #14181A;
    --ds-glass-fill:          rgba(33, 39, 42, 0.975);
    --ds-glass-fill-strong:   rgba(46, 53, 57, 0.985);
    --ds-glass-fill-faint:    rgba(40, 47, 50, 0.48);
    --ds-glass-fill-warm:     rgba(48, 44, 30, 0.97);
    --ds-glass-fill-tint:     rgba(255, 199, 0, 0.14);
    --ds-glass-fill-ink:      rgba(20, 24, 26, 0.96);
    --ds-glass-border:        rgba(255, 255, 255, 0.12);
    --ds-glass-border-soft:   rgba(255, 255, 255, 0.08);
    --ds-glass-border-warm:   rgba(255, 199, 0, 0.38);
    --ds-glass-highlight:     rgba(255, 255, 255, 0.10);
    --ds-grad-glass:          linear-gradient(160deg, rgba(60,52,24,0.30) 0%, rgba(40,47,50,0.20) 55%, rgba(24,29,31,0.30) 100%);
    --ds-grad-safety:         linear-gradient(160deg, #25292B 0%, #2C2A22 100%);
    --ds-shadow-glass-inset:  inset 0 1px 0 rgba(255, 255, 255, 0.08),
                              inset 0 0 0 0.5px rgba(255, 255, 255, 0.05);
    --ds-shadow-panel:        0 40px 90px -24px rgba(0, 0, 0, 0.62),
                              0 16px 40px -16px rgba(0, 0, 0, 0.42),
                              0 2px 8px rgba(0, 0, 0, 0.30);
    --ds-ring-focus:          0 0 0 3px rgba(255, 199, 0, 0.50);
  }
}

/* ----------------------------------------------------------------------------
   12. REDUCED MOTION  (respect user preference globally)
   ---------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  :root {
    --ds-dur-instant: 1ms; --ds-dur-fast: 1ms; --ds-dur-base: 1ms;
    --ds-dur-slow: 1ms; --ds-dur-slower: 1ms; --ds-dur-ambient: 1ms;
  }
  .ds-anim-bubble-in { animation: none; }
}

/* ===== widget.css ===== */
/* ============================================================================
   MY35 PHARMACY — AI ASSISTANT  ·  WIDGET COMPONENT LAYER  (B2)
   ----------------------------------------------------------------------------
   Consumes ONLY tokens + primitives from design-system.css. Defines geometry +
   layout for: FAB launcher · glass panel · header · message stream · bubbles
   (assistant / user) · SAFETY bubble (distinct, non-glass) · product card ·
   quick-reply chips · input bar · welcome/empty state.

   Nothing here redefines a token. Brand soul = #FFC700; ink = #2D3436.
   ============================================================================ */

/* ----------------------------------------------------------------------------
   0. ROOT WRAPPER  — fixed bottom-right anchor for FAB + panel
   ---------------------------------------------------------------------------- */
.my35w {
  position: fixed;
  right: var(--ds-space-6);
  bottom: var(--ds-space-6);
  z-index: var(--ds-z-fab);
  font-family: var(--ds-font-body);
}
.my35w * { box-sizing: border-box; }
.my35w button { font-family: inherit; }

/* Mobile layout (anchoring, FAB position/size, full-height sheet) lives in
   responsive.css as the SINGLE source of truth (@media <=600px). widget.css
   keeps only desktop/base geometry below — no duplicate mobile @media bands. */

/* ----------------------------------------------------------------------------
   1. FAB  (closed launcher)
   ---------------------------------------------------------------------------- */
.my35w-fab {
  position: relative;
  width: var(--ds-fab-size);
  height: var(--ds-fab-size);
  border: 0;
  border-radius: var(--ds-radius-fab);
  background: var(--ds-grad-brand);
  color: var(--ds-text-on-yellow);
  cursor: pointer;
  display: grid;
  place-items: center;
  box-shadow: var(--ds-shadow-fab);
  transition: transform var(--ds-dur-fast) var(--ds-ease-spring),
              box-shadow var(--ds-dur-fast) var(--ds-ease-out);
  animation: ds-fab-breathe var(--ds-dur-ambient) var(--ds-ease-in-out) infinite;
}
.my35w-fab::after {                 /* sonar ring */
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--ds-radius-fab);
  animation: ds-fab-sonar var(--ds-dur-ambient) var(--ds-ease-out) infinite;
  pointer-events: none;
}
.my35w-fab:hover {
  transform: translateY(-3px) scale(1.04);
  box-shadow: var(--ds-shadow-fab-hover);
}
.my35w-fab:active { transform: translateY(-1px) scale(0.99); }
.my35w-fab svg { width: 30px; height: 30px; display: block; }

/* online dot on the FAB */
.my35w-fab-dot {
  position: absolute;
  top: 4px; right: 4px;
  width: 13px; height: 13px;
  border-radius: var(--ds-radius-fab);
  background: var(--ds-success);
  border: 2px solid var(--my35-white);
  animation: ds-online-pulse var(--ds-dur-ambient) var(--ds-ease-in-out) infinite;
}

/* FAB hidden while panel is open */
.my35w.is-open .my35w-fab {
  opacity: 0;
  transform: scale(0.6);
  pointer-events: none;
  animation: none;
}

/* ----------------------------------------------------------------------------
   2. PANEL  (open chat)
   ---------------------------------------------------------------------------- */
.my35w-panel {
  position: absolute;
  right: 0;
  /* Anchor ONLY to the bottom-right corner. `top: auto` is asserted explicitly:
     it guarantees the box is never over-constrained on the block axis. If any
     leaked/inherited `top`/`inset` ever resolved to a value here, the abspos box
     would become over-constrained (top + bottom both definite) and `height:auto`
     would collapse to `containing-block-height − top` — a FIXED height that
     ignores content (this is the exact mechanism behind the old 640px dead-zone:
     height stopped hugging content because `top` was effectively pinned). With
     `top:auto` the only block-axis anchor is `bottom:0`, so `height:auto` ALWAYS
     resolves to shrink-to-fit content. The mobile sheet re-sets `inset:0`
     (top:0) on purpose under @media (max-width:900px) and is unaffected. */
  top: auto;
  bottom: 0;
  /* Desktop base governs the panel width at EVERY non-sheet breakpoint (incl.
     tablet 601–900px, where responsive.css intentionally sets only height).
     clamp() keeps the preferred --ds-panel-width (400px) but is viewport-aware:
     it never exceeds the screen, and never drops below 360px. NEVER use
     calc(100% - …) — the panel is absolute inside the FAB-sized (~64px) root,
     so % resolves to ~64px and collapses it. clamp()+vw is viewport-relative. */
  width: clamp(360px, var(--ds-panel-width), calc(100vw - var(--ds-space-7)));
  max-width: calc(100vw - var(--ds-space-7));
  /* Height HUGS the content (header + stream + input) instead of a fixed 640px
     block — an empty chat (welcome + chips only) must NOT leave dead space below
     the input bar. The panel grows with messages up to the cap, then the stream
     scrolls. Cap = the smaller of the design max (640px) and the viewport. */
  height: auto;
  /* Floor: the panel is generously tall FROM THE START (even empty: welcome +
     chips), so it reads as a substantial assistant, not a tiny popover. Capped
     so it never exceeds the viewport on short laptops (min() picks whichever is
     smaller). The stream's flex-grow:1 inside the floor fills the extra height
     gracefully; once messages exceed the floor the panel keeps growing to the
     max, then scrolls. */
  min-height: min(620px, calc(100vh - var(--ds-space-7)));
  /* Cap: taller panel so a real conversation shows MORE text before scrolling.
     760px design max, but never closer than 32px to the viewport edges. */
  max-height: min(var(--ds-panel-max-height), calc(100vh - var(--ds-space-7)));
  display: none;
  flex-direction: column;
  overflow: hidden;
  border-radius: var(--ds-radius-xl);
  background-image: var(--ds-grad-glass);
  z-index: var(--ds-z-panel);
  transform-origin: bottom right;
  /* HARD RESET host-theme padding. The panel is a <section>, and the storefront
     theme styles `section { padding: 64px 0 }` (page-builder default). That leaked
     64px top + 64px bottom INSIDE the panel → content (~512px) + 128px padding = the
     phantom 640px height with dead space above the header AND below the input bar.
     `!important` because the theme rule may be equally/more specific. The mobile
     sheet re-applies safe-area padding under @media (max-width:900px). */
  padding: 0 !important;
}
/* Panel open-state visibility lives here; the entrance ANIMATION is owned by
   motion.css (@keyframes my35w-panel-in-spring on .my35w.is-open .my35w-panel).
   The old local @keyframes my35w-panel-in is removed to kill the name collision. */
.my35w.is-open .my35w-panel {
  display: flex;
}

/* glass substrate sits under header + stream + input */
.my35w-panel::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--ds-glass-fill);
  -webkit-backdrop-filter: var(--ds-backdrop-panel);
  backdrop-filter: var(--ds-backdrop-panel);
  z-index: 0;
  pointer-events: none;
}

/* (mobile full-height sheet for the panel is owned by responsive.css §2.2) */

/* ----------------------------------------------------------------------------
   3. HEADER
   ---------------------------------------------------------------------------- */
.my35w-header {
  position: relative;
  z-index: var(--ds-z-panel-header);
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--ds-space-3);
  /* A touch more vertical breathing room than the 16px rail so the eyebrow +
     24px title don't feel pinned to the top edge (owner spacing fine-tune). */
  padding: var(--ds-space-5) var(--ds-space-4);
  background: var(--ds-grad-header);
  overflow: hidden;
}
/* aurora sheen drift over the header */
.my35w-header::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--ds-grad-aurora);
  animation: ds-aurora-drift 9s var(--ds-ease-in-out) infinite;
  pointer-events: none;
}
.my35w-header-avatar {
  position: relative;
  flex: 0 0 auto;
  width: 40px; height: 40px;
  border-radius: var(--ds-radius-fab);
  background: var(--my35-white);
  display: grid;
  place-items: center;
  box-shadow: var(--ds-shadow-sm);
}
.my35w-header-avatar svg { width: 24px; height: 24px; color: var(--my35-yellow-deep); }
.my35w-header-meta { flex: 1 1 auto; min-width: 0; }
/* The header gradient stays yellow in BOTH light & dark schemes, so all header
   text is pinned to the dark on-yellow ink (#4A3500) directly — never to a
   semantic token like --ds-text-primary that flips near-white in dark mode.
   #4A3500 on the #FFC225 header → contrast ≈ 7.9:1 (passes AA + AAA). */
.my35w-header-title {
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-bold);
  letter-spacing: var(--ds-tracking-tight);
  line-height: var(--ds-leading-tight);
  /* Bumped to match the welcome hero title (--ds-text-2xl) so the open-panel
     identity reads at the same scale as the empty-state greeting. */
  font-size: var(--ds-text-2xl);
  color: #4A3500;
  margin: 0;
}
.my35w-header-eyebrow {
  font-family: var(--ds-font-body);
  font-size: var(--ds-text-2xs);
  font-weight: var(--ds-weight-semibold);
  letter-spacing: var(--ds-tracking-caps);
  text-transform: uppercase;
  color: rgba(74, 53, 0, 0.82);
  margin: 0 0 1px;
}
.my35w-status {
  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-1);
  font-size: var(--ds-text-2xs);
  font-weight: var(--ds-weight-semibold);
  color: rgba(74, 53, 0, 0.88);
  margin-top: 2px;
}
.my35w-status-dot {
  width: 8px; height: 8px;
  border-radius: var(--ds-radius-fab);
  background: var(--ds-success);
  animation: ds-online-pulse var(--ds-dur-ambient) var(--ds-ease-in-out) infinite;
}
.my35w-close {
  position: relative;
  flex: 0 0 auto;
  width: 34px; height: 34px;
  border: 0;
  border-radius: var(--ds-radius-fab);
  background: rgba(255, 255, 255, 0.32);
  color: var(--ds-text-on-yellow);
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background var(--ds-dur-fast) var(--ds-ease-out);
}
.my35w-close:hover { background: rgba(255, 255, 255, 0.55); }
.my35w-close svg { width: 18px; height: 18px; }

/* ----------------------------------------------------------------------------
   4. MESSAGE STREAM
   ---------------------------------------------------------------------------- */
.my35w-stream {
  position: relative;
  z-index: var(--ds-z-base);
  /* The stream GROWS to fill the panel's min-height floor (so the input bar
     pins to the bottom of a generously-tall panel, no dead gap). Once messages
     exceed the floor, the panel grows to its max-height, then min-height:0 +
     overflow-y:auto makes the stream the scroll region. Mobile (100dvh sheet)
     uses the same flex:1 1 auto to fill the screen. */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--ds-space-4) var(--ds-space-4) var(--ds-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-4);
}

/* ----------------------------------------------------------------------------
   5. MESSAGE ROW + BUBBLES
   ---------------------------------------------------------------------------- */
.my35w-row {
  display: flex;
  gap: var(--ds-space-2);
  align-items: flex-end;
  max-width: 100%;
}
.my35w-row.is-user { flex-direction: row-reverse; }

.my35w-avatar {
  flex: 0 0 auto;
  width: var(--ds-avatar-size);
  height: var(--ds-avatar-size);
  border-radius: var(--ds-radius-fab);
  background: var(--ds-grad-brand);
  display: grid;
  place-items: center;
  box-shadow: var(--ds-shadow-xs);
  align-self: flex-start;
  margin-top: 2px;
}
.my35w-avatar svg { width: 19px; height: 19px; color: var(--ds-text-on-yellow); }

.my35w-bubble {
  max-width: 80%;
  border-radius: var(--ds-radius-lg);
  padding: var(--ds-space-3) var(--ds-space-4);
  font-size: var(--ds-text-base);
  line-height: var(--ds-leading-relaxed);
  word-wrap: break-word;
  overflow-wrap: anywhere;
}
/* assistant — warm glass */
.my35w-bubble.is-assistant {
  background: var(--ds-glass-fill-warm);
  -webkit-backdrop-filter: var(--ds-backdrop-bubble);
  backdrop-filter: var(--ds-backdrop-bubble);
  border: var(--ds-hairline) solid var(--ds-glass-border-warm);
  color: var(--ds-text-primary);
  border-bottom-left-radius: var(--ds-radius-sm);
}
/* user — confident brand fill. Stronger/more saturated than the pale assistant
   glass so user vs assistant reads instantly: solid sunflower gradient + defining
   warm border + deep on-yellow ink (#4A3500 ≈ 8:1 on this fill). */
.my35w-bubble.is-user {
  background: var(--ds-grad-brand);
  color: #4A3500;
  font-weight: var(--ds-weight-medium);
  border: var(--ds-hairline) solid var(--my35-yellow-deep);
  box-shadow: var(--ds-shadow-sm);
  border-bottom-right-radius: var(--ds-radius-sm);
}
.my35w-bubble p { margin: 0 0 var(--ds-space-2); }
.my35w-bubble p:last-child { margin-bottom: 0; }

/* a column wrapper so cards / chips stack under an assistant bubble */
.my35w-block {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-3);
  max-width: 92%;
}
.my35w-row.is-assistant + .my35w-block,
.my35w-block { align-self: flex-start; padding-left: calc(var(--ds-avatar-size) + var(--ds-space-2)); }

/* ----------------------------------------------------------------------------
   6. SAFETY BUBBLE  (mode: safety_handoff | blocked_safety)
   Deliberately NON-glass. Calm, solid, serious. NO product cards, NO shimmer.
   ---------------------------------------------------------------------------- */
.my35w-safety {
  align-self: stretch;
  background: var(--ds-grad-safety);
  border: 1px solid var(--ds-glass-border-soft);
  border-left: 3px solid var(--ds-warning);
  border-radius: var(--ds-radius-lg);
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  padding: var(--ds-space-4) var(--ds-space-4) var(--ds-space-4);
  box-shadow: var(--ds-shadow-sm);
  color: var(--ds-text-primary);
}
.my35w-safety.is-emergency { border-left-color: var(--ds-danger); }

.my35w-safety-head {
  display: flex;
  align-items: center;
  gap: var(--ds-space-2);
  font-weight: var(--ds-weight-semibold);
  font-size: var(--ds-text-md);
  color: var(--ds-warning);
  margin-bottom: var(--ds-space-2);
}
.my35w-safety.is-emergency .my35w-safety-head { color: var(--ds-danger); }
.my35w-safety-head svg { width: 20px; height: 20px; flex: 0 0 auto; }

.my35w-safety-body {
  font-size: var(--ds-text-base);
  line-height: var(--ds-leading-relaxed);
  color: var(--ds-text-primary);
  margin: 0 0 var(--ds-space-4);
}

.my35w-safety-actions {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-2);
}
.my35w-tel {
  display: flex;
  align-items: center;
  gap: var(--ds-space-3);
  text-decoration: none;
  padding: var(--ds-space-3) var(--ds-space-4);
  border-radius: var(--ds-radius-md);
  font-weight: var(--ds-weight-semibold);
  font-size: var(--ds-text-md);
  transition: filter var(--ds-dur-fast) var(--ds-ease-out),
              transform var(--ds-dur-fast) var(--ds-ease-out);
}
.my35w-tel:hover { filter: brightness(0.97); transform: translateY(-1px); }
.my35w-tel svg { width: 20px; height: 20px; flex: 0 0 auto; }
.my35w-tel-label { flex: 1 1 auto; display: flex; flex-direction: column; line-height: 1.2; }
.my35w-tel-label small {
  font-size: var(--ds-text-2xs);
  font-weight: var(--ds-weight-medium);
  opacity: 0.8;
}
.my35w-tel-num { font-size: var(--ds-text-lg); letter-spacing: 0.02em; }
/* pharmacy line — warm */
.my35w-tel.is-pharmacy {
  background: var(--my35-yellow-tint);
  color: var(--ds-text-on-yellow);
  border: 1px solid var(--ds-glass-border-warm);
}
/* emergency line — high-contrast danger */
.my35w-tel.is-ekab {
  background: var(--ds-danger);
  color: var(--my35-white);
}

/* ----------------------------------------------------------------------------
   7. PRODUCT CARD  (only in non-safety modes)
   ---------------------------------------------------------------------------- */
.my35w-products {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-3);
}
.my35w-card {
  display: flex;
  gap: var(--ds-space-3);
  padding: var(--ds-space-3);
  border-radius: var(--ds-radius-lg);
  /* Near-solid fill — NO backdrop-filter. The card sits on the panel ::before
     frost layer; a second blur here stacks glass-on-glass (muddy + extra GPU
     layer). Solid strong fill keeps the card crisp. Matches the input-bar. */
  background: var(--ds-glass-fill-strong);
  border: var(--ds-hairline) solid var(--ds-glass-border);
  box-shadow: var(--ds-shadow-sm);
  transition: box-shadow var(--ds-dur-base) var(--ds-ease-out),
              border-color var(--ds-dur-base) var(--ds-ease-out),
              transform var(--ds-dur-base) var(--ds-ease-out);
}
.my35w-card:hover {
  box-shadow: var(--ds-shadow-md);
  border-color: var(--ds-glass-border-warm);
  transform: translateY(-2px);
}
.my35w-card-img {
  flex: 0 0 auto;
  /* Fluid thumbnail: scales with panel width (18vw) within a 56–76px band so
     the card stays balanced on a narrow phone sheet and a roomier tablet card. */
  width: clamp(56px, 18vw, 76px);
  height: clamp(56px, 18vw, 76px);
  border-radius: var(--ds-radius-md);
  object-fit: cover;
  background: var(--ds-surface-3);
  border: var(--ds-hairline) solid var(--ds-glass-border-soft);
}
.my35w-card-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-1);
}
.my35w-card-title {
  font-size: var(--ds-text-md);
  font-weight: var(--ds-weight-medium);
  color: var(--ds-text-primary);
  line-height: var(--ds-leading-snug);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.my35w-card-reason {
  font-size: var(--ds-text-sm);
  color: var(--ds-text-secondary);
  line-height: var(--ds-leading-snug);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.my35w-card-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--ds-space-2);
  margin-top: 2px;
}
.my35w-card-price {
  font-size: var(--ds-text-md);
  font-weight: var(--ds-weight-bold);
  color: var(--ds-price-ink);
}
.my35w-card-strike {
  font-size: var(--ds-text-sm);
  color: var(--ds-price-strike);
  text-decoration: line-through;
}
.my35w-pill-stock-out { background: var(--ds-stock-out-bg); color: var(--ds-stock-out-fg); }

.my35w-card-cta {
  margin-top: var(--ds-space-2);
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-1);
  position: relative;
  overflow: hidden;
  border: 0;
  cursor: pointer;
  text-decoration: none;
  padding: var(--ds-space-2) var(--ds-space-4);
  border-radius: var(--ds-radius-md);
  background: var(--ds-grad-brand);
  color: var(--ds-text-on-yellow);
  font-size: var(--ds-text-sm);
  font-weight: var(--ds-weight-semibold);
  box-shadow: var(--ds-shadow-xs);
  transition: transform var(--ds-dur-fast) var(--ds-ease-out),
              box-shadow var(--ds-dur-fast) var(--ds-ease-out);
}
.my35w-card-cta:hover { transform: translateY(-1px); box-shadow: var(--ds-shadow-sm); }
.my35w-card-cta svg { width: 15px; height: 15px; }
/* shimmer sweep on hover */
.my35w-card-cta::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  background: var(--ds-grad-shimmer);
  transform: translateX(-120%);
  pointer-events: none;
}
.my35w-card-cta:hover::before {
  animation: ds-shimmer-sweep var(--ds-dur-slow) var(--ds-ease-out);
}
.my35w-card.is-oos .my35w-card-cta {
  background: var(--ds-surface-3);
  color: var(--ds-text-tertiary);
  pointer-events: none;
  box-shadow: none;
}

/* ----------------------------------------------------------------------------
   8. QUICK-REPLY CHIPS  (quick_replies[] + smart_links[])
   ---------------------------------------------------------------------------- */
.my35w-chips {
  position: relative;
  z-index: var(--ds-z-quickreplies);
  display: flex;
  flex-wrap: wrap;
  gap: var(--ds-space-2);
  padding-top: var(--ds-space-1);
}
.my35w-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-1);
  border-radius: var(--ds-radius-pill);
  padding: var(--ds-space-2) var(--ds-space-3);
  font-size: var(--ds-text-xs);
  font-weight: var(--ds-weight-medium);
  line-height: 1;
  cursor: pointer;
  text-decoration: none;
  color: var(--ds-text-primary);
  /* Solid strong fill — NO backdrop-filter. Chips are the loudest interactive
     surface; stacking a 2nd blur over the panel frost muddies them. Solid fill
     keeps them crisp + cheap (matches input-bar / product card). */
  background: var(--ds-glass-fill-strong);
  border: var(--ds-hairline) solid var(--ds-glass-border-warm);
  box-shadow: var(--ds-shadow-xs);
  transition: background var(--ds-dur-fast) var(--ds-ease-out),
              transform var(--ds-dur-fast) var(--ds-ease-out),
              box-shadow var(--ds-dur-fast) var(--ds-ease-out);
}
.my35w-chip:hover {
  background: var(--ds-glass-fill-tint);
  transform: translateY(-1px);
  box-shadow: var(--ds-shadow-sm);
}
.my35w-chip:active { transform: translateY(0); }
.my35w-chip svg { width: 13px; height: 13px; opacity: 0.7; }
.my35w-chip.is-link { color: var(--ds-text-link); }

/* ----------------------------------------------------------------------------
   9. TYPING INDICATOR
   ---------------------------------------------------------------------------- */
.my35w-typing {
  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-1);
  background: var(--ds-glass-fill-warm);
  -webkit-backdrop-filter: var(--ds-backdrop-bubble);
  backdrop-filter: var(--ds-backdrop-bubble);
  border: var(--ds-hairline) solid var(--ds-glass-border-warm);
  border-radius: var(--ds-radius-lg);
  border-bottom-left-radius: var(--ds-radius-sm);
  padding: var(--ds-space-3) var(--ds-space-4);
}
/* Box styling only — the typing-dot CADENCE (animation + per-dot delays) is the
   single responsibility of motion.css §6. No `animation`/`animation-delay` here. */
.my35w-typing span {
  width: 7px; height: 7px;
  border-radius: var(--ds-radius-fab);
  background: var(--my35-yellow-400);
}

/* ----------------------------------------------------------------------------
   10. WELCOME / EMPTY STATE  — premium first impression (full-width hero,
   NOT an 80% bubble). Dedicated welcome state styled here; widget.js owns the
   state, this owns the look.
   ---------------------------------------------------------------------------- */
.my35w-welcome {
  align-self: stretch;          /* full bleed in the stream, not a bubble */
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-4);
  padding: var(--ds-space-4) 0 var(--ds-space-3);
}
/* Hero avatar: a compact circular branded badge. Without an explicit size the
   inline SVG stretches to fill the flex column (~357px) and dominates the panel. */
.my35w-welcome-avatar {
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--ds-grad-brand);
  color: var(--my35-ink, #2D3436);
  box-shadow: var(--ds-shadow-sm);
}
.my35w-welcome-avatar svg { width: 28px; height: 28px; }
.my35w-welcome-title {
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-bold);
  font-size: var(--ds-text-2xl);          /* ~24px Advent Pro display */
  line-height: var(--ds-leading-tight);
  letter-spacing: var(--ds-tracking-tight);
  color: var(--ds-text-primary);
  margin: 0;
  text-wrap: balance;
}
.my35w-welcome-sub {
  font-size: var(--ds-text-md);           /* ~15px — a step up from body */
  line-height: var(--ds-leading-normal);
  color: var(--ds-text-secondary);
  margin: 0;
  max-width: 38ch;
}
/* Starter chips = the LOUDEST interactive surface in the welcome hero. Solid
   warm tint + defining border (no glass-on-glass), bigger tap, full presence.
   Stronger than the quieter quick-reply chips so they pull the first click. */
.my35w-starters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ds-space-2);
  margin-top: var(--ds-space-1);
}
.my35w-starters .my35w-chip {
  font-size: var(--ds-text-sm);
  font-weight: var(--ds-weight-semibold);
  padding: var(--ds-space-3) var(--ds-space-4);
  background: var(--ds-glass-fill-tint);
  border-color: var(--my35-yellow-deep);
  box-shadow: var(--ds-shadow-sm);
}
.my35w-starters .my35w-chip:hover {
  background: var(--my35-yellow-tint);
  box-shadow: var(--ds-shadow-md);
}

/* ----------------------------------------------------------------------------
   11. INPUT BAR  (sticky bottom)
   ---------------------------------------------------------------------------- */
.my35w-inputbar {
  position: relative;
  z-index: var(--ds-z-sticky-input);
  flex: 0 0 auto;
  display: flex;
  align-items: flex-end;
  gap: var(--ds-space-2);
  /* Horizontal padding matches the stream's --ds-space-4 rail so the field
     left/right edges align with the message bubbles above. A little extra below
     the field so the bar doesn't feel pinned to the panel's bottom edge
     (owner spacing fine-tune). */
  padding: var(--ds-space-4) var(--ds-space-4) var(--ds-space-5);
  /* No own backdrop-filter: it sits directly on the panel ::before frost layer.
     A second blur here would stack over an already-frosted substrate (muddy +
     GPU cost). Solid strong fill keeps the bar visually distinct, one blur layer. */
  background: var(--ds-glass-fill-strong);
  border-top: var(--ds-hairline) solid var(--ds-glass-border-soft);
}
.my35w-field {
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--ds-control-height);
  max-height: 120px;
  resize: none;
  border: var(--ds-hairline) solid var(--ds-glass-border-soft);
  border-radius: var(--ds-radius-pill);
  background: var(--ds-surface-3);
  color: var(--ds-text-primary);
  font-family: var(--ds-font-body);
  font-size: var(--ds-text-base);
  line-height: var(--ds-leading-snug);
  padding: var(--ds-space-3) var(--ds-space-4);
  outline: none;
  transition: border-color var(--ds-dur-fast) var(--ds-ease-out),
              box-shadow var(--ds-dur-fast) var(--ds-ease-out);
}
.my35w-field::placeholder { color: var(--ds-text-placeholder, #6B7479); opacity: 1; }
.my35w-field:focus-visible {
  border-color: var(--ds-glass-border-warm);
  box-shadow: var(--ds-ring-focus);
}
.my35w-send {
  flex: 0 0 auto;
  width: var(--ds-control-height);
  height: var(--ds-control-height);
  border: 0;
  border-radius: var(--ds-radius-fab);
  background: var(--ds-grad-brand);
  color: var(--ds-text-on-yellow);
  cursor: pointer;
  display: grid;
  place-items: center;
  box-shadow: var(--ds-shadow-xs);
  transition: transform var(--ds-dur-fast) var(--ds-ease-spring),
              box-shadow var(--ds-dur-fast) var(--ds-ease-out),
              opacity var(--ds-dur-fast) var(--ds-ease-out);
}
.my35w-send:hover:not(:disabled) { transform: scale(1.06); box-shadow: var(--ds-shadow-sm); }
/* :active press feedback is owned by motion.css §8 (scale .9 transition). */
.my35w-send:disabled { opacity: 0.45; cursor: default; }
.my35w-send svg { width: 20px; height: 20px; }

/* NOTE: no permanent `will-change` on rows/blocks/safety here. A blanket
   will-change on every message leaks compositor memory (each row keeps a GPU
   layer forever). The entrance animation is transient — motion.css drives it via
   `.ds-anim-bubble-in { animation: ... both }`, and the browser auto-promotes for
   the duration of the animation, then releases. F3 may toggle will-change only
   around active transitions. */

/* ----------------------------------------------------------------------------
   12. A11Y / UTILITY
   ---------------------------------------------------------------------------- */
.my35w-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.my35w :focus-visible {
  outline: none;
  box-shadow: var(--ds-ring-focus);
}

/* ----------------------------------------------------------------------------
   13. SHORT VIEWPORT  — component-level compression of the welcome hero.
   Mirrors the exact trigger responsive.css §5 uses (which trims header/welcome/
   stream PADDING). Here we own the welcome-avatar SIZE: on a short screen the
   52px hero badge eats scarce vertical space, so shrink it to 40px and tighten
   the welcome block's own padding. Same trigger = both bands apply together. */
@media (max-height: 560px),
       (max-height: 480px) and (orientation: landscape) {
  .my35w-welcome-avatar {
    width: 40px;
    height: 40px;
  }
  .my35w-welcome-avatar svg { width: 22px; height: 22px; }
  .my35w-welcome {
    gap: var(--ds-space-3);
    padding: var(--ds-space-2) 0 var(--ds-space-2);
  }
}

@media (prefers-reduced-motion: reduce) {
  .my35w-fab,
  .my35w-fab::after,
  .my35w-fab-dot,
  .my35w-status-dot,
  .my35w-header::after,
  .my35w-typing span { animation: none; }
  .my35w.is-open .my35w-panel { animation: none; }
  .my35w-card-cta:hover::before { animation: none; }
}

/* ===== motion.css ===== */
/* ============================================================================
   MY35 PHARMACY — AI ASSISTANT · MOTION LAYER  (rewritten against the REAL DOM)
   ----------------------------------------------------------------------------
   OWNER:    Motion Designer (F-motion)
   DEPENDS:  design-system.css  (--ds-* tokens + ambient keyframes)
   LOADS:    AFTER widget.css  →  equal-specificity rules here WIN the cascade,
             so we upgrade the panel-open spring and add what widget.css lacks
             (real CLOSE keyframe, product-card stagger, richer FAB hover/press)
             WITHOUT any !important battles.

   CONTRACT — this file targets ONLY the canonical `.my35w-*` names + the real
   state hooks. The old `.ai-*` / `.my35-ai-*` namespaces are DEAD and gone.

   GROUND-TRUTH HOOKS (from DOM-CONTRACT.md / widget.js):
     #my35-ai-widget-root.my35w.ds-root        ← root; gains `.is-open` when open
     .my35w-fab  +  .my35w-fab-dot             ← launcher + online dot
     .my35w-panel                              ← dialog (transform-origin set here)
     .my35w-panel.my35w-closing                ← *** F3 must set this on close ***
     .my35w-row.is-assistant / .is-user
     .my35w-row[data-typing]                   ← typing row
     .my35w-row.ds-anim-bubble-in              ← entrance hook (also on .my35w-block,
                                                  .my35w-safety)
     .my35w-typing > span (×3)                 ← typing dots
     .my35w-products > .my35w-card             ← product list (siblings → nth-child
                                                  stagger is correct)
     .my35w-chip / .my35w-card-cta / .my35w-send

   PRINCIPLES (Disney, adapted for UI):
     ANTICIPATION · FOLLOW-THROUGH · STAGGER/SECONDARY · SLOW-IN/SLOW-OUT ·
     NATURAL ORIGIN (panel unfolds from the FAB's bottom-right corner).

   RULES
     · transform / opacity / filter ONLY — never animate width/height/top/left.
     · Every timing & easing is a --ds-* token. No magic linears (except the
       infinite ambient loops, which use token eases anyway).
     · A COMPLETE `prefers-reduced-motion: reduce` block at the bottom neutralises
       every animation + transition authored here. Motion is pure enhancement.

   *** HANDOFF TO F3 (widget.js) — REQUIRED FOR THE CLOSE ANIMATION ***
     On close(), instead of immediately removing `.is-open`, F3 must:
       1) add class `my35w-closing` to the PANEL element (.my35w-panel),
       2) listen once for `animationend` on the panel,
       3) then remove `.is-open` from the root AND remove `.my35w-closing`,
          and move focus back to the FAB.
     Fallback: if reduced-motion or animations are off, a ~200ms setTimeout is a
     safe substitute for animationend. The keyframe `my35w-panel-out` below is
     what plays during `.my35w-closing`.
   ============================================================================ */


/* ----------------------------------------------------------------------------
   0. MOTION-LOCAL KEYFRAMES
   Ambient loops (ds-fab-breathe, ds-fab-sonar, ds-online-pulse,
   ds-shimmer-sweep, ds-typing-bounce, ds-aurora-drift) live in design-system.css
   and are reused as-is. Here we author the component moves that file lacks or
   that we want to enrich.
   ---------------------------------------------------------------------------- */

/* PANEL OPEN — unfolds FROM the FAB (bottom-right). Spring follow-through that
   settles to exactly 1.0 (deliberately NO overshoot past 1.0: the panel is a
   blurred glass surface, and a visible bounce on backdrop-filter looks
   cheap/jittery). The "spring" character lives in the ease curve + the deep
   wind-up, not in a scale > 1 keyframe.

   NAME: `my35w-panel-in-spring` — DISTINCT from widget.css's `my35w-panel-in`.
   The two files previously shared the name `my35w-panel-in`, so this later-loaded
   motion-layer definition silently shadowed widget.css's keyframe (a global
   keyframe-name collision). Renamed so the motion layer owns ITS OWN keyframe and
   references only this one; widget.css's `my35w-panel-in` is now untouched/inert
   here (we override the consuming rule below to point at the spring variant). */
@keyframes my35w-panel-in-spring {
  0% {
    opacity: 0;
    /* origin = bottom-right (the FAB). Start nudged DOWN + RIGHT toward the FAB
       center and scaled down, so with transform-origin:bottom right the panel
       visibly grows OUT of the launcher, then settles to transform:none. */
    transform: translate(14px, 22px) scale(0.86);
  }
  55% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: none;
  }
}

/* PANEL CLOSE — a real, authored exit. Folds back toward the FAB corner: sinks
   + shrinks + fades. Snappy so the UI feels responsive, not sticky. F3 plays
   this via `.my35w-closing` and waits for animationend. */
@keyframes my35w-panel-out {
  0% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
  100% {
    opacity: 0;
    transform: translateY(12px) scale(0.92);
  }
}

/* FAB hand-off when the panel opens: the launcher tucks away toward its corner
   (it is hidden behind the panel, but the brief shrink reads as "becoming" the
   panel rather than blinking out). */
@keyframes my35w-fab-tuck {
  0%   { opacity: 1; transform: translateY(0)   scale(1); }
  100% { opacity: 0; transform: translateY(4px) scale(0.6); }
}

/* BUBBLE ENTRANCE — pop + slide. transform/opacity only. Assistant rows lean in
   from the left edge, user rows from the right (set per-side below). */
@keyframes my35w-bubble-in {
  0% {
    opacity: 0;
    transform: translateY(10px) scale(0.96);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* PRODUCT CARD entrance — slightly deeper rise than a bubble so the stagger
   cascade reads clearly as a sequence (SECONDARY ACTION). */
@keyframes my35w-card-in {
  0% {
    opacity: 0;
    transform: translateY(14px) scale(0.97);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* NOTE: the send-button press is handled by a TRANSITION to a held compressed
   :active state (scale .9), NOT a keyframe — so a quick tap always shows
   feedback and cannot be visually "cut". See §8. */


/* ----------------------------------------------------------------------------
   1. FAB — idle breathing, sonar ring, online dot, hover lift, press
   widget.css already runs ds-fab-breathe / ds-fab-sonar / ds-online-pulse.
   We loading-order-WIN to guarantee they're live, add a richer hover lift +
   glow, and a real press anticipation dip. Pure transform/opacity/shadow.
   ---------------------------------------------------------------------------- */
.my35w-fab {
  /* keep the ambient breathe + spring-eased interaction transition explicit so
     this layer is the source of truth for FAB motion timing */
  animation: ds-fab-breathe var(--ds-dur-ambient) var(--ds-ease-in-out) infinite;
  transition:
    transform var(--ds-dur-fast) var(--ds-ease-spring),
    box-shadow var(--ds-dur-base) var(--ds-ease-out);
  /* will-change is NOT declared at rest: a permanent compositor-layer hint on an
     always-present resting element wastes memory and can hurt paint. It is
     promoted transiently on interaction states below, just before the transform
     transition fires. */
}

/* sonar ring — emitted from ::after, expanding + fading on the ambient loop */
.my35w-fab::after {
  animation: ds-fab-sonar var(--ds-dur-ambient) var(--ds-ease-out) infinite;
}

/* online dot — gentle living pulse */
.my35w-fab-dot {
  animation: ds-online-pulse var(--ds-dur-ambient) var(--ds-ease-in-out) infinite;
  will-change: transform, opacity;
}

/* HOVER / FOCUS-VISIBLE — lift + scale, stronger glow. The breathe pauses so the
   lift reads as a deliberate, controlled state (no fighting between two
   transforms). Keyboard users get the SAME affordance as pointer users. */
.my35w-fab:hover,
.my35w-fab:focus-visible {
  transform: translateY(-3px) scale(1.05);
  box-shadow: var(--ds-shadow-fab-hover);
  animation-play-state: paused;
  will-change: transform; /* transient promotion only while interacting */
}

/* PRESS — anticipation dip (compress slightly before the panel springs open). */
.my35w-fab:active {
  transform: translateY(-1px) scale(0.97);
  transition-duration: var(--ds-dur-instant);
  will-change: transform; /* transient promotion only while interacting */
}

/* When the panel is open, the FAB tucks away toward its corner. */
.my35w.is-open .my35w-fab {
  pointer-events: none;
  animation: my35w-fab-tuck var(--ds-dur-fast) var(--ds-ease-emphasis) forwards;
}


/* ----------------------------------------------------------------------------
   2. PANEL — open spring (from FAB corner) + authored CLOSE keyframe
   ---------------------------------------------------------------------------- */
.my35w-panel {
  /* the natural origin: panel grows from the launcher's bottom-right corner */
  transform-origin: bottom right;
  will-change: transform, opacity;
}

/* OPEN — 240ms base, settles to transform:none with NO overshoot. The keyframe
   ends exactly at scale(1); pairing it with an overshooting spring ease would
   push past 1.0 and snap back (a visible bounce on a blurred glass surface looks
   cheap). So we use --ds-ease-out (cubic-bezier(0.22,1,0.36,1)) — a fast-out /
   slow-settle curve. The "spring" character lives entirely in the deep wind-up
   (translate + scale 0.86 start), not in an overshoot. `both` holds the end
   frame. References the renamed motion-layer keyframe ONLY (never the widget.css
   `my35w-panel-in`), so there is no silent name collision. This rule loads after
   widget.css, so it cleanly supersedes widget.css's open rule. */
.my35w.is-open .my35w-panel {
  animation: my35w-panel-in-spring var(--ds-dur-base) var(--ds-ease-out) both;
}

/* CLOSE — F3 sets `.my35w-closing` on the panel; this plays then animationend
   fires. Slightly faster than open so dismissal feels instant. `forwards` keeps
   the panel at its faded-out frame until JS tears it down. */
.my35w-panel.my35w-closing {
  animation: my35w-panel-out var(--ds-dur-fast) var(--ds-ease-emphasis) forwards;
  pointer-events: none;
}

/* The header aurora sheen keeps drifting while open (defined in widget.css /
   design-system.css). Nothing to add — it inherits the ambient loop. */


/* ----------------------------------------------------------------------------
   3. MESSAGE ROWS / BUBBLES — entrance pop, side-aware
   widget.js stamps `.ds-anim-bubble-in` on new rows, the content `.my35w-block`,
   and `.my35w-safety`. We own that hook here so the move is consistent.
   ---------------------------------------------------------------------------- */
.my35w-row.ds-anim-bubble-in,
.my35w-block.ds-anim-bubble-in {
  animation: my35w-bubble-in var(--ds-dur-base) var(--ds-ease-out) both;
}

/* Assistant rows lean in from the left; user rows from the right — subtle x-bias
   layered onto the base rise via the bubble itself for a directional feel. */
.my35w-row.is-assistant.ds-anim-bubble-in .my35w-bubble {
  animation: my35w-bubble-in var(--ds-dur-base) var(--ds-ease-out) both;
}
.my35w-row.is-user.ds-anim-bubble-in .my35w-bubble {
  animation: my35w-bubble-in var(--ds-dur-base) var(--ds-ease-out) both;
}

/* The typing row should appear instantly (no entrance pop) — it is a transient
   placeholder; only its dots animate. Cancel any inherited entrance. */
.my35w-row[data-typing] {
  animation: none;
}


/* ----------------------------------------------------------------------------
   4. SAFETY block — calm, deliberate entrance (a touch slower; serious tone)
   ---------------------------------------------------------------------------- */
.my35w-safety.ds-anim-bubble-in {
  animation: my35w-bubble-in var(--ds-dur-slow) var(--ds-ease-out) both;
}
/* tel rows get a gentle press feedback (the only motion the safety box needs) */
.my35w-tel {
  transition:
    transform var(--ds-dur-fast) var(--ds-ease-out),
    filter var(--ds-dur-fast) var(--ds-ease-out);
}
.my35w-tel:hover,
.my35w-tel:focus-visible { transform: translateY(-1px); }
.my35w-tel:active { transform: translateY(0) scale(0.99); transition-duration: var(--ds-dur-instant); }


/* ----------------------------------------------------------------------------
   5. PRODUCT-CARD STAGGER — cascade so the eye reads the set, not a flash.
   Cards are direct siblings inside `.my35w-products`, so :nth-child indices are
   the real card positions. Delay is RELATIVE to the block's own entrance.
   ---------------------------------------------------------------------------- */
.my35w-products > .my35w-card {
  animation: my35w-card-in var(--ds-dur-base) var(--ds-ease-spring) both;
}
.my35w-products > .my35w-card:nth-child(1) { animation-delay:  40ms; }
.my35w-products > .my35w-card:nth-child(2) { animation-delay: 100ms; }
.my35w-products > .my35w-card:nth-child(3) { animation-delay: 160ms; }
.my35w-products > .my35w-card:nth-child(4) { animation-delay: 220ms; }
.my35w-products > .my35w-card:nth-child(5) { animation-delay: 280ms; }
.my35w-products > .my35w-card:nth-child(6) { animation-delay: 340ms; }
/* graceful cap for any 7th+ card */
.my35w-products > .my35w-card:nth-child(n + 7) { animation-delay: 380ms; }

/* Card hover lift (motion-layer owns the timing; widget.css owns the look).
   The lift is a quick micro-interaction → --ds-dur-fast (160ms), not the 240ms
   base; box-shadow keeps the base duration so the elevation eases in a touch
   softer than the snap of the rise. */
.my35w-card {
  transition:
    transform var(--ds-dur-fast) var(--ds-ease-out),
    box-shadow var(--ds-dur-base) var(--ds-ease-out);
}
.my35w-card:hover { transform: translateY(-2px); }

/* Card CTA — lift on hover + a quick shimmer sweep (keyframe in widget.css). */
.my35w-card-cta {
  transition:
    transform var(--ds-dur-fast) var(--ds-ease-out),
    box-shadow var(--ds-dur-fast) var(--ds-ease-out);
}
.my35w-card-cta:hover,
.my35w-card-cta:focus-visible { transform: translateY(-1px); }
.my35w-card-cta:active { transform: translateY(0) scale(0.98); transition-duration: var(--ds-dur-instant); }


/* ----------------------------------------------------------------------------
   6. TYPING DOTS — snappy, staggered bounce (transform only)
   widget.css defines the @keyframes ds-typing-bounce (in design-system.css);
   we own the CADENCE (duration + per-dot delay) here.

   *** DUAL-DEFINITION CONFLICT (resolved by ownership) ***
   widget.css ALSO sets `animation:` + `animation-delay:` on `.my35w-typing span`
   (slower duration, 120/240ms delays). motion.css loads AFTER widget.css, so by
   equal-specificity cascade the rules below WIN. To make that win total and not
   merely partial, motion.css re-declares the delay for ALL THREE dots — including
   nth-child(1):0ms — so no widget.css delay value can leak through on any dot.
   Motion.css is now the single source of truth for typing cadence.
   *** HANDOFF NOTE for the widget.css owner: remove the `animation` +
   `animation-delay` declarations from `.my35w-typing span` in widget.css; keep
   only the dot's box styling there. Timing belongs to the motion layer. ***
   ---------------------------------------------------------------------------- */
.my35w-typing span {
  animation: ds-typing-bounce var(--ds-dur-slow) var(--ds-ease-in-out) infinite;
  will-change: transform, opacity;
}
.my35w-typing span:nth-child(1) { animation-delay:   0ms; }
.my35w-typing span:nth-child(2) { animation-delay: 130ms; }
.my35w-typing span:nth-child(3) { animation-delay: 260ms; }


/* ----------------------------------------------------------------------------
   7. CHIPS — quick-reply + starter chips: hover lift, press settle
   ---------------------------------------------------------------------------- */
.my35w-chip {
  transition:
    transform var(--ds-dur-fast) var(--ds-ease-spring),
    box-shadow var(--ds-dur-fast) var(--ds-ease-out),
    background var(--ds-dur-fast) var(--ds-ease-out),
    border-color var(--ds-dur-fast) var(--ds-ease-out);
}
.my35w-chip:hover,
.my35w-chip:focus-visible { transform: translateY(-2px); box-shadow: var(--ds-shadow-sm); }
.my35w-chip:active { transform: translateY(0) scale(0.97); transition-duration: var(--ds-dur-instant); }


/* ----------------------------------------------------------------------------
   8. SEND BUTTON — anticipation compress + success kick on press
   ---------------------------------------------------------------------------- */
.my35w-send {
  transition:
    transform var(--ds-dur-fast) var(--ds-ease-spring),
    box-shadow var(--ds-dur-fast) var(--ds-ease-out),
    opacity var(--ds-dur-fast) var(--ds-ease-out);
  /* will-change is NOT declared at rest (resting button); it is promoted
     transiently on the interaction states below. */
}
.my35w-send:hover:not(:disabled),
.my35w-send:focus-visible:not(:disabled) { transform: scale(1.07); box-shadow: var(--ds-shadow-sm); will-change: transform; }
/* PRESS — transition to a compressed state (scale .9) instead of a keyframe.
   A keyframe animation can be visually "cut" if the press is released before it
   completes (or never restarts on a rapid re-tap). A pure transition to a held
   :active state means even a quick tap snaps to the compressed transform
   immediately, then springs back on release — so feedback is ALWAYS shown. */
.my35w-send:active:not(:disabled) {
  transform: scale(0.9);
  transition-duration: var(--ds-dur-instant);
}
.my35w-send:disabled { opacity: 0.45; }


/* ----------------------------------------------------------------------------
   9. STREAM scroll viewport — JS owns smoothness (rAF easing sets scrollTop)
   CSS `scroll-behavior: smooth` would fight the JS rAF scroll: the browser's
   native smooth-scroll and the script's per-frame scrollTop writes interfere,
   causing stutter/overshoot. So this is `auto` — instant CSS scroll, leaving the
   JS rAF loop as the single source of scroll smoothness.
   ---------------------------------------------------------------------------- */
.my35w-stream {
  scroll-behavior: auto;
}


/* ============================================================================
   10. prefers-reduced-motion: reduce  —  COMPLETE NEUTRALISATION
   Disables / neutralises EVERY animation + transition authored above. The
   widget remains fully usable; only the enhancement layer is removed. Panel
   open/close become instant opacity swaps so state is still legible.
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {

  /* kill every authored keyframe animation on every hook we touch
     (the send button press is now a transition, neutralised in the next block) */
  .my35w-fab,
  .my35w-fab::after,
  .my35w-fab-dot,
  .my35w.is-open .my35w-fab,
  .my35w-panel,
  .my35w.is-open .my35w-panel,
  .my35w-panel.my35w-closing,
  .my35w-row.ds-anim-bubble-in,
  .my35w-block.ds-anim-bubble-in,
  .my35w-row.is-assistant.ds-anim-bubble-in .my35w-bubble,
  .my35w-row.is-user.ds-anim-bubble-in .my35w-bubble,
  .my35w-safety.ds-anim-bubble-in,
  .my35w-products > .my35w-card,
  .my35w-typing span {
    animation: none !important;
    animation-delay: 0ms !important;
    transition: none !important;
  }

  /* neutralise interaction transforms so nothing visibly moves on
     hover / focus-visible / press */
  .my35w-fab,
  .my35w-fab:hover,
  .my35w-fab:focus-visible,
  .my35w-fab:active,
  .my35w-fab-dot,
  .my35w-tel,
  .my35w-tel:hover,
  .my35w-tel:focus-visible,
  .my35w-tel:active,
  .my35w-card,
  .my35w-card:hover,
  .my35w-card-cta,
  .my35w-card-cta:hover,
  .my35w-card-cta:focus-visible,
  .my35w-card-cta:active,
  .my35w-chip,
  .my35w-chip:hover,
  .my35w-chip:focus-visible,
  .my35w-chip:active,
  .my35w-send,
  .my35w-send:hover:not(:disabled),
  .my35w-send:focus-visible:not(:disabled),
  .my35w-send:active:not(:disabled),
  .my35w-products > .my35w-card,
  .my35w-row.ds-anim-bubble-in,
  .my35w-block.ds-anim-bubble-in,
  .my35w-safety.ds-anim-bubble-in,
  .my35w-row.is-assistant.ds-anim-bubble-in .my35w-bubble,
  .my35w-row.is-user.ds-anim-bubble-in .my35w-bubble {
    transform: none !important;
  }

  /* state must still read: open = visible, closing = hidden — instant, no move */
  .my35w.is-open .my35w-panel { opacity: 1 !important; }
  .my35w-panel.my35w-closing  { opacity: 0 !important; }
  .my35w.is-open .my35w-fab   { opacity: 0 !important; }

  /* entrances must not leave content stuck invisible (animation `both` fill) */
  .my35w-row.ds-anim-bubble-in,
  .my35w-block.ds-anim-bubble-in,
  .my35w-safety.ds-anim-bubble-in,
  .my35w-products > .my35w-card,
  .my35w-row.is-assistant.ds-anim-bubble-in .my35w-bubble,
  .my35w-row.is-user.ds-anim-bubble-in .my35w-bubble {
    opacity: 1 !important;
  }

  /* smooth programmatic scroll → instant */
  .my35w-stream { scroll-behavior: auto !important; }
}

/* ===== responsive.css ===== */
/* ==========================================================================
   MY35 AI Chat Widget — RESPONSIVE / MOBILE / SAFE-AREA / A11Y LAYER
   --------------------------------------------------------------------------
   Owner: Mobile & Accessibility Engineer (F5)
   Ground truth: ./DOM-CONTRACT.md  ·  loads LAST (wins ties over widget.css).

   CONTRACT — this file targets ONLY the real rendered names:
     root      #my35-ai-widget-root  →  .my35w .ds-root  (+ .is-open when open)
     launcher  .my35w-fab (+ .my35w-fab-dot)
     panel     .my35w-panel
     header    .my35w-header / -avatar / -meta / -eyebrow / -title
     status    .my35w-status / -dot
     close     .my35w-close
     stream    .my35w-stream (.ds-scroll)
     rows      .my35w-row (.is-assistant|.is-user|[data-typing]) / -avatar / -bubble
     welcome   .my35w-welcome / -title / -sub / .my35w-starters
     chips     .my35w-chips / .my35w-chip
     products  .my35w-products / -card / -card-img / -card-main / -card-title /
               -card-reason / -card-meta / -card-price / -card-strike /
               -card-cta / .my35w-pill-stock-out
     safety    .my35w-safety / -head / -body / -actions / .my35w-tel*
     input     .my35w-inputbar (form) / .my35w-field (textarea) / .my35w-send

   The OLD .my35-ai-* / .ai-* namespaces are DEAD and never appear below.

   Tokens consumed (from design-system.css): --ds-space-*, --ds-radius-*,
   --ds-text-*, --ds-font-*, --ds-weight-*, --ds-surface-*, --ds-glass-*,
   --ds-text-*, --ds-ring-focus*, --ds-z-*, --my35-yellow*, --my35-ink.

   Motion (prefers-reduced-motion) is owned by motion.css (F2). This file
   introduces NO animation/transition, so there is nothing to reduce here.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Local responsive variables (resolve from base tokens, with fallbacks
      so the layer is robust even if a token is renamed upstream).
   -------------------------------------------------------------------------- */
.my35w {
  /* Safe-area insets (0 where there is no notch / home-indicator). */
  --my35-ai-sa-top:    env(safe-area-inset-top, 0px);
  --my35-ai-sa-right:  env(safe-area-inset-right, 0px);
  --my35-ai-sa-bottom: env(safe-area-inset-bottom, 0px);
  --my35-ai-sa-left:   env(safe-area-inset-left, 0px);

  /* Storefront bottom call-bar height ("Ρώτα φαρμακοποιό" mobile bar).
     The host page may override --my35-ai-callbar-h; default ≈ 56px. */
  --my35-ai-callbar-h: var(--my35-ai-callbar, 56px);

  /* WCAG / ergonomic floors. */
  --my35-ai-tap-min:   44px;
  --my35-ai-text-min:  13px;   /* hard floor for chips / reason / strike */
}

/* --------------------------------------------------------------------------
   1. GLOBAL GUARD — never let the widget cause horizontal overflow, and let
      long product names / URLs wrap instead of stretching the panel.
      Cheap + safe at every width.
   -------------------------------------------------------------------------- */
.my35w,
.my35w * { box-sizing: border-box; }

/* NOTE: do NOT add a global `.my35w-panel { max-width: 100% }` here — the
   desktop panel is position:absolute inside the .my35w root, which is only
   FAB-sized (~64px), so `max-width:100%` would clamp the panel to 64px.
   The desktop panel already guards overflow via its own
   `max-width: calc(100vw - ...)` in widget.css; the mobile sheet sets
   width:100% inside the <=600px block below. */

.my35w-card-img,
.my35w-avatar svg,
.my35w-fab svg {
  max-width: 100%;
}

.my35w-bubble,
.my35w-card-title,
.my35w-card-reason,
.my35w-chip {
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* ==========================================================================
   2. MOBILE  (<=600px) — full-height sheet, safe-areas, iOS no-zoom, taps.
   ========================================================================== */
@media (max-width: 900px) {

  /* ----- 2.1 FAB: clear of the live bottom call-bar + notch ----------------
     The FAB is `position:relative` inside the fixed root in widget.css. On
     mobile we anchor it directly to the viewport, lifted above the call-bar,
     with safe-area on bottom + right. Tap target >=44px guaranteed. */
  .my35w-fab {
    position: fixed;
    right: calc(var(--ds-space-4) + var(--my35-ai-sa-right));
    bottom: calc(
      var(--my35-ai-callbar-h) +
      env(safe-area-inset-bottom, 0px) +
      var(--ds-space-4)
    );
    /* Slightly trimmer FAB on phones (moved here from widget.css so this layer
       is the single mobile source of truth) — never below the 44px floor. */
    width: var(--ds-fab-size-mobile);
    height: var(--ds-fab-size-mobile);
    min-width: var(--my35-ai-tap-min);
    min-height: var(--my35-ai-tap-min);
    z-index: var(--ds-z-fab);
  }
  .my35w-fab svg { width: 26px; height: 26px; }

  /* ----- 2.2 PANEL → full-height sheet ------------------------------------
     Edge-to-edge sheet filling the dynamic viewport. 100dvh (not 100vh) so
     the URL bar / on-screen keyboard don't clip the input. */
  .my35w-panel {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100dvh;
    max-width: 100%;
    max-height: 100dvh;
    margin: 0;
    border-radius: 0;
    box-shadow: none;

    /* Honour the notch on three sides; the bottom inset is applied on the
       input bar so the keyboard can dock the bar against the viewport.
       `!important` so it beats the desktop base `padding:0 !important` reset. */
    padding-top:   env(safe-area-inset-top, 0px) !important;
    padding-right: env(safe-area-inset-right, 0px) !important;
    padding-bottom: 0 !important;
    padding-left:  env(safe-area-inset-left, 0px) !important;

    /* iOS keyboard hook: the JS visualViewport handler writes the live
       keyboard overlap into --my35-kb-offset on the ROOT (#my35-ai-widget-root);
       the input bar (a panel descendant) inherits it and translates up by that
       amount. We deliberately do NOT redeclare --my35-kb-offset here — a local
       declaration on .my35w-panel would shadow the root value for every
       descendant and pin the input bar at 0 (keyboard would cover it). The
       fallback default lives on the var() usage at .my35w-inputbar. */
  }

  /* Keep the FAB out of the way (and non-tappable) while the sheet is open. */
  .my35w.is-open .my35w-fab {
    display: none;
  }

  /* ----- 2.3 HEADER: tappable close, comfortable height -------------------- */
  .my35w-header {
    min-height: var(--my35-ai-tap-min);
  }
  .my35w-header-avatar {
    min-width: var(--my35-ai-tap-min);
    min-height: var(--my35-ai-tap-min);
  }
  .my35w-close {
    /* Visual chip can stay compact; this guarantees a >=44px hit area. */
    position: relative;
    min-width: var(--my35-ai-tap-min);
    min-height: var(--my35-ai-tap-min);
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* ----- 2.4 STREAM: the ONLY scroll region; iOS momentum + contained ------ */
  .my35w-stream {
    flex: 1 1 auto;
    min-height: 0;                 /* let the flex child actually shrink */
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;  /* don't scroll the page behind the sheet */
  }

  /* Bubbles must not exceed the sheet and copy stays readable. */
  .my35w-bubble {
    max-width: 88%;
    font-size: max(var(--ds-text-base), 15px);
    line-height: var(--ds-leading-normal);
  }

  /* ----- 2.5 INPUT BAR: keyboard-safe + iOS no-zoom ------------------------
     It is the last flex child of the sheet, so it docks at the bottom. With
     100dvh + interactive-widget=resizes-content (host), it rides up with the
     keyboard. `position: sticky; bottom:0` is a belt-and-braces guarantee
     that it never scrolls out of reach. */
  .my35w-inputbar {
    position: sticky;
    bottom: 0;
    flex: 0 0 auto;
    /* A touch more top breathing room + extra bottom over the home indicator so
       the bar doesn't feel pinned to the sheet edge (owner spacing fine-tune). */
    padding-top: var(--ds-space-4);
    padding-bottom: calc(var(--ds-space-4) + env(safe-area-inset-bottom, 0px));
    padding-left:   calc(var(--ds-space-3) + env(safe-area-inset-left, 0px));
    padding-right:  calc(var(--ds-space-3) + env(safe-area-inset-right, 0px));

    /* iOS keyboard fallback: when interactive-widget=resizes-content is NOT
       honoured (older iOS Safari), the JS visualViewport handler sets
       --my35-kb-offset on the panel to the keyboard overlap; the bar rides
       up by that amount so it is never hidden behind the keyboard. Default
       0 = no shift. transform (not bottom) keeps it cheap + compositor-only. */
    transform: translateY(calc(-1 * var(--my35-kb-offset, 0px)));
    will-change: transform;
  }

  /* The textarea MUST be 16px on mobile — below it Safari force-zooms the
     page on focus. This is mandatory, not cosmetic. */
  .my35w-field {
    font-size: 16px;
    min-height: var(--my35-ai-tap-min);
  }

  /* Send button is a real 44px target. */
  .my35w-send {
    min-width: var(--my35-ai-tap-min);
    min-height: var(--my35-ai-tap-min);
  }

  /* ----- 2.6 CHIPS: wrap, comfortable tap height, text floor --------------- */
  .my35w-chips,
  .my35w-starters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ds-space-2);
  }
  .my35w-chip {
    min-height: var(--my35-ai-tap-min);
    display: inline-flex;
    align-items: center;
    font-size: max(var(--ds-text-sm), var(--my35-ai-text-min));
  }

  /* ----- 2.7 PRODUCT CARDS: single comfortable column, image not cramped --- */
  .my35w-products {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-3);
  }
  .my35w-card {
    width: 100%;
    max-width: 100%;
  }
  .my35w-card-img {
    width: 76px;
    height: 76px;
  }
  .my35w-card-reason,
  .my35w-card-strike {
    /* Never drop below the legible floor on mobile. */
    font-size: max(var(--ds-text-sm), var(--my35-ai-text-min));
  }
  /* CTA is a genuine tap target and may go full-width on tight rows. */
  .my35w-card-cta {
    min-height: var(--my35-ai-tap-min);
  }

  /* ----- 2.8 SAFETY card: tel action is a real target ---------------------- */
  .my35w-safety-actions { flex-wrap: wrap; gap: var(--ds-space-2); }
  .my35w-tel {
    min-height: var(--my35-ai-tap-min);
    display: inline-flex;
    align-items: center;
  }
}

/* --------------------------------------------------------------------------
   3. NARROW PHONES (<=380px) — trim chrome so nothing is cramped, while
      keeping text >=13px and taps >=44px. Full-width CTAs avoid wrap-clip.
   -------------------------------------------------------------------------- */
@media (max-width: 380px) {
  .my35w-stream    { padding-left: var(--ds-space-3); padding-right: var(--ds-space-3); }
  .my35w-bubble    { max-width: 92%; }
  .my35w-card-img  { width: 64px; height: 64px; }

  .my35w-card-cta,
  .my35w-chip {
    width: 100%;
    justify-content: center;
  }
}

/* --------------------------------------------------------------------------
   4. TABLET band REMOVED. The full-screen sheet (§2, @media <=900px) now owns
      every phone AND tablet-portrait width, so there is no floating-card band
      left to leave black gaps above the header / below the input bar. The
      desktop floating card applies only at >900px. Product cards are already
      single-column via the base .my35w-products rule.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   5. SHORT VIEWPORTS — don't waste scarce height on fixed chrome.
      Triggered by a short viewport regardless of orientation, so it covers:
        · landscape phones (max-height:480px + landscape)
        · keyboard-squeezed PORTRAIT phones (keyboard halves the height)
        · short tablets / split-screen panes
      The pure (max-height:560px) trigger catches the portrait + tablet cases
      the landscape-only rule used to miss. The sheet rules from §2 still
      apply at <=600px; here we only compress header + welcome + stream
      padding so the stream and input bar stay reachable.
   -------------------------------------------------------------------------- */
@media (max-height: 560px),
       (max-height: 480px) and (orientation: landscape) {
  .my35w-header {
    min-height: 0;
    padding-top: var(--ds-space-2);
    padding-bottom: var(--ds-space-2);
  }
  .my35w-welcome {
    padding-top: var(--ds-space-3);
    padding-bottom: var(--ds-space-3);
  }
  .my35w-stream {
    padding-top: var(--ds-space-2);
    padding-bottom: var(--ds-space-2);
  }
  /* On very short screens the panel still fills the dynamic viewport. */
  .my35w-panel { height: 100dvh; max-height: 100dvh; }
}

/* ==========================================================================
   6. ACCESSIBILITY — focus rings that DO NOT depend on JS, + forced-colors.
      (ARIA/roles live in JS; this guarantees the VISUAL focus side.)
   ========================================================================== */

/* 6.1 Primary ring on the design-system focusable primitive + every native
   interactive element. :focus-visible so it doesn't fire on mouse taps. */
.my35w .ds-focusable:focus-visible,
.my35w-fab:focus-visible,
.my35w-close:focus-visible,
.my35w-header-avatar:focus-visible,
.my35w-chip:focus-visible,
.my35w-card-cta:focus-visible,
.my35w-tel:focus-visible,
.my35w-send:focus-visible,
.my35w-field:focus-visible,
.my35w a:focus-visible,
.my35w button:focus-visible,
.my35w textarea:focus-visible,
.my35w [tabindex]:focus-visible {
  outline: 3px solid var(--my35-ink, #2D3436);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgba(255, 199, 0, 0.55);
  border-radius: var(--ds-radius-sm, 8px);
}

/* 6.2 Fallback for engines without :focus-visible — keyboard users always
   get a ring. Plain :focus, no JS required. */
.my35w .ds-focusable:focus,
.my35w-fab:focus,
.my35w-close:focus,
.my35w-chip:focus,
.my35w-card-cta:focus,
.my35w-send:focus,
.my35w-field:focus,
.my35w a:focus,
.my35w button:focus,
.my35w textarea:focus {
  outline: 2px solid var(--my35-ink, #2D3436);
  outline-offset: 2px;
}

/* 6.3 Suppress the fallback when :focus-visible IS supported but not active
   (so mouse clicks don't show a ring on engines that have :focus-visible). */
@supports selector(:focus-visible) {
  .my35w .ds-focusable:focus:not(:focus-visible),
  .my35w-fab:focus:not(:focus-visible),
  .my35w-close:focus:not(:focus-visible),
  .my35w-chip:focus:not(:focus-visible),
  .my35w-card-cta:focus:not(:focus-visible),
  .my35w-send:focus:not(:focus-visible),
  .my35w-field:focus:not(:focus-visible),
  .my35w a:focus:not(:focus-visible),
  .my35w button:focus:not(:focus-visible),
  .my35w textarea:focus:not(:focus-visible) {
    outline: none;
    box-shadow: none;
  }
}

/* 6.4 Forced-colors (Windows High Contrast) — keep a system-colored ring;
   our brand halo is dropped automatically by the OS, so re-assert outline. */
@media (forced-colors: active) {
  .my35w .ds-focusable:focus-visible,
  .my35w-fab:focus-visible,
  .my35w-close:focus-visible,
  .my35w-chip:focus-visible,
  .my35w-card-cta:focus-visible,
  .my35w-send:focus-visible,
  .my35w-field:focus-visible,
  .my35w a:focus-visible,
  .my35w button:focus-visible,
  .my35w textarea:focus-visible {
    outline: 3px solid CanvasText;
    outline-offset: 2px;
  }
}

/* ============================================================================
   LIVE CASCADE GUARD — the host theme sets `body h1..h6 { font-family: Geologica }`
   (specificity 0,0,2 with the `body` prefix) which was overriding the widget's
   single-class `.my35w-header-title`. Scope our typography under `.my35w` with
   doubled classes so it wins on the LIVE page without touching the theme.
   ========================================================================== */
.my35w .my35w-header-title,
.my35w-panel .my35w-header-title { font-family: var(--ds-font-display) !important; }
.my35w .my35w-welcome-title,
.my35w-panel .my35w-welcome-title { font-family: var(--ds-font-display) !important; }
.my35w .my35w-bubble, .my35w .my35w-bubble *,
.my35w .my35w-card-title, .my35w .my35w-card-reason,
.my35w .my35w-field, .my35w .my35w-chip,
.my35w .my35w-header-eyebrow, .my35w .my35w-status,
.my35w .my35w-welcome-sub, .my35w .my35w-card-price,
.my35w .my35w-safety, .my35w .my35w-safety * {
  font-family: var(--ds-font-body) !important;
}
/* the title/welcome heading must NOT inherit the theme heading color/transform either */
.my35w .my35w-header-title, .my35w .my35w-welcome-title {
  text-transform: none !important;
  letter-spacing: var(--ds-tracking-tight) !important;
}
