﻿.footer-cta {
position: relative;
display: flex;
min-height: 262px;
align-items: center;
overflow: hidden;
background-color: var(--color-dark-blue-10);
background-image: radial-gradient( 35% 500% at 26% -250%, var(--color-brand-blue-0) 0%, var(--color-dark-blue-10) 100% )
}
.footer-cta__inner {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--spacing-8);
}
.footer-cta__text {
max-width: 660px;
margin: 0;
color: var(--color-brand-blue-30);
}
.footer-cta__decoration {
position: absolute;
top: -457px;
left: calc(50% - 250px);
width: 858.893px;
height: 858px;
pointer-events: none;
}
.button__icon img {
display: block;
}
.site-footer {
--footer-marker-offset: 17px;
--footer-marker-size: 34px;
--footer-marker-asset-size: 42px;
position: relative;
padding-block: var(--spacing-14) var(--spacing-8);
border-top: 1px solid var(--color-dark-blue-0);
background-color: var(--color-dark-blue-0);
}
.site-footer__content {
display: flex;
flex-direction: column;
gap: var(--spacing-6);
}
.site-footer__brand-line {
display: flex;
align-items: center;
flex-direction: column;
color: var(--color-white-opacity-24);
}
.site-footer__wordmark-wrap {
--footer-wordmark-font-size: 11.05cqw;
container-type: inline-size;
width: 100%;
}
.site-footer__wordmark {
margin: 0;
color: inherit;
font-size: var(--footer-wordmark-font-size);
font-weight: var(--font-weight-semibold);
letter-spacing: -0.035em;
line-height: 1.22;
text-align: center;
white-space: nowrap;
}
.site-footer__tagline {
margin: 0;
color: inherit;
text-align: center;
}
.site-footer__details {
display: flex;
align-items: center;
flex-direction: column;
gap: var(--spacing-8);
}
.site-footer__links-row {
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
padding-block: var(--spacing-7);
border-bottom: 1px solid var(--color-white-opacity-24);
}
.site-footer__contact {
color: var(--color-white);
font-size: var(--type-body-md-size);
font-weight: var(--font-weight-medium);
line-height: var(--type-body-md-line-height);
text-decoration: underline;
text-decoration-color: currentColor;
text-underline-offset: var(--spacing-1);
transition: color 180ms ease, text-decoration-color 180ms ease;
}
.site-footer__contact:hover,
.site-footer__contact:focus-visible {
color: var(--color-brand-blue-0);
}
.site-footer__brands {
display: flex;
align-items: center;
gap: var(--spacing-8);
}
.site-footer__logo {
display: block;
}
.site-footer__consulfarma-logo {
display: block;
flex: 0 0 auto;
width: 160px;
}
.site-footer__privacy {
width: 100%;
max-width: 1036px;
margin: 0;
color: var(--color-white-opacity-56);
text-align: center;
}
.site-footer__marker {
position: absolute;
top: calc(0px - var(--footer-marker-offset));
left: max(var(--container-gutter), calc((100% - var(--container-max-width)) / 2));
width: var(--footer-marker-size);
height: var(--footer-marker-size);
overflow: visible;
pointer-events: none;
}
.site-footer__marker img {
position: absolute;
top: -4px;
left: -4px;
display: block;
width: var(--footer-marker-asset-size);
height: var(--footer-marker-asset-size);
}
@media (max-width: 760px) {
.footer-cta {
padding-block: var(--spacing-8);
}
.footer-cta__inner {
align-items: flex-start;
flex-direction: column;
}
.footer-cta__decoration {
left: calc(50% - 250px);
}
.site-footer {
padding-block: var(--spacing-12) var(--spacing-8);
}
.site-footer__links-row {
align-items: center;
flex-direction: column;
gap: var(--spacing-6);
}
.site-footer__brands {
flex-wrap: wrap;
gap: var(--spacing-6);
justify-content: center;
}
.site-footer__logo {
height: 12px;
}
.site-footer__consulfarma-logo {
height: 26px;
}
}
.statistics {
position: relative;
display: flex;
overflow: hidden;
flex-direction: column;
align-items: center;
gap: var(--spacing-12);
padding-top: var(--spacing-12);
background: linear-gradient(180deg, var(--color-dark-blue-0) 52%, var(--color-brand-blue-0) 100%);
}
.statistics__illustration {
position: absolute;
z-index: 0;
inset: 0;
overflow: hidden;
pointer-events: none;
}
.statistics__orbit {
position: absolute;
top: 224%;
left: 50%;
display: block;
max-width: none;
height: auto;
transform-origin: center;
animation-duration: 62s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.statistics__orbit--one {
width: 141vw;
animation-name: statistics-orbit-one;
}
.statistics__orbit--two {
width: 136vw;
animation-name: statistics-orbit-two;
}
.statistics__orbit--three {
width: 145vw;
animation-name: statistics-orbit-three;
}
.statistics__ticker,
.statistics__mockup-wrap {
position: relative;
z-index: 1;
}
.statistics__ticker {
position: relative;
width: min(100% - var(--spacing-6), 964px);
overflow: hidden;
padding: var(--spacing-4) var(--spacing-5);
}
.statistics__track,
.statistics__group,
.statistics__item {
display: flex;
align-items: center;
}
.statistics__track {
width: max-content;
animation: statistics-scroll 40s linear infinite;
}
.statistics__group {
flex: 0 0 auto;
gap: var(--spacing-8);
padding-right: var(--spacing-8);
}
.statistics__item {
flex: 0 0 auto;
gap: var(--spacing-5);
color: var(--color-dark-blue-60);
white-space: nowrap;
}
.statistics__item strong {
font-size: var(--type-heading-5-size);
font-weight: var(--font-weight-semibold);
line-height: var(--type-heading-5-line-height);
letter-spacing: var(--type-heading-5-letter-spacing);
}
.statistics__item span {
font-size: var(--type-body-sm-size);
line-height: var(--type-body-sm-line-height);
}
.statistics__edge {
position: absolute;
z-index: 1;
top: 0;
width: var(--spacing-10);
height: 100%;
pointer-events: none;
}
.statistics__edge--start {
left: 0;
background: linear-gradient(90deg, var(--color-dark-blue-0), transparent);
}
.statistics__edge--end {
right: 0;
background: linear-gradient(270deg, var(--color-dark-blue-0), transparent);
}
.statistics__mockup-wrap {
width: min(100% - var(--spacing-6), 1509px);
}
.statistics__mockup {
position: relative;
overflow: hidden;
min-height: 579px;
border: 2px solid var(--color-dark-blue-30);
border-bottom: 0;
border-radius: var(--spacing-6) var(--spacing-6) 0 0;
background-color: var(--color-dark-blue-0);
}
.statistics__window-bar {
position: relative;
z-index: 1;
display: flex;
height: 51px;
align-items: center;
gap: var(--spacing-5);
padding-inline: var(--spacing-5);
border-bottom: 1px solid var(--color-dark-blue-30);
background-color: var(--color-dark-blue-opacity-80);
}
.statistics__dots {
display: flex;
align-items: center;
gap: var(--spacing-3);
}
.statistics__dots i {
width: var(--spacing-2);
height: var(--spacing-2);
border-radius: 50%;
background-color: var(--color-dark-blue-50);
}
.statistics__window-title {
display: inline-flex;
align-items: center;
gap: var(--spacing-3);
padding: var(--spacing-2) var(--spacing-3) var(--spacing-2) var(--spacing-2);
border-radius: var(--spacing-2);
background-color: var(--color-white-opacity-12);
color: var(--color-dark-blue-50);
font-size: var(--type-body-xs-size);
font-weight: var(--font-weight-semibold);
line-height: var(--type-body-xs-line-height);
}
.statistics__logo-mark {
display: grid;
width: 22px;
height: 22px;
place-items: center;
border-radius: var(--spacing-2);
background-color: var(--color-brand-blue-0);
}
.statistics__logo-mark img {
display: block;
width: 18px;
height: 18px;
}
.statistics__mockup-content {
position: relative;
display: grid;
min-height: 528px;
place-items: center;
overflow: hidden;
padding: var(--spacing-9) var(--spacing-7);
background: radial-gradient(ellipse at 50% 100%, var(--color-dark-blue-10), var(--color-dark-blue-0) 68%);
}
.statistics__interface-media {
position: absolute;
z-index: 0;
inset: 0;
}
.statistics__interface-media img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.statistics__mockup-content::before {
position: absolute;
z-index: 1;
inset: 0;
background: radial-gradient(ellipse at center, var(--color-dark-blue-0) 28%, var(--color-dark-blue-opacity-32) 100%);
content: "";
pointer-events: none;
}
.statistics__mockup-copy {
position: relative;
z-index: 2;
display: flex;
max-width: 869px;
flex-direction: column;
align-items: center;
gap: var(--spacing-4);
text-align: center;
}
.statistics__eyebrow {
margin: 0;
color: var(--color-dark-blue-60);
font-size: var(--type-body-lg-size);
line-height: var(--type-body-lg-line-height);
}
.statistics__title {
margin: 0;
color: var(--color-white);
}
.statistics__title span {
color: var(--color-brand-blue-10);
}
@keyframes statistics-scroll {
to { transform: translateX(-50%); }
}
@keyframes statistics-orbit-one {
from { transform: translate(-50%, -50%) rotate(22.51deg); }
to { transform: translate(-50%, -50%) rotate(382.51deg); }
}
@keyframes statistics-orbit-two {
from { transform: translate(-50%, -50%) rotate(0deg); }
to { transform: translate(-50%, -50%) rotate(-360deg); }
}
@keyframes statistics-orbit-three {
from { transform: translate(-50%, -50%) rotate(-27.07deg); }
to { transform: translate(-50%, -50%) rotate(332.93deg); }
}
@media (prefers-reduced-motion: reduce) {
.statistics__track,
.statistics__orbit { animation: none; }
}
@media (max-width: 700px) {
.statistics { gap: var(--spacing-9); padding-top: var(--spacing-9); }
.statistics__mockup { min-height: 400px; }
.statistics__mockup-content { min-height: 349px; padding: var(--spacing-7) var(--spacing-5); }
.statistics__title { font-size: var(--type-heading-3-size); line-height: var(--type-heading-3-line-height); }
}
.resources {
padding-block: var(--spacing-14);
overflow-x: clip;
background-color: var(--color-white);
}
.resources__container {
display: flex;
flex-direction: column;
gap: var(--spacing-9);
}
.resources__heading {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: var(--spacing-6);
}
.resources__title {
max-width: 22ch;
margin: 0;
color: var(--color-dark-blue-0);
font-weight: var(--font-weight-semibold);
}
.resources__title img {
display: inline-block;
width: 32px;
height: 32px;
margin-inline: var(--spacing-2);
vertical-align: middle;
}
.resources__controls {
display: flex;
flex: 0 0 auto;
align-items: center;
gap: var(--spacing-5);
padding-bottom: var(--spacing-2);
}
.resources__arrow {
display: grid;
width: 40px;
height: 40px;
flex: 0 0 auto;
place-items: center;
padding: 0;
border: 1px solid var(--color-dark-blue-0);
border-radius: 50%;
background-color: var(--color-dark-blue-0);
color: var(--color-white);
cursor: pointer;
transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease;
}
.resources__arrow svg {
display: block;
width: 24px;
height: 24px;
}
.resources__arrow--previous svg {
transform: rotate(180deg);
}
.resources__arrow:disabled {
border-color: var(--color-dark-blue-70);
background-color: var(--color-white);
color: var(--color-dark-blue-0);
cursor: default;
}
.resources__arrow:focus-visible {
outline: 2px solid var(--color-brand-blue-0);
outline-offset: 3px;
}
/* Sangra ate a borda direita da janela para os proximos cards ficarem visiveis. */
.resources__viewport {
--resources-bleed: calc(50vw - 50%);
width: calc(100% + var(--spacing-2) + var(--resources-bleed));
overflow-x: auto;
overflow-y: hidden;
margin: calc(-1 * var(--spacing-2)) calc(-1 * var(--resources-bleed)) calc(-1 * var(--spacing-3)) calc(-1 * var(--spacing-2));
padding: var(--spacing-2) var(--resources-bleed) var(--spacing-3) var(--spacing-2);
scrollbar-width: none;
scroll-behavior: smooth;
scroll-snap-type: x mandatory;
scroll-padding-inline: var(--spacing-2);
overscroll-behavior-inline: contain;
}
.resources__viewport::-webkit-scrollbar {
display: none;
}
.resources__viewport:focus-visible {
outline: 2px solid var(--color-brand-blue-0);
outline-offset: 2px;
}
.resources__track {
display: flex;
width: max-content;
min-width: 100%;
align-items: stretch;
gap: var(--spacing-6);
}
.resources__card {
display: flex;
width: min(391px, calc(100vw - var(--spacing-6) - var(--spacing-6)));
flex: 0 0 min(391px, calc(100vw - var(--spacing-6) - var(--spacing-6)));
flex-direction: column;
align-items: flex-start;
gap: var(--spacing-6);
padding: var(--spacing-6);
border: 1px solid var(--color-dark-blue-70);
border-radius: var(--spacing-5);
background-color: var(--color-white);
box-shadow: 8px 8px 2px var(--color-dark-blue-opacity-12);
scroll-snap-align: start;
transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;
}
/* O deslocamento mantem a borda externa da sombra no mesmo lugar, dentro do padding do viewport. */
@media (hover: hover) {
.resources__card:hover {
border-color: var(--color-dark-blue-60);
box-shadow: 10px 10px 2px var(--color-dark-blue-opacity-12);
transform: translate(-2px, -2px);
}
}
.resources__icon {
position: relative;
display: block;
width: 56px;
height: 56px;
flex: 0 0 auto;
overflow: hidden;
border-radius: var(--spacing-3);
}
.resources__icon img {
position: absolute;
inset: 0;
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.resources__icon--marketing img {
inset: auto;
top: -11.76%;
left: -14.92%;
width: 121.93%;
height: 121.93%;
max-width: none;
}
.resources__card-copy {
display: flex;
width: 100%;
flex-direction: column;
gap: var(--spacing-5);
}
.resources__card-title {
margin: 0;
color: var(--color-dark-blue-0);
font-weight: var(--font-weight-semibold);
}
.resources__description {
margin: 0;
color: var(--color-dark-blue-40);
}
.resources__tags {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: var(--spacing-5);
margin: var(--spacing-3) 0 0;
padding: 0;
list-style: none;
}
.resources__tags li {
display: inline-flex;
align-items: center;
justify-content: center;
padding: var(--spacing-3) var(--spacing-4);
border-radius: var(--spacing-7);
background-color: var(--color-brand-blue-20);
color: var(--color-dark-blue-0);
font-size: var(--type-body-sm-size);
font-weight: var(--font-weight-semibold);
line-height: var(--type-body-sm-line-height);
white-space: nowrap;
}
.resources__footer {
display: flex;
justify-content: flex-end;
margin-top: var(--spacing-4);
}
.resources__cta {
gap: var(--spacing-3);
}
.resources__cta .button__icon img {
display: block;
width: 100%;
height: 100%;
}
@media (max-width: 700px) {
.resources {
padding-block: var(--spacing-11);
}
.resources__container {
gap: var(--spacing-7);
}
.resources__heading {
flex-wrap: wrap;
align-items: flex-end;
}
.resources__title {
flex-basis: 100%;
max-width: none;
font-size: var(--type-heading-4-size);
line-height: var(--type-heading-4-line-height);
text-wrap: balance;
}
.resources__title img {
width: 24px;
height: 24px;
}
.resources__controls {
align-self: flex-end;
gap: var(--spacing-3);
padding-bottom: 0;
}
.resources__arrow {
width: 36px;
height: 36px;
}
.resources__arrow svg {
width: 20px;
height: 20px;
}
.resources__track {
gap: var(--spacing-5);
}
.resources__footer {
margin-top: var(--spacing-3);
justify-content: center;
}
}
@media (prefers-reduced-motion: reduce) {
.resources__viewport {
scroll-behavior: auto;
}
.resources__arrow,
.resources__card {
transition: none;
}
.resources__card:hover {
transform: none;
}
}
.solutions {
/* Altura do menu fixo: padding-top + texto + gap + indicador. */
--solutions-nav-height: calc(var(--spacing-7) + var(--type-body-md-line-height) + var(--spacing-4) + 2px);
--solutions-sticky-top: var(--site-header-height, 0px);
padding-top: var(--spacing-14);
padding-bottom: var(--spacing-11);
background-color: var(--color-dark-blue-0);
color: var(--color-white);
}
.solutions__container {
display: flex;
flex-direction: column;
gap: var(--spacing-12);
}
.solutions__title {
margin: 0;
color: var(--color-white);
font-weight: var(--font-weight-bold);
text-align: center;
}
.solutions__nav {
position: sticky;
z-index: 10;
top: var(--solutions-sticky-top);
padding-top: var(--spacing-4);
background-color: var(--color-dark-blue-0);
}
.solutions__nav-list {
display: flex;
gap: var(--spacing-1);
margin: 0;
padding: 0;
overflow-x: auto;
list-style: none;
scrollbar-width: none;
}
.solutions__nav-list::-webkit-scrollbar {
display: none;
}
.solutions__nav-list li {
display: flex;
flex: 1 0 0;
min-width: max-content;
}
.solutions__nav-link {
display: flex;
width: 100%;
flex-direction: column;
gap: var(--spacing-4);
color: var(--color-dark-blue-60);
text-decoration: none;
white-space: nowrap;
transition: color 160ms ease;
font-size: var(--type-body-md-size);
line-height: var(--type-body-md-line-height);
}
/* Trilho + preenchimento; --solutions-progress (0 a 1) e atualizado pelo solutions.js conforme a rolagem. */
.solutions__nav-link::after {
content: "";
display: block;
width: 100%;
height: 2px;
border-radius: var(--spacing-4);
background-color: var(--color-white-opacity-16);
background-image: linear-gradient(var(--color-brand-blue-10), var(--color-brand-blue-10));
background-repeat: no-repeat;
background-size: calc(var(--solutions-progress, 0) * 100%) 100%;
}
.solutions__nav-link:hover,
.solutions__nav-link.is-active {
color: var(--color-brand-blue-10);
}
.solutions__nav-link:focus-visible {
outline: 2px solid var(--color-brand-blue-0);
outline-offset: 2px;
}
.solutions__block {
display: flex;
flex-direction: column;
gap: var(--spacing-9);
padding-block: var(--spacing-12);
border-bottom: 1px solid var(--color-white-opacity-24);
scroll-margin-top: calc(var(--solutions-sticky-top) + var(--solutions-nav-height));
}
.solutions__block-header {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: var(--spacing-6);
}
.solutions__block-title {
max-width: 816px;
margin: 0;
color: var(--color-white);
font-weight: var(--font-weight-semibold);
}
.solutions__block-description {
width: 531px;
max-width: 100%;
flex: 0 1 auto;
margin: 0;
color: var(--color-dark-blue-70);
}
/* Area de midia de cada bloco: placeholder ate o conteudo especifico ser montado. */
.solutions__media {
position: relative;
width: 100%;
aspect-ratio: 1640 / 716;
overflow: hidden;
border-radius: var(--spacing-5);
background-color: var(--color-dark-blue-10);
}
/* contain, nao cover: o video e uma animacao de texto: cortar esconde o conteudo. */
.solutions__media-video {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
/* Desktop e mobile sao dois <video> irmaos, trocados por display. O atributo
`media` no <source> seria o caminho obvio, mas o Chrome o removeu na versao
34 e simplesmente ignora - o mobile acabaria baixando o video do desktop.
Escondido com display:none o elemento nao tem caixa, entao o
IntersectionObserver do solutions.js nunca o considera visivel e nunca manda
tocar; com preload="none" ele tambem nao baixa nada. */
.solutions__media-video--mobile {
display: none;
}
@media (max-width: 960px) {
.solutions__block-header {
flex-direction: column;
align-items: flex-start;
gap: var(--spacing-5);
}
.solutions__block-description {
width: auto;
max-width: 531px;
}
}
@media (max-width: 700px) {
.solutions {
padding-top: var(--spacing-11);
padding-bottom: var(--spacing-9);
}
.solutions__nav-link {
font-size: var(--type-body-sm-size);
line-height: var(--type-body-sm-line-height);
}
.solutions__container {
gap: var(--spacing-9);
}
.solutions__title {
font-size: var(--type-heading-3-size);
line-height: var(--type-heading-3-line-height);
letter-spacing: var(--type-heading-3-letter-spacing);
}
.solutions__nav-list {
gap: var(--spacing-5);
}
.solutions__block {
gap: var(--spacing-7);
padding-block: var(--spacing-10);
}
.solutions__block-title {
font-size: var(--type-heading-4-size);
line-height: var(--type-heading-4-line-height);
letter-spacing: var(--type-heading-4-letter-spacing);
}
.solutions .solutions__media {
aspect-ratio: 1640 / 1200;
}
.solutions__media-video--desktop {
display: none;
}
.solutions__media-video--mobile {
display: block;
}
}
@media (prefers-reduced-motion: reduce) {
.solutions__nav-link {
transition: none;
}
}
/* Bloco Farmacoflix (dentro de .solutions): carrossel horizontal de videos + mural vertical de capas. */
.farmacoflix {
--farmacoflix-video-width: min(1080px, 66vw);
--farmacoflix-video-aspect: 980 / 608;
--farmacoflix-reel-gap: var(--spacing-6);
--farmacoflix-reel-fade: 66px;
--farmacoflix-covers-height: clamp(240px, 23vw, 380px);
--farmacoflix-covers-columns: 5;
--farmacoflix-covers-column-gap: var(--spacing-12);
--farmacoflix-covers-row-gap: var(--spacing-9);
/* Um ciclo = a altura de um mural + o espaco entre os dois murais. */
--farmacoflix-covers-duration: 33s;
display: flex;
flex-direction: column;
gap: var(--spacing-7);
width: 100%;
}
#solucoes-farmacoflix .solutions__block-title {
max-width: 19ch;
}
/* ---------- Carrossel horizontal de videos ---------- */
.farmacoflix__reel {
position: relative;
overflow: hidden;
/* Isola repaints do marquee do resto da pagina. */
contain: paint;
}
.farmacoflix__reel-track {
display: flex;
width: max-content;
align-items: center;
gap: var(--farmacoflix-reel-gap);
/* O transform e escrito pelo farmacoflix.js a cada quadro. */
will-change: transform;
}
.farmacoflix__video {
position: relative;
display: flex;
width: var(--farmacoflix-video-width);
flex: 0 0 auto;
flex-direction: column;
justify-content: flex-end;
padding-block: var(--spacing-10);
border-radius: var(--spacing-6);
aspect-ratio: var(--farmacoflix-video-aspect);
background-color: var(--color-dark-blue-10);
container-type: inline-size;
isolation: isolate;
overflow: hidden;
}
.farmacoflix__video-media {
position: absolute;
z-index: -1;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.farmacoflix__video-label {
margin: 0;
color: var(--color-brand-blue-20);
/* 120px sobre o card de 1080px do design. cqw mantem essa proporcao em
qualquer largura de card; o clamp e o fallback de quem nao tem cqw. */
font-size: clamp(40px, 7.3vw, 120px);
font-size: 11.1cqw;
font-weight: var(--font-weight-medium);
letter-spacing: -0.035em;
line-height: 0.7;
mix-blend-mode: difference;
text-align: center;
white-space: nowrap;
}
/* Borda esquerda e direita dissolvem os cards que entram e saem do trilho. */
.farmacoflix__reel-fade {
position: absolute;
inset: 0;
background-image:
linear-gradient(90deg, var(--color-dark-blue-0), var(--color-dark-blue-opacity-0)),
linear-gradient(270deg, var(--color-dark-blue-0), var(--color-dark-blue-opacity-0));
background-position: left center, right center;
background-repeat: no-repeat;
background-size: var(--farmacoflix-reel-fade) 100%;
pointer-events: none;
}
/* ---------- Mural vertical de capas ---------- */
.farmacoflix__covers {
position: relative;
height: var(--farmacoflix-covers-height);
overflow: hidden;
contain: paint;
}
.farmacoflix__covers-track {
display: flex;
flex-direction: column;
gap: var(--farmacoflix-covers-row-gap);
animation: farmacoflix-covers-scroll var(--farmacoflix-covers-duration) linear infinite;
will-change: transform;
}
/* -50% para na metade do trilho; o meio-gap extra fecha a emenda entre os dois murais. */
@keyframes farmacoflix-covers-scroll {
from {
transform: translate3d(0, 0, 0);
}
to {
transform: translate3d(0, calc(-50% - var(--farmacoflix-covers-row-gap) / 2), 0);
}
}
.farmacoflix__covers-grid {
display: grid;
grid-template-columns: repeat(var(--farmacoflix-covers-columns), minmax(0, 1fr));
column-gap: var(--farmacoflix-covers-column-gap);
row-gap: var(--farmacoflix-covers-row-gap);
}
.farmacoflix__cover {
display: block;
overflow: hidden;
border-radius: var(--spacing-3);
aspect-ratio: 273 / 153;
background-color: var(--color-dark-blue-10);
}
.farmacoflix__cover img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
/* Backdrop do mural: escurece topo, base e laterais para as capas surgirem e sumirem. */
.farmacoflix__covers-shade {
position: absolute;
z-index: 1;
inset: 0;
background-image:
linear-gradient(180deg, var(--color-dark-blue-0) 4%, var(--color-dark-blue-opacity-0) 33%),
linear-gradient(0deg, var(--color-dark-blue-0) 4%, var(--color-dark-blue-opacity-0) 48%),
linear-gradient(90deg, var(--color-dark-blue-0) 1%, var(--color-dark-blue-opacity-0) 11%),
linear-gradient(270deg, var(--color-dark-blue-0) 2%, var(--color-dark-blue-opacity-0) 9%);
pointer-events: none;
}
.farmacoflix__covers-overlay {
position: absolute;
z-index: 2;
display: flex;
flex-direction: column;
justify-content: space-between;
inset: 0;
pointer-events: none;
}
.farmacoflix__logo {
display: block;
width: 200px;
height: auto;
}
.farmacoflix__more {
margin: 0;
align-self: flex-end;
color: var(--color-white);
}
@media (max-width: 1100px) {
.farmacoflix {
--farmacoflix-covers-columns: 4;
--farmacoflix-covers-column-gap: var(--spacing-9);
--farmacoflix-covers-row-gap: var(--spacing-7);
}
}
@media (max-width: 768px) {
.farmacoflix {
/* Card retrato: a altura manda (~60% da tela) e a largura sai do aspect.
svh em vez de vh para a barra do navegador nao redimensionar o card na rolagem. */
--farmacoflix-video-height: 60vh;
--farmacoflix-video-height: 60svh;
--farmacoflix-video-aspect: 9 / 16;
--farmacoflix-video-width: min(
calc(var(--farmacoflix-video-height) * 9 / 16),
calc(100vw - var(--spacing-11))
);
--farmacoflix-reel-gap: var(--spacing-4);
--farmacoflix-reel-fade: 24px;
--farmacoflix-covers-columns: 3;
--farmacoflix-covers-column-gap: var(--spacing-6);
--farmacoflix-covers-row-gap: var(--spacing-5);
--farmacoflix-covers-height: 200px;
gap: var(--spacing-5);
}
.farmacoflix__video {
padding-block: var(--spacing-7);
padding-inline: var(--spacing-4);
border-radius: var(--spacing-7);
}
/* Proporcionalmente maior que no desktop: o card retrato e estreito, mas
tem folga vertical de sobra, entao o rotulo quebra em duas linhas. */
.farmacoflix__video-label {
font-size: clamp(24px, 8vw, 32px);
font-size: 12cqw;
line-height: 0.9;
white-space: normal;
overflow-wrap: break-word;
}
.farmacoflix__logo {
width: 132px;
}
}
/* Sem movimento: os dois carrosseis param e o mural fica na posicao inicial. */
@media (prefers-reduced-motion: reduce) {
.farmacoflix__covers-track {
animation: none;
}
}
.solutions__media--app {
aspect-ratio: 1640 / 722;
container-type: inline-size;
background-color: var(--color-dark-blue-0);
background-image: radial-gradient( 42% 300% at 20% -150%, var(--color-brand-blue-0) 0%, var(--color-dark-blue-0) 100% )
}
/* Com JS e ponteiro fino, o brilho vira uma camada propria que segue o mouse;
o gradiente estatico acima sai de cena para nao somar dois focos de luz. */
.solutions__media--app.is-glow-interactive {
background-image: none;
}
#solucoes-projetos-cientificos .solutions__block-title {
max-width: 19ch;
}
/* Um unico gradiente pintado uma vez. O movimento e so transform, entao o
navegador recompoe a camada sem repintar o fundo a cada quadro. */
.app-glow {
position: absolute;
top: 0;
left: 0;
width: 76%;
aspect-ratio: 1;
background-image: radial-gradient(closest-side, rgb(107 214 242 / 34%), var(--color-dark-blue-opacity-0));
opacity: 0;
pointer-events: none;
transition: opacity 500ms ease;
will-change: transform;
}
.is-glow-interactive .app-glow {
opacity: 1;
}
/* Posicao da janela dentro da area de midia: x=112, y=110 de 1640x722 no design.
A altura de 831 estoura os 722 da midia, entao a base fica recortada de proposito. */
.app-preview {
position: absolute;
top: 15.235%;
left: 6.829%;
width: 86.341%;
aspect-ratio: 1416 / 831;
overflow: hidden;
border-radius: 0.976cqw;
}
.app-preview__ui,
.app-preview__covers img {
display: block;
width: 100%;
height: auto;
}
.app-preview__covers {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
/* Dissolve a segunda fileira de capas, que o recorte da midia ja corta. */
.app-preview__shade {
position: absolute;
top: 54.63%;
left: 0;
width: 100%;
height: 25.51%;
background-image: linear-gradient(180deg, var(--color-dark-blue-opacity-0), var(--color-dark-blue-0) 82%);
pointer-events: none;
}
@media (max-width:700px) {
.app-preview {
top: auto;
bottom: 0;
left: 6.829%;
width: 112.341%;
}
.app-preview__shade {
position: absolute;
top: auto;
bottom: 0;
}
}
.iamagistral {
display: flex;
flex-direction: column;
gap: var(--spacing-9);
}
.solutions__media--chat {
background-color: var(--color-dark-blue-0);
background-image: radial-gradient(circle at 47% 47%, var(--color-brand-blue-10), var(--color-dark-blue-0) 105%);
}
.chat-frame__video {
position: absolute;
top: 13.1285%;
left: 5.9756%;
display: block;
width: 88.0488%;
height: auto;
border-radius: var(--spacing-5);
}
/* Desktop e mobile sao dois <video> irmaos trocados por display, como no bloco
de Canal Direto: o atributo `media` no <source> foi removido do Chrome na
versao 34, entao o mobile acabaria baixando o arquivo do desktop. Escondido
com display:none o elemento nao tem caixa, o IntersectionObserver do
solutions.js nunca o considera visivel e com preload="none" ele nao baixa
nada. */
.chat-frame__video--mobile {
display: none;
}
.chat-frame__shade {
position: absolute;
right: 5.9756%;
bottom: 0;
left: 5.9756%;
height: 8.1006%;
background-image: linear-gradient(180deg, var(--color-dark-blue-opacity-0), var(--color-dark-blue-0));
pointer-events: none;
}
.iamagistral__footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--spacing-6);
}
.iamagistral__stats {
display: flex;
flex-wrap: wrap;
gap: var(--spacing-11);
margin: 0;
padding: 0;
list-style: none;
}
.iamagistral__stat {
display: flex;
align-items: center;
gap: var(--spacing-4);
}
.iamagistral__stat-value {
margin: 0;
background-image: linear-gradient(180deg, var(--color-dark-blue-30), var(--color-brand-blue-20));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.iamagistral__stat-label {
max-width: 140px;
margin: 0;
color: var(--color-dark-blue-70);
}
.iamagistral__logo {
display: block;
height: auto;
max-width: 180px;
}
@media (max-width: 960px) {
.iamagistral__footer {
flex-direction: column;
align-items: flex-start;
gap: var(--spacing-8);
}
.iamagistral__stats {
gap: var(--spacing-8);
}
}
@media (max-width: 700px) {
.iamagistral {
gap: var(--spacing-7);
}
.iamagistral__footer {
align-items: center;
flex-direction: column-reverse;
}
.chat-frame__video {
top: auto;
bottom: 0;
left: var(--spacing-6);
width: 128%;
border-radius: var(--spacing-4);
}
.chat-frame__video--desktop {
display: none;
}
.chat-frame__video--mobile {
display: block;
}
.chat-frame__shade {
right: var(--spacing-4);
left: var(--spacing-6);
height: var(--spacing-12);
}
.iamagistral__stats {
gap: var(--spacing-6) var(--spacing-8);
justify-content: center;
}
.iamagistral__stat-value {
font-size: var(--type-heading-3-size);
line-height: var(--type-heading-3-line-height);
letter-spacing: var(--type-heading-3-letter-spacing);
}
.iamagistral__logo {
max-width: 132px;
}
}
/* Carrossel de Materiais de Visitacao, dentro de .solutions__media.
Sete capas em fileira que avancam de uma em uma, sozinhas, so com CSS: o
trilho anda um passo por vez e cada card acende quando chega ao centro. */
.solutions__media--materials {
/* Passo = largura do card + o vao ate o proximo. */
--mv-card-width: 290px;
--mv-gap: var(--spacing-9);
--mv-step: calc(var(--mv-card-width) + var(--mv-gap));
/* Tempo que cada card fica no centro; o ciclo completo passa pelos 7. */
--mv-slot: 4s;
--mv-duration: calc(var(--mv-slot) * 7);
/* A altura acompanha os cards em vez de uma proporcao fixa: com a capa
encolhendo por breakpoint, 1640/716 cortaria o carrossel nas telas
menores. No desktop o resultado bate com os 716px do design. */
display: flex;
align-items: center;
justify-content: center;
padding-block: var(--spacing-12);
aspect-ratio: auto;
background-color: var(--color-dark-blue-0);
background-image: radial-gradient( 120% 86% at 33% -6%, var(--color-dark-blue-30) 0%, #192431 26%, #0e151f 48%, var(--color-dark-blue-0) 76% );
}
#solucoes-materiais-visitacao .solutions__block-title {
max-width: 21ch;
}
.materials {
display: flex;
width: 100%;
flex-direction: column;
align-items: center;
gap: var(--spacing-9);
}
.materials__carousel {
display: flex;
width: 100%;
flex-direction: column;
align-items: center;
gap: var(--spacing-7);
overflow: hidden;
}
.materials__hint {
display: block;
width: 28px;
height: 28px;
flex: none;
}
.materials__hint img {
display: block;
width: 100%;
height: 100%;
}
/* O padding empurra o primeiro card para o centro do trilho: a partir dai cada
passo de --mv-step centraliza o card seguinte. A porcentagem e medida sobre
a largura do carrossel, nao a do trilho. */
.materials__track {
display: flex;
width: 100%;
align-items: center;
padding-left: calc(50% - var(--mv-card-width) / 2);
gap: var(--mv-gap);
animation: mv-slide var(--mv-duration) ease-in-out infinite;
}
.materials__card {
display: block;
width: var(--mv-card-width);
flex: none;
border-radius: var(--spacing-5);
opacity: 0.56;
animation: mv-focus var(--mv-duration) ease-in-out infinite;
}
.materials__card img {
display: block;
width: 100%;
height: auto;
border-radius: var(--spacing-5);
}
/* Os 7 cards sao renderizados duas vezes, o bastante para cobrir os 5 que
cabem na tela ao longo de todo o ciclo. O 4o card e o que nasce no centro,
e dali para a direita cada um acende um slot depois, dando a volta a cada 7.
As duas copias do mesmo indice acendem juntas (a de fora sempre fora da area
visivel), entao dividem o mesmo atraso. O atraso negativo faz o ciclo ja
comecar em curso, em vez de esperar. */
.materials__card:nth-child(7n + 4) { animation-delay: calc(var(--mv-slot) * -7); }
.materials__card:nth-child(7n + 5) { animation-delay: calc(var(--mv-slot) * -6); }
.materials__card:nth-child(7n + 6) { animation-delay: calc(var(--mv-slot) * -5); }
.materials__card:nth-child(7n + 7) { animation-delay: calc(var(--mv-slot) * -4); }
.materials__card:nth-child(7n + 1) { animation-delay: calc(var(--mv-slot) * -3); }
.materials__card:nth-child(7n + 2) { animation-delay: calc(var(--mv-slot) * -2); }
.materials__card:nth-child(7n + 3) { animation-delay: calc(var(--mv-slot) * -1); }
/* Fora da tela nao ha o que animar; o materiais-visitacao.js liga e desliga.
E `animation: none`, nao `animation-play-state: paused`: pausado o navegador
para de compor quadros mas costuma segurar as 15 camadas na GPU, enquanto sem
animacao nenhuma ele nao tem motivo para promover elemento algum. O ciclo
recomeca do primeiro quadro ao voltar para a tela, que e justamente o
enquadramento do design. */
.materials.is-paused .materials__track,
.materials.is-paused .materials__card {
animation: none;
}
.materials__tags {
display: flex;
max-width: 1111px;
flex-wrap: wrap;
justify-content: center;
gap: var(--spacing-6);
margin: 0;
padding: 0;
list-style: none;
}
.materials__tag {
display: flex;
align-items: center;
gap: var(--spacing-3);
padding: var(--spacing-2) var(--spacing-3);
border-radius: var(--spacing-3);
background-color: var(--color-dark-blue-opacity-56);
color: var(--color-dark-blue-70);
white-space: nowrap;
}
.materials__tag img {
display: block;
width: 18px;
height: 18px;
flex: none;
}
/* Um passo por vez: o trilho segura o card no centro e so entao desliza para o
proximo. Os pares de porcentagem sao o inicio e o fim de cada pausa.
O ciclo comeca no passo 3, nao no zero: no ponto mais largo (1640px, o teto
do container) cabem 2 capas de cada lado do centro, entao partir do 3 garante
fileira cheia nos dois lados do primeiro ao ultimo quadro. Termina no 10, que
mostra o mesmo que o 3, e por isso a volta nao tem emenda. */
@keyframes mv-slide {
0%, 8.571% { transform: translate3d(calc(var(--mv-step) * -3), 0, 0); }
14.286%, 22.857% { transform: translate3d(calc(var(--mv-step) * -4), 0, 0); }
28.571%, 37.143% { transform: translate3d(calc(var(--mv-step) * -5), 0, 0); }
42.857%, 51.429% { transform: translate3d(calc(var(--mv-step) * -6), 0, 0); }
57.143%, 65.714% { transform: translate3d(calc(var(--mv-step) * -7), 0, 0); }
71.429%, 80% { transform: translate3d(calc(var(--mv-step) * -8), 0, 0); }
85.714%, 94.286% { transform: translate3d(calc(var(--mv-step) * -9), 0, 0); }
100% { transform: translate3d(calc(var(--mv-step) * -10), 0, 0); }
}
/* Opaco enquanto e o card do centro (a pausa no inicio do ciclo) e transparente
no resto da volta; o atraso de cada card alinha essa janela a sua vez. */
@keyframes mv-focus {
0%, 8.571% { opacity: 1; }
14.286%, 94.286% { opacity: 0.56; }
100% { opacity: 1; }
}
@media (max-width: 960px) {
.solutions__media--materials {
--mv-card-width: 240px;
--mv-gap: var(--spacing-7);
padding-block: var(--spacing-10);
}
.materials {
gap: var(--spacing-7);
}
}
@media (max-width: 700px) {
/* A proporcao unica do mobile vem do solutions.css; aqui a capa passa a
escalar com a tela para o conjunto caber nela. O min-height e uma
garantia: num celular bem estreito o conteudo ainda estoura por alguns
pixels, e e melhor a caixa crescer um pouco do que cortar o carrossel. */
.solutions__media--materials {
--mv-card-width: clamp(112px, 30vw, 200px);
--mv-gap: var(--spacing-6);
min-height: max-content;
padding-block: var(--spacing-4);
}
.materials {
gap: var(--spacing-5);
}
.materials__carousel {
gap: var(--spacing-3);
}
.materials__hint {
width: 16px;
height: 16px;
}
/* Os 6 selos em 4 linhas comeriam a altura toda do quadro. Em fileira unica
rolavel eles ocupam 26px, o mesmo recurso que .solutions__nav-list ja usa
nesta secao. */
.materials__tags {
width: 100%;
flex-wrap: nowrap;
justify-content: flex-start;
overflow-x: auto;
gap: var(--spacing-4);
scrollbar-width: none;
}
.materials__tags::-webkit-scrollbar {
display: none;
}
.materials__tag {
flex: none;
}
}
/* Sem animacao o trilho para no primeiro card; a rolagem manual mantem as
outras capas alcancaveis. */
@media (prefers-reduced-motion: reduce) {
.materials__carousel {
overflow-x: auto;
scrollbar-width: none;
}
.materials__carousel::-webkit-scrollbar {
display: none;
}
.materials__track {
width: max-content;
padding-left: 0;
animation: none;
}
.materials__card {
opacity: 1;
animation: none;
}
/* Sem o desfile as copias so repetiriam a rolagem; fica so a fileira. */
.materials__card:nth-child(n + 8) {
display: none;
}
}
/* Vitrine de Midias Digitais, dentro de .solutions__media: o video preenche a
area inteira e a palavra em blend de diferenca se inverte conforme o que
passa atras dela. */
.solutions__media--social {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
padding: var(--spacing-7) var(--spacing-7) var(--spacing-11);
/* Escala a palavra pela largura da midia, nao da janela: assim ela guarda a
proporcao do design (120px numa area de 1640px) em qualquer breakpoint. */
container-type: inline-size;
/* Prende o mix-blend-mode a esta caixa. Sem isolar, a palavra se misturaria
com tudo que estivesse atras da secao. */
isolation: isolate;
background-color: var(--color-dark-blue-10);
}
#solucoes-midias-digitais .solutions__block-title {
max-width: 20ch;
}
.social__video {
position: absolute;
display: block;
width: 100%;
height: 100%;
inset: 0;
object-fit: cover;
}
.social__shade {
position: absolute;
inset: 0;
background-image: linear-gradient( 180deg, var(--color-dark-blue-opacity-0), var(--color-dark-blue-opacity-80) );
pointer-events: none;
}
/* 120px sobre 1640px = 7.317cqw; o entressilhas -0.035em e o mesmo do display-1. */
.social__word {
position: relative;
margin: 0;
color: var(--color-brand-blue-20);
font-size: clamp(28px, 7.317cqw, 120px);
font-weight: var(--font-weight-medium);
letter-spacing: var(--type-display-1-letter-spacing);
line-height: 0.7;
text-align: center;
white-space: nowrap;
mix-blend-mode: difference;
}
.social__tags {
position: relative;
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: var(--spacing-3);
margin: var(--spacing-8) 0 0;
padding: 0;
list-style: none;
max-width: 960px;
}
.social__tag {
display: flex;
align-items: center;
gap: var(--spacing-3);
padding: var(--spacing-2) var(--spacing-3);
border-radius: var(--spacing-3);
background-color: var(--color-dark-blue-opacity-56);
color: var(--color-dark-blue-70);
white-space: nowrap;
}
.social__tag img {
display: block;
width: 18px;
height: 18px;
flex: none;
}
@media (max-width: 700px) {
.solutions__media--social {
padding: var(--spacing-5);
}
/* No mobile o quadro vira 1640/1200 e o cover passa a cortar as laterais,
deixando visiveis cerca de 60% da largura: o recorte a 26% mantem o
celular e o rosto dentro da janela. */
.social__video {
object-position: 26% center;
}
.social__tags {
width: calc(100% + var(--spacing-5) * 2);
margin: var(--spacing-5) calc(-1 * var(--spacing-5)) 0;
padding: 0 var(--spacing-5);
flex-wrap: nowrap;
justify-content: flex-start;
gap: var(--spacing-3);
overflow-x: auto;
scrollbar-width: none;
}
.social__tags::-webkit-scrollbar {
display: none;
}
.social__tag {
flex: none;
}
}
/* Bloco Auditoria de Fornecedores, dentro de .solutions__media.
Tres camadas sobre a area de 1640x716 do design: o gradiente de fundo, a fileira
de logos e o print da interface. Todas as medidas em % da area, entao o bloco
inteiro encolhe proporcional. */
.solutions__media--audit {
/* Pico do gradiente amostrado do render do Figma: nao ha equivalente na paleta. */
--audit-backdrop: #6e92a5;
aspect-ratio: 1640 / 716;
background-image: linear-gradient(
180deg,
var(--color-dark-blue-20) 0%,
var(--audit-backdrop) 46%,
var(--color-dark-blue-10) 100%
);
}
/* Fileira de logos: x=69.5, y=80, 1500.9x70 no design; 6 colunas iguais com 64 de gap. */
.audit-logos {
position: absolute;
top: 11.173%;
left: 4.240%;
display: flex;
width: 91.521%;
align-items: center;
margin: 0;
padding: 0;
gap: 4.264%;
list-style: none;
}
.audit-logos li {
display: flex;
min-width: 0;
flex: 1 1 0;
}
.audit-logos img {
display: block;
width: 100%;
height: auto;
}
/* Janela: x=151, y=216, 1338 de largura. A altura de 500 fecha exatamente na
base da area de midia, porque o print ja vem recortado do Figma. */
.audit-window {
position: absolute;
top: 30.168%;
left: 9.207%;
width: 81.585%;
}
.audit-window img {
display: block;
width: 100%;
height: auto;
}
/* Sombra de 68px no rodape da janela, dissolvendo a segunda fileira de cards. */
.audit-window__shade {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 13.6%;
background-image: linear-gradient(180deg, var(--color-dark-blue-opacity-0), var(--color-dark-blue-0));
pointer-events: none;
}
@media (max-width: 700px) {
.audit-window {
top: 27%;
bottom: 0;
left: 6.207%;
width: 166.585%;
}
.solutions__block-title {
text-wrap: balance;
}
}
.cta {
overflow: clip;
padding-top: var(--spacing-11);
background-color: var(--color-dark-blue-0);
color: var(--color-white);
}
.cta__extras {
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
gap: var(--spacing-8);
}
.cta__extras-title {
max-width: 832px;
margin: 0;
color: var(--color-white);
font-weight: var(--font-weight-semibold);
}
.cta__grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: var(--spacing-6);
margin: 0;
padding: 0;
list-style: none;
}
.cta__card {
display: flex;
min-height: 238px;
flex-direction: column;
align-items: flex-start;
padding: var(--spacing-7);
border: 1px solid var(--color-white-opacity-12);
border-radius: var(--spacing-3);
background-color: var(--color-dark-blue-opacity-8);
backdrop-filter: blur(1px);
}
.cta__card-icon {
display: block;
width: 28px;
height: 28px;
margin-bottom: var(--spacing-6);
}
.cta__card-title {
margin: 0 0 var(--spacing-5);
color: var(--color-white);
font-weight: var(--font-weight-semibold);
}
.cta__card-description {
margin: 0;
color: var(--color-dark-blue-70);
}
/* Area do CTA final, com o efeito de linhas animado ao fundo. */
.cta__banner {
position: relative;
display: flex;
min-height: 684px;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--spacing-6);
text-align: center;
}
.cta__banner > :not(.cta__lines) {
position: relative;
z-index: 1;
}
/* No Figma o centro do efeito fica 25px (2,25% da altura) abaixo do centro do banner
e o topo passa por tras dos cards, que tem fundo translucido com blur. */
.cta__lines {
position: absolute;
z-index: 0;
top: 50%;
left: 50%;
width: min(1114px, 200vw);
max-width: none;
height: auto;
aspect-ratio: 1;
/* Usar translate (e nao transform): ele e aplicado antes de rotate/scale, entao o giro
acontece em torno do proprio centro do efeito. Com transform, o efeito orbitava para fora do CTA. */
translate: -50% -47.75%;
color: var(--color-brand-blue-10);
pointer-events: none;
user-select: none;
will-change: rotate, scale;
/* Giro e respiracao do Figma (loop de 40s); o brilho de cada traco e desenhado pelo cta.js. */
animation:
cta-lines-rotate 40s linear infinite,
cta-lines-breathe 20s infinite;
}
@keyframes cta-lines-rotate {
to {
rotate: 360deg;
}
}
@keyframes cta-lines-breathe {
0%,
50%,
100% {
scale: 1;
animation-timing-function: cubic-bezier(0.45, 0, 0.55, 1);
}
25% {
scale: 1.045;
animation-timing-function: cubic-bezier(0.45, 0, 0.55, 1);
}
75% {
scale: 0.97;
animation-timing-function: cubic-bezier(0.45, 0, 0.55, 1);
}
}
@media (prefers-reduced-motion: reduce) {
.cta__lines {
animation: none;
}
}
.cta__title {
max-width: 781px;
margin: 0;
color: var(--color-white);
font-weight: var(--font-weight-semibold);
}
@media (max-width: 1200px) {
.cta__grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 700px) {
.cta {
padding-top: var(--spacing-9);
}
.cta__extras {
gap: var(--spacing-7);
}
.cta__extras-title {
font-size: var(--type-heading-4-size);
line-height: var(--type-heading-4-line-height);
letter-spacing: var(--type-heading-4-letter-spacing);
}
.cta__grid {
grid-template-columns: minmax(0, 1fr);
gap: var(--spacing-5);
}
.cta__card {
min-height: 0;
padding: var(--spacing-6);
position: sticky;
top: var(--spacing-12);
background: var(--color-dark-blue-0);
}
.cta__banner {
min-height: 0;
padding-block: var(--spacing-14);
}
.cta__title {
font-size: var(--type-heading-2-size);
line-height: var(--type-heading-2-line-height);
letter-spacing: var(--type-heading-2-letter-spacing);
}
}
/* Secao de planos: tabela comparativa.
As larguras de coluna vivem nas variaveis abaixo; --plans-count vem do Razor
(quantidade de planos), entao a largura total se ajusta sozinha. */
.plans {
--plans-count: 4;
--plans-feature-width: 467px;
--plans-plan-width: 214px;
--plans-sticky-top: var(--site-header-height, 0px);
--plans-fixed-column-bg: var(--color-white);
--plans-line: var(--color-dark-blue-80);
--plans-row-line: var(--color-dark-blue-opacity-8);
padding-block: var(--spacing-14);
border-top: 1px solid var(--plans-line);
border-bottom: 1px solid var(--plans-line);
background-color: var(--color-white);
color: var(--color-dark-blue-0);
}
.plans__container {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--spacing-12);
}
.plans__title {
margin: 0;
font-weight: var(--font-weight-semibold);
text-align: center;
}
/* align-self: stretch (e nao width: 100%) porque o container e flex com
align-items: center - so assim as margens negativas da sangria funcionam. */
.plans__scroller {
align-self: stretch;
}
.plans__scroller:focus-visible {
outline: 2px solid var(--color-dark-blue-0);
outline-offset: var(--spacing-2);
}
.plans__table {
/* Ancora a <caption> oculta, pelo mesmo motivo do .plans__plan-cta. */
position: relative;
width: calc(var(--plans-feature-width) + (var(--plans-count) * var(--plans-plan-width)));
margin-inline: auto;
border-collapse: separate;
border-spacing: 0;
table-layout: fixed;
text-align: left;
}
/* Legenda e complementos so para leitores de tela. */
.plans__caption,
.plans__plan-cta-context {
position: absolute;
overflow: hidden;
width: 1px;
height: 1px;
padding: 0;
border: 0;
margin: -1px;
clip-path: inset(50%);
white-space: nowrap;
}
/* Cabecalho: coluna de titulo + uma coluna por plano. */
.plans__head th {
position: sticky;
z-index: 2;
top: var(--plans-sticky-top);
border-bottom: 1px solid var(--plans-line);
background-color: var(--color-white);
vertical-align: middle;
}
.plans__intro {
z-index: 3;
width: var(--plans-feature-width);
padding: var(--spacing-3) var(--spacing-6) var(--spacing-3) 0;
}
.plans__intro-text {
display: block;
max-width: 297px;
font-weight: var(--font-weight-semibold);
}
/* Recuo lateral de 12px (e nao 16px): com a coluna de 214px sobra 189px uteis,
o suficiente para "Consulfarma One" caber em uma linha nos 22px do Figma. */
.plans__plan {
width: var(--plans-plan-width);
padding: var(--spacing-4);
border-left: 1px solid var(--plans-line);
}
/* Empilha topo/nome/botao e mantem o botao colado na base da celula, para que
um nome de plano mais longo nao desalinhe os CTAs entre as colunas. */
.plans__plan-inner {
display: flex;
height: 100%;
flex-direction: column;
}
.plans__plan:last-child {
border-right: 1px solid var(--plans-line);
}
.plans__plan-accent {
display: block;
width: 32px;
height: 4px;
border-radius: var(--spacing-1);
background-color: var(--plan-accent, var(--color-dark-blue-0));
}
.plans__plan-name {
display: block;
margin-top: var(--spacing-2);
/* Espaco minimo ate o botao; o resto da folga vem do margin-top: auto dele. */
margin-bottom: var(--spacing-5);
font-weight: var(--font-weight-semibold);
}
/* position: relative ancora o texto oculto do CTA. Sem isso ele se posiciona
pelo viewport, escapa do recorte do scroller e estica a largura da pagina. */
.plans__plan-cta {
position: relative;
display: flex;
width: 100%;
margin-top: auto;
}
/* Fundo branco opaco em todas as celulas: as colunas fixas passam por cima
das vizinhas quando a tabela rola na horizontal. */
.plans__row > * {
background-color: var(--color-white);
border-bottom: 1px solid var(--plans-row-line);
}
.plans__row:nth-child(even) > * {
background-image: linear-gradient(var(--plans-row-line), var(--plans-row-line));
}
.plans__row:last-child > * {
border-bottom-color: var(--plans-line);
}
.plans__feature {
padding: var(--spacing-2) var(--spacing-3);
font-weight: var(--font-weight-regular);
vertical-align: middle;
}
.plans__feature-label {
display: block;
font-weight: var(--font-weight-medium);
}
.plans__feature-description {
display: block;
margin-top: var(--spacing-2);
color: var(--color-dark-blue-50);
}
.plans__value {
padding: var(--spacing-2) var(--spacing-3);
border-left: 1px solid var(--plans-line);
text-align: center;
vertical-align: middle;
}
.plans__value:last-child {
border-right: 1px solid var(--plans-line);
}
.plans__icon {
display: block;
width: 20px;
height: 20px;
margin-inline: auto;
}
.plans__help {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: var(--spacing-6);
}
.plans__help-title {
margin: 0;
font-weight: var(--font-weight-semibold);
text-align: center;
}
/* Cabecalho flutuante (criado pelo plans.js) para as larguras em que o sticky
nativo nao funciona - ver o comentario no plans.js. Fica abaixo do header do
site, que usa z-index 1000. */
.plans__floating {
position: fixed;
z-index: 900;
top: var(--plans-sticky-top);
right: 0;
left: 0;
overflow: hidden;
border-bottom: 1px solid var(--plans-line);
background-color: var(--color-white);
opacity: 0;
transition: opacity 120ms linear, visibility 120ms linear;
visibility: hidden;
/* Nao intercepta o toque: o arrasto horizontal cai na tabela de baixo. */
pointer-events: none;
}
.plans__floating.is-visible {
opacity: 1;
visibility: visible;
}
.plans__floating-track {
width: max-content;
will-change: transform;
}
/* Tapa a faixa ocupada pela coluna fixa: sem isso os nomes que passam por baixo
dela na tabela apareceriam soltos na barra. Geometria vem do plans.js, para
acompanhar exatamente onde a coluna esta ancorada. */
.plans__floating::before {
position: absolute;
z-index: 1;
top: 0;
bottom: 0;
left: var(--plans-mask-left, 0px);
width: var(--plans-mask-width, 0px);
border-right: 1px solid var(--plans-row-line);
background-color: var(--plans-fixed-column-bg);
content: "";
}
/* Sem o botao, o nome nao precisa do respiro que o separa dele na tabela. */
.plans__table--floating .plans__plan-name {
margin-bottom: 0;
}
.plans__table--floating .plans__head th {
position: static;
border-bottom: 0;
}
@media (prefers-reduced-motion: reduce) {
.plans__floating {
transition: none;
}
}
/* Abaixo da largura da tabela ela passa a rolar na horizontal e a coluna de
recursos fica fixa a esquerda. Ai o cabecalho deixa de ser sticky no topo,
porque o container de rolagem tem seu proprio contexto.
A tabela ocupa 467 + 4x214 = 1323px; somando os gutters (2x24px) e a barra de
rolagem, ela cabe inteira a partir de 1400px - por isso o corte em 1399px. */
@media (max-width: 1399px) {
.plans__scroller {
overflow-x: auto;
margin-inline: calc(0px - var(--container-gutter));
padding-inline: var(--container-gutter);
overscroll-behavior-x: contain;
scrollbar-gutter: stable;
}
/* Esmaecer a borda direita enquanto houver colunas fora da tela (classes do plans.js). */
.plans__scroller.is-scrollable:not(.is-at-end) {
mask-image: linear-gradient(to left, transparent 0, #000 var(--spacing-8));
}
.plans__head th {
position: static;
}
.plans__intro,
.plans__feature {
position: sticky;
z-index: 3;
left: 0;
}
.plans__intro {
padding-right: var(--spacing-5);
background-clip: padding-box;
}
.plans__feature {
border-right: 1px solid var(--plans-row-line);
}
}
@media (max-width: 1000px) {
.plans {
--plans-feature-width: 320px;
--plans-plan-width: 200px;
}
.plans__intro-text {
max-width: none;
font-size: var(--type-heading-6-size);
line-height: var(--type-heading-6-line-height);
letter-spacing: var(--type-heading-6-letter-spacing);
}
}
/* Mobile: a area util e escassa, entao a tabela sangra ate a borda da tela,
o texto cai para 12px e os recuos encolhem. A coluna fixa fica estreita de
proposito - ela quebra em mais linhas para sobrar largura as colunas de
plano, que sao o que o usuario precisa comparar. */
@media (max-width: 767px) {
.plans {
--plans-feature-width: 140px;
--plans-plan-width: 160px;
padding-block: var(--spacing-12);
}
.plans__container {
gap: var(--spacing-9);
}
/* Sangria total: sem recuo lateral, o scroller usa a largura inteira. */
.plans__scroller {
padding-inline: 0;
}
.plans__plan {
padding: var(--spacing-3);
}
/* 16px: o maior tamanho em que "Consulfarma One" ainda cabe em uma linha
nos 143px uteis da coluna de 160px. */
.plans__plan-name {
margin-bottom: var(--spacing-4);
font-size: var(--type-body-md-size);
line-height: var(--type-body-md-line-height);
letter-spacing: 0;
}
.plans__intro-text {
font-size: var(--type-body-md-size);
line-height: var(--type-body-md-line-height);
letter-spacing: 0;
}
.plans__plan-cta {
padding-inline: var(--spacing-2);
}
/* Recuo proprio nas celulas da coluna fixa, ja que o scroller perdeu o dele:
evita o texto colado na borda da tela. */
.plans__intro,
.plans__feature {
padding-right: var(--spacing-3);
padding-left: var(--container-gutter);
box-shadow: 6px 5px 9px var(--color-dark-blue-opacity-8);
}
.plans__value {
padding-inline: var(--spacing-2);
}
.plans__feature-label,
.plans__feature-description,
.plans__value .body-sm {
font-size: var(--type-body-xs-size);
line-height: var(--type-body-xs-line-height);
}
.plans__feature-description {
margin-top: var(--spacing-1);
}
.plans__icon {
width: 16px;
height: 16px;
}
.plans__help-title {
font-size: var(--type-heading-6-size);
line-height: var(--type-heading-6-line-height);
letter-spacing: var(--type-heading-6-letter-spacing);
}
}
/* Secao Depoimentos: carrossel horizontal de cards de larguras diferentes
(retrato 816, texto 392, video 968), centrados por scroll-snap. A rolagem e
nativa - o depoimentos.js so cuida dos pontinhos, do card inicial e do
player do Vimeo. */
.testimonials {
--testimonial-height: 545px;
/* Largura do card mais estreito: define o espaco das pontas do trilho. */
--testimonial-min-width: 392px;
padding-block: var(--spacing-14);
background-color: var(--color-dark-blue-0);
color: var(--color-white);
}
.testimonials__header {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--spacing-3);
margin-bottom: var(--spacing-12);
text-align: center;
}
.testimonials__eyebrow {
margin: 0;
color: var(--color-dark-blue-60);
}
.testimonials__title {
max-width: 592px;
margin: 0;
color: var(--color-white);
font-weight: var(--font-weight-semibold);
text-wrap: balance;
}
/* O trilho sangra ate as bordas da tela de proposito: o design mostra os cards
vizinhos entrando pelos cantos. */
.testimonials__carousel {
position: relative;
}
.testimonials__track {
display: flex;
align-items: stretch;
gap: var(--spacing-6);
margin: 0;
/* Espaco nas pontas para o primeiro e o ultimo card tambem alcancarem o
centro; sem isso o snap nao consegue centralizar as extremidades. A conta
usa o card mais estreito, que e o que precisa de mais folga. */
padding-inline: max(var(--container-gutter), calc((100% - var(--testimonial-min-width)) / 2));
padding-block: var(--spacing-3);
list-style: none;
overflow-x: auto;
scroll-snap-type: x mandatory;
overscroll-behavior-x: contain;
scrollbar-width: none;
}
.testimonials__track::-webkit-scrollbar {
display: none;
}
/* Com a rolagem automatica ligada (depoimentos.js) o snap brigaria com o
movimento continuo: cada passo do loop seria puxado de volta para o centro do
card mais proximo. Sem autoplay - reduced motion, ou JS fora do ar - o snap
nativo continua valendo. */
.testimonials__carousel.is-autoplay .testimonials__track {
scroll-snap-type: none;
scroll-behavior: auto;
}
.testimonials__track:focus-visible {
outline: 2px solid var(--color-brand-blue-0);
outline-offset: 4px;
}
.testimonial {
position: relative;
display: flex;
height: var(--testimonial-height);
flex: none;
padding: var(--spacing-6);
border: 2px solid var(--color-white-opacity-12);
border-radius: var(--spacing-5);
background-color: var(--color-dark-blue-0);
scroll-snap-align: center;
}
/* Card de retrato: foto a esquerda, citacao a direita. */
.testimonial--photo {
width: 816px;
align-items: flex-end;
gap: var(--spacing-6);
/* box-shadow, nao filter: drop-shadow - mesmo resultado num retangulo
arredondado, sem promover o card inteiro a uma camada filtrada. */
box-shadow: 4px 4px 0 0 var(--color-white-opacity-12);
}
.testimonial__portrait {
position: relative;
display: flex;
width: 340px;
flex: none;
flex-direction: column;
align-self: stretch;
justify-content: flex-end;
margin: 0;
padding: var(--spacing-6);
overflow: hidden;
border-radius: var(--spacing-5);
}
.testimonial__portrait img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
/* Escurece a metade de baixo do retrato para o nome ficar legivel. */
.testimonial__portrait::after {
content: "";
position: absolute;
inset: 0;
background-image: linear-gradient(180deg, var(--color-dark-blue-opacity-0) 48.29%, var(--color-dark-blue-0) 100%);
pointer-events: none;
}
.testimonial__identity {
position: relative;
display: flex;
flex-direction: column;
gap: var(--spacing-1);
z-index: 2;
}
.testimonial__name {
color: var(--color-white);
font-weight: var(--font-weight-semibold);
}
.testimonial__pharmacy {
color: var(--color-brand-blue-10);
}
.testimonial__quote {
display: flex;
min-width: 0;
flex: 1 1 0;
flex-direction: column;
gap: var(--spacing-6);
margin: 0;
}
.testimonial__text {
margin: 0;
color: var(--color-white);
overflow-wrap: break-word;
}
/* 80x49.404 no design. Raster, nao SVG: o traco e desenhado a mao e o vetor
fica em 54KB contra 8KB aqui, sempre exibido no mesmo tamanho. */
.testimonial__marks {
display: block;
width: 80px;
height: auto;
flex: none;
}
.testimonial--photo .testimonial__marks {
align-self: flex-end;
margin-block: var(--spacing-6);
}
/* Card so de texto: aspas numa ponta, citacao na outra. */
.testimonial--text {
width: 392px;
flex-direction: column;
justify-content: space-between;
gap: var(--spacing-6);
}
.testimonial--text .testimonial__marks {
order: 2;
margin-block: var(--spacing-6);
}
.testimonial--text .testimonial__quote {
order: 1;
flex: 0 1 auto;
}
/* Variante com as aspas no topo (Eunice, no design). */
.testimonial--marks-top .testimonial__marks {
order: 1;
align-self: flex-end;
}
.testimonial--marks-top .testimonial__quote {
order: 2;
}
.testimonial--text .testimonial__identity {
gap: var(--spacing-3);
}
.testimonial--text .testimonial__pharmacy {
color: var(--color-white);
}
/* Card de video. */
.testimonial--video {
width: 968px;
padding: 0;
border: 0;
overflow: hidden;
background-color: var(--color-dark-blue-10);
}
.testimonial__player {
position: relative;
display: flex;
width: 100%;
align-items: center;
justify-content: center;
}
.testimonial__poster,
.testimonial__player iframe {
position: absolute;
inset: 0;
display: block;
width: 100%;
height: 100%;
border: 0;
object-fit: cover;
}
.testimonial__play {
position: relative;
z-index: 2;
display: flex;
width: 64px;
height: 64px;
padding: 0;
border: 0;
border-radius: 50%;
background: none;
cursor: pointer;
transition: transform 160ms ease, opacity 160ms ease;
}
.testimonial__play img {
display: block;
width: 100%;
height: 100%;
}
.testimonial__play:hover {
transform: scale(1.08);
}
.testimonial__play:focus-visible {
outline: 2px solid var(--color-brand-blue-0);
outline-offset: 4px;
}
/* Depois que o som e ligado o botao perde a funcao e sai de cena. */
.testimonial__player.is-playing .testimonial__play {
opacity: 0;
pointer-events: none;
}
/* Dissolve os cards contra o fundo nas duas bordas da tela. */
.testimonials__fade {
position: absolute;
top: 0;
width: var(--spacing-9);
height: 100%;
pointer-events: none;
}
.testimonials__fade--start {
left: 0;
background-image: linear-gradient(90deg, var(--color-dark-blue-0), var(--color-dark-blue-opacity-0));
}
.testimonials__fade--end {
right: 0;
background-image: linear-gradient(270deg, var(--color-dark-blue-0), var(--color-dark-blue-opacity-0));
}
.testimonials__dots {
display: flex;
justify-content: center;
gap: var(--spacing-4);
margin-top: var(--spacing-8);
}
.testimonials__dot {
width: 8px;
height: 8px;
padding: 0;
border: 0;
border-radius: var(--spacing-7);
background-color: var(--color-white-opacity-16);
cursor: pointer;
transition: background-color 160ms ease;
}
.testimonials__dot[aria-selected="true"] {
background-color: var(--color-brand-blue-10);
}
.testimonials__dot:focus-visible {
outline: 2px solid var(--color-brand-blue-0);
outline-offset: 4px;
}
@media (max-width: 960px) {
.testimonials {
--testimonial-height: 500px;
}
.testimonial--photo {
width: min(816px, 88vw);
}
.testimonial--video {
width: min(968px, 88vw);
}
.testimonial--text {
width: min(392px, 80vw);
}
}
@media (max-width: 700px) {
.testimonials {
--testimonial-height: 560px;
padding-block: var(--spacing-11);
}
.testimonials__header {
margin-bottom: var(--spacing-9);
}
.testimonials__track {
gap: var(--spacing-5);
padding-inline: var(--container-gutter);
}
/* Num celular a foto ao lado do texto deixaria as duas colunas estreitas
demais; o retrato vai para cima e vira uma faixa. */
.testimonial--photo {
width: 88vw;
flex-direction: column;
align-items: stretch;
gap: var(--spacing-5);
}
.testimonial__portrait {
width: 100%;
height: 200px;
flex: none;
padding: var(--spacing-5);
}
.testimonial--photo .testimonial__quote {
min-height: 0;
overflow-y: auto;
scrollbar-width: none;
}
.testimonial--photo .testimonial__quote::-webkit-scrollbar {
display: none;
}
/* As aspas no card de retrato comem altura que o texto precisa no mobile. */
.testimonial--photo .testimonial__marks {
display: none;
}
.testimonial--text {
width: 88vw;
}
.testimonial--video {
width: 88vw;
}
.testimonial__marks {
width: 56px;
}
.testimonials__fade {
width: var(--spacing-6);
}
}
@media (prefers-reduced-motion: reduce) {
.testimonials__track {
scroll-behavior: auto;
}
.testimonial__play {
transition: none;
}
}
.faq {
padding-block: var(--spacing-14);
background-color: var(--color-white);
}
.faq__container {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: var(--spacing-9);
}
.faq__intro {
display: flex;
width: 575px;
max-width: 100%;
flex-direction: column;
gap: var(--spacing-3);
}
.faq__eyebrow {
margin: 0;
color: var(--color-dark-blue-50);
}
.faq__title {
margin: 0;
color: var(--color-dark-blue-0);
font-weight: var(--font-weight-semibold);
}
.faq__list {
width: 808px;
max-width: 100%;
flex: 0 1 auto;
}
.faq__item {
border-bottom: 1px solid var(--color-dark-blue-70);
}
.faq__question {
margin: 0;
font-weight: var(--font-weight-semibold);
}
.faq__toggle {
appearance: none;
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
gap: var(--spacing-5);
padding: var(--spacing-6) 0;
border: 0;
background: none;
color: var(--color-dark-blue-0);
font: inherit;
letter-spacing: inherit;
text-align: left;
cursor: pointer;
}
.faq__toggle:focus-visible {
outline: 2px solid var(--color-brand-blue-0);
outline-offset: 2px;
}
.faq__icon {
display: block;
width: 24px;
height: 24px;
flex: 0 0 auto;
transition: transform 200ms ease;
}
.faq__item.is-open .faq__icon {
transform: rotate(180deg);
}
/* Abre com transicao de altura via grid (0fr -> 1fr), sem medir o conteudo no JS. */
.faq__answer {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 250ms ease;
}
.faq__item.is-open .faq__answer {
grid-template-rows: 1fr;
}
/* visibility esconde a resposta fechada de leitores de tela; so muda depois que a altura fecha. */
.faq__answer-inner {
min-height: 0;
overflow: hidden;
visibility: hidden;
transition: visibility 0s linear 250ms;
}
.faq__item.is-open .faq__answer-inner {
visibility: visible;
transition-delay: 0s;
}
.faq__answer-inner p {
margin: 0;
padding-bottom: var(--spacing-6);
color: var(--color-dark-blue-0);
}
@media (max-width: 960px) {
.faq {
padding-block: var(--spacing-12);
}
.faq__container {
flex-direction: column;
gap: var(--spacing-7);
}
.faq__list {
width: 100%;
}
}
@media (prefers-reduced-motion: reduce) {
.faq__icon,
.faq__answer {
transition: none;
}
}
.contact-modal {
position: fixed;
inset: 0;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
padding: var(--spacing-5);
}
.contact-modal[hidden] {
display: none;
}
.contact-modal__overlay {
position: absolute;
inset: 0;
background: var(--color-dark-blue-opacity-64);
}
.contact-modal__dialog {
position: relative;
z-index: 1;
width: min(90vw, 480px);
max-height: 90vh;
overflow-y: auto;
background: var(--color-white);
padding: var(--spacing-6);
border-radius: var(--spacing-5);
}
.contact-modal__dialog h2 {
margin: 0 0 var(--spacing-6);
font-size: var(--type-heading-6-size);
line-height: var(--type-heading-6-line-height);
letter-spacing: var(--type-heading-6-letter-spacing);
font-weight: var(--font-weight-semibold);
color: var(--color-dark-blue-0);
}
.contact-modal__close {
position: absolute;
top: var(--spacing-4);
right: var(--spacing-4);
width: 40px;
height: 40px;
appearance: none;
border: 0;
border-radius: 50%;
background-color: transparent;
color: var(--color-dark-blue-50);
font-size: 28px;
line-height: 1;
cursor: pointer;
}
.contact-modal__close:hover {
background-color: var(--color-dark-blue-opacity-8);
color: var(--color-dark-blue-0);
}
body.has-open-modal {
overflow: hidden;
}
/*
Widget flutuante de WhatsApp.
Fica fixo no canto inferior-direito e é mostrado via JS apenas quando
a seção #beneficios (Solutions) está intersectando o viewport.
*/
.wa-widget {
position: fixed;
right: var(--spacing-6);
bottom: var(--spacing-6);
z-index: 1000;
display: inline-flex;
flex-direction: column;
align-items: center;
gap: var(--spacing-3);
text-decoration: none;
pointer-events: auto;
opacity: 0;
transform: translateY(16px);
transition: opacity 240ms ease, transform 240ms ease;
border-radius: var(--spacing-6, 24px);
background: var(--white-opacity-24, rgba(255, 255, 255, 0.24));
backdrop-filter: blur(30px);
padding: var(--spacing-2, 4px);
}
.wa-widget[hidden] {
display: none;
}
.wa-widget.is-visible {
opacity: 1;
transform: translateY(0);
}
.wa-widget__avatar {
display: block;
width: 72px;
height: 72px;
overflow: hidden;
border-radius: var(--spacing-6);
background-color: var(--color-brand-blue-20);
box-shadow: 0 8px 24px var(--color-dark-blue-opacity-24);
}
.wa-widget__avatar img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center top;
}
.wa-widget__pill {
min-width: 108px;
}
.wa-widget__labels {
display: inline-grid;
grid-template-areas: "label";
align-items: center;
justify-items: center;
}
.wa-widget__label {
grid-area: label;
opacity: 0;
transition: opacity 240ms ease;
}
.wa-widget__label.is-active {
opacity: 1;
}
.wa-widget:focus-visible {
outline: none;
}
.wa-widget:focus-visible .wa-widget__avatar {
box-shadow: 0 8px 24px var(--color-dark-blue-opacity-24), 0 0 0 4px var(--color-dark-blue-opacity-12);
}
.wa-widget:hover .wa-widget__avatar {
box-shadow: 0 10px 28px var(--color-dark-blue-opacity-32);
}
/* Mobile: encosta um pouco mais na borda e diminui a foto. */
@media (max-width: 700px) {
.wa-widget {
right: var(--spacing-5);
bottom: var(--spacing-5);
gap: var(--spacing-2);
flex-direction: row-reverse;
}
.wa-widget__avatar {
width: 36px;
height: 36px;
}
}
/* Respeitar prefers-reduced-motion. */
@media (prefers-reduced-motion: reduce) {
.wa-widget {
transition: opacity 120ms linear;
transform: none;
}
.wa-widget.is-visible {
transform: none;
}
}
