/* =============================================================================
   DEX Portal - Agent Meeko
   The chat panel (header sparkle) and the Settings › Agent Meeko page extras.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   THE DOCKED PANE
   Agent Meeko sits on the right edge as its own pane. While it is open the page
   and every slide-over panel move left by its width, so a record it opens
   lands beside the chat rather than on top of it. On narrow screens it
   overlays instead.
   ----------------------------------------------------------------------------- */

:root {
    --agent-meeko-dock-width: clamp(360px, 30vw, 520px);
    --agent-meeko-dock-offset: 0px;
}

html.agent-meeko-docked:not(.agent-meeko-docked--overlay) {
    --agent-meeko-dock-offset: var(--agent-meeko-dock-width);
}

.agent-meeko-dock {
    position: fixed;
    top: var(--height-top-header);
    right: 0;
    bottom: 0;
    width: var(--agent-meeko-dock-width);
    display: flex;
    flex-direction: column;
    background: var(--surface-subtle);
    border-left: 1px solid var(--border-subtle);
    box-shadow: var(--shadow-slide-over);
    transform: translateX(100%);
    visibility: hidden;
    z-index: 103;
    transition:
        transform var(--duration-panel-close) var(--easing-standard),
        visibility 0s linear var(--duration-panel-close);
}

.agent-meeko-dock--open {
    transform: translateX(0);
    visibility: visible;
    transition:
        transform var(--duration-panel-open) var(--easing-standard),
        visibility 0s;
}

.agent-meeko-dock__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 12px 12px 16px;
    background: var(--surface-panel);
    border-bottom: 1px solid var(--border-subtle);
    flex: none;
}

.agent-meeko-dock__mark {
    width: 32px;
    height: 32px;
    border-radius: 10px;
    display: grid;
    place-items: center;
    color: var(--accent);
    background: var(--accent-tint);
    border: 1px solid var(--accent-border);
    flex: none;
}

.agent-meeko-dock__titles {
    flex: 1;
    min-width: 0;
}

.agent-meeko-dock__title {
    margin: 0;
    font-size: var(--font-size-medium);
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.2;
}

.agent-meeko-dock__subtitle {
    margin: 1px 0 0;
    font-size: var(--font-size-tiny);
    color: var(--text-muted);
}

.agent-meeko-dock__tools {
    display: flex;
    gap: 4px;
    flex: none;
}

.agent-meeko-dock__tool {
    appearance: none;
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--text-secondary);
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}

.agent-meeko-dock__tool:hover {
    background: var(--surface-subtle);
    color: var(--text-primary);
}

.agent-meeko-dock__body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

/* The page and the slide-over panels make room. */
.application-body {
    transition: padding-right var(--duration-panel-open) var(--easing-standard);
}

html.agent-meeko-docked:not(.agent-meeko-docked--overlay) .application-body {
    padding-right: var(--agent-meeko-dock-offset);
}

html.agent-meeko-docked:not(.agent-meeko-docked--overlay) .slide-over,
html.agent-meeko-docked:not(.agent-meeko-docked--overlay) .slide-over-scrim {
    right: var(--agent-meeko-dock-offset);
}

html.agent-meeko-docked:not(.agent-meeko-docked--overlay) .slide-over {
    max-width: calc(96vw - var(--agent-meeko-dock-offset));
}

@media (max-width: 900px) {
    .agent-meeko-dock {
        width: 100vw;
        border-left: 0;
    }
}

.agent-meeko {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}

.agent-meeko__thread {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: var(--gutter-tight);
    display: flex;
    flex-direction: column;
    gap: 14px;
}

/* Welcome state */
.agent-meeko__welcome {
    margin: auto 0;
    padding: 28px 8px 12px;
    text-align: center;
}

.agent-meeko__welcome-mark {
    width: 46px;
    height: 46px;
    margin: 0 auto 12px;
    border-radius: 14px;
    display: grid;
    place-items: center;
    color: var(--accent);
    background: var(--accent-tint);
    border: 1px solid var(--accent-border);
}

.agent-meeko__welcome-title {
    margin: 0 0 6px;
    font-size: var(--font-size-medium);
    font-weight: 700;
    color: var(--text-primary);
}

.agent-meeko__welcome-text {
    margin: 0 auto 18px;
    max-width: 320px;
    font-size: var(--font-size-small);
    line-height: 1.55;
    color: var(--text-secondary);
}

.agent-meeko__suggest {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
}

.agent-meeko__chip {
    appearance: none;
    border: 1px solid var(--border-strong);
    background: var(--surface-panel);
    color: var(--text-primary);
    border-radius: var(--radius-pill);
    padding: 7px 12px;
    font: inherit;
    font-size: var(--font-size-small);
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease;
}

.agent-meeko__chip:hover {
    border-color: var(--accent);
    background: var(--accent-tint);
}

/* Messages */
.agent-meeko__row {
    display: flex;
    gap: 10px;
    align-items: flex-end;
}

.agent-meeko__row--user {
    justify-content: flex-end;
}

.agent-meeko__avatar {
    flex: 0 0 26px;
    width: 26px;
    height: 26px;
    border-radius: 8px;
    display: grid;
    place-items: center;
    color: var(--accent);
    background: var(--accent-tint);
    border: 1px solid var(--accent-border);
}

.agent-meeko__row--error .agent-meeko__avatar {
    color: #b42318;
    background: #fef3f2;
    border-color: #fecdca;
}

.agent-meeko__column {
    display: flex;
    flex-direction: column;
    gap: 4px;
    max-width: 86%;
    min-width: 0;
}

.agent-meeko__row--user .agent-meeko__column {
    align-items: flex-end;
}

.agent-meeko__bubble {
    padding: 10px 13px;
    border-radius: 14px;
    font-size: var(--font-size-base);
    line-height: 1.55;
    color: var(--text-primary);
    background: var(--surface-panel);
    border: 1px solid var(--border-default);
    word-wrap: break-word;
    overflow-wrap: anywhere;
}

.agent-meeko__row--assistant .agent-meeko__bubble {
    border-bottom-left-radius: 5px;
}

.agent-meeko__row--user .agent-meeko__bubble {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
    border-bottom-right-radius: 5px;
    white-space: pre-wrap;
}

.agent-meeko__row--error .agent-meeko__bubble {
    background: #fef3f2;
    border-color: #fecdca;
    color: #b42318;
}

.agent-meeko__bubble p {
    margin: 0 0 8px;
}

.agent-meeko__bubble p:last-child,
.agent-meeko__bubble ul:last-child,
.agent-meeko__bubble ol:last-child {
    margin-bottom: 0;
}

.agent-meeko__bubble ul,
.agent-meeko__bubble ol {
    margin: 0 0 8px;
    padding-left: 18px;
}

.agent-meeko__bubble li {
    margin: 2px 0;
}

.agent-meeko__bubble code {
    font-family: var(--font-monospace);
    font-size: 0.92em;
    background: var(--surface-subtle);
    padding: 1px 5px;
    border-radius: 4px;
}

.agent-meeko__heading {
    font-weight: 700;
}

.agent-meeko__meta {
    font-size: var(--font-size-tiny);
    color: var(--text-muted);
    padding-left: 4px;
}

/* Working indicator: a grey ring and a word */
.agent-meeko__bubble--thinking {
    display: inline-flex;
    gap: 9px;
    align-items: center;
    padding: 10px 14px;
}

.agent-meeko__ring {
    width: 14px;
    height: 14px;
    flex: 0 0 14px;
    border-radius: 50%;
    border: 2px solid var(--border-default);
    border-top-color: var(--text-muted);
    animation: agent-meeko-spin .9s linear infinite;
}

.agent-meeko__working {
    font-size: var(--font-size-small);
    color: var(--text-muted);
}

@keyframes agent-meeko-spin {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .agent-meeko__ring { animation-duration: 2.4s; }
}

/* ---- What it is actually doing --------------------------------------------

   The word beside the ring used to change on a timer. It now changes when the
   server says so, and the phase colours the ring, because "looking something
   up" and "changing something" deserve to read differently at a glance. The
   second one is the one worth noticing.
-------------------------------------------------------------------------- */

.agent-meeko__bubble--thinking[data-phase="investigating"] .agent-meeko__ring {
    border-top-color: var(--accent);
}

.agent-meeko__bubble--thinking[data-phase="investigating"] .agent-meeko__working {
    color: var(--text-secondary);
}

/* Meeko is changing something, not reading it. Amber, and the ring slows down:
   a spinner racing while a record is being written reads as panic. */
.agent-meeko__bubble--thinking[data-phase="actioning"] .agent-meeko__ring {
    border-top-color: var(--status-warning, #f59e0b);
    animation-duration: 1.4s;
}

.agent-meeko__bubble--thinking[data-phase="actioning"] .agent-meeko__working {
    color: var(--text-primary);
    font-weight: 550;
}

/* The word changes often enough that a hard cut reads as a flicker. */
.agent-meeko__working {
    transition: color var(--duration-instant, .12s) ease;
}

/* Plan card */
.agent-meeko__plan-steps {
    margin: 0;
    padding: 4px 12px 10px 30px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.agent-meeko__plan-step {
    padding-left: 2px;
}

.agent-meeko__plan-step::marker {
    color: var(--text-muted);
    font-size: var(--font-size-tiny);
}

.agent-meeko__plan-step-title {
    display: block;
    color: var(--text-primary);
}

.agent-meeko__plan-step-detail {
    display: block;
    color: var(--text-muted);
    font-size: var(--font-size-tiny);
}

.agent-meeko__dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--text-muted);
    animation: agent-meeko-pulse 1.2s infinite ease-in-out;
}

.agent-meeko__dot:nth-child(2) { animation-delay: .15s; }
.agent-meeko__dot:nth-child(3) { animation-delay: .3s; }

@keyframes agent-meeko-pulse {
    0%, 80%, 100% { opacity: .25; transform: translateY(0); }
    40% { opacity: 1; transform: translateY(-3px); }
}

/* Composer */
.agent-meeko__composer-holder {
    flex: 0 0 auto;
    padding: 10px var(--gutter-tight) 12px;
    background: var(--surface-panel);
    border-top: 1px solid var(--border-default);
}

.agent-meeko__composer {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    padding: 6px 6px 6px 12px;
    border: 1px solid var(--border-strong);
    border-radius: 14px;
    background: var(--surface-panel);
    transition: border-color .15s ease, box-shadow .15s ease;
}

.agent-meeko__composer:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-tint);
}

.agent-meeko__input {
    flex: 1;
    min-width: 0;
    resize: none;
    border: 0;
    outline: 0;
    background: transparent;
    font: inherit;
    font-size: var(--font-size-base);
    line-height: 1.5;
    color: var(--text-primary);
    padding: 6px 0;
    max-height: 140px;
}

.agent-meeko__send,
.agent-meeko__mic,
.agent-meeko__talk {
    appearance: none;
    flex: 0 0 32px;
    width: 32px;
    height: 32px;
    border-radius: 10px;
    border: 0;
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: background .15s ease, opacity .15s ease;
}

.agent-meeko__send {
    color: #fff;
    background: var(--accent);
}

.agent-meeko__send:hover { background: var(--accent-hover); }

.agent-meeko__send:disabled {
    opacity: .45;
    cursor: default;
}

.agent-meeko__mic,
.agent-meeko__talk {
    color: var(--text-secondary);
    background: var(--surface-subtle);
    touch-action: none;
    user-select: none;
}

.agent-meeko__mic:hover,
.agent-meeko__talk:hover {
    color: var(--accent);
    background: var(--accent-tint);
}

/* Held: red, with a soft ring that breathes while it listens. */
.agent-meeko__mic--listening {
    color: #fff;
    background: #d92d20;
    animation: agent-meeko-listen 1.4s infinite ease-in-out;
}

@keyframes agent-meeko-listen {
    0%, 100% { box-shadow: 0 0 0 0 rgba(217, 45, 32, .45); }
    50% { box-shadow: 0 0 0 7px rgba(217, 45, 32, 0); }
}

/* Conversation mode is a switch rather than a hold, so its ON state has to be
   unmissable: the microphone is open for as long as this is lit. Same red as
   the held mic, because it means the same thing - DEX is listening. */
.agent-meeko__talk--on {
    position: relative;
    color: #fff;
    background: #d92d20;
}

.agent-meeko__talk--on:hover {
    color: #fff;
    background: #b42318;
}

.agent-meeko__talk--on::after {
    content: "";
    position: absolute;
    inset: -3px;
    border-radius: 13px;
    border: 2px solid #d92d20;
    opacity: .5;
    animation: agent-meeko-talk-halo 1.6s infinite ease-out;
    pointer-events: none;
}

@keyframes agent-meeko-talk-halo {
    0% { transform: scale(1); opacity: .5; }
    70% { transform: scale(1.3); opacity: 0; }
    100% { transform: scale(1.3); opacity: 0; }
}

/* Anyone who would rather things did not move. The colour still says it. */
@media (prefers-reduced-motion: reduce) {
    .agent-meeko__mic--listening { animation: none; }
    .agent-meeko__talk--on::after { animation: none; opacity: .35; }
}

.agent-meeko--listening .agent-meeko__composer {
    border-color: #d92d20;
    box-shadow: 0 0 0 3px rgba(217, 45, 32, .12);
}

.agent-meeko--listening .agent-meeko__input::placeholder {
    color: #d92d20;
}

/* Read-aloud on an answer */
.agent-meeko__speak {
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--text-muted);
    width: 22px;
    height: 22px;
    border-radius: 6px;
    display: inline-grid;
    place-items: center;
    cursor: pointer;
    margin-left: 4px;
    vertical-align: middle;
}

.agent-meeko__speak:hover {
    color: var(--accent);
    background: var(--accent-tint);
}

.agent-meeko__speak--on {
    color: var(--accent);
    background: var(--accent-tint);
    animation: agent-meeko-pulse-soft 1.2s infinite ease-in-out;
}

@keyframes agent-meeko-pulse-soft {
    0%, 100% { opacity: 1; }
    50% { opacity: .55; }
}

.agent-meeko__meta {
    display: flex;
    align-items: center;
    gap: 2px;
}

/* The header sparkle while "Hey Meeko" is listening: a small live dot. */
.header-icon-button--listening {
    position: relative;
}

.header-icon-button--listening::after {
    content: '';
    position: absolute;
    top: 6px;
    right: 6px;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #d92d20;
    box-shadow: 0 0 0 2px var(--surface-header);
    animation: agent-meeko-pulse-soft 1.6s infinite ease-in-out;
}

.gs-ai-voice-actions {
    margin-top: 12px;
}

.agent-meeko__footnote {
    margin: 8px 2px 0;
    font-size: var(--font-size-tiny);
    color: var(--text-muted);
}

/* -----------------------------------------------------------------------------
   THE HEADER SPARKLE - white, with a soft halo, and a little alive
   ----------------------------------------------------------------------------- */

#headerAgentMeekoButton {
    color: #ffffff;
    overflow: visible;
    isolation: isolate;
}

/* A faint violet glow that breathes slowly behind the icon. */
#headerAgentMeekoButton::before {
    content: '';
    position: absolute;
    inset: 4px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(124, 92, 255, .55) 0%, rgba(124, 92, 255, 0) 70%);
    opacity: .55;
    z-index: -1;
    animation: agent-meeko-breathe 4.2s ease-in-out infinite;
    pointer-events: none;
}

#headerAgentMeekoButton .icon {
    filter: drop-shadow(0 0 4px rgba(151, 128, 255, .8));
    transform-origin: 50% 60%;
    transition: transform .2s ease;
}

/* Every so often the sparkle gives a small twinkle, so it never looks static. */
#headerAgentMeekoButton:not(.header-icon-button--dex-waving) .icon {
    animation: agent-meeko-twinkle 14s ease-in-out infinite;
}

#headerAgentMeekoButton:hover .icon {
    transform: scale(1.12) rotate(-8deg);
}

/* Open: the button reads as pressed. Minimised: the glow is stronger, it is waiting. */
.header-icon-button--dex-open {
    background: var(--surface-header-hover);
}

.header-icon-button--dex-minimised::before {
    opacity: .95;
    animation-duration: 1.8s;
}

/* The blue ring that runs round the sparkle while Meeko is listening to you
   (after "Hey Meeko", during the follow-up window) or working on an answer. */
.agent-meeko-ring {
    position: absolute;
    inset: 2px;
    border-radius: 50%;
    pointer-events: none;
    opacity: 0;
    transform: scale(.8);
    transition: opacity .2s ease, transform .25s ease;
    z-index: 0;
}

.agent-meeko-ring::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: conic-gradient(from 0deg, rgba(56, 189, 248, 0) 0%, rgba(56, 189, 248, 0) 55%, #38bdf8 85%, #e0f2fe 100%);
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2px));
    mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2px));
    animation: agent-meeko-ring-spin 1.1s linear infinite;
    filter: drop-shadow(0 0 4px rgba(56, 189, 248, .9));
}

/* A soft blue glow inside the ring, so it reads at a glance. */
.agent-meeko-ring::after {
    content: '';
    position: absolute;
    inset: 3px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(56, 189, 248, .35) 0%, rgba(56, 189, 248, 0) 70%);
    animation: agent-meeko-breathe 1.6s ease-in-out infinite;
}

.agent-meeko-ring--on {
    opacity: 1;
    transform: scale(1);
}

/* "Heard you": a bright pulse that bursts outwards once. */
.agent-meeko-ring--flash {
    opacity: 1;
    transform: scale(1);
}

.agent-meeko-ring--flash::after {
    animation: agent-meeko-ring-burst .9s ease-out 1;
}

@keyframes agent-meeko-ring-spin {
    to { transform: rotate(360deg); }
}

@keyframes agent-meeko-ring-burst {
    0% { inset: 3px; opacity: 1; background: radial-gradient(circle, rgba(56, 189, 248, .8) 0%, rgba(56, 189, 248, .3) 60%, rgba(56, 189, 248, 0) 70%); }
    100% { inset: -14px; opacity: 0; background: radial-gradient(circle, rgba(56, 189, 248, 0) 0%, rgba(56, 189, 248, .25) 60%, rgba(56, 189, 248, 0) 70%); }
}

/* While the ring is on, the violet halo steps back so the blue reads clearly. */
#headerAgentMeekoButton:has(.agent-meeko-ring--on)::before {
    opacity: .15;
}

/* The wave when it says hello. */
.header-icon-button--dex-waving .icon {
    animation: agent-meeko-wave .5s ease-in-out 4;
}

@keyframes agent-meeko-wave {
    0%, 100% { transform: rotate(0deg) scale(1); }
    25% { transform: rotate(-16deg) scale(1.15); }
    75% { transform: rotate(14deg) scale(1.15); }
}

@keyframes agent-meeko-breathe {
    0%, 100% { transform: scale(.9); opacity: .4; }
    50% { transform: scale(1.25); opacity: .75; }
}

@keyframes agent-meeko-twinkle {
    0%, 92%, 100% { transform: scale(1) rotate(0deg); filter: drop-shadow(0 0 4px rgba(151, 128, 255, .8)); }
    94% { transform: scale(1.18) rotate(-10deg); filter: drop-shadow(0 0 9px rgba(190, 175, 255, 1)); }
    97% { transform: scale(.96) rotate(6deg); }
}

/* The speech bubble under the sparkle: "Hi Leone 👋", "I'm here". */
.agent-meeko-hello {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 12px;
    border-radius: 12px;
    background: #ffffff;
    color: #1f2430;
    font-size: var(--font-size-small);
    font-weight: 600;
    white-space: nowrap;
    box-shadow: 0 8px 24px rgba(16, 24, 40, .22);
    opacity: 0;
    transform: translateY(-6px) scale(.94);
    transform-origin: top right;
    transition: opacity .22s ease, transform .26s cubic-bezier(.34, 1.4, .64, 1);
    pointer-events: none;
    z-index: 200;
}

.agent-meeko-hello::before {
    content: '';
    position: absolute;
    top: -5px;
    right: 14px;
    width: 10px;
    height: 10px;
    background: #ffffff;
    transform: rotate(45deg);
    border-radius: 2px;
}

.agent-meeko-hello--in {
    opacity: 1;
    transform: translateY(0) scale(1);
}

/* The sticky "I'm here" bobs gently while minimised. */
.header-icon-button--dex-minimised .agent-meeko-hello--in {
    animation: agent-meeko-bob 2.6s ease-in-out infinite;
}

.agent-meeko-hello__hand {
    display: inline-block;
    font-size: 15px;
    transform-origin: 70% 70%;
    animation: agent-meeko-hand-wave 1.6s ease-in-out 2;
}

@keyframes agent-meeko-hand-wave {
    0%, 100% { transform: rotate(0deg); }
    15% { transform: rotate(16deg); }
    30% { transform: rotate(-8deg); }
    45% { transform: rotate(16deg); }
    60% { transform: rotate(-6deg); }
    75% { transform: rotate(10deg); }
}

@keyframes agent-meeko-bob {
    0%, 100% { transform: translateY(0) scale(1); }
    50% { transform: translateY(3px) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    .agent-meeko-ring::before,
    .agent-meeko-ring::after,
    #headerAgentMeekoButton::before,
    #headerAgentMeekoButton .icon,
    .agent-meeko-hello__hand,
    .header-icon-button--dex-minimised .agent-meeko-hello--in {
        animation: none !important;
    }
}

/* Action cards - the confirm step */
.agent-meeko__action {
    margin-top: 6px;
    border: 1px solid var(--accent-border);
    background: var(--surface-panel);
    border-radius: 12px;
    overflow: hidden;
    font-size: var(--font-size-small);
}

.agent-meeko__action--done { border-color: #bbf7d0; }
.agent-meeko__action--failed { border-color: #fecdca; }
.agent-meeko__action--cancelled,
.agent-meeko__action--composer { opacity: .7; }

.agent-meeko__action-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    background: var(--accent-tint);
    color: var(--text-primary);
    font-weight: 700;
}

.agent-meeko__action--done .agent-meeko__action-head { background: #f0fdf4; }
.agent-meeko__action--failed .agent-meeko__action-head { background: #fef3f2; }

.agent-meeko__action-icon {
    display: inline-grid;
    place-items: center;
    color: var(--accent);
}

.agent-meeko__action--done .agent-meeko__action-icon { color: #15803d; }
.agent-meeko__action--failed .agent-meeko__action-icon { color: #b42318; }

.agent-meeko__action-state {
    margin-left: auto;
    font-size: var(--font-size-tiny);
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.agent-meeko__action-state--failed { color: #b42318; }

.agent-meeko__action-body {
    padding: 10px 12px 4px;
}

.agent-meeko__action-line {
    display: grid;
    grid-template-columns: 76px 1fr;
    gap: 8px;
    padding: 2px 0;
    line-height: 1.45;
}

.agent-meeko__action-key {
    color: var(--text-muted);
}

.agent-meeko__action-value {
    color: var(--text-primary);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.agent-meeko__action-value--wide {
    grid-column: 1 / -1;
}

.agent-meeko__action-gap {
    height: 6px;
}

.agent-meeko__action-result {
    padding: 6px 12px 10px;
    color: #15803d;
    font-weight: 600;
}

.agent-meeko__action-result--failed {
    color: #b42318;
}

.agent-meeko__action-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 8px 12px 12px;
}

.agent-meeko__action--running .agent-meeko__action-buttons {
    opacity: .5;
    pointer-events: none;
}

/* Quiet status lines in the thread */
.agent-meeko__note,
.agent-meeko__done {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: var(--font-size-tiny);
    color: #15803d;
}

.agent-meeko__note {
    justify-content: center;
    padding: 2px 0;
}

.agent-meeko__done {
    padding-left: 4px;
}

.agent-meeko__note--danger,
.agent-meeko__done--failed {
    color: #b42318;
}

/* -----------------------------------------------------------------------------
   SETTINGS › Agent Meeko
   ----------------------------------------------------------------------------- */

.gs-ai-row {
    padding: 10px 0;
    border-top: 1px solid var(--border-subtle);
}

.gs-ai-row:first-of-type {
    border-top: 0;
}

.gs-ai-row__hint {
    margin: 4px 0 0 52px;
}

/* Which types get triaged. Indented to the same 52px as the hint above it, so
   it reads as part of the switch it belongs to rather than a new section. */
.gs-ai-filter {
    margin: 12px 0 2px 52px;
    padding: 12px 14px;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-button, 10px);
    background: var(--surface-muted, #f8fafc);
}

.gs-ai-filter[hidden] {
    display: none;
}

.gs-ai-filter__label {
    margin: 0 0 8px;
    font-size: var(--font-size-tiny);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-secondary, #6b7280);
}

.gs-ai-filter__search {
    width: 100%;
    margin-bottom: 10px;
}

/* Capped rather than endless: nine ticket types is a list, forty would be a
   wall, and the search box above is what makes a long one usable. */
.gs-ai-filter__list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 10px;
    max-height: 168px;
    overflow-y: auto;
}

.gs-ai-filter__option {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 5px 10px 5px 7px;
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    background: var(--surface-card, #fff);
    font-size: var(--font-size-small);
    cursor: pointer;
}

.gs-ai-filter__option:has(input:disabled) {
    cursor: default;
    opacity: .65;
}

.gs-ai-filter__swatch {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex: none;
}

.gs-ai-filter__summary {
    margin: 10px 0 0;
}

.gs-ai-badge {
    margin-left: auto;
    font-size: var(--font-size-tiny);
}

.gs-ai-facts {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 6px 18px;
    margin: 0 0 14px;
    font-size: var(--font-size-small);
}

.gs-ai-facts dt {
    color: var(--text-muted);
}

.gs-ai-facts dd {
    margin: 0;
    color: var(--text-primary);
    font-weight: 600;
}

.gs-ai-facts__value--on { color: #15803d; }
.gs-ai-facts__value--off { color: #b42318; }

.gs-ai-status {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 12px;
    font-size: var(--font-size-small);
}

.gs-ai-status--off { color: #b42318; }

.gs-ai-models {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 12px;
}

.gs-ai-model {
    appearance: none;
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 14px;
    border-radius: 10px;
    border: 1px solid var(--border-strong);
    background: var(--surface-panel);
    font: inherit;
    cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.gs-ai-model:hover:not(:disabled) {
    border-color: var(--accent);
}

.gs-ai-model--active {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-tint);
}

.gs-ai-model:disabled {
    cursor: default;
    opacity: .8;
}

.gs-ai-model__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.gs-ai-model__name {
    font-weight: 700;
    color: var(--text-primary);
}

.gs-ai-model__tag {
    font-size: var(--font-size-tiny);
    color: var(--accent);
    background: var(--accent-tint);
    border: 1px solid var(--accent-border);
    padding: 2px 8px;
    border-radius: var(--radius-pill);
}

.gs-ai-model__blurb {
    font-size: var(--font-size-small);
    color: var(--text-secondary);
    line-height: 1.45;
}

.gs-ai-model__price {
    font-size: var(--font-size-tiny);
    color: var(--text-muted);
}

.gs-ai-model__price em {
    font-style: normal;
    opacity: .8;
}

.gs-ai-budget-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.gs-ai-budget__prefix {
    color: var(--text-muted);
    font-weight: 600;
}

.gs-ai-budget {
    width: 120px;
}

.gs-ai-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 12px;
    margin-bottom: 14px;
}

.gs-ai-tile {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 12px 14px;
    border-radius: 10px;
    background: var(--surface-subtle);
    border: 1px solid var(--border-subtle);
}

.gs-ai-tile__label {
    font-size: var(--font-size-tiny);
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.gs-ai-tile__value {
    font-size: var(--font-size-large);
    font-weight: 700;
    color: var(--text-primary);
}

.gs-ai-tile__sub {
    font-size: var(--font-size-tiny);
    color: var(--text-secondary);
}

/* -----------------------------------------------------------------------------
   RECORD CHIPS - [[kind:id|label]] in an answer
   ----------------------------------------------------------------------------- */

.agent-meeko__ref {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 100%;
    margin: 1px 0;
    padding: 2px 9px 2px 7px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--accent-border);
    background: var(--accent-tint);
    color: var(--accent);
    font: inherit;
    font-size: 0.94em;
    font-weight: 600;
    line-height: 1.35;
    vertical-align: baseline;
    cursor: pointer;
    text-align: left;
    transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
}

.agent-meeko__ref .icon {
    flex: none;
    opacity: .85;
}

.agent-meeko__ref span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.agent-meeko__ref:hover {
    background: var(--surface-panel);
    border-color: var(--accent);
    box-shadow: 0 1px 2px rgba(16, 24, 40, .1);
}

.agent-meeko__ref:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

.agent-meeko__bubble li .agent-meeko__ref {
    margin-right: 2px;
}

/* -----------------------------------------------------------------------------
   THE PICKER CARD
   ----------------------------------------------------------------------------- */

.agent-meeko__picker {
    margin-top: 6px;
    border: 1px solid var(--accent-border);
    background: var(--surface-panel);
    border-radius: 12px;
    font-size: var(--font-size-small);
}

.agent-meeko__picker--used,
.agent-meeko__picker--cancelled {
    opacity: .7;
}

.agent-meeko__picker-fields {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px 12px 4px;
}

.agent-meeko__picker-field {
    position: relative;
}

.agent-meeko__picker-label {
    display: block;
    margin-bottom: 4px;
    font-size: var(--font-size-tiny);
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.agent-meeko__picker-box {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 8px;
    border: 1px solid var(--border-strong);
    border-radius: 9px;
    background: var(--surface-panel);
    transition: border-color .15s ease, box-shadow .15s ease;
}

.agent-meeko__picker-box:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-tint);
}

.agent-meeko__picker-field--chosen .agent-meeko__picker-box {
    border-color: #86efac;
    background: #f0fdf4;
}

.agent-meeko__picker-icon {
    color: var(--text-muted);
    display: inline-flex;
    flex: none;
}

.agent-meeko__picker-field--chosen .agent-meeko__picker-icon {
    color: #15803d;
}

.agent-meeko__picker-input {
    flex: 1;
    min-width: 0;
    border: 0;
    background: transparent;
    padding: 8px 0;
    font: inherit;
    font-size: var(--font-size-small);
    color: var(--text-primary);
    outline: none;
}

.agent-meeko__picker-field--chosen .agent-meeko__picker-input {
    font-weight: 600;
}

/* Plain form fields on the same card: text, date, time, select, textarea. */
.agent-meeko__picker-box--plain {
    padding: 0 10px;
}

.agent-meeko__picker-select {
    appearance: none;
    background: transparent url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>") no-repeat right 2px center;
    padding-right: 20px;
    cursor: pointer;
}

.agent-meeko__picker-textarea {
    resize: vertical;
    min-height: 64px;
    line-height: 1.45;
}

.agent-meeko__picker-input[type="date"],
.agent-meeko__picker-input[type="time"] {
    color-scheme: light;
}

.agent-meeko__picker-clear {
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--text-muted);
    width: 22px;
    height: 22px;
    border-radius: 6px;
    display: grid;
    place-items: center;
    cursor: pointer;
}

.agent-meeko__picker-clear:hover {
    background: var(--surface-subtle);
    color: var(--text-primary);
}

.agent-meeko__picker-results {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    margin-top: 4px;
    max-height: 240px;
    overflow-y: auto;
    background: var(--surface-panel);
    border: 1px solid var(--border-strong);
    border-radius: 10px;
    box-shadow: 0 10px 30px rgba(16, 24, 40, .14);
    z-index: 5;
    padding: 4px;
}

.agent-meeko__picker-option {
    appearance: none;
    display: flex;
    flex-direction: column;
    gap: 1px;
    width: 100%;
    text-align: left;
    padding: 7px 9px;
    border: 0;
    border-radius: 7px;
    background: transparent;
    font: inherit;
    cursor: pointer;
}

.agent-meeko__picker-option:hover,
.agent-meeko__picker-option:focus-visible {
    background: var(--accent-tint);
    outline: none;
}

.agent-meeko__picker-option-label {
    font-size: var(--font-size-small);
    font-weight: 600;
    color: var(--text-primary);
}

.agent-meeko__picker-option-detail {
    font-size: var(--font-size-tiny);
    color: var(--text-muted);
}

.agent-meeko__picker-empty {
    padding: 9px 10px;
    font-size: var(--font-size-tiny);
    color: var(--text-muted);
}

.agent-meeko__picker .agent-meeko__action-buttons {
    padding: 8px 12px 12px;
}

/* ---- Conversation mode: the countdown on the last answer ----------------- */

.agent-meeko__listen {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-left: 6px;
    padding: 2px 9px 2px 7px;
    border-radius: var(--radius-pill);
    border: 1px solid #fecdca;
    background: #fef3f2;
    color: #b42318;
    font: inherit;
    font-size: var(--font-size-tiny);
    font-weight: 600;
    cursor: pointer;
    animation: agent-meeko-listen-in .25s ease;
}

.agent-meeko__listen:hover {
    background: #fee4e2;
}

.agent-meeko__listen-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #d92d20;
    animation: agent-meeko-pulse-soft 1.2s infinite ease-in-out;
}

@keyframes agent-meeko-listen-in {
    from { opacity: 0; transform: translateY(2px); }
    to { opacity: 1; transform: none; }
}

/* ---- Settings: the voice chooser ---------------------------------------- */

.gs-ai-voice {
    padding: 12px 0 2px;
    border-top: 1px solid var(--border-subtle);
    margin-top: 6px;
}

.gs-ai-voice__row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 8px;
}

.gs-ai-voice__select {
    max-width: 380px;
}

/* ---- Settings: microphone state ---------------------------------------- */

.gs-ai-mic {
    margin-top: 12px;
}

.gs-ai-mic .gs-ai-voice-actions {
    margin-top: 8px;
}

/* ---- Agent Mode: the card grid -------------------------------------------

   One card per area of the portal, in the same grid Connected Apps and Modules
   use. Those classes are borrowed rather than copied so the three screens stay
   one product: change the card face once and all three follow.

   What used to be here was eleven stacked cards and forty-eight switches down
   five thousand pixels, with the module permissions on a tab of their own. A
   grid of sixteen cards fits on a screen, and each one opens onto everything
   about its own subject.
-------------------------------------------------------------------------- */

.gs-ai-intro {
    margin-bottom: 14px;
}

.gs-ai-grid {
    margin-top: 14px;
}

/* The whole card is the control, so it has to look like one. */
.gs-ai-card {
    cursor: pointer;
}

.gs-ai-card:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* ---- Inside a card's panel ------------------------------------------------

   The panel is a stack of sections, and each section is a heading, a sentence
   of explanation, and a group of controls in one bordered box.

   The cards these are built from drop their own frame - a modal that is a box
   of boxes, each one narrower than the last, is what the old page looked like.
   But dropping the frame also drops the padding the rows inside it were
   relying on, which left every switch pressed against the edge of the panel.
   So the padding moves onto the rows, and the rows group themselves into a
   box: first and last take the rounded corners, the ones between take a single
   hairline. No markup changes and adjacent rows read as one control group.
-------------------------------------------------------------------------- */

.gs-ai-panel .gs-card {
    padding: 0;
    border: 0;
    background: transparent;
    margin: 0 0 30px;
}

.gs-ai-panel .gs-card:last-child {
    margin-bottom: 4px;
}

/* A hairline above every section but the first. Generous spacing alone reads
   as "unfinished" on a long panel; a rule reads as "new subject". */
.gs-ai-panel .gs-card + .gs-card {
    padding-top: 26px;
    border-top: 1px solid var(--border-subtle);
}

.gs-ai-panel .gs-card__title {
    margin: 0 0 5px;
    font-size: 15px;
    font-weight: 650;
    letter-spacing: -0.01em;
}

/* The sentence under a heading explains the group below it, so it sits closer
   to the controls than to the heading it follows. */
.gs-ai-panel .gs-card > .gs-hint {
    margin: 0 0 14px;
}

/* A hint AFTER the controls is a footnote, not an introduction. */
.gs-ai-panel .gs-card > .gs-hint:last-child {
    margin: 12px 0 0;
}

.gs-ai-panel > .gs-hint:first-child {
    margin: 0 0 22px;
    font-size: var(--font-size-small);
    line-height: 1.6;
}

.gs-ai-panel .inline-notice {
    margin: 0 0 22px;
}

/* ---- Switch rows, grouped ------------------------------------------------- */

.gs-ai-panel .gs-ai-row {
    padding: 14px 16px;
    border: 1px solid var(--border-subtle);
    border-top: 0;
    background: var(--surface-panel);
}

.gs-ai-panel .gs-ai-row:first-of-type {
    border-top: 1px solid var(--border-subtle);
    border-radius: 10px 10px 0 0;
}

.gs-ai-panel .gs-ai-row:last-of-type {
    border-radius: 0 0 10px 10px;
}

.gs-ai-panel .gs-ai-row:only-of-type {
    border-radius: 10px;
}

/* The switch and its label, then everything explaining them lined up under the
   label rather than under the switch. */
.gs-ai-panel .gs-ai-row__hint {
    margin: 5px 0 0 50px;
    line-height: 1.55;
}

/* The type picker belongs to the switch above it, so it keeps that indent -
   but it is a box inside a box now, so it loses some of its own inset. */
.gs-ai-panel .gs-ai-filter {
    margin: 12px 0 2px 50px;
    padding: 12px 13px;
    background: var(--surface-subtle);
}

/* ---- Module and rewrite rows ---------------------------------------------- */

/* Already a bordered group. It only needs to breathe a little more here, and
   to stop the level selector from being pushed against the panel edge. */
.gs-ai-panel .gs-ai-modules {
    border-radius: 10px;
}

.gs-ai-panel .gs-ai-module {
    padding: 14px 16px;
    gap: 14px;
}

/* At panel width the name, the description and a three-way selector cannot
   share a line without the selector being squeezed. Below that, the selector
   drops under the text it belongs to rather than shrinking into it. */
@media (max-width: 1100px) {
    .gs-ai-panel .gs-ai-module {
        grid-template-columns: auto auto minmax(0, 1fr);
        row-gap: 12px;
    }

    .gs-ai-panel .gs-ai-module .gs-ai-levels {
        grid-column: 1 / -1;
        justify-self: stretch;
    }
}

/* ---- Module access rows (was the Permissions tab) ------------------------ */

.gs-ai-quick {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    margin: 0 0 14px;
    border-radius: 10px;
    background: var(--surface-subtle);
    border: 1px solid var(--border-subtle);
}

.gs-ai-quick__label {
    margin-right: 4px;
    font-size: var(--font-size-small);
    font-weight: 600;
    color: var(--text-secondary);
}

.gs-ai-modules {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
    overflow: hidden;
}

.gs-ai-module {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border-top: 1px solid var(--border-subtle);
    background: var(--surface-panel);
    transition: background-color .15s ease, opacity .15s ease;
}

.gs-ai-module:first-child {
    border-top: 0;
}

.gs-ai-module:hover {
    background: var(--surface-subtle);
}

.gs-ai-module--off .gs-ai-module__icon,
.gs-ai-module--off .gs-ai-module__text {
    opacity: .5;
}

.gs-ai-module__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 8px;
    background: var(--accent-tint);
    color: var(--accent);
    flex-shrink: 0;
}

.gs-ai-module__text {
    min-width: 0;
}

.gs-ai-module__name {
    font-weight: 600;
    color: var(--text-primary);
}

.gs-ai-module__hint {
    margin-top: 2px;
    font-size: var(--font-size-tiny);
    color: var(--text-muted);
    line-height: 1.4;
}

.gs-ai-levels {
    display: inline-flex;
    padding: 3px;
    border-radius: var(--radius-pill);
    background: var(--surface-subtle);
    border: 1px solid var(--border-subtle);
    flex-shrink: 0;
}

.gs-ai-level {
    appearance: none;
    border: 0;
    background: transparent;
    font: inherit;
    font-size: var(--font-size-tiny);
    font-weight: 600;
    color: var(--text-secondary);
    padding: 6px 12px;
    border-radius: var(--radius-pill);
    cursor: pointer;
    white-space: nowrap;
    transition: background-color .15s ease, color .15s ease, box-shadow .15s ease;
}

.gs-ai-level:hover:not(:disabled):not(.gs-ai-level--active) {
    color: var(--text-primary);
    background: var(--surface-panel);
}

.gs-ai-level--active {
    color: var(--accent);
    background: var(--surface-panel);
    box-shadow: 0 1px 2px rgba(16, 24, 40, .12);
}

.gs-ai-level:disabled {
    cursor: not-allowed;
    color: var(--text-muted);
    opacity: .55;
}

.gs-ai-level--active:disabled {
    opacity: .75;
}

.gs-ai-module--off .gs-ai-levels {
    opacity: .5;
}

@media (max-width: 900px) {
    .gs-ai-module {
        grid-template-columns: auto auto minmax(0, 1fr);
    }

    .gs-ai-levels {
        grid-column: 1 / -1;
        justify-self: start;
    }
}

.agent-meeko__action--undone { opacity: .65; }
.agent-meeko__action--undone .agent-meeko__action-result { color: var(--text-muted); }
.agent-meeko__undo:hover { color: #b42318; border-color: #fecdca; }

.agent-meeko__listen--starting {
    color: var(--text-muted);
    border-color: var(--border-strong);
    background: var(--surface-subtle);
}

.agent-meeko__listen--starting .agent-meeko__listen-dot {
    background: var(--text-muted);
}

/* While you are talking the pill turns blue and drops the seconds. */
.agent-meeko__listen--hearing {
    color: #0369a1;
    border-color: #7dd3fc;
    background: #e0f2fe;
}

.agent-meeko__listen--hearing .agent-meeko__listen-dot {
    background: #0ea5e9;
    animation-duration: .6s;
}

/* =============================================================================
   THE FLOATING LAUNCHER, AND THE COMPACT POPUP IT OPENS

   The second way in. The circle sits bottom right and opens the same chat as
   the header sparkle, wearing a different shape: a card that floats over the
   page rather than a panel that pushes it across. One pane, two
   presentations - see `presentation` in agent-meeko-panel.js.
   ============================================================================= */

/* The launcher sits bottom right, which is also where every slide-over panel
   puts its primary action. With a panel open the bubble covered Save, Publish
   or Next, and a click meant for the button opened the assistant instead.

   Lifting it clear of the footer was the first fix and it was not enough: the
   panel fills the whole right-hand side, so wherever the bubble goes down
   there it is over the panel's own content - it was sitting on top of a
   detail row's value. A panel has the person's attention while it is open,
   and Meeko is one Escape and one click away, so the bubble gets out of the
   way entirely and comes back when the panel closes. */
body:has(.slide-over--open) .agent-meeko-launcher {
    opacity: 0;
    pointer-events: none;
    transform: translateY(8px) scale(0.9);
}

.agent-meeko-launcher {
    position: fixed;
    right: 24px;
    bottom: 31px;
    z-index: 102;

    width: 56px;
    height: 56px;
    border: 0;
    border-radius: 50%;
    display: grid;
    place-items: center;
    cursor: pointer;

    color: #fff;
    /* Black, matching the app's own ink rather than an arbitrary pure black,
       so it sits with the interface instead of on top of it. It also gives the
       blue listening ring the most contrast it can get. */
    background: var(--text-primary);
    box-shadow: 0 10px 26px rgba(15, 23, 42, .28), 0 2px 6px rgba(15, 23, 42, .16);

    /* The ring is positioned against this, exactly as it is in the header. */
    isolation: isolate;

    transition: transform .18s var(--easing-standard), box-shadow .18s var(--easing-standard),
        background .18s var(--easing-standard), opacity .18s var(--easing-standard);
}

.agent-meeko-launcher .icon {
    position: relative;
    z-index: 1;
}

.agent-meeko-launcher:hover {
    transform: translateY(-2px);
    box-shadow: 0 14px 32px rgba(15, 23, 42, .34), 0 3px 8px rgba(15, 23, 42, .2);
}

.agent-meeko-launcher:active {
    transform: translateY(0);
}

.agent-meeko-launcher:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

/* While its own popup is open, the circle is the way to close it again: it
   stays black and shows a close mark instead of the sparkle. */
.agent-meeko-launcher--open {
    background: #2b3038;
}

/* The microphone is open and waiting for "Hey Meeko". The same red dot the
   header sparkle has carried, on the button that may well be the only one on
   screen. Deliberately NOT the blue ring: red means the microphone is open,
   blue means Meeko is listening to you right now. */
.agent-meeko-launcher--listening::after {
    content: '';
    position: absolute;
    top: 5px;
    right: 5px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #d92d20;
    /* Ringed in the page's own background so it reads as a badge sitting on
       the circle rather than a hole punched in it. */
    box-shadow: 0 0 0 2.5px var(--surface-page, #fff);
    animation: agent-meeko-pulse-soft 1.6s infinite ease-in-out;
    z-index: 2;
}

@media (prefers-reduced-motion: reduce) {
    .agent-meeko-launcher--listening::after { animation: none; }
}

/* The popup: a card above the circle, not a panel beside the page. Nothing
   here moves the application body, which is what `presentation` decides. */
.agent-meeko-dock--popup {
    top: auto;
    right: 20px;
    bottom: 92px;

    width: min(400px, calc(100vw - 40px));
    height: min(620px, calc(100vh - var(--height-top-header) - 120px));

    border: 1px solid var(--border-subtle);
    border-radius: 18px;
    overflow: hidden;
    box-shadow: 0 24px 60px rgba(15, 23, 42, .3), 0 4px 12px rgba(15, 23, 42, .14);

    /* Rises from the circle rather than sliding in from the edge. */
    transform: translateY(12px) scale(.98);
    transform-origin: 100% 100%;
    opacity: 0;
    transition:
        transform var(--duration-panel-close) var(--easing-standard),
        opacity var(--duration-panel-close) var(--easing-standard),
        visibility 0s linear var(--duration-panel-close);
}

.agent-meeko-dock--popup.agent-meeko-dock--open {
    transform: translateY(0) scale(1);
    opacity: 1;
    transition:
        transform var(--duration-panel-open) var(--easing-standard),
        opacity var(--duration-panel-open) var(--easing-standard),
        visibility 0s;
}

/* On a phone the popup is the sheet, and the circle gets out of its way. */
@media (max-width: 560px) {
    .agent-meeko-dock--popup {
        right: 12px;
        left: 12px;
        bottom: 12px;
        width: auto;
        height: min(78vh, calc(100vh - var(--height-top-header) - 24px));
    }

    .agent-meeko-dock--popup.agent-meeko-dock--open ~ .agent-meeko-launcher,
    .agent-meeko-launcher--open {
        opacity: 0;
        pointer-events: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .agent-meeko-launcher { transition: none; }
    .agent-meeko-launcher:hover { transform: none; }
    .agent-meeko-dock--popup { transform: none; }
}

/* -----------------------------------------------------------------------------
   Agent Mode: the Google Ads card
   ----------------------------------------------------------------------------- */

/* Which accounts the daily pass covers. Empty means every one, so the list is
   a way of narrowing rather than a list that has to be filled in. */
.gs-ads-accounts__list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    margin-top: 8px;
}

.gs-ads-accounts__item {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: var(--font-size-small);
    color: var(--text-secondary);
    cursor: pointer;
}

.gs-ads-accounts__item input {
    accent-color: var(--text-primary);
    cursor: pointer;
}

.gs-ads-level {
    width: auto;
    min-width: 240px;
    max-width: 100%;
    margin-top: 8px;
}

/* Shown only at the level that can actually change a budget. A cap on a power
   nothing holds is a control that teaches the wrong thing. */
.gs-ads-caps__fields {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
    margin-top: 8px;
}

.gs-ads-caps__field {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.gs-ads-caps__field .gs-hint {
    margin: 0;
}

/* =============================================================================
   THE INTRODUCTION

   A five minute conversation, not a form with a mascot on it. So it is built
   like a conversation: Meeko's lines arrive one at a time and type themselves
   in, the person's answers sit on the other side, and the whole thing scrolls
   like a chat rather than replacing itself like a wizard.
   ========================================================================== */

.meeko-intro {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: grid;
    place-items: center;
    padding: 24px;
    opacity: 0;
    transition: opacity .28s var(--easing-standard, ease);
}

.meeko-intro--open { opacity: 1; }

.meeko-intro__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(12, 14, 22, .55);
    backdrop-filter: blur(3px);
}

.meeko-intro__card {
    position: relative;
    width: min(620px, 100%);
    /* A fixed frame rather than a card that grows with every line. The mark
       and the answer box stay where they were put; the conversation moves
       between them. A card that grew would walk the answer box down the
       screen mid-sentence, which is what made this feel like it was coming
       apart. */
    height: min(720px, 88vh);
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
    border-radius: 20px;
    background: var(--surface-panel, #fff);
    box-shadow: 0 30px 80px rgba(12, 14, 22, .34);
    transform: translateY(14px) scale(.985);
    transition: transform .34s var(--easing-standard, cubic-bezier(.2, .8, .3, 1));
}

.meeko-intro--open .meeko-intro__card { transform: none; }

.meeko-intro__close {
    position: absolute;
    top: 14px;
    right: 14px;
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
}

.meeko-intro__close:hover { background: var(--surface-subtle); color: var(--text-primary); }

/* ---- The mark, breathing -------------------------------------------------
   It is the only thing on screen before the first line lands, so it has to
   look alive rather than like a logo somebody centred. */

/* ---- The pinned head and foot ---------------------------------------------
   Meeko's face, whose turn it is and how far through you are never scroll
   away, and neither does the box you answer in. Only the conversation moves.
   The hairlines appear once there is something above or below to scroll to,
   so an introduction that fits on one screen has no furniture on it. */
.meeko-intro__head {
    flex: 0 0 auto;
    padding: 28px 30px 0;
    background: var(--surface-panel, #fff);
    border-bottom: 1px solid transparent;
    transition: border-color .2s ease;
}

.meeko-intro__card[data-scrolled="top"] .meeko-intro__head,
.meeko-intro__card[data-scrolled="both"] .meeko-intro__head {
    border-bottom-color: var(--border-subtle, rgba(15, 23, 42, .08));
}

.meeko-intro__foot {
    flex: 0 0 auto;
    padding: 16px 30px 22px;
    background: var(--surface-panel, #fff);
    border-top: 1px solid transparent;
    transition: border-color .2s ease;
}

.meeko-intro__card[data-scrolled="bottom"] .meeko-intro__foot,
.meeko-intro__card[data-scrolled="both"] .meeko-intro__foot {
    border-top-color: var(--border-subtle, rgba(15, 23, 42, .08));
}

/* The same black circle, the same sparkle, the same blue ring as the chat
   launcher. Meeko has one face in this product; a second mark invented for the
   introduction would be the first thing that told you it was bolted on. The
   ring is the real .agent-meeko-ring, so "listening" looks identical here and
   in the corner of every other screen. */
.meeko-intro__mark {
    position: relative;
    width: 64px;
    height: 64px;
    margin: 0 auto 4px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--text-primary);
    color: #fff;
    box-shadow: 0 10px 26px rgba(15, 23, 42, .28), 0 2px 6px rgba(15, 23, 42, .16);
    isolation: isolate;
    transition: box-shadow .3s var(--easing-standard, ease), transform .3s var(--easing-standard, ease);
}

.meeko-intro__mark .icon {
    position: relative;
    z-index: 1;
}

/* Meeko is talking: the mark breathes gently, so a long spoken passage is
   visibly coming from somewhere rather than the screen having stalled. */
.meeko-intro__mark[data-state="speaking"] {
    animation: meeko-intro-speaking 1.9s ease-in-out infinite;
}

/* Your turn. The blue ring runs, and the whole mark lifts slightly toward you. */
.meeko-intro__mark[data-state="listening"] {
    transform: scale(1.04);
    box-shadow: 0 0 0 4px rgba(56, 189, 248, .18),
                0 12px 30px rgba(15, 23, 42, .3);
}

@keyframes meeko-intro-speaking {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.035); }
}

/* Who is speaking, in words, under the mark. In voice mode this is the whole
   interface: you are not reading, you are waiting to be asked something, and
   "it is your turn" has to be readable from across a desk. */
.meeko-intro__turn {
    margin: 10px 0 0;
    text-align: center;
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--text-muted);
    min-height: 1em;
}

.meeko-intro__turn--listening {
    color: #0284c7;
}

.meeko-intro__turn--listening::before {
    content: '';
    display: inline-block;
    width: 7px;
    height: 7px;
    margin-right: 7px;
    border-radius: 50%;
    background: #38bdf8;
    vertical-align: middle;
    animation: meeko-intro-breathe 1.4s ease-in-out infinite;
}

/* ---- Where you are ------------------------------------------------------- */

.meeko-intro__progress {
    display: flex;
    justify-content: center;
    gap: 6px;
    margin: 14px 0 18px;
}

.meeko-intro__dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--border-default);
    transition: background .3s ease, width .3s ease;
}

.meeko-intro__dot--done { background: var(--accent, #635bff); }

.meeko-intro__dot--now {
    width: 20px;
    border-radius: 3px;
    background: var(--accent, #635bff);
}

/* ---- The conversation ---------------------------------------------------- */

.meeko-intro__script {
    flex: 1 1 auto;
    /* min-height:0 is what lets a flex child actually scroll instead of
       growing past its parent. Without it the column stretches and the card
       overflows. */
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 16px 30px;
}

.meeko-intro__script::-webkit-scrollbar { width: 8px; }
.meeko-intro__script::-webkit-scrollbar-thumb {
    border-radius: 4px;
    background: var(--border-default, rgba(15, 23, 42, .16));
}
.meeko-intro__script::-webkit-scrollbar-track { background: transparent; }

.meeko-intro__line {
    margin: 0;
    /* In a flex column every child shrinks by default, so once the
       conversation was longer than the card each paragraph was squeezed
       shorter than its own text and the lines printed straight over one
       another. They do not shrink. The column scrolls instead. */
    flex: 0 0 auto;
    font-size: 15px;
    line-height: 1.6;
    color: var(--text-primary);
    min-height: 1.6em;
}

/* Their own words, on the other side, quieter. This is the line that makes it
   look like a conversation rather than a script with inputs under it. */
.meeko-intro__line--theirs {
    align-self: flex-end;
    max-width: 80%;
    padding: 9px 14px;
    border-radius: 14px 14px 4px 14px;
    background: var(--accent-tint, #eef0ff);
    color: var(--text-primary);
    font-size: 14px;
    animation: meeko-intro-rise .26s var(--easing-standard, ease) both;
}

@keyframes meeko-intro-rise {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}

/* ---- Answering ----------------------------------------------------------- */

.meeko-intro__answer {
    opacity: 0;
    transform: translateY(8px);
    transition: opacity .3s ease, transform .3s var(--easing-standard, ease);
    pointer-events: none;
}

.meeko-intro__answer--ready {
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

.meeko-intro__choices {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.meeko-intro__choice {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 15px;
    border: 1px solid var(--border-default);
    border-radius: 11px;
    background: var(--surface-panel, #fff);
    color: var(--text-primary);
    font-size: 14px;
    font-weight: 550;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, transform .12s ease;
}

.meeko-intro__choice:hover {
    border-color: var(--accent, #635bff);
    background: var(--accent-tint, #eef0ff);
    transform: translateY(-1px);
}

.meeko-intro__choice--primary {
    border-color: var(--accent, #635bff);
    background: var(--accent, #635bff);
    color: #fff;
}

.meeko-intro__choice--primary:hover { background: var(--accent, #635bff); color: #fff; }

.meeko-intro__field {
    display: flex;
    gap: 8px;
    align-items: flex-end;
}

.meeko-intro__input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 11px 13px;
    border: 1px solid var(--border-default);
    border-radius: 11px;
    background: var(--surface-panel, #fff);
    color: var(--text-primary);
    font: inherit;
    font-size: 14px;
    resize: vertical;
}

.meeko-intro__input:focus {
    outline: none;
    border-color: var(--accent, #635bff);
    box-shadow: 0 0 0 3px var(--accent-tint, #eef0ff);
}

.meeko-intro__send { flex: 0 0 auto; }

.meeko-intro__skip {
    margin-top: 10px;
    border: 0;
    background: transparent;
    color: var(--text-muted);
    font-size: 13px;
    cursor: pointer;
    text-decoration: underline;
}

.meeko-intro__note {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 10px 0 0;
    font-size: 12.5px;
    color: var(--text-muted);
}

/* A dot that breathes while the microphone is open, so "listening" is
   something you can see rather than something you have to believe. */
.meeko-intro__mic {
    width: 8px;
    height: 8px;
    flex: none;
    border-radius: 50%;
    background: var(--status-danger, #ef4444);
    animation: meeko-intro-breathe 1.5s ease-in-out infinite;
}

@keyframes meeko-intro-breathe {
    0%, 100% { opacity: .35; transform: scale(.85); }
    50%      { opacity: 1;   transform: scale(1.15); }
}

/* The microphone, as a control rather than a state you have to trust. It is
   the only thing on screen that says whose turn it is while you are looking at
   the box rather than at the mark, and pressing it starts listening again when
   the browser has quietly given up. */
.meeko-intro__listen {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 10px;
    padding: 8px 12px;
    border: 1px solid var(--border-subtle, rgba(15, 23, 42, .1));
    border-radius: 999px;
    background: var(--surface-subtle, #f6f7f9);
    color: var(--text-muted);
    font-size: 12.5px;
    cursor: pointer;
    transition: border-color .2s ease, color .2s ease, background .2s ease;
}

.meeko-intro__listen:hover { border-color: var(--border-strong, rgba(15, 23, 42, .2)); }

.meeko-intro__listen[data-listening="yes"] {
    border-color: rgba(56, 189, 248, .5);
    background: rgba(56, 189, 248, .08);
    color: var(--text-primary);
}

.meeko-intro__listen .icon { flex: none; }

.meeko-intro__listen-bars {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    height: 12px;
}

.meeko-intro__listen-bars span {
    width: 2px;
    height: 4px;
    border-radius: 1px;
    background: currentColor;
    opacity: .35;
}

.meeko-intro__listen[data-listening="yes"] .meeko-intro__listen-bars span {
    animation: meeko-intro-bars .9s ease-in-out infinite;
    opacity: 1;
}

.meeko-intro__listen-bars span:nth-child(2) { animation-delay: .15s; }
.meeko-intro__listen-bars span:nth-child(3) { animation-delay: .3s; }
.meeko-intro__listen-bars span:nth-child(4) { animation-delay: .45s; }

@keyframes meeko-intro-bars {
    0%, 100% { height: 4px; }
    50%      { height: 12px; }
}

@media (prefers-reduced-motion: reduce) {
    .meeko-intro__listen-bars span { animation: none !important; height: 8px; }
}

/* ---- What it learned ------------------------------------------------------
   Each fact lands in turn rather than all at once. It is the moment the
   introduction proves it was listening, and a list that simply appears does
   not read as a proof of anything. */

.meeko-intro__learned {
    margin: 6px 0 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.meeko-intro__fact {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 9px 12px;
    border-radius: 10px;
    background: var(--surface-subtle);
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--text-secondary);
    opacity: 0;
    animation: meeko-intro-rise .3s var(--easing-standard, ease) both;
}

.meeko-intro__fact .icon { color: var(--status-success, #16a34a); flex: none; margin-top: 2px; }

@media (prefers-reduced-motion: reduce) {
    .meeko-intro,
    .meeko-intro__card,
    .meeko-intro__answer { transition: none; }

    .meeko-intro__pulse,
    .meeko-intro__mic,
    .meeko-intro__fact,
    .meeko-intro__line--theirs { animation: none; opacity: 1; }
}

@media (max-width: 620px) {
    .meeko-intro { padding: 12px; }
    .meeko-intro__card { height: 94vh; }
    .meeko-intro__head { padding: 24px 20px 0; }
    .meeko-intro__script { padding: 14px 20px; }
    .meeko-intro__foot { padding: 14px 20px 18px; }
    .meeko-intro__choice { flex: 1 1 auto; justify-content: center; }
}
