/* ==========================================================================
   Ask Amna — NCSC chatbot component
   Source: Figma "Chat Bot_Ask Amna_latest" (file AS5VhAwylNFhFOrKExGATY)
     - launcher .......... node 183:4027  (96px circle, first screen)
     - chat panel ........ node 183:3750  (1025x714 panel)
     - user bubble ....... node 183:3924

   Every rule is scoped under #cb-widget. Nothing here selects a bare element
   outside that root, so it cannot bleed into the host page's Bootstrap 4 /
   styles.css cascade.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Fonts — mirrors the per-weight family names already used by _sass/theme.scss
   so the widget renders identically whether or not styles.css is present.
   -------------------------------------------------------------------------- */
@font-face {
    font-family: 'Poppins ExtraLight';
    font-style: normal;
    font-weight: normal;
    font-display: swap;
    src: local('Poppins ExtraLight'), url('/static_assets/fonts/Poppins-ExtraLight.woff') format('woff');
}

@font-face {
    font-family: 'Poppins Regular';
    font-style: normal;
    font-weight: normal;
    font-display: swap;
    src: local('Poppins Regular'), url('/static_assets/fonts/Poppins-Regular.woff') format('woff');
}

@font-face {
    font-family: 'Poppins Medium';
    font-style: normal;
    font-weight: normal;
    font-display: swap;
    src: local('Poppins Medium'), url('/static_assets/fonts/Poppins-Medium.woff') format('woff');
}

@font-face {
    font-family: 'Poppins Bold';
    font-style: normal;
    font-weight: normal;
    font-display: swap;
    src: local('Poppins Bold'), url('/static_assets/fonts/Poppins-Bold.woff') format('woff');
}

/* Arabic — mirrors the family names used by _sass/arabic.scss. */
@font-face {
    font-family: 'Tajawal ExtraLight';
    font-style: normal;
    font-weight: normal;
    font-display: swap;
    src: local('Tajawal ExtraLight'), url('/static_assets/fonts/Tajawal-ExtraLight.woff') format('woff');
}

@font-face {
    font-family: 'Tajawal Regular';
    font-style: normal;
    font-weight: normal;
    font-display: swap;
    src: local('Tajawal Regular'), url('/static_assets/fonts/Tajawal-Regular.woff') format('woff');
}

@font-face {
    font-family: 'Tajawal Medium';
    font-style: normal;
    font-weight: normal;
    font-display: swap;
    src: local('Tajawal Medium'), url('/static_assets/fonts/Tajawal-Medium.woff') format('woff');
}

@font-face {
    font-family: 'Tajawal Bold';
    font-style: normal;
    font-weight: normal;
    font-display: swap;
    src: local('Tajawal Bold'), url('/static_assets/fonts/Tajawal-Bold.woff') format('woff');
}

/* --------------------------------------------------------------------------
   Design tokens (Figma values, verbatim)
   -------------------------------------------------------------------------- */
#cb-widget {
    --cb-navy: #1c2435;
    --cb-red: #e8332a;
    /* The site's own button red — rgb(237, 29, 36), .NCSC-btn-primary in
       _sass/theme.scss, which is what the Subscribe button and the
       scroll-to-top arrow are painted with. Deliberately NOT --cb-red above:
       that one comes from the Figma file and is a slightly different hue, and
       the launcher label sits on the page beside those controls where the two
       reds would be seen together. */
    --cb-site-red: #ed1d24;
    /* The app's OWN primary red - $primary-color in _sass/base.scss, the fill
       behind .NCSC-btn-primary across the site. The Figma red above is a
       different hue by a few degrees (3deg against this one's 358deg), which
       reads as two nearly-but-not-quite matching reds once the drawer opens
       over a page carrying site buttons. The drawer's primary CTA uses this
       so it matches the page behind it.

       --cb-red stays as it was for the focus ring, the error text and the
       send button: those are the widget's own chrome, not a match to
       anything on the host page.

       Contrast note: white on this measures 4.37:1, just under the 4.5:1 AA
       wants for a 14px label (and 14px is too small for the 3:1 large-text
       allowance, which starts at 24px). It is a shade better than the Figma
       red's 4.25:1, and matching the site was the deliberate call. */
    --cb-red-app: #ed1d24;
    /* darken($primary-color, 8%) - the same step .NCSC-btn-primary:hover
       takes on its border. 5.52:1 behind white. */
    --cb-red-app-hover: #d11117;
    --cb-surface: #ffffff;
    --cb-bar: #1c2435; /* logo bar — Figma node 209:142, the opaque fill over #1b3c6a */
    --cb-bubble-bot: #f5f5f5;
    /* The ground both views stand on. Replaces the solid navy band: the wave
       keeps Figma's own gradient, which resolves toward #1C2435, and a navy
       wave on a navy block is invisible. This is the site's own paper grey.
       Named for the intro when only the intro used it; the conversation now
       carries the same ground and the same wave along its foot. */
    --cb-ground: #f6f6f6;
    /* Suggested-topic chips. Cool-tinted rather than the bubbles' neutral
       #f5f5f5, so an ACTION separates from the message content beside it,
       and light enough that the red CTA stays the loudest thing in view.
       White chips on the white log left only a hairline to define them. */
    --cb-chip: #e6eaf2;
    --cb-chip-line: rgba(28, 36, 53, 0.28);
    --cb-bubble-user: rgba(0, 0, 0, 0.15);
    --cb-ink: #000000;
    --cb-ink-muted: rgba(0, 0, 0, 0.4);

    --cb-radius-bubble: 16px;
    /* The drawer's own corners. The PANEL is rounded; the controls inside it
       are not. It is a floating surface over the page rather than a control,
       and it hosts the bubbles that already curve at 16px. The controls take a
       small 8px softening of their own via --cb-radius-btn below - enough to
       take the hard edge off, not enough to read as pills.

       .cb-drawer sets overflow:hidden, so the bar and the intro hero ground
       clip to this. */
    --cb-radius-panel: 16px;
    --cb-radius-btn: 8px;

    --cb-font-regular: 'Poppins Regular', 'Poppins', 'Segoe UI', sans-serif;
    --cb-font-medium: 'Poppins Medium', 'Poppins', 'Segoe UI', sans-serif;
    --cb-font-bold: 'Poppins Bold', 'Poppins', 'Segoe UI', sans-serif;
    --cb-font-light: 'Poppins ExtraLight', 'Poppins', 'Segoe UI', sans-serif;

    --cb-shadow: 0 12px 40px rgba(28, 36, 53, 0.22);
    --cb-shadow-launcher: 0 6px 20px rgba(28, 36, 53, 0.28);

    /* Component geometry — overridden per surface below. */
    --cb-pad-x: 20px;
    --cb-compose-h: 56px;
    /* The launcher shares a vertical column with the site's scroll-to-top
       button (#myBtn, _sass/theme.scss), which now sits on the same horizontal
       line as the accessiBe accessibility trigger. Three fixed values, because
       the two neighbours are fixed too - a launcher that scaled with the
       viewport would drift out of the column exactly where space is tightest.

       20px from the inline edge, matching the inset accessiBe uses on the
       left and the scroll-to-top button beside it. */
    --cb-edge-x: 20px;
    /* Bottom-RIGHT on English - the same corner the accessiBe trigger occupies,
       so the launcher has to sit above it: accessiBe's 20px bottom + its 48px
       height + a 12px gap. The RTL block below drops this back to 20px, because
       there the launcher mirrors to the opposite, empty corner. */
    --cb-edge-y: 80px;

    /* 72px — the ceiling of the fluid clamp this replaced, and the largest the
       design was ever willing to go. At 48px, matching the accessiBe trigger
       exactly, it read as a third utility button rather than the way into the
       service, and people did not find it.

       It no longer matches the trigger's 48px, so the two share a flush right
       edge instead of a centre line. That is a deliberate trade: a right-ranged
       column of unequal sizes is a normal arrangement, and matching the
       trigger's size is what made the launcher too small to notice.

       Read together with --cb-launcher-edge-y below and with #myBtn's fixed
       right/left/bottom in _sass/theme.scss and _sass/arabic.scss — those are
       the neighbours it has to clear, and they do not move. */
    --cb-launcher-size: 72px;

    /* The launcher's own bottom inset, separate from --cb-edge-y because only
       the launcher has to clear the button row: the drawer covers those buttons
       outright at z-index 1080, so it is free to sit lower. LTR they are the
       same value; RTL is where they diverge (see below). */
    --cb-launcher-edge-y: 80px;
}

/* The drawer carries its own direction via the host page's <html dir="rtl">
   rather than an attribute of its own (it is not a page), so this keys off
   that instead of a selector on #cb-widget itself. Now that the standalone
   Arabic page is gone, #cb-widget is the ONLY Arabic surface this stylesheet
   serves — without this swap Arabic copy would render in Poppins, which has
   no Arabic glyphs, and fall back to whatever the browser picks. Same four
   Tajawal families as the retired page used, verbatim. */
/* The widget mirrors to the bottom-LEFT here, and the accessiBe trigger stays
   bottom-RIGHT on every locale - it does not mirror. So the RTL launcher has an
   empty corner to itself and sits at the plain 20px inset; only the LTR one
   above needs to clear the trigger. */
[dir='rtl'] #cb-widget {
    --cb-edge-y: 20px;

    /* The launcher does NOT drop to 20px with the drawer. The corner is empty of
       accessiBe, but #myBtn mirrors into it (left: 80px, bottom: 26.5px, 35px
       square) and a 72px circle at a 20px inset reaches 92px across — straight
       through it. It cleared only while the launcher was 48px. Same 80px as LTR
       rather than the 74px that would just clear, so the launcher sits on one
       line in both locales. */
    --cb-launcher-edge-y: 80px;

    --cb-font-regular: 'Tajawal Regular', 'Tajawal', 'Segoe UI', sans-serif;
    --cb-font-medium: 'Tajawal Medium', 'Tajawal', 'Segoe UI', sans-serif;
    --cb-font-bold: 'Tajawal Bold', 'Tajawal', 'Segoe UI', sans-serif;
    --cb-font-light: 'Tajawal ExtraLight', 'Tajawal', 'Segoe UI', sans-serif;
}

#cb-widget,
#cb-widget *,
#cb-widget *::before,
#cb-widget *::after {
    box-sizing: border-box;
}

/* ==========================================================================
   1. Floating widget shell
   ========================================================================== */

/* Positioned with logical inset so it sits bottom-right on LTR pages and
   mirrors to bottom-left on the RTL Arabic pages. */
#cb-widget {
    position: fixed;
    /* The shell holds only the launcher — .cb-drawer is position:fixed and
       places itself off --cb-edge-y — so this is the launcher's inset. */
    inset-block-end: var(--cb-launcher-edge-y);
    inset-inline-end: var(--cb-edge-x);
    /* Bootstrap 4.6.2 puts its navbar at 1030, dropdown at 1000, modal
       backdrop at 1040, modal at 1050, popover at 1060, tooltip at 1070.
       1080 deliberately sits above all of those — the widget is meant to
       float over everything. */
    z-index: 1080;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 16px;
    pointer-events: none;
}

#cb-widget > * {
    pointer-events: auto;
}

/* --- 1a. Launcher — Figma node 183:4027. Toggles the drawer below. ------ */
/* Smaller than Figma's 96px on purpose — at that size the launcher dominated the
   homepage. 72px ceiling, scaling with the smaller of width and height so a
   short landscape phone shrinks it too. The 56px floor stays well above the
   44px minimum tap target; the source PNG is 288px so it is never upscaled. */
/* The launcher and its label. The dock is what .cb-launcher__tip positions
   against now that the tip is a sibling rather than a child — the tip hangs
   outside the circle, so the context has to be something that contains both. */
#cb-widget .cb-launcher-dock {
    position: relative;
    display: block;
    width: var(--cb-launcher-size);
    height: var(--cb-launcher-size);
}

/* The circle itself arrives first and the label follows (see the keyframes
   below): a label sliding out of a button that is not there yet has nothing to
   slide out OF. */
#cb-widget .cb-launcher {
    display: block;
    /* No fill mode. `both`/`forwards` would leave the end keyframe applied for
       the life of the page, and an animation origin outranks normal
       declarations — so .cb-widget--open's opacity:0 / scale(0.8) below would
       never take effect and the launcher would refuse to get out of the
       drawer's way. There is no delay to cover, so nothing is lost. */
    animation: cb-launcher-in 0.32s ease;
    width: var(--cb-launcher-size);
    height: var(--cb-launcher-size);
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--cb-surface) url('/chatbot/assets/amna-launcher.png') center / cover no-repeat;
    box-shadow: var(--cb-shadow-launcher);
    text-decoration: none;
    cursor: pointer;
    transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease, visibility 0s linear 0s;
    -webkit-appearance: none;
    appearance: none;
}

/* A 1.05 lift was too slight to register as a response at this size. 1.08 with
   a deeper shadow reads as the button coming toward the cursor, which is the
   cue that it is pressable — and it is the same gesture the tip's slide plays
   against, so the two land as one movement rather than two. */
#cb-widget .cb-launcher:hover,
#cb-widget .cb-launcher:focus-visible {
    transform: scale(1.08);
    box-shadow: 0 14px 34px rgba(28, 36, 53, 0.42);
}

#cb-widget .cb-launcher:focus-visible {
    outline: 3px solid var(--cb-red);
    outline-offset: 3px;
}

/* The launcher's name, revealed on hover and on keyboard focus. Sits on the
   inline-start side, i.e. inward from whichever corner the launcher occupies,
   so it opens over the page rather than off the edge of the viewport -
   inset-inline-end handles the RTL flip on its own. */
#cb-widget .cb-launcher__tip {
    position: absolute;
    inset-inline-end: calc(100% + 12px);
    top: 50%;
    display: flex;
    align-items: center;
    padding: 8px 14px;
    border-radius: var(--cb-radius-btn);
    background: var(--cb-site-red);
    color: var(--cb-surface);
    font-family: var(--cb-font-medium);
    /* 14px, matching message text. The label is the one place the launcher says
       what it is in words; set smaller than the conversation it opens, it read
       as a caption on the picture rather than the name of the thing. */
    font-size: 14px;
    line-height: 20px;
    white-space: nowrap;
    box-shadow: var(--cb-shadow-launcher);
    /* Always on, not revealed on hover. A hover-only label is invisible to
       everyone who never hovers — every touch device, and anyone who does not
       already suspect the circle is worth pointing at. The name is the only
       thing that says what this opens, so it cannot be behind an interaction.

       It stays aria-hidden: the button already carries the fuller sr-only
       label, and announcing both would say the name twice.

       pointer-events stays auto now that it is permanent — the label is part of
       the target. Clicks bubble to the button that contains it, and hovering it
       lights the whole control rather than flickering. */
    /* Delayed past the launcher's own entrance, so the two read as a sequence:
       the character appears, then introduces itself. `both` holds the from-state
       through the delay — without it the label is briefly visible at full
       opacity before the animation starts. */
    /* `backwards`, not `both`, for the same reason as the launcher — but here
       the delay DOES need covering, and backwards holds the from-state through
       it without pinning the end-state afterwards. The resting values below are
       what the cascade returns to once it finishes; translateY(-50%) in
       particular has to stay, or the label drops half its height at the moment
       the animation ends. */
    opacity: 1;
    transform: translateY(-50%);
    animation: cb-tip-in 0.34s ease 0.42s backwards;
    transition: transform 0.18s ease, box-shadow 0.18s ease;
}

#cb-widget .cb-launcher__tip-text {
    cursor: pointer;
}

/* Straddling the pill's top edge — half on the label, half off it — so it
   reads as something attached to the label rather than a third word inside it.
   Sat inline, it competed with the name for the same line.

   inset-inline-END: top-right in English, mirroring to top-left in Arabic, the
   corner a close control is conventionally looked for. That was ruled out while
   the badge overhung horizontally too, because the launcher's circle bulges
   back toward the pill right about there. Now that the overhang is vertical
   only, the badge never leaves the pill's own width and the clearance question
   does not arise.

   Light chip on a dark pill, with its own shadow: the top half overhangs onto
   whatever the page happens to have behind it, so it cannot borrow the pill's
   contrast for legibility. */
#cb-widget .cb-launcher__tip-close {
    position: absolute;
    top: 0;
    /* Sat ON the corner, centred over the corner POINT, it floated in the gap
       the 8px radius curves away from — a detached blob with the pill nowhere
       near it. Nudged along the top edge onto the straight run instead: half
       above the edge, half over the label, touching it the whole way.

       This also drops the RTL transform pair. Overhang is now vertical only, so
       inset-inline-end mirrors the position on its own and there is no signed
       X to flip. */
    inset-inline-end: 2px;
    /* -40%, not -50%: more of the chip sits on the pill than off it, so it
       reads as belonging to the label rather than balancing on its edge. */
    transform: translateY(-40%);
    z-index: 1;
    /* 20. Big enough that the mark inside it is legible at a glance and the
       chip is a comfortable target, small enough that it stays subordinate to
       the label — 22 read as two objects of comparable weight. */
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--cb-surface);
    color: var(--cb-site-red);
    /* Tight and low — it sits ON the pill now, so the shadow only has to lift it
       off that, not carry it across open page. */
    box-shadow: 0 1px 3px rgba(28, 36, 53, 0.3);
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.15s ease, transform 0.15s ease;
    -webkit-appearance: none;
    appearance: none;
}

/* Stroked rather than filled, so weight is a number here instead of a
   font's opinion. currentColor keeps it in step with the chip's hover swap. */
#cb-widget .cb-launcher__tip-close-icon {
    width: 10px;
    height: 10px;
    display: block;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
}

/* Navy on hover, not red. Red-on-red was the previous pairing inverted onto a
   navy pill; against a red one it would be the chip disappearing into its own
   background at the moment it is being pointed at. */
#cb-widget .cb-launcher__tip-close:hover,
#cb-widget .cb-launcher__tip-close:focus-visible {
    background: var(--cb-bar);
    color: var(--cb-surface);
    transform: translateY(-40%) scale(1.12);
}

#cb-widget .cb-launcher__tip-close:focus-visible {
    outline: 2px solid var(--cb-bar);
    outline-offset: 2px;
}

/* Dismissed for the session. display:none rather than opacity so it stops being
   a hit target and leaves the tab order — a control faded to nothing is still
   focusable, and a keyboard would land on a close button for a label that is
   not on screen. */
#cb-widget.cb-widget--tip-off .cb-launcher__tip {
    display: none;
}

@keyframes cb-launcher-in {
    from {
        opacity: 0;
        transform: scale(0.6);
    }

    to {
        opacity: 1;
        transform: scale(1);
    }
}

/* Slides out from behind the launcher. translateX is unsigned here and flipped
   for RTL below, so the label always emerges from the circle rather than from
   whichever side the LTR layout happened to put it on. */
@keyframes cb-tip-in {
    from {
        opacity: 0;
        transform: translateY(-50%) translateX(16px) scale(0.92);
    }

    to {
        opacity: 1;
        transform: translateY(-50%) translateX(0) scale(1);
    }
}

[dir='rtl'] #cb-widget .cb-launcher__tip {
    animation-name: cb-tip-in-rtl;
}

@keyframes cb-tip-in-rtl {
    from {
        opacity: 0;
        transform: translateY(-50%) translateX(-16px) scale(0.92);
    }

    to {
        opacity: 1;
        transform: translateY(-50%) translateX(0) scale(1);
    }
}

/* Hover now nudges the label toward the launcher instead of revealing it — the
   pair moves as one object, which is the cue that they are one control. The
   direction mirrors with the layout, so RTL leans the other way. */
#cb-widget .cb-launcher:hover .cb-launcher__tip,
#cb-widget .cb-launcher:focus-visible .cb-launcher__tip {
    transform: translateY(-50%) translateX(4px);
    box-shadow: 0 8px 20px rgba(28, 36, 53, 0.32);
}

[dir='rtl'] #cb-widget .cb-launcher:hover .cb-launcher__tip,
[dir='rtl'] #cb-widget .cb-launcher:focus-visible .cb-launcher__tip {
    transform: translateY(-50%) translateX(-4px);
}

/* Open: the launcher gets out of the way, on every viewport rather than only
   on the phone sheet that used to bury it. The drawer grows out of the corner
   the launcher occupied, so leaving a 72px circle sitting under it reads as
   two objects instead of one becoming the other.

   visibility, not display: display cannot be transitioned, so the shrink
   would never play. Its 0s step is delayed to the END of the fade on the way
   out (so the launcher stays hit-testable and focusable until it has actually
   gone) and runs at 0s on the way back in, from the base rule above. */
#cb-widget.cb-widget--open .cb-launcher {
    opacity: 0;
    transform: scale(0.8);
    visibility: hidden;
    pointer-events: none;
    transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease, visibility 0s linear 0.2s;
}

/* Screen-reader-only label riding along with the launcher. */
#cb-widget .cb-sr {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* No motion means no motion, but the elements still have to ARRIVE at the open
   and closed states — only the tweening goes. init() reads the same query and
   drops its close delay to 0 in step, so the drawer is not left rendered and
   focusable for 220ms after it has visually vanished. */
@media (prefers-reduced-motion: reduce) {
    #cb-widget .cb-launcher,
    #cb-widget .cb-launcher__tip,
    #cb-widget .cb-launcher__tip-close,
    #cb-widget.cb-widget--open .cb-launcher,
    #cb-widget .cb-drawer,
    #cb-widget .cb-topic,
    #cb-widget .cb-btn-new {
        transition: none;
    }

    /* The staged entrance is motion for its own sake — the launcher and its
       label are simply present. animation:none also drops the tip's delay, so
       the label is there from the first paint rather than after 420ms of
       nothing. */
    #cb-widget .cb-launcher,
    #cb-widget .cb-launcher__tip,
    [dir='rtl'] #cb-widget .cb-launcher__tip {
        animation: none;
    }
}

/* --- 1b. Drawer -------------------------------------------------------- */

/* Anchored to the same corner the launcher occupies, on the same inline edge
   so it mirrors with it. It sits ON the launcher rather than above it: the
   launcher is hidden for as long as the drawer is open, and offsetting past a
   control that is not there left dead space under the panel. Sharing the
   corner also puts the transform-origin exactly where the launcher was, which
   is what makes the two read as one object. */
#cb-widget .cb-drawer {
    position: fixed;
    inset-block-end: var(--cb-edge-y);
    inset-inline-end: var(--cb-edge-x);
    z-index: 1080;
    display: flex;
    flex-direction: column;
    width: min(400px, calc(100vw - 2 * var(--cb-edge-x)));
    /* edge-y is bottom clearance for the button stack, not a symmetric margin,
       so the top gets its own smaller inset rather than the same 67px. */
    height: min(700px, calc(100vh - var(--cb-edge-y) - 24px));
    border-radius: var(--cb-radius-panel);
    background: var(--cb-surface);
    box-shadow: var(--cb-shadow);
    overflow: hidden;

    /* Closed resting state. The drawer grows out of the corner the launcher
       just vacated, so the origin is the bottom inline edge. Only opacity and
       transform animate: both are compositor-driven, so a 400x700 panel over a
       full homepage does not force a repaint on every frame. */
    opacity: 0;
    transform: scale(0.92) translateY(8px);
    transform-origin: bottom right;
    transition: opacity 0.22s ease, transform 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}

/* transform-origin takes no logical keywords, so the RTL mirror is explicit —
   without it the Arabic drawer sits on the left but expands from the right. */
[dir='rtl'] #cb-widget .cb-drawer {
    transform-origin: bottom left;
}

#cb-widget.cb-widget--open .cb-drawer {
    opacity: 1;
    transform: none;
}

/* Still painted for the 220ms it takes to fade out, so stop it swallowing
   clicks meant for the page behind it during the close. */
#cb-widget:not(.cb-widget--open) .cb-drawer {
    pointer-events: none;
}

/* Applied by setOpen() only once the close transition has finished — set it
   up front and display:none cancels the fade outright. */
#cb-widget .cb-drawer[hidden] {
    display: none;
}

#cb-widget .cb-drawer__bar {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-inline: 16px;
    height: 56px;
    background: var(--cb-bar);
    color: var(--cb-surface);
}

/* Avatar + name, so the bot is identified once in the chrome rather than
   beside every message it sends. */
#cb-widget .cb-drawer__identity {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

#cb-widget .cb-drawer__avatar {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--cb-bubble-bot) url('/chatbot/assets/amna-avatar.png') center / cover no-repeat;
}

#cb-widget .cb-drawer__title {
    font-family: var(--cb-font-bold);
    font-size: 16px;
}

/* The intro already says "Hi, I'm Amna" in 20px right below the bar, so the
   bar repeating the name is the same words twice in one glance. Hidden with
   visibility, not display, so it keeps its space and the close button stays
   put instead of jumping edge-to-edge when the view swaps. Driven by the
   same data-cb-view attribute as the view toggle itself. */
#cb-widget .cb-drawer:not([data-cb-view='chat']) .cb-drawer__title,
#cb-widget .cb-drawer:not([data-cb-view='chat']) .cb-drawer__avatar {
    visibility: hidden;
}

/* On the intro the bar carries the hero ground rather than sitting on it, so
   the panel opens as one field from its top edge down to the copy. Flat colour
   on both the bar and the figure below, so there is no seam to align. The
   CHAT view keeps the navy bar - this is scoped to the intro deliberately. */
#cb-widget .cb-drawer:not([data-cb-view='chat']) .cb-drawer__bar {
    background: var(--cb-ground);
    color: var(--cb-navy);
}

/* White on a paper ground would be invisible. */
#cb-widget .cb-drawer:not([data-cb-view='chat']) .cb-drawer__close {
    color: var(--cb-navy);
}

#cb-widget .cb-drawer:not([data-cb-view='chat']) .cb-drawer__close:focus-visible {
    outline-color: var(--cb-navy);
}

#cb-widget .cb-drawer__close {
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: var(--cb-radius-btn);
    background: transparent;
    color: var(--cb-surface);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
}

#cb-widget .cb-drawer__close:focus-visible {
    outline: 2px solid var(--cb-surface);
    outline-offset: -2px;
}

/* Reset + close, grouped so they sit together at the bar's trailing edge and
   the title keeps the leading one. */
#cb-widget .cb-drawer__actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Ghost, not a fill. Red is the brand primary-action colour and this is an
   undoable reset; the primary action in this panel is asking a question. It
   also sits right beside the close button, and two filled treatments competing
   inside a 56px bar reads busier than one. White on the navy bar measures
   15.52:1, so the label is far clearer here than on any red. The plus glyph is
   filled white in the source SVG, so it carries over unchanged.
   (.cb-start keeps a fill - that button IS the primary action of its view,
   and it now carries the site's own red so it matches the page behind.) */
#cb-widget .cb-btn-new {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    /* 36px, as it was on the retired row — the 56px bar has the room, and
       shrinking it would have cut the tap target for no gain. */
    min-height: 36px;
    padding: 7px 12px;
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: var(--cb-radius-btn);
    background: transparent;
    color: var(--cb-surface);
    font-family: var(--cb-font-regular);
    font-size: 13px;
    line-height: 18px;
    white-space: nowrap; /* the label must never wrap inside a 56px bar */
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
    -webkit-appearance: none;
    appearance: none;
}

#cb-widget .cb-btn-new:hover,
#cb-widget .cb-btn-new:focus-visible {
    border-color: var(--cb-surface);
    background: rgba(255, 255, 255, 0.14);
}

/* Ringed OUTSIDE the button, not inset: inset, a 2px white ring would sit on
   top of the 1px border and thicken it; outside it lands on the bare navy. */
#cb-widget .cb-btn-new:focus-visible {
    outline: 2px solid var(--cb-surface);
    outline-offset: 2px;
}

#cb-widget .cb-btn-new__icon {
    width: 12px;
    height: 12px;
    display: block;
    flex: 0 0 auto;
}

/* Nothing to reset before the conversation starts, and the bar is shared by
   both views — so it hides on the intro, driven by the same data-cb-view
   attribute as the view swap below. */
#cb-widget .cb-drawer:not([data-cb-view='chat']) .cb-btn-new {
    display: none;
}

#cb-widget .cb-drawer__body {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

/* The conversation panel hosted inside the drawer body. Uses the base token
   values (--cb-pad-x, --cb-compose-h, etc. set on #cb-widget) as-is — the drawer
   is ~400px wide, far narrower than the retired full-page screen's 1025px
   panel, which no longer exists to override them larger. */
#cb-widget .cb-drawer .cb-panel {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    /* Paper, not white — the wave below is a gradient that starts fully
       transparent, so it needs a ground to dissolve into. On white it would
       stop at an edge instead of fading out. */
    background: var(--cb-ground);
    /* Positioning context for that wave. */
    position: relative;
}

/* The wave along the foot of the conversation, the same treatment the intro
   gives its hero band (see .cb-intro__figure::after below) — same asset, same
   untouched Figma gradient, same bottom anchor. Carried across so the drawer
   reads as one surface from the moment it opens through to the chat, rather
   than as an illustrated cover over a plain panel.

   Pinned to the PANEL rather than sitting at the end of the log: the log
   scrolls and the wave must not: it is the ground the conversation stands on,
   so messages travel over it. Taller than the intro's 150px because it has no
   character standing on it to set the scale, and the panel is the full height
   of the drawer body. */
#cb-widget .cb-drawer .cb-panel::after {
    content: '';
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    height: 170px;
    background: url('/chatbot/assets/wave.svg') bottom center / 100% 100% no-repeat;
    pointer-events: none;
}

/* The wave is a ::after on .cb-panel, so it paints after both of these and
   would otherwise cover the last messages and the composer. Raising them is
   what puts the conversation ON the wave instead of under it. */
#cb-widget .cb-drawer .cb-log,
#cb-widget .cb-drawer .cb-compose {
    position: relative;
    z-index: 1;
}

/* Compact intro, as a hero band over a block of text.
   The character used to float on white with ~98px of dead space above it (16%
   of the panel): the column bottom-anchored its content, so every pixel of
   leftover height collected in one void at the top, and the figure rendered
   only 122px wide in a 400px panel. A full-bleed navy ground turns that space
   into structure, gives the character something to stand on, and ties the view
   to the title bar directly above it. */
#cb-widget .cb-drawer .cb-intro {
    flex: 1 1 auto;
    min-height: 0;
    flex-direction: column;
    justify-content: flex-start;
    /* stretch, not the base rule's center: the band has to reach both edges. */
    align-items: stretch;
    gap: 0;
    /* The band bleeds to the drawer's edges, so the horizontal inset moves onto
       the text blocks below instead of sitting on the column. */
    padding: 0;
    overflow-y: auto;
}

/* The hero ground. Was a solid navy block; it now carries the paper tone and
   the wave, which sits along its foot. A fixed share of the panel, so the text
   below always keeps its room, and the figure stands ON the bottom edge. */
#cb-widget .cb-drawer .cb-intro__figure {
    order: 1;
    /* Shrinkable, not fixed: on a short panel the band gives height back
       instead of pushing the blurb into a scroll. The image is object-fit
       contained at height:100%, so shrinking scales the character down rather
       than cropping its head off. */
    flex: 0 1 auto;
    align-self: stretch;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    /* Sized to absorb the panel'''s slack. Left smaller, the leftover height
       reappeared as a ~98px hole between the blurb and the button. */
    height: clamp(160px, 46vh, 380px);
    /* The band is the ONLY thing that gives on a short panel (the card below
       is flex: 1 0 auto), so it needs to shrink past its preferred height
       rather than stopping there and pushing the CTA below the fold. The floor
       keeps the character legible; under that the intro scrolls instead. */
    min-height: 140px;
    margin: 0;
    background: var(--cb-ground);
    /* Positioning context for the wave, and the clip that keeps it off the
       copy below. */
    position: relative;
    overflow: hidden;
}

/* The wave, along the foot of the ground. Figma's gradient is untouched -
   transparent at the crown, resolving toward #1C2435 at the foot - so it
   dissolves upward into the paper instead of stopping at an edge. Clipped by
   the figure above, so it can never run under the heading or the blurb. */
#cb-widget .cb-drawer .cb-intro__figure::after {
    content: '';
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    height: 150px;
    background: url('/chatbot/assets/wave.svg') bottom center / 100% 100% no-repeat;
    pointer-events: none;
}

/* Fills the band's height, which is the only lever on how wide it reads — the
   source is a tall 440x830 portrait, so width follows height. */
#cb-widget .cb-drawer .cb-intro__figure img {
    /* Above the wave, which is a ::after on the same element. */
    position: relative;
    z-index: 1;
    width: auto;
    height: 100%;
    max-width: 100%;
    object-fit: contain;
    object-position: center bottom;
}

#cb-widget .cb-drawer .cb-intro__heading {
    order: 2;
    margin: 20px 0 10px;
    padding-inline: 20px;
    font-size: 20px;
    text-align: center;
}

/* A size down from the greeting it follows. The two are one statement — a name
   and what that name does — so the second reads as the subordinate half rather
   than a second heading of equal rank. */
#cb-widget .cb-drawer .cb-intro__heading-sub {
    font-size: 18px;
}

/* Grows into whatever is left, so the slack lands as a gap above the button
   rather than as a void above the character. */
#cb-widget .cb-drawer .cb-intro__card {
    order: 3;
    /* Grows into spare height, never shrinks — the blurb and the CTA keep
       their room and the band absorbs any shortfall instead. */
    flex: 1 0 auto;
    width: 100%;
    min-height: 0;
    /* stretch + flex-start so the blurb fills the width and stacks from the
       top; the base rule centres and shrink-wraps for the retired full page. */
    align-items: stretch;
    justify-content: flex-start;
    padding: 0 20px 16px;
}

/* Ranged left and a size down. 189 characters centred over five lines made
   this both the largest and the least readable type in the panel.

   Carries the #cb-widget id deliberately. The host site stylesheet has
   `:root[dir="rtl"] body p { font-size: 16px }` at specificity (0,2,2), which
   outranks a plain (0,2,0) .cb-drawer .cb-intro__card-text and silently held
   the Arabic blurb at 16px while English took the 14px. The id makes this
   (1,2,0) and settles it without !important. */
#cb-widget .cb-drawer .cb-intro__card-text {
    text-align: start;
    font-size: 14px;
}

/* Sits at the bottom of the card whatever the blurb's length, so the CTA
   lands in the same place in both locales. */
#cb-widget .cb-drawer .cb-start {
    margin-top: auto;
}

/* View toggle: the drawer shows exactly one of the two sections, driven by
   data-cb-view on the drawer root rather than by hiding/showing from JS
   directly, so the swap is pure CSS and easy to re-verify from the console. */
#cb-widget .cb-drawer[data-cb-view='chat'] .cb-intro,
#cb-widget .cb-drawer:not([data-cb-view='chat']) .cb-panel {
    display: none;
}

/* ==========================================================================
   2. Chat panel internals (the conversation inside the drawer)
   ========================================================================== */

/* --- 2a. Message log ----------------------------------------------------- */
#cb-widget .cb-log {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    /* The retired .cb-head used to supply the gap under the title bar. */
    padding: 16px var(--cb-pad-x);
    display: flex;
    flex-direction: column;
    gap: 16px;
    scrollbar-width: thin;
}

#cb-widget .cb-log::-webkit-scrollbar {
    width: 6px;
}

#cb-widget .cb-log::-webkit-scrollbar-thumb {
    background: rgba(28, 36, 53, 0.2);
    border-radius: 3px;
}

/* No avatar gutter any more - the portrait moved to the title bar, so a bot
   bubble starts at the log's own edge like the visitor's does. */
#cb-widget .cb-msg {
    display: flex;
    align-items: flex-start;
    max-width: 100%;
}

/* The stamp is out of flow, so it adds nothing to the bubble's intrinsic
   width: a one-word message like "hi" sized the bubble to the word and left
   the stamp 25px, which wrapped "11:45 am" onto two lines and pushed it up
   into the text. The floor is the widest stamp ("10:38 pm", 42px) plus the
   16px lead-in padding and the 16px the user bubble keeps on the far side;
   the bot's 12px end inset fits inside the same figure. */
#cb-widget .cb-bubble {
    position: relative;
    min-width: 76px;
    padding: 12px 16px 22px;
    font-family: var(--cb-font-regular);
    font-size: 14px;
    line-height: 1.5;
    color: var(--cb-ink);
    word-break: break-word;
    /* API answers arrive as plain text with real newlines and "- " bullets;
       without this they collapse into one run-on paragraph. */
    white-space: pre-wrap;
}

/* The backend auto-detects language, so an Arabic answer can land on the
   English surface. Keep it in a face that actually has Arabic glyphs. */
#cb-widget .cb-bubble[lang='ar'] {
    font-family: 'Tajawal Regular', 'Tajawal', 'Segoe UI', sans-serif;
}

/* Bot: square corner on the leading side (top-left in LTR, top-right in RTL).
   Logical radii let the Arabic page mirror without a second rule set. */
#cb-widget .cb-msg--bot .cb-bubble {
    background: var(--cb-bubble-bot);
    border-radius: var(--cb-radius-bubble);
    border-start-start-radius: 0;
}

/* On the drawer the log stands on the paper ground, and #f5f5f5 on #f6f6f6 is
   1.009:1 — one value apart per channel, so the bubble has no edge at all. No
   fill fixes that on its own: to reach the 1.41:1 the user's bubble gets from
   its own fill, a grey would have to land on #d1d1d1 and become the user's
   bubble. So the edge comes from a border, and the fill goes the other way.

   White rather than grey: it lifts off the paper instead of dissolving into
   it, and it holds up best where the wave darkens the ground beneath it
   (2.27:1 at the wave's foot, against 2.08:1 for the old #f5f5f5).

   0.18 resolves to #cfd0d3, which is 1.43:1 on the ground — level with the
   user bubble's own 1.41:1, so neither speaker's edge outranks the other, and
   both stay quieter than the composer field (1.65:1) and the chips (1.78:1),
   which are controls and should keep the loudest edges on the surface. */
#cb-widget .cb-drawer .cb-msg--bot .cb-bubble {
    background: var(--cb-surface);
    border: 1px solid rgba(28, 36, 53, 0.18);
}

/* User: mirrored — square corner on the trailing side, pinned to the far edge. */
#cb-widget .cb-msg--user {
    justify-content: flex-end;
}

#cb-widget .cb-msg--user .cb-bubble {
    background: var(--cb-bubble-user);
    border-radius: var(--cb-radius-bubble);
    border-start-end-radius: 0;
}

#cb-widget .cb-bubble__lead {
    font-family: var(--cb-font-medium);
}

#cb-widget .cb-time {
    position: absolute;
    bottom: 6px;
    font-family: var(--cb-font-light);
    font-size: 10px;
    line-height: 1;
    color: var(--cb-ink);
    /* The bubble's pre-wrap inherits down here. A stamp is one reading, not a
       sentence, so it stays on one line whatever the bubble does. */
    white-space: nowrap;
}

#cb-widget .cb-msg--bot .cb-time {
    inset-inline-end: 12px;
}

#cb-widget .cb-msg--user .cb-time {
    inset-inline-start: 16px;
}

/* --- 2b. Typing indicator ------------------------------------------------ */

/* No timestamp on this one, so it is not held to the stamp's width floor:
   three dots in a 76px bubble read as a gap rather than a pause. */
#cb-widget [data-cb-typing] .cb-bubble {
    min-width: 0;
}

#cb-widget .cb-typing {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 0;
}

#cb-widget .cb-typing span {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: rgba(28, 36, 53, 0.45);
    animation: cb-blink 1.2s infinite ease-in-out both;
}

#cb-widget .cb-typing span:nth-child(2) {
    animation-delay: 0.16s;
}

#cb-widget .cb-typing span:nth-child(3) {
    animation-delay: 0.32s;
}

@keyframes cb-blink {
    0%,
    80%,
    100% {
        opacity: 0.25;
    }
    40% {
        opacity: 1;
    }
}

@media (prefers-reduced-motion: reduce) {
    #cb-widget .cb-typing span {
        animation: none;
        opacity: 0.6;
    }
}

/* --- 2c. Suggested topic chips ------------------------------------------- */
/* A wrapping row of chips, not a stack of rows. Each chip prints a short label
   and sends the full question behind it (see buildTopics() in script.js) -
   printing the question made every chip a full-width two-line block, which
   reads as a list, not as a set of choices.

   Rounded at the bubble radius, unlike the square controls around them: these
   sit directly under a bubble that uses it, and belong to that conversational
   language rather than the button language. */
#cb-widget .cb-topics {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    /* .cb-log is a flex column with gap:16px, which already spaces this off the
       greeting it belongs to. */
    margin: 0;
    padding: 0;
    list-style: none;
}

#cb-widget .cb-topics > li {
    display: flex;
}

/* Outlined rather than filled: these sit directly under the bot's grey bubble,
   and solid navy blocks there become the loudest thing in the panel. The fill
   arrives on hover instead. */
#cb-widget .cb-topic {
    display: inline-flex;
    align-items: center;
    /* auto, not 100%: the chip is as wide as its label, so two fit on a row. */
    width: auto;
    max-width: 100%;
    padding: 8px 14px;
    border: 1px solid var(--cb-chip-line);
    border-radius: var(--cb-radius-bubble);
    background: var(--cb-chip);
    color: var(--cb-navy);
    /* A button does not inherit the page font, so the chip states its own
       rather than leaving the UA stack to show through. */
    font-family: var(--cb-font-medium);
    font-size: 13px;
    line-height: 18px;
    /* start, not left, so it mirrors on the RTL Arabic surface. */
    text-align: start;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
    -webkit-appearance: none;
    appearance: none;
}

/* The short label - the only thing the chip prints. */
#cb-widget .cb-topic__label {
    min-width: 0;
}

#cb-widget .cb-topic:hover,
#cb-widget .cb-topic:focus-visible {
    border-color: var(--cb-navy);
    background: var(--cb-navy);
    color: var(--cb-surface);
}

#cb-widget .cb-topic:focus-visible {
    outline: 3px solid var(--cb-red);
    outline-offset: 2px;
}

/* --- 2d. Composer -------------------------------------------------------- */
#cb-widget .cb-compose {
    flex: 0 0 auto;
    display: flex;
    margin: 0;
    padding: 0 var(--cb-pad-x) var(--cb-pad-x);
    /* Positioning context for the send button, which sits INSIDE the field
       rather than beside it. On the base rule rather than the drawer-scoped one
       below, so a panel mounted on its own still anchors the button correctly. */
    position: relative;
}

#cb-widget .cb-compose__field {
    flex: 1 1 auto;
    min-width: 0;
    height: var(--cb-compose-h);
    /* Trailing room for the button standing on top of this edge: 44 wide, 6
       clear of the border, and 10 so the text stops short of it rather than
       running under. Logical, so the Arabic surface reserves the other side. */
    padding: 0 20px;
    padding-inline-end: 60px;
    /* The field is white now, and so is the bar behind it - without a boundary
       the input would be invisible and only the send button would mark where to
       type. Same hairline the chips use, so the two agree. */
    border: 1px solid rgba(28, 36, 53, 0.25);
    border-radius: var(--cb-radius-btn);
    background: var(--cb-surface);
    font-family: var(--cb-font-regular);
    font-size: 16px;
    line-height: var(--cb-compose-h);
    color: var(--cb-navy);
    -webkit-appearance: none;
    appearance: none;
}

#cb-widget .cb-compose__field::placeholder {
    color: var(--cb-ink-muted);
    opacity: 1;
}

/* Focus ring picks up the logo bar's colour so the composer reads as part of
   the same chrome. */
#cb-widget .cb-compose__field:focus {
    outline: 2px solid var(--cb-bar);
    outline-offset: -2px;
}

/* Shown only when the composer is in URL-only mode and the value is not a URL. */
#cb-widget .cb-compose__error {
    flex: 0 0 auto;
    margin: 0;
    padding: 0 var(--cb-pad-x) 8px;
    font-family: var(--cb-font-regular);
    font-size: 13px;
    line-height: 1.4;
    color: var(--cb-red);
}

/* Inside the field, not beside it — the composer reads as one control, and the
   field gets the drawer's full width instead of surrendering 64px of it.

   Absolutely positioned against .cb-compose and anchored with a logical inset,
   so the Arabic surface mirrors it with no second rule. 44px rather than the
   field's own 56: at full height it would sit edge to edge and read as glued
   on, and 44 is still a comfortable target. */
#cb-widget .cb-compose__send {
    position: absolute;
    inset-inline-end: calc(var(--cb-pad-x) + 6px);
    top: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: var(--cb-radius-btn);
    background: var(--cb-red);
    cursor: pointer;
    transition: background 0.15s ease, opacity 0.15s ease;
    -webkit-appearance: none;
    appearance: none;
}

#cb-widget .cb-compose__send:hover:not(:disabled),
#cb-widget .cb-compose__send:focus-visible:not(:disabled) {
    background: #d02c24;
}

#cb-widget .cb-compose__send:disabled {
    opacity: 0.45;
    cursor: default;
}

#cb-widget .cb-compose__send:focus-visible {
    outline: 2px solid var(--cb-navy);
    outline-offset: -2px;
}

#cb-widget .cb-compose__send img {
    width: 24px;
    height: 24px;
    display: block;
}

/* ==========================================================================
   3. Intro content — Figma node 209:135. Was part of the retired full-page
   screen; now consumed only by the drawer's compact intro, which overrides
   several properties below (see .cb-drawer .cb-intro* in section 1b).
   ========================================================================== */

#cb-widget .cb-intro {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Figma: character right edge 632, heading left edge 665. */
    gap: 33px;
    padding: 0 20px;
}

/* Figma: character 440 x 830 at the left edge, bottom-aligned to the page. */
#cb-widget .cb-intro__figure {
    flex: 0 0 auto;
    align-self: flex-end;
    margin: 0;
    line-height: 0;
}

/* Sizing lives entirely in the drawer's own override now — the retired
   full-page screen's viewport-proportional height formula went with it. */
#cb-widget .cb-intro__figure img {
    display: block;
    width: auto;
    max-width: 100%;
}

/* "Hi, I'm Amna / Your Intelligent Chatbot." — 32px, "Amna" bold. */
#cb-widget .cb-intro__heading {
    margin: 0;
    font-family: var(--cb-font-regular);
    font-size: 32px;
    font-weight: normal;
    line-height: 1.45;
    text-align: center;
    color: var(--cb-navy);
}

#cb-widget .cb-intro__heading strong {
    font-family: var(--cb-font-bold);
    font-weight: normal;
}

/* The second clause. display:block is what breaks the line now that the <br />
   is gone — it exists so the clause can be sized independently of the
   greeting above it. */
#cb-widget .cb-intro__heading-sub {
    display: block;
}

/* Card: 466 x 280, white, square corners. */
#cb-widget .cb-intro__card {
    width: 466px;
    max-width: 100%;
    min-height: 280px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 25px 21px;
    background: var(--cb-surface);
}

#cb-widget .cb-intro__card-text {
    margin: 0;
    font-family: var(--cb-font-regular);
    font-size: 16px;
    line-height: 1.6;
    text-align: center;
    color: var(--cb-navy);
}

/* Start Chat — Figma node 209:215, an anchor in the design too. */
#cb-widget .cb-start {
    width: 100%;
    min-height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 8px 16px;
    border: 0;
    border-radius: var(--cb-radius-btn);
    background: var(--cb-red-app);
    color: var(--cb-surface);
    font-family: var(--cb-font-regular);
    font-size: 14px;
    line-height: 20px;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

#cb-widget .cb-start:hover,
#cb-widget .cb-start:focus-visible {
    background: var(--cb-red-app-hover);
    color: var(--cb-surface);
}

#cb-widget .cb-start:focus-visible {
    outline: 3px solid var(--cb-navy);
    outline-offset: 2px;
}

#cb-widget .cb-start__icon {
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
    display: block;
}

/* ==========================================================================
   4. Responsive
   ========================================================================== */

/* Drawer breakpoint — deliberately 640px, wider than the 600px block below. A
   400px side panel needs the extra room before it gives up and goes
   full-screen; folding this into the 600px block would tie two unrelated
   rule sets to the same number. */
@media (max-width: 640px) {
    /* Full-screen sheet, as Intercom/Drift/Zendesk do: a 400px panel on a
       375px screen leaves nothing for the conversation once the on-screen
       keyboard appears. */
    #cb-widget .cb-drawer {
        inset: 0;
        width: 100%;
        height: 100%;
        max-height: none;
        /* Square again: rounded corners on a sheet that fills the screen just
           show slivers of the page at the edges. */
        border-radius: 0;
        /* Bottom sheet, not a corner pop: scaling a full-screen surface out of
           one corner reads as a glitch at this size, and sliding up from the
           bottom edge is the established phone idiom. */
        transform: translateY(100%);
    }

    #cb-widget.cb-widget--open .cb-drawer {
        transform: none;
    }

    /* Hiding the launcher while open is no longer a phone-only concern — see
       #cb-widget.cb-widget--open .cb-launcher in section 1a. */
}

/* No 600px block any more: the launcher size and its insets are fluid (see
   .cb-launcher and the --cb-edge-* tokens), and the topic chips wrap on their
   own, so there is nothing left that needs a second breakpoint. */

/* ── Link-check verdicts ────────────────────────────────────────────────────
   Three designs, one per API tier (safe / suspicious / malicious), rendered
   from link_check.status rather than from the model's sentence — see
   Chat.prototype.addVerdict for why that distinction is load-bearing.

   Deliberately NOT colour-coded green/amber/red. The headline already carries
   the verdict in words, and colour alone would leave it unreadable to a
   colour-blind visitor and silent to a screen reader. The left border is a
   weight cue that survives both. */
/* The verdict parts state the bubble's own type explicitly rather than relying
   on inheritance. Inheritance loses to ANY matching rule, and these are the
   only bot-message elements that are real <ul>/<li>/<span> tags rather than a
   text node — so a bare `li` or `ul` rule anywhere in the host site's CSS would
   restyle the tips while the rest of the conversation stayed put. Same defence,
   and same reason, as the #cb-widget id on .cb-intro__card-text. */
#cb-widget .cb-verdict,
#cb-widget .cb-verdict__headline,
#cb-widget .cb-verdict__lead,
#cb-widget .cb-verdict__tips-lead,
#cb-widget .cb-verdict__tips,
#cb-widget .cb-verdict__tips li {
    font-size: 14px;
    line-height: 1.5;
    color: var(--cb-ink);
}

#cb-widget .cb-verdict,
#cb-widget .cb-verdict__lead,
#cb-widget .cb-verdict__tips,
#cb-widget .cb-verdict__tips li {
    font-family: var(--cb-font-regular);
}

#cb-widget .cb-verdict {
    display: block;
}

#cb-widget .cb-verdict__headline {
    display: block;
    font-family: var(--cb-font-medium);
    margin-bottom: 2px;
}

#cb-widget .cb-verdict__lead {
    display: block;
}

#cb-widget .cb-verdict__tips-lead {
    display: block;
    font-family: var(--cb-font-medium);
    margin-top: 10px;
}

/* Flush with the text above them, not indented under it.

   Every other list in the conversation is model prose — plain text with literal
   "- " prefixes, which lands hard against the bubble's text edge. These tips
   were the only real <ul> in the log, and an 18px list indent put them in a
   different column from every other bullet the visitor sees. list-style-position
   is what moves the marker itself to that edge; the negative text-indent against
   an equal padding keeps the hanging indent on a wrapped line, so alignment does
   not cost the readability of the second line.

   Padding, not margin — margin-left would push the markers outside the bubble
   under RTL. */
#cb-widget .cb-verdict__tips {
    margin: 4px 0 0;
    padding-inline-start: 0;
    /* The marker is drawn by ::before below, not by the browser. A native
       marker — `outside` or `inside` — sets its own gap before the text, and
       that gap is not a length any rule can read. Indenting the wrapped lines
       to match therefore means guessing it, and the guess was wrong: the second
       line landed short of the first. Drawing the marker ourselves makes the
       text column a number we control, so the two agree exactly. */
    list-style: none;
}

/* Padding on the item, so it applies to EVERY line. The marker is lifted out of
   the flow and pinned to the leading edge, which leaves first and wrapped lines
   starting at the same 1.1em. Logical properties throughout — the Arabic page
   mirrors this without a second rule set. */
#cb-widget .cb-verdict__tips li {
    position: relative;
    margin: 0 0 4px;
    padding-inline-start: 1.1em;
}

#cb-widget .cb-verdict__tips li::before {
    content: '\2022';
    position: absolute;
    inset-inline-start: 0;
    top: 0;
}

#cb-widget .cb-verdict__tips li:last-child {
    margin-bottom: 0;
}

/* The AI-accuracy notice, on the intro screen beneath the start button. Smaller
   than the card text it follows — it is a caveat, not a selling point — but not
   so faint that it reads as decorative, because it is the one place the limits
   of the service are stated before a visitor begins. */
#cb-widget .cb-intro__notice {
    margin: 6px 0 0;
    font-family: var(--cb-font-regular);
    /* A step below the card text it follows, not a different voice: small
       enough to read as a footnote to the button, large enough that a required
       disclosure is not fine print. */
    font-size: 12px;
    line-height: 1.5;
    text-align: center;
    color: var(--cb-ink);
}

/* The label only. */
#cb-widget .cb-intro__notice strong {
    font-family: var(--cb-font-medium);
}
