/* Viva Mais AI — "travel agency desk" design system. Every surface is paper: cream desk, sand ticket stock, navy ink, coral rubber stamps. Hard offset shadows, never glass. */ @font-face { font-family: "Nunito"; font-style: normal; font-weight: 400 800; font-display: swap; src: url("/static/fonts/nunito-var.woff2") format("woff2"); } @font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 400 600; font-display: swap; src: url("/static/fonts/jetbrains-mono-var.woff2") format("woff2"); } :root { --vm-mango: #FFC83D; --vm-coral: #FF7A4D; --vm-teal: #1FBAC2; --vm-navy: #123452; --vm-deep-navy: #071E34; --vm-sky: #DDF7F7; --vm-sand: #FFF4D7; --vm-cream: #FFFDF7; --vm-route-blue: #2F6FED; --vm-mint: #7CE0C3; --vm-rose: #FFB3A7; --vm-slate: #6A7685; --vm-ink-shadow: rgba(7, 30, 52, 0.14); --vm-font: "Nunito", system-ui, sans-serif; --vm-mono: "JetBrains Mono", ui-monospace, monospace; --vm-radius-card: 0; --vm-radius-ticket: 0; /* objects-on-a-desk depth: contact shadow + ambient + a whisper of the brand hard offset */ --vm-elev-1: 0 1px 2px rgba(7, 30, 52, 0.16), 2px 3px 8px rgba(7, 30, 52, 0.08), 3px 3px 0 var(--vm-ink-shadow); --vm-elev-2: 0 1px 2px rgba(7, 30, 52, 0.18), 6px 10px 18px rgba(7, 30, 52, 0.12), 4px 4px 0 var(--vm-ink-shadow); --vm-elev-3: 0 2px 3px rgba(7, 30, 52, 0.2), 12px 18px 28px rgba(7, 30, 52, 0.18), 4px 4px 0 var(--vm-ink-shadow); --vm-paper-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E"); } * { box-sizing: border-box; } * { scrollbar-width: thin; scrollbar-color: rgba(18, 52, 82, 0.3) transparent; } ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: rgba(18, 52, 82, 0.3); border-radius: 0; } .vm-sidebar { scrollbar-color: rgba(221, 247, 247, 0.25) transparent; } .vm-sidebar::-webkit-scrollbar-thumb { background: rgba(221, 247, 247, 0.25); } html, body { height: 100%; } body { margin: 0; font-family: var(--vm-font); background: var(--vm-cream); color: var(--vm-navy); font-size: 15px; line-height: 1.45; } /* faint paper grain over everything */ body::before { content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 999; opacity: 0.035; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E"); } /* ---------- layout ---------- */ .vm-app { display: grid; grid-template-areas: "sidebar topbar chatdock" "sidebar main chatdock"; grid-template-columns: 248px minmax(0, 1fr) 332px; grid-template-rows: auto 1fr; min-height: 100vh; } .vm-sidebar { grid-area: sidebar; background: var(--vm-paper-grain), linear-gradient(160deg, #0B2541, var(--vm-deep-navy) 55%, #051323); color: var(--vm-cream); padding: 14px 16px 14px 12px; display: flex; flex-direction: column; gap: 10px; position: sticky; top: 0; height: 100vh; overflow-y: auto; box-shadow: inset -8px 0 14px -10px rgba(0, 0, 0, 0.8); } /* stitched leather edge */ .vm-sidebar::after { content: ""; position: absolute; top: 8px; bottom: 8px; right: 5px; border-right: 2px dashed rgba(221, 247, 247, 0.18); pointer-events: none; } .vm-topbar { grid-area: topbar; display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 14px 28px; background: var(--vm-cream); border-bottom: 2px solid var(--vm-sand); } .vm-main { grid-area: main; padding: 26px 30px 60px; min-width: 0; /* the desk itself: warm wood-grain bands under everything */ background: repeating-linear-gradient(90deg, rgba(122, 90, 56, 0.03) 0 2px, transparent 2px 120px), repeating-linear-gradient(0deg, rgba(122, 90, 56, 0.022) 0 1px, transparent 1px 64px), linear-gradient(170deg, #F8F0DF, #F2E7D1); } .vm-chatdock { grid-area: chatdock; border-left: 2px solid var(--vm-sand); background: #FBF7EC; padding: 18px 16px; display: flex; flex-direction: column; gap: 12px; position: sticky; top: 0; height: 100vh; overflow-y: auto; } /* ---------- sidebar ---------- */ .vm-nav { display: flex; flex-direction: column; gap: 2px; flex: 1; } .vm-nav-item { display: flex; align-items: center; gap: 9px; color: var(--vm-sky); text-decoration: none; padding: 5px 9px; border-radius: 0; font-weight: 600; font-size: 13.5px; border-left: 3px solid transparent; transition: background 0.15s ease; } .vm-nav-item:hover { background: rgba(255, 255, 255, 0.08); } /* the active item protrudes like an index-tab divider */ .vm-nav-item--active { background: rgba(31, 186, 194, 0.22); border-left-color: var(--vm-mango); color: #fff; transform: translateX(5px); box-shadow: -3px 2px 5px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.1); } .vm-nav-item { transition: background 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease; } .vm-nav-icon { width: 30px; height: 30px; object-fit: contain; flex-shrink: 0; } .vm-badge { margin-left: auto; font-size: 11.5px; font-family: var(--vm-mono); min-width: 14px; text-align: center; } .vm-badge--on { background: var(--vm-mango); color: var(--vm-deep-navy); border-radius: 0; padding: 1px 7px; font-weight: 700; } /* ---------- status panel (sidebar widget) ---------- */ .vm-status { background: rgba(255, 255, 255, 0.07); border-radius: var(--vm-radius-card); padding: 12px; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; } .vm-status--success { background: rgba(124, 224, 195, 0.15); } .vm-status--danger { background: rgba(255, 122, 77, 0.18); } .vm-status-text { margin: 0; font-size: 12.5px; color: var(--vm-cream); font-weight: 600; } .vm-progress { width: 100%; height: 8px; appearance: none; border: none; border-radius: 0; overflow: hidden; background: rgba(255, 255, 255, 0.15); } .vm-progress::-webkit-progress-bar { background: rgba(255, 255, 255, 0.15); } .vm-progress::-webkit-progress-value { background: var(--vm-mango); } .vm-progress::-moz-progress-bar { background: var(--vm-mango); } /* ---------- mascot sprite (8 frames per sheet) ---------- */ .vm-mascot { display: inline-block; width: 96px; height: 96px; background-repeat: no-repeat; background-size: 768px 96px; animation: vm-mascot-play 0.9s steps(8) infinite; } .vm-mascot--lg { width: 144px; height: 144px; background-size: 1152px 144px; } .vm-mascot--lg ~ * { display: block; } @keyframes vm-mascot-play { to { background-position-x: -768px; } } .vm-mascot--lg { animation-name: vm-mascot-play-lg; } @keyframes vm-mascot-play-lg { to { background-position-x: -1152px; } } .vm-mascot[data-state="smiling"] { background-image: url("/assets/mascot/spritesheets/robot-cowfish-smiling-spritesheet.png"); } .vm-mascot[data-state="thinking"] { background-image: url("/assets/mascot/spritesheets/robot-cowfish-thinking-spritesheet.png"); } .vm-mascot[data-state="loading"] { background-image: url("/assets/mascot/spritesheets/robot-cowfish-loading-puffed-spritesheet.png"); } .vm-mascot[data-state="scanning"] { background-image: url("/assets/mascot/spritesheets/robot-cowfish-scanning-document-spritesheet.png"); } .vm-mascot[data-state="celebrating"] { background-image: url("/assets/mascot/spritesheets/robot-cowfish-celebrating-reservation-spritesheet.png"); } .vm-mascot[data-state="sleepy"] { background-image: url("/assets/mascot/spritesheets/robot-cowfish-sleepy-low-power-spritesheet.png"); animation-duration: 1.6s; } /* ---------- topbar ---------- */ .vm-customer { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; } .vm-customer-name { font-size: 19px; font-weight: 800; } .vm-customer--empty .vm-customer-name { color: var(--vm-slate); font-weight: 600; font-size: 15px; } .vm-customer-detail { font-size: 13px; color: var(--vm-slate); } .vm-topbar-right { display: flex; align-items: center; gap: 10px; } /* The three top controls share one height and an 8px radius so they read as a single, aligned action group instead of three differently-sized buttons. */ .vm-lang-toggle, .vm-upload-label, .vm-clear-btn { height: 38px; box-sizing: border-box; display: inline-flex; align-items: center; border-radius: 0; } .vm-lang-toggle { background: rgba(18, 52, 82, 0.08); padding: 3px; gap: 2px; } .vm-lang-btn { border: none; background: transparent; color: var(--vm-slate); font-family: inherit; font-weight: 700; font-size: 12.5px; letter-spacing: 0.04em; height: 100%; display: inline-flex; align-items: center; padding: 0 12px; border-radius: 0; cursor: pointer; transition: background 0.12s ease, color 0.12s ease; } .vm-lang-btn:hover { color: var(--vm-navy); } .vm-lang-btn.vm-lang--active { background: var(--vm-cream); color: var(--vm-navy); box-shadow: var(--vm-elev-1); } .vm-upload-label { background: var(--vm-teal); color: #fff; font-weight: 700; font-size: 13px; padding: 0 16px; cursor: pointer; box-shadow: var(--vm-elev-1), inset 0 1px 0 rgba(255, 255, 255, 0.25); transition: transform 0.1s ease, box-shadow 0.1s ease; } .vm-upload-label:hover { transform: translate(-1px, -1px); box-shadow: var(--vm-elev-2), inset 0 1px 0 rgba(255, 255, 255, 0.25); } .vm-upload-label:active { transform: translate(2px, 2px); box-shadow: inset 0 2px 5px rgba(7, 30, 52, 0.35); } .vm-upload--over .vm-upload-label { outline: 3px dashed var(--vm-mango); outline-offset: 3px; } body.vm-busy .vm-upload-label { opacity: 0.55; pointer-events: none; } /* ---------- main sections ---------- */ .vm-section-title { font-size: 22px; font-weight: 800; margin: 0 0 18px; letter-spacing: -0.2px; } .vm-session-note { margin-top: 26px; font-size: 12px; color: var(--vm-slate); } /* first-run hero dropzone */ .vm-hero { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 56px 24px; border: 3px dashed var(--vm-teal); border-radius: 0; background: var(--vm-sky); cursor: pointer; text-align: center; transition: background 0.15s ease, border-color 0.15s ease; } .vm-hero strong { font-size: 19px; font-weight: 800; } .vm-hero span:last-child { color: var(--vm-slate); font-size: 14px; } .vm-hero:hover, .vm-hero--over { background: #CDF2F2; border-color: var(--vm-mango); } .vm-hero-wrap { display: flex; flex-direction: column; align-items: center; gap: 14px; } .vm-example-btn { border: none; background: var(--vm-mango); color: var(--vm-deep-navy); font-family: var(--vm-font); font-weight: 800; font-size: 14px; padding: 10px 18px; border-radius: 0; cursor: pointer; box-shadow: 3px 3px 0 var(--vm-ink-shadow); transition: transform 0.1s ease; } .vm-example-btn:hover:not(:disabled) { transform: translate(-1px, -1px); box-shadow: var(--vm-elev-2), inset 0 1px 0 rgba(255, 255, 255, 0.35); } .vm-example-btn:active:not(:disabled) { transform: translate(2px, 2px); box-shadow: inset 0 2px 5px rgba(7, 30, 52, 0.3); } .vm-example-btn:disabled { opacity: 0.55; cursor: progress; } /* empty state = a quiet passport page */ .vm-empty { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 42px 20px; background: repeating-linear-gradient(0deg, transparent 0 34px, rgba(18, 52, 82, 0.04) 34px 35px), var(--vm-sand); border-radius: var(--vm-radius-card); border: 1.5px solid rgba(18, 52, 82, 0.08); color: var(--vm-slate); font-weight: 600; } .vm-empty-mascot { width: 88px; opacity: 0.9; } .vm-empty p { margin: 0; } /* ---------- ticket cards ---------- */ .vm-tickets { display: grid; grid-template-columns: repeat(auto-fill, minmax(420px, 1fr)); gap: 18px; } .vm-ticket { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) 128px; background-color: var(--vm-cream); background-image: var(--vm-paper-grain); border: 1.5px solid rgba(18, 52, 82, 0.12); border-radius: var(--vm-radius-ticket); box-shadow: var(--vm-elev-1); overflow: hidden; transition: rotate 0.18s ease, translate 0.18s ease, box-shadow 0.18s ease; /* side notches at the perforation line */ --vm-perf-x: calc(100% - 128px); mask-image: radial-gradient(circle 9px at var(--vm-perf-x) 0, transparent 8px, black 9px), radial-gradient(circle 9px at var(--vm-perf-x) 100%, transparent 8px, black 9px); mask-composite: intersect; -webkit-mask-composite: source-in; } /* resting tilt: cards thrown on the desk, never perfectly square */ .vm-tickets .vm-ticket:nth-child(3n) { rotate: 0.45deg; } .vm-tickets .vm-ticket:nth-child(3n + 1) { rotate: -0.35deg; } .vm-tickets .vm-ticket:nth-child(3n + 2) { rotate: 0.2deg; } .vm-ticket:hover { rotate: 0deg; translate: 0 -3px; box-shadow: var(--vm-elev-3); } /* dog-eared corner */ .vm-ticket::before { content: ""; position: absolute; top: 0; left: 0; width: 15px; height: 15px; background: linear-gradient(135deg, #EFE6CE 48%, rgba(7, 30, 52, 0.16) 50%, transparent 52%); } .vm-ticket-main { padding: 14px 16px; display: flex; flex-wrap: wrap; gap: 10px 22px; align-content: flex-start; } .vm-ticket-field { display: flex; flex-direction: column; min-width: 0; } .vm-ticket-label { font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; /* letterpress: ink pressed into the cardstock */ color: #87929F; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.85); } .vm-ticket-value { font-family: var(--vm-mono); font-size: 13.5px; font-weight: 600; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; } .vm-ticket-stub { border-left: 2px dashed rgba(18, 52, 82, 0.25); background: var(--vm-sand); padding: 12px 10px; display: flex; flex-direction: column; align-items: center; justify-content: space-between; gap: 8px; transition: transform 0.18s ease, box-shadow 0.18s ease; } /* the stub starts tearing when you pick the ticket up */ .vm-ticket:hover .vm-ticket-stub { transform: translateX(2px) rotate(0.4deg); box-shadow: -4px 0 5px -3px rgba(7, 30, 52, 0.25); } .vm-ticket-file { font-size: 11px; text-align: center; overflow-wrap: anywhere; } .vm-ticket-file a, .crm-file-link { color: var(--vm-route-blue); font-weight: 700; } /* barcode out of layered gradients, no assets */ .vm-barcode { width: 78px; height: 26px; background: repeating-linear-gradient(90deg, var(--vm-deep-navy) 0 2px, transparent 2px 5px), repeating-linear-gradient(90deg, var(--vm-deep-navy) 0 1px, transparent 1px 4px), repeating-linear-gradient(90deg, var(--vm-deep-navy) 0 3px, transparent 3px 9px); background-blend-mode: multiply; opacity: 0.85; } /* luggage-tag chips */ .vm-tag { font-size: 10.5px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--vm-deep-navy); background: var(--vm-mango); padding: 4px 10px 4px 16px; clip-path: polygon(0 50%, 10px 0, 100% 0, 100% 100%, 10px 100%); mask-image: radial-gradient(circle 2.5px at 7px 50%, transparent 2.5px, black 3px); } .vm-tag--orcamentos { background: var(--vm-route-blue); color: #fff; } .vm-tag--reservas { background: var(--vm-teal); color: #fff; } .vm-tag--embarques { background: var(--vm-mango); } .vm-tag--pagamentos { background: var(--vm-mint); } .vm-tag--pedidos { background: var(--vm-coral); color: #fff; } .vm-tag--hospedagens { background: var(--vm-rose); } .vm-tag--documentos { background: var(--vm-slate); color: #fff; } .vm-tag--nao-categorizados { background: var(--vm-sand); } /* ---------- departure board (KPIs) ---------- */ .vm-board { position: relative; background: linear-gradient(178deg, #0A2440, var(--vm-deep-navy) 30%, #051524); border-radius: 0; padding: 22px 26px; box-shadow: var(--vm-elev-2), inset 0 0 0 3px rgba(255, 255, 255, 0.05), inset 0 3px 8px rgba(0, 0, 0, 0.55); display: flex; flex-direction: column; gap: 12px; margin-bottom: 20px; } /* corner bolts on the board frame */ .vm-board::before { content: ""; position: absolute; inset: 7px; pointer-events: none; background: radial-gradient(circle 3.5px at 3px 3px, #4A6884 2.2px, rgba(0, 0, 0, 0.65) 2.9px, transparent 3.6px), radial-gradient(circle 3.5px at calc(100% - 3px) 3px, #4A6884 2.2px, rgba(0, 0, 0, 0.65) 2.9px, transparent 3.6px), radial-gradient(circle 3.5px at 3px calc(100% - 3px), #4A6884 2.2px, rgba(0, 0, 0, 0.65) 2.9px, transparent 3.6px), radial-gradient(circle 3.5px at calc(100% - 3px) calc(100% - 3px), #4A6884 2.2px, rgba(0, 0, 0, 0.65) 2.9px, transparent 3.6px); background-repeat: no-repeat; } .vm-board-row { display: flex; align-items: center; gap: 12px; } .vm-board-icon { width: 30px; height: 30px; object-fit: contain; flex-shrink: 0; } .vm-board-label { width: 110px; color: var(--vm-sky); font-size: 12px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; } .vm-flaps { display: inline-flex; gap: 2px; } .vm-flaps { perspective: 300px; } .vm-flap { display: inline-grid; place-items: center; min-width: 20px; height: 30px; padding: 0 2px; background: linear-gradient(rgba(255, 255, 255, 0.1), transparent 42%), linear-gradient(#1A4060 49%, #0D2B47 51%); color: var(--vm-mango); text-shadow: 0 0 7px rgba(255, 200, 61, 0.45); font-family: var(--vm-mono); font-size: 16px; font-weight: 600; border-radius: 0; position: relative; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 1px 2px rgba(0, 0, 0, 0.55); animation: vm-flap-settle 0.4s ease-out backwards; } .vm-flap:nth-child(2n) { animation-delay: 0.05s; } .vm-flap:nth-child(3n) { animation-delay: 0.1s; } @keyframes vm-flap-settle { from { transform: rotateX(-85deg); } to { transform: rotateX(0); } } .vm-flap::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: rgba(0, 0, 0, 0.45); } .vm-flap--gap { background: transparent; } .vm-flap--gap::after { display: none; } .vm-board-status { width: 8px; height: 8px; border-radius: 50%; margin-left: auto; } .vm-board-status--ok { background: var(--vm-mint); } .vm-board-status--warn { background: var(--vm-coral); } .vm-board-note { color: var(--vm-sky); font-size: 12.5px; margin: 0; } /* ---------- WhatsApp replay (conversa section): a phone on the desk ---------- */ .vm-phone { position: relative; max-width: 820px; background: linear-gradient(165deg, #14233A, #0B1320 60%, #08101C); border-radius: 0; padding: 42px 14px 30px; box-shadow: var(--vm-elev-3), inset 0 0 0 2px rgba(255, 255, 255, 0.07), inset 0 1px 0 rgba(255, 255, 255, 0.14); } /* earpiece slit and home indicator */ .vm-phone::before { content: ""; position: absolute; top: 19px; left: 50%; translate: -50%; width: 64px; height: 6px; border-radius: 0; background: #1D2940; box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.7); } .vm-phone::after { content: ""; position: absolute; bottom: 12px; left: 50%; translate: -50%; width: 96px; height: 4px; border-radius: 0; background: rgba(255, 255, 255, 0.22); } .vm-phone .vm-chat { max-width: none; border: none; box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.15); border-radius: 0; } .vm-chat { max-width: 780px; display: flex; flex-direction: column; gap: 4px; padding: 18px 16px 24px; border-radius: var(--vm-radius-card); background: radial-gradient(circle at 20% 30%, rgba(18, 52, 82, 0.025) 0 2px, transparent 3px), radial-gradient(circle at 70% 60%, rgba(18, 52, 82, 0.025) 0 2px, transparent 3px), radial-gradient(circle at 45% 85%, rgba(18, 52, 82, 0.025) 0 2px, transparent 3px), #EFEAE2; background-size: 90px 90px, 110px 110px, 70px 70px, auto; border: 1.5px solid rgba(18, 52, 82, 0.1); box-shadow: 4px 4px 0 var(--vm-ink-shadow); } .vm-chat .vm-empty { background: transparent; border: none; } .vm-chat-day { align-self: center; position: sticky; top: 10px; z-index: 2; background: #FFFFFF; color: var(--vm-slate); font-size: 11.5px; font-weight: 700; padding: 4px 12px; border-radius: 0; margin: 10px 0 6px; box-shadow: 0 1px 1px rgba(7, 30, 52, 0.12); } .vm-bubble { position: relative; max-width: 72%; padding: 6px 10px 7px; border-radius: 0; font-size: 13.5px; box-shadow: 0 1px 1px rgba(7, 30, 52, 0.12); } .vm-bubble--them { align-self: flex-start; background: #FFFFFF; border-top-left-radius: 0; } .vm-bubble--them::before { content: ""; position: absolute; top: 0; left: -7px; border: 7px solid transparent; border-top-color: #FFFFFF; border-right-color: #FFFFFF; border-left-width: 0; } .vm-bubble--me { align-self: flex-end; background: #D9FDD3; border-top-right-radius: 0; } .vm-bubble--me::before { content: ""; position: absolute; top: 0; right: -7px; border: 7px solid transparent; border-top-color: #D9FDD3; border-left-color: #D9FDD3; border-right-width: 0; } .vm-bubble-sender { display: block; font-size: 12px; font-weight: 800; color: var(--vm-teal); margin-bottom: 1px; } .vm-bubble-body { overflow-wrap: anywhere; white-space: pre-wrap; } .vm-bubble-meta { display: inline-flex; align-items: center; gap: 3px; float: right; margin: 8px 0 0 10px; font-size: 10.5px; color: var(--vm-slate); } .vm-ticks { color: #53BDEB; font-size: 11px; letter-spacing: -2px; } .vm-media-note { font-style: italic; color: var(--vm-slate); } .vm-voice { display: inline-grid; grid-template-columns: auto 1fr; align-items: center; gap: 4px 10px; min-width: 180px; } .vm-voice-wave { flex: 1; height: 22px; min-width: 110px; background: repeating-linear-gradient(90deg, var(--vm-slate) 0 2.5px, transparent 2.5px 6px); mask-image: linear-gradient(0deg, transparent 0 20%, black 20% 80%, transparent 80% 100%); opacity: 0.7; border-radius: 0; } .vm-voice::before { content: ""; width: 0; height: 0; border-left: 11px solid var(--vm-teal); border-top: 7px solid transparent; border-bottom: 7px solid transparent; } .vm-voice-text { grid-column: 1 / -1; font-size: 12px; font-style: italic; color: var(--vm-slate); } /* ---------- chat dock + bubbles ---------- */ .vm-chatdock-title { margin: 0; font-size: 15px; font-weight: 800; } .vm-qa-form { display: flex; gap: 8px; } .vm-qa-form input { flex: 1; border: 1.5px solid rgba(18, 52, 82, 0.2); border-radius: 0; padding: 9px 12px; font-family: var(--vm-font); font-size: 13.5px; background: #fff; box-shadow: inset 0 2px 4px rgba(7, 30, 52, 0.08); } .vm-qa-send { border: none; background: var(--vm-teal); border-radius: 0; width: 40px; font-size: 17px; cursor: pointer; box-shadow: var(--vm-elev-1), inset 0 1px 0 rgba(255, 255, 255, 0.25); } .vm-qa-send:active { transform: translate(1px, 1px); box-shadow: inset 0 2px 4px rgba(7, 30, 52, 0.35); } .vm-clear-btn { border: 1.5px solid var(--vm-teal); background: transparent; color: var(--vm-teal); font-weight: 700; font-size: 13px; padding: 0 16px; cursor: pointer; white-space: nowrap; transition: transform 0.1s ease, background 0.1s ease; } .vm-clear-btn:hover { background: rgba(13, 110, 130, 0.08); transform: translate(-1px, -1px); } .vm-clear-btn:active { transform: translate(1px, 1px); } body.vm-busy .vm-clear-btn { opacity: 0.55; pointer-events: none; } .vm-chatdock .vm-bubble--bot { background: #fff; border-radius: 0; padding: 10px 12px; font-size: 13.5px; box-shadow: 2px 2px 0 var(--vm-ink-shadow); max-width: none; align-self: stretch; flex: 0 1 auto; min-height: 20px; overflow-y: auto; } .vm-chatdock .vm-bubble-body :is(p, ul, ol) { margin: 0 0 8px; } .vm-chatdock .vm-bubble-body :is(p, ul, ol):last-child { margin-bottom: 0; } .vm-chatdock .vm-bubble-body :is(ul, ol) { padding-left: 18px; } .vm-chatdock .vm-bubble-body li { margin-bottom: 3px; } .vm-chatdock .vm-bubble-body :is(h4, h5, h6) { margin: 10px 0 4px; font-size: 13.5px; } .vm-chatdock .vm-bubble-body :is(h4, h5, h6):first-child { margin-top: 0; } .vm-chatdock .vm-bubble-body hr { border: none; border-top: 1px dashed rgba(106, 118, 133, 0.35); margin: 8px 0; } .vm-chatdock .vm-bubble-body code { font-family: var(--vm-mono); font-size: 12px; background: rgba(18, 52, 82, 0.07); border-radius: 0; padding: 1px 4px; } .vm-qa-form { margin-top: auto; } .vm-bubble--bot:empty::before { content: "Pergunte qualquer coisa sobre os clientes desta sessao."; color: var(--vm-slate); } .vm-bubble--bot[data-state="streaming"] { border-left: 3px solid var(--vm-mango); } body.vm-thinking .vm-chatdock .vm-qa-send { opacity: 0.55; pointer-events: none; } .vm-qa-thinking { display: block; margin-bottom: 8px; padding-bottom: 8px; border-bottom: 1px dashed rgba(106, 118, 133, 0.35); } .vm-qa-thinking-label { display: block; font-size: 10.5px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--vm-slate); margin-bottom: 2px; } .vm-qa-thinking-body { display: block; color: var(--vm-slate); font-size: 12px; line-height: 1.45; white-space: pre-wrap; max-height: 7.5em; overflow-y: auto; } .vm-bubble--bot[data-state="streaming"] .vm-qa-thinking-label::after { content: "..."; animation: vm-thinking-pulse 1.2s ease-in-out infinite; } @keyframes vm-thinking-pulse { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; } } /* ---------- trace (control tower) ---------- */ /* the trace panel is a CRT monitor on the desk */ .vm-trace { background: radial-gradient(ellipse 120% 110% at 50% 45%, #0C2945, var(--vm-deep-navy) 65%, #04101D); border: 9px solid #102A3F; border-radius: 0; padding: 16px; box-shadow: var(--vm-elev-2), inset 0 0 26px rgba(0, 0, 0, 0.55), inset 0 0 0 1px rgba(31, 186, 194, 0.12); position: relative; overflow: hidden; } .vm-trace-table { animation: vm-crt-flicker 7s infinite; } @keyframes vm-crt-flicker { 0%, 95.5%, 97.5%, 100% { opacity: 1; } 96.5% { opacity: 0.88; } } .vm-trace::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: repeating-linear-gradient(0deg, transparent 0 2px, rgba(0, 0, 0, 0.12) 2px 4px); } .vm-trace .vm-empty { background: transparent; border: none; color: var(--vm-sky); } .vm-trace-table { width: 100%; border-collapse: collapse; font-family: var(--vm-mono); font-size: 12px; color: var(--vm-teal); text-shadow: 0 0 5px rgba(31, 186, 194, 0.45); } .vm-trace-table th { text-align: left; color: var(--vm-sky); font-weight: 600; border-bottom: 1px solid rgba(221, 247, 247, 0.25); padding: 4px 8px; } .vm-trace-table td { padding: 4px 8px; vertical-align: top; } .vm-trace-num { text-align: right; } .vm-trace-payload { color: rgba(221, 247, 247, 0.75); overflow-wrap: anywhere; } .vm-trace-table tfoot td { border-top: 1px solid rgba(221, 247, 247, 0.25); color: var(--vm-mango); } .vm-radar { width: 64px; height: 64px; border-radius: 50%; margin: 0 0 12px; background: conic-gradient(transparent 0 318deg, rgba(31, 186, 194, 0.08) 326deg, rgba(31, 186, 194, 0.75) 360deg), repeating-radial-gradient(circle, transparent 0 9px, rgba(31, 186, 194, 0.25) 9px 10px); border: 1px solid rgba(31, 186, 194, 0.4); animation: vm-radar-sweep 4s linear infinite; } @keyframes vm-radar-sweep { to { transform: rotate(360deg); } } /* ---------- htmx affordances ---------- */ #vm-main.htmx-swapping { opacity: 0.4; transition: opacity 0.12s ease; } #vm-main.htmx-settling { opacity: 1; transition: opacity 0.2s ease; } ::view-transition-old(root) { animation-duration: 0.12s; } ::view-transition-new(root) { animation-duration: 0.18s; } /* ---------- reduced motion ---------- */ @media (prefers-reduced-motion: reduce) { .vm-mascot, .vm-radar, .vm-flap, .vm-trace-table { animation: none !important; } .vm-nav-item { transition: none !important; } .vm-ticket, .vm-ticket-stub { transition: none !important; } } /* ---------- responsive ---------- */ @media (max-width: 1180px) { .vm-app { grid-template-areas: "sidebar topbar" "sidebar main" "sidebar chatdock"; grid-template-columns: 220px minmax(0, 1fr); grid-template-rows: auto 1fr auto; } .vm-chatdock { height: auto; position: static; border-left: none; border-top: 2px solid var(--vm-sand); } } @media (max-width: 820px) { .vm-app { grid-template-areas: "topbar" "main" "chatdock"; grid-template-columns: 1fr; } .vm-sidebar { display: none; } .vm-tickets { grid-template-columns: 1fr; } } /* ---------- demo privacy blur ---------- */ /* Toggled by the BLUR_SENSITIVE_INFO_DEMO env var, which adds .vm-blur-demo to . Obscure client data on the cards (and the topbar identity) and soften the conversation a touch so a screen recording can be shared without exposing real names, values, ids or documents. */ .vm-blur-demo .vm-ticket-value, .vm-blur-demo .vm-ticket-file, .vm-blur-demo .crm-file-link, .vm-blur-demo .vm-customer-name, .vm-blur-demo .vm-customer-detail { filter: blur(2.5px); user-select: none; } .vm-blur-demo .vm-bubble-body, .vm-blur-demo .vm-bubble-sender { filter: blur(1px); user-select: none; }