.ao-panel,
.ao-auth,
.ao-withdraw {
	padding-block: var(--ao-space-11);
}

/*
 * O `--ao-conteudo` global trava em 1196 — a medida do artboard de 1440 do Figma,
 * certa para a vitrine. As telas logadas sao aplicacao, com tabela e sidebar: nesse
 * caso o teto sobrava margem inutil em monitor largo. Aqui o conteudo respira ate
 * 1600 e volta a acompanhar a viewport quando ela e menor.
 * `[DECISÃO:2026-09-15]` — desvio deliberado do artboard, ver D27 em `docs/09`.
 */
.ao-panel > .ao-container,
.ao-withdraw > .ao-container {
	width: calc(min(94vw, 1600px) + var(--ao-respiro) * 2);
}

/* A tela cheia de autenticacao nao usa o <main> com respiro do tema. */
body.ao-tela-cheia .ao-main {
	display: flex;
	flex-direction: column;
}

body.ao-tela-cheia .ao-page,
body.ao-tela-cheia .ao-entry {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	margin: 0;
	padding: 0;
}

.ao-panel__inner {
	display: flex;
	align-items: flex-start;
	gap: var(--ao-grid-gap);
}

/* Figma 102942:1645 — a sidebar do painel nao tem cartao nem fundo proprio. */
.ao-panel__aside {
	flex: 0 0 18.9%;
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-11);
}

.ao-panel__user {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-4);
}

.ao-panel__user-name {
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-black);
	overflow-wrap: anywhere;
}

.ao-panel__user-mail {
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	color: var(--ao-muted);
	overflow-wrap: break-word;
}

.ao-panel__nav {
	display: flex;
	flex-direction: column;
}

/* Figma 102942:1650 — o item ativo e marcado por uma borda esquerda laranja. */
.ao-panel__nav-item {
	padding: var(--ao-space-7) var(--ao-space-5);
	border-left: 2px solid transparent;
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	color: var(--ao-muted);
	text-decoration: none;
}

@media (hover: hover) {
	.ao-panel__nav-item:hover {
		color: var(--ao-accent);
	}
}

.ao-panel__nav-item.is-active {
	border-left-color: var(--ao-accent);
	color: var(--ao-accent);
	font-weight: var(--ao-fw-bold);
}

.ao-panel__content {
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-8);
}

.ao-panel__head {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-2);
}

.ao-panel__toolbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--ao-space-5);
	flex-wrap: wrap;
}

.ao-panel__empty {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--ao-space-5);
	padding: var(--ao-space-11) var(--ao-space-7);
	background: var(--ao-white);
	border-radius: var(--ao-radius-card);
}

/*
 * RN-62 — o aviso de downgrade. Mesma anatomia do .ao-validate__result (cartao
 * branco com faixa colorida a esquerda), na cor de acento porque e um pedido de
 * decisao, nao um erro.
 */
.ao-downgrade {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--ao-space-4);
	padding: var(--ao-space-7);
	background: var(--ao-white);
	border-radius: var(--ao-radius-card);
	border-left: 8px solid var(--ao-accent);
}

.ao-downgrade__title {
	margin: 0;
	font-size: var(--ao-fs-h3);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-accent);
}

.ao-downgrade__text {
	margin: 0;
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-body);
}

.ao-downgrade__lista {
	width: 100%;
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-2);
}

.ao-downgrade__item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--ao-space-5);
	flex-wrap: wrap;
	padding: var(--ao-space-4) 0;
	border-top: 1px solid var(--ao-grey-10);
}

.ao-downgrade__oferta {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-1);
	min-width: 0;
}

.ao-downgrade__nome {
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-semibold);
	color: var(--ao-body);
	overflow-wrap: anywhere;
}

.ao-downgrade__seg {
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-muted);
}

/* O estado desabilitado do botao ja vem do tema (.ao-btn[disabled]). */

/*
 * Figma 103052:29 — uma tabela unica dentro de um cartao branco: cabecalho uma
 * vez so, linhas zebradas e um icone de olho na coluna "Acoes".
 */
.ao-vouchers {
	background: var(--ao-white);
	border: 1px solid var(--ao-grey-10);
	border-radius: 12px;
	/* As faixas da zebra vao de borda a borda; sem isso elas vazam pelos cantos. */
	overflow: hidden;
}

.ao-vouchers__table {
	width: 100%;
	border-collapse: collapse;
	/* O padding lateral do Figma (43 de 864) vive nas celulas das pontas, e nao no
	   cartao: a zebra precisa alcancar a borda. */
	--ao-vouchers-gutter: calc(43 / 864 * 100%);
}

.ao-vouchers__table th,
.ao-vouchers__table td {
	padding-inline: var(--ao-space-4);
	text-align: left;
	vertical-align: middle;
}

.ao-vouchers__table th:first-child,
.ao-vouchers__table td:first-child {
	padding-left: var(--ao-vouchers-gutter);
}

.ao-vouchers__table th:last-child,
.ao-vouchers__table td:last-child {
	padding-right: var(--ao-vouchers-gutter);
}

.ao-vouchers__table th {
	padding-block: var(--ao-space-7);
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-black);
	border-bottom: 1px solid var(--ao-grey-10);
}

.ao-vouchers__table td {
	padding-block: var(--ao-space-6);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-muted);
	overflow-wrap: anywhere;
}

/* Zebra do Figma: as linhas pares recebem a faixa cinza a 25%. */
.ao-vouchers__table tbody tr:nth-child(even) {
	background: rgba(217, 217, 217, 0.25);
}

/* O codigo e o que a pessoa mostra no balcao: e o dado principal da linha. */
.ao-vouchers__code {
	font-weight: var(--ao-fw-bold);
	color: var(--ao-body);
	letter-spacing: 0.02em;
}

/*
 * A celula de status carrega badge + "Expira em N dias" lado a lado: sao a mesma
 * informacao ("disponivel, e por quanto tempo") e empilhados desalinhavam a linha.
 *
 * Centralizada, e com o cabecalho junto: o badge tem largura fixa (93px) e o
 * "Status" e mais largo que ele, entao alinhados a esquerda os dois nunca batem
 * — o titulo ficava deslocado sobre a pilha de badges.
 */
.ao-vouchers__table th:first-child,
.ao-vouchers__table td:first-child {
	text-align: center;
}

.ao-vouchers__table td:first-child {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--ao-space-2) var(--ao-space-4);
}

.ao-vouchers__table td > .ao-badge-status {
	flex: none;
	white-space: nowrap;
}

/* "Expira em 45 dias" e uma unidade: quebrar no meio atrapalha a leitura. Vive
   na box do cupom (tela de detalhe), nao mais na lista — D37. */
.ao-coupon .ao-time-alert {
	align-self: flex-start;
	white-space: nowrap;
}

/* O olho e um alvo de 24px sob um cabecalho de cinco letras: encostado a direita
   ele descolava do "Acoes". Centralizado, cabecalho e icone compartilham o eixo. */
.ao-vouchers__acoes {
	text-align: center;
	white-space: nowrap;
}

/* `position: relative` ancora o rotulo `.ao-visually-hidden`, que e absoluto: sem
   contexto ele mede a partir da pagina e estica o documento no mobile. */
.ao-vouchers__ver {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	color: var(--ao-primary);
}

.ao-vouchers__ver .ao-icon {
	display: block;
	width: 24px;
	height: 24px;
}

.ao-vouchers__ver:hover,
.ao-vouchers__ver:focus-visible {
	color: var(--ao-institucional-01);
}

/* Cupom indisponivel nao tem para onde levar: o icone fica, apagado e sem foco. */
.ao-vouchers__ver.is-disabled {
	color: var(--ao-grey-30);
	cursor: default;
}

/*
 * `overflow-x: auto` NAO deixa o eixo Y livre: quando um eixo recorta, a spec
 * obriga o outro a virar `auto` — e a tabela ganhava uma barra de rolagem
 * vertical inutil (o plano vai ate 3 ofertas, sempre cabem). `clip` com
 * `overflow-clip-margin` recorta so na horizontal e deixa o vertical transbordar,
 * entao o menu de acoes da ultima linha aparece inteiro sem barra nenhuma.
 */
.ao-table-wrap {
	overflow-x: clip;
	overflow-y: visible;
	overflow-clip-margin: var(--ao-radius-card);
	border-radius: var(--ao-radius-card);
	background: var(--ao-white);
}

/*
 * Fallback para quem nao tem `overflow: clip` (Safari < 16): volta ao scroll
 * horizontal, e o JS libera o recorte enquanto ha menu aberto.
 */
@supports not (overflow: clip) {
	.ao-table-wrap {
		overflow-x: auto;
		overflow-y: auto;
	}

	.ao-table-wrap.has-menu-aberto {
		overflow: visible;
	}
}

.ao-table-wrap .ao-table thead th:first-child {
	border-top-left-radius: var(--ao-radius-card);
}

.ao-table-wrap .ao-table thead th:last-child {
	border-top-right-radius: var(--ao-radius-card);
}

.ao-table__disabled {
	color: var(--ao-subtle);
	cursor: not-allowed;
}

.ao-root .ao-table__actions form {
	margin: 0;
}

.ao-link {
	color: var(--ao-primary);
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	text-decoration: underline;
}

@media (hover: hover) {
	.ao-link:hover {
		color: var(--ao-accent);
	}
}

.ao-link--button {
	padding: 0;
	border: 0;
	background: transparent;
	font-family: var(--ao-font);
	cursor: pointer;
}

.ao-link--danger {
	color: var(--ao-danger);
}

.ao-pager {
	display: flex;
	gap: var(--ao-space-2);
	flex-wrap: wrap;
}

.ao-pager__item {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: var(--ao-btn-h-card);
	height: var(--ao-btn-h-card);
	padding-inline: var(--ao-space-4);
	border-radius: var(--ao-radius-btn);
	background: var(--ao-white);
	color: var(--ao-body);
	font-size: var(--ao-fs-body-2);
	text-decoration: none;
}

.ao-pager__item.is-active {
	background: var(--ao-primary);
	color: var(--ao-on-dark);
	font-weight: var(--ao-fw-bold);
}

.ao-auth__inner,
.ao-withdraw__inner {
	display: flex;
	justify-content: center;
}

/*
 * Figma 102942:1751 — tela cheia, sem header nem footer. O artboard e 1440x950 com
 * inset uniforme de 26.67px: duas colunas de 680 e gap de 26.67. O formulario fica
 * centrado na coluna esquerda; o painel escuro ocupa a direita inteira.
 */
.ao-auth--split {
	display: flex;
	min-height: 100vh;
	min-height: 100dvh;
	padding: 26.67px;
	box-sizing: border-box;
	background: var(--ao-white);
}

.ao-auth--split .ao-auth__inner {
	flex: 1 1 auto;
	display: flex;
	align-items: stretch;
	justify-content: flex-start;
	gap: 26.67px;
	width: 100%;
	max-width: none;
	margin: 0;
	padding: 0;
}

.ao-auth--split .ao-auth__card {
	flex: 1 1 50%;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	align-self: stretch;
	max-width: none;
	gap: 0;
	padding: 0;
	background: none;
}

/*
 * O Figma desenha o bloco com 323px, que sobra estreito numa coluna de 680.
 * Alargado para 420 — `[DECISÃO:2026-09-15]`, desvio deliberado do design: 520 ficou
 * largo demais. O resto das medidas (alturas, radius, cores) segue o Figma.
 */
.ao-auth--split .ao-auth__card > * {
	width: 100%;
	max-width: 420px;
}

/* `[FIGMA:login]` — o titulo desta tela e cinza #4D4D4D, nao o azul-marinho das secoes. */
.ao-auth--split .ao-section-title {
	margin: 0;
	font-size: 32px;
	line-height: 40px;
	font-weight: 600;
	color: var(--ao-grey-70);
}

.ao-auth--split .ao-auth__lead {
	margin: 23.33px 0 0;
}

.ao-auth--split .ao-form {
	margin-top: 40px;
}

/* O seletor de perfil fica entre o subtitulo e o formulario, com o mesmo respiro. */
.ao-auth--split .ao-auth__tabs {
	margin-top: 40px;
}

.ao-auth--split .ao-auth__tabs + .ao-form {
	margin-top: 20px;
}

.ao-auth--split .ao-auth__alt {
	margin-top: 41px;
	text-align: center;
}

/* Saida da tela cheia: sem header, este e o caminho de volta a vitrine. */
.ao-auth__voltar {
	margin: var(--ao-space-5) 0 0;
	text-align: center;
	font-size: var(--ao-fs-body-2);
}

.ao-auth__voltar .ao-link {
	color: var(--ao-grey-50);
	text-decoration: none;
}

.ao-auth__voltar .ao-link:hover,
.ao-auth__voltar .ao-link:focus-visible {
	color: var(--ao-institucional-01);
	text-decoration: underline;
}

/* A logo do painel tambem leva para a home. */
.ao-auth__art-link {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	max-width: 428px;
	border-radius: var(--ao-radius-btn);
}

.ao-auth__art-link:focus-visible {
	outline: 2px solid var(--ao-white);
	outline-offset: 8px;
}

.ao-auth__art {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 1 1 50%;
	align-self: stretch;
	min-height: 0;
	padding: var(--ao-space-6);
	border-radius: 20px;
	background: var(--ao-surface-dark);
}

/* Logo: 428x125 no Figma, centrado no painel de 680. */
.ao-auth__art img {
	width: 100%;
	max-width: 428px;
	height: auto;
}

.ao-auth__card,
.ao-withdraw__card {
	flex: 0 1 48%;
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-7);
	padding: var(--ao-space-10);
	background: var(--ao-white);
	border-radius: var(--ao-radius-card);
}

/*
 * Figma 102942:1320 — o cartao ocupa os 1196 inteiros e e vazado sobre a pagina,
 * com borda cinza. O conteudo fica centrado numa coluna de 648, nao encostado a
 * esquerda: era o que fazia a tela parecer estreita e torta.
 */
.ao-withdraw__inner {
	display: block;
}

.ao-withdraw__card {
	flex: 1 1 auto;
	align-items: center;
	justify-content: center;
	gap: var(--ao-space-9);
	padding: var(--ao-space-9);
	background: transparent;
	border: 1px solid var(--ao-grey-30);
	text-align: center;
}

.ao-withdraw__card > * {
	width: 100%;
	max-width: 648px;
}

/* o bloco de texto do Figma tem 555 dentro da coluna de 648 */
.ao-withdraw__card > .ao-section-title,
.ao-withdraw__card > .ao-section-subtitle {
	max-width: 555px;
}

.ao-withdraw__card > .ao-section-title {
	color: var(--ao-grey-70);
}

.ao-withdraw__card > .ao-section-subtitle {
	color: var(--ao-grey-30);
}

/* 102942:1325 — o botao tem largura propria, nao a da coluna */
.ao-withdraw__card .ao-btn {
	width: auto;
	align-self: center;
}

.ao-withdraw__card .ao-form {
	display: flex;
	justify-content: center;
}

/* 102942:1320 tem 251 de altura com o conteudo centrado na vertical */
.ao-withdraw__card {
	min-height: 251px;
	padding-block: var(--ao-space-10);
}

/* a caixa "Pague no Estabelecimento" acompanha a coluna de texto, nao os 1196 */
.ao-withdraw__card .ao-pay-onsite {
	align-items: center;
	max-width: 555px;
	text-align: center;
}

.ao-auth__lead {
	margin: 0;
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	color: var(--ao-muted);
}

.ao-auth__tabs {
	display: flex;
	gap: var(--ao-space-2);
}

.ao-auth__tab {
	flex: 1 1 0;
	padding: var(--ao-space-4);
	border-radius: var(--ao-radius-btn);
	background: var(--ao-page);
	color: var(--ao-body);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	transition: background-color .18s ease, color .18s ease;
}

/*
 * O negrito do estado ativo mudaria a largura do texto e faria a aba "pular" na
 * troca. A sombra interna reserva o espaco do bold desde sempre, entao so a cor anima.
 */
.ao-auth__tab::after {
	display: block;
	height: 0;
	overflow: hidden;
	font-weight: var(--ao-fw-bold);
	content: attr(data-ao-rotulo);
	visibility: hidden;
}

@media (hover: hover) {
	.ao-auth__tab:hover {
		background: var(--ao-grey-95, #ececec);
	}
}

.ao-auth__tab.is-active {
	background: var(--ao-primary);
	color: var(--ao-on-dark);
	font-weight: var(--ao-fw-bold);
}

@media (hover: hover) {
	.ao-auth__tab.is-active:hover {
		background: var(--ao-primary);
	}
}

/*
 * Troca de perfil no cadastro: os campos do anunciante entram e saem no lugar,
 * sem recarregar.
 *
 * O ESPACAMENTO e incondicional. Ele ja viveu junto da animacao, atras de
 * `--perfil-vivo` -- classe que o CSS previa e que o JS nunca chegou a aplicar
 * (nasceu assim em 45c053a). O bloco ficava `display:block` sem `gap`, e os
 * tres campos do anunciante (Tipo, Estado, Cidade) colavam: medido 0px entre
 * eles contra 16px entre os demais. Mesmo que o JS passasse a marcar a classe,
 * o lugar disto nao seria ali: sem JS o bloco continua na tela -- e continuaria
 * colado. Layout nao pode depender de script. [DECISAO:2026-09-20]
 */
.ao-form__perfil {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-5);
}

/*
 * `[hidden]` precisa vencer o `display:flex` acima -- o do user-agent perde
 * para qualquer display explicito, e sem isto o bloco do anunciante apareceria
 * na aba do consumidor.
 */
.ao-form__perfil[hidden] {
	display: none;
}

/* Ja a ANIMACAO e do JS: sem ele a troca de aba e uma troca de pagina seca. */
.ao-form--perfil-vivo .ao-form__perfil {
	animation: ao-perfil-entra .22s cubic-bezier(.2, .8, .3, 1) both;
}

@keyframes ao-perfil-entra {
	from {
		opacity: 0;
		transform: translateY(-4px);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.ao-auth__tab {
		transition: none;
	}

	.ao-form--perfil-vivo .ao-form__perfil {
		animation: none;
	}
}

.ao-auth__alt {
	margin: 0;
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-muted);
}

.ao-form {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-5);
	margin: 0;
}

.ao-form--painel {
	padding: var(--ao-space-10);
	background: var(--ao-white);
	border-radius: var(--ao-radius-card);
}

/* Figma 102942:2616 — a tela de perfil nao usa cartao: os campos ficam sobre a pagina. */
.ao-form--conta {
	gap: var(--ao-space-11);
}

.ao-form--conta .ao-form__group {
	gap: var(--ao-space-9);
}

.ao-form--conta .ao-form__group + .ao-form__group {
	padding-top: 0;
	border-top: 0;
}

/*
 * <legend> nao entra no fluxo flex do <fieldset>, entao o primeiro campo subiria
 * por cima do titulo. Voltar o grupo para fluxo normal resolve sem margem negativa.
 */
.ao-form--conta .ao-form__group {
	display: block;
}

.ao-form--conta .ao-form__group > .ao-section-title {
	display: block;
	float: none;
	width: 100%;
	margin-bottom: var(--ao-space-9);
	padding: 0;
	color: var(--ao-body); /* Figma 102942:2647 usa cinza 70, nao o azul das demais telas. */
}

.ao-form--conta .ao-form__group > .ao-field + .ao-field {
	margin-top: var(--ao-space-5);
}

/*
 * Estabelecimento a esquerda, Dados da Conta a direita (pedido do usuario, 17/09).
 * O Figma empilha os dois blocos em 892px (102942:2616), mas as telas logadas usam
 * `min(94vw, 1600px)` (D27): em monitor largo sobrava metade da tela vazia a direita
 * e "Dados da Conta" caia abaixo da dobra. So para o anunciante — o consumidor tem
 * "Seus dados" com um campo so e nao forma segunda coluna.
 */
@media (min-width: 900px) {
	.ao-form--conta-duo {
		display: grid;
		grid-template-columns: 1fr 1fr;
		column-gap: var(--ao-space-11);
		row-gap: 0;
		align-items: start;
	}

	/* O avatar e do estabelecimento: fica sobre a coluna da esquerda. O
	   seletor e o do dropzone -- `.ao-avatar--conta` era o circulo azul
	   decorativo do Figma 102942:2620, substituido pelo upload em 17/09;
	   a regra antiga ficou orfa e nunca voltou a valer. */
	.ao-form--conta-duo > .ao-dropzone--avatar {
		grid-column: 1;
	}

	.ao-form--conta-duo > .ao-form__group {
		grid-column: 1;
	}

	.ao-form--conta-duo > .ao-form__group + .ao-form__group {
		grid-row: 2;
		grid-column: 2;
	}

	/*
	 * O botao salva o formulario inteiro, mas mora dentro do segundo fieldset —
	 * sozinho na coluna da direita, parecia acao so de "Dados da Conta".
	 * `position: absolute` tira-o do fluxo da coluna e o centra sobre as duas
	 * (pedido do usuario, 17/09); o `padding-bottom` no form reserva a faixa que
	 * ele passa a ocupar, senao cobriria o rodape da coluna mais alta.
	 */
	.ao-form--conta-duo {
		position: relative;
		padding-bottom: calc(var(--ao-btn-h) + var(--ao-space-11));
	}

	/*
	 * O seletor mirava o botao DENTRO do ultimo fieldset. Em 21/09 ele saiu
	 * dos fieldsets -- na pagina de Estabelecimento, que nao imprime "Dados
	 * da Conta", o formulario ficaria sem como salvar --, e o posicionamento
	 * deixou de valer: o botao caiu no fluxo, colado no fim da coluna.
	 * Agora e filho direto do form.
	 */
	.ao-form--conta-duo > .ao-form__submit {
		position: absolute;
		bottom: 0;
		left: 50%;
		transform: translateX(-50%);
		margin-top: 0;
	}
}

.ao-form--conta .ao-form__group > .ao-btn {
	margin-top: var(--ao-space-9);
}

/*
 * `.ao-avatar--conta` (o circulo azul decorativo do Figma 102942:2620) foi
 * removido daqui em 20/09: o upload de foto tomou o lugar dele em 17/09 e
 * nenhum PHP/JS emitia mais a classe -- eram 3 regras pintando um elemento
 * que nao existia. O que vale hoje e `.ao-dropzone--avatar` (mais abaixo).
 */

/*
 * Figma 102942:2622 — o rotulo fica sobre a borda do campo, recortando-a com
 * o fundo da pagina. Por isso o rotulo precisa vir depois do input no fluxo.
 */
.ao-field--float {
	position: relative;
	display: block;
	padding-top: var(--ao-space-2);
}

.ao-field--float .ao-input {
	height: 51px;
	border-color: var(--ao-grey-30);
	background: transparent;
	color: var(--ao-body);
}

.ao-field--float .ao-field__label {
	position: absolute;
	/*
	 * MEDIDO no navegador: no campo de SENHA o input mora dentro de
	 * `.ao-field__wrap`, que e `position: relative`. Um elemento posicionado
	 * pinta na camada dos descendentes posicionados, ACIMA dos blocos em
	 * fluxo normal -- nao importa que o rotulo venha antes no HTML. Resultado:
	 * a borda do input passava POR CIMA do rotulo e "Nova senha" aparecia
	 * riscado, enquanto os campos sem olho (Telefone, E-mail) recortavam a
	 * borda certo. O `z-index` traz o rotulo de volta para cima do wrapper.
	 */
	z-index: 1;
	top: 0;
	left: 18px;
	padding-inline: 7px 6px;
	background: var(--ao-page);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	font-weight: var(--ao-fw-regular);
	color: var(--ao-grey-30);
}

.ao-field--float .ao-field__req {
	margin-left: 0;
	color: inherit;
}

.ao-field--float .ao-field__hint {
	display: block;
	margin-top: var(--ao-space-2);
}

.ao-form__group {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-5);
	margin: 0;
	padding: 0;
	border: 0;
}

.ao-form__group + .ao-form__group {
	padding-top: var(--ao-space-8);
	border-top: 1px solid var(--ao-grey-10);
}

.ao-form__row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--ao-space-5);
	flex-wrap: wrap;
}

.ao-form__row--end {
	justify-content: flex-end;
}

.ao-form__actions {
	display: flex;
	align-items: center;
	gap: var(--ao-space-5);
	flex-wrap: wrap;
}

/*
 * No formulario de oferta as acoes empilham: o checkbox de publicar vem acima do
 * botao (pedido do usuario, 17/09). Lado a lado, a escolha de publicar disputava a
 * atencao com a acao de salvar, e a frase de apoio nao tinha onde caber.
 */
.ao-form--oferta .ao-form__actions {
	flex-direction: column;
	align-items: flex-start;
	gap: var(--ao-space-7);
	padding-top: var(--ao-space-4);
}


.ao-root .ao-form__submit {
	align-self: flex-start;
}

/* Figma 102942:1771 — o botao do login ocupa toda a coluna do formulario. */
.ao-root .ao-form__submit--block {
	align-self: stretch;
	width: 100%;
	border-radius: var(--ao-radius-card);
}

.ao-link--accent {
	color: var(--ao-accent);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	text-decoration: none;
}

@media (hover: hover) {
	.ao-link--accent:hover {
		text-decoration: underline;
	}
}

/* Figma 102942:1763 — no login o campo e mais baixo, com fundo cinza e raio maior. */
.ao-auth--split .ao-input {
	height: 40px;
	border-color: var(--ao-grey-10);
	border-radius: var(--ao-radius-card);
	background: var(--ao-page);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
}

.ao-auth--split .ao-field__label {
	font-weight: var(--ao-fw-regular);
	color: var(--ao-body);
}

.ao-field {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-2);
	margin: 0;
}

.ao-field__label {
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-body);
}

/*
 * O asterisco esta sempre no HTML e quem decide se aparece e o proprio campo.
 * No cadastro o `required` entra e sai com a troca de perfil; assim o rotulo
 * acompanha sozinho, sem o JS ter de mexer na marcacao.
 */
.ao-field__req {
	margin-left: var(--ao-space-1);
	color: var(--ao-accent);
}

/*
 * Sem `:has()` o asterisco fica visivel em todo campo — exagera, mas nao esconde
 * obrigatoriedade de ninguem, que seria o erro grave.
 */
@supports selector(.ao-field:has(.ao-input:required)) {
	.ao-field__req {
		display: none;
	}

	.ao-field:has(.ao-input:required) .ao-field__req {
		display: inline;
	}
}

.ao-field__hint {
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-muted);
}


.ao-input {
	width: 100%;
	height: var(--ao-btn-h);
	padding: 0 var(--ao-space-5);
	border: 1px solid var(--ao-grey-10);
	border-radius: var(--ao-radius-btn);
	background: var(--ao-white);
	color: var(--ao-body);
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
}

textarea.ao-input {
	height: auto;
	padding: var(--ao-space-4) var(--ao-space-5);
	resize: vertical;
}

.ao-input:focus-visible {
	outline: 2px solid var(--ao-primary);
	outline-offset: 2px;
}

/*
 * Estado de erro do campo.
 *
 * A borda muda de cor E a mensagem aparece em texto: cor sozinha nao chega a quem
 * nao a distingue. O slot .ao-field__erro existe sempre no HTML, vazio, para o
 * layout nao pular quando a mensagem entra.
 */
.ao-field.is-invalid .ao-input,
.ao-input[aria-invalid="true"] {
	border-color: var(--ao-danger);
}

.ao-field.is-invalid .ao-input:focus-visible {
	outline-color: var(--ao-danger);
}

.ao-field__erro {
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-danger);
}

.ao-field__erro:empty {
	display: none;
}

/*
 * Uma cidade de outro estado continua no <select> do cadastro, so escondida
 * pelo JS (ao-front.js, filtroCidadePorUf). Sem isto o Firefox ainda a desenha
 * na lista aberta, mesmo com o atributo `hidden`.
 */
.ao-select option[hidden] {
	display: none;
}

/*
 * Erro do servidor, no topo do formulario.
 *
 * Ele repete o que o campo ja diz quando a falha e de um campo so, mas cobre os
 * casos em que nao ha campo culpado ("Nao foi possivel criar a conta") e garante
 * que a mensagem exista sem JavaScript — antes o toast era a unica exibicao, e sem
 * script a pessoa via um recarregamento mudo.
 */
.ao-form__erro {
	display: flex;
	align-items: flex-start;
	gap: var(--ao-space-3);
	margin: 0 0 var(--ao-space-4);
	padding: var(--ao-space-4);
	border: 1px solid var(--ao-danger);
	border-radius: var(--ao-radius-card);
	background: color-mix(in srgb, var(--ao-danger) 8%, var(--ao-white));
	color: var(--ao-danger);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
}

/* Sem color-mix o fundo cai para branco: a borda e o texto ja identificam o erro. */
@supports not (background: color-mix(in srgb, red 8%, white)) {
	.ao-form__erro {
		background: var(--ao-white);
	}
}

.ao-form__erro-icone {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: var(--ao-danger);
	color: var(--ao-white);
	font-size: var(--ao-fs-body-2);
	font-weight: var(--ao-fw-bold);
	line-height: 1;
}

/*
 * Campo de senha com o olho de "mostrar". O wrapper so existe nesse tipo de campo,
 * entao os demais continuam filhos diretos de .ao-field e nada muda para eles.
 */
.ao-field__wrap {
	position: relative;
	display: block;
}

/* reserva o espaco do botao para o texto nao passar por baixo do icone */
.ao-input--senha {
	padding-right: var(--ao-space-10);
}

/* o Edge desenha o proprio olho e ficariam dois lado a lado */
.ao-input--senha::-ms-reveal,
.ao-input--senha::-ms-clear {
	display: none;
}

.ao-field__olho {
	position: absolute;
	top: 50%;
	right: var(--ao-space-3);
	transform: translateY(-50%);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 0;
	border-radius: var(--ao-radius-badge);
	background: transparent;
	color: var(--ao-muted);
	cursor: pointer;
}

@media (hover: hover) {
	.ao-field__olho:hover {
		color: var(--ao-primary);
	}
}

.ao-field__olho:focus-visible {
	outline: 2px solid var(--ao-primary);
	outline-offset: 2px;
}

.ao-field__olho-icone {
	display: block;
}

/* o [hidden] do user-agent nao vence a regra acima, entao a classe repete aqui */
.ao-field__olho-icone[hidden] {
	display: none;
}

/*
 * SUFIXO DENTRO DO CAMPO ("% off" no campo de desconto).
 *
 * OLHADO NA TELA, nao so medido: a primeira versao ancorava o sufixo em
 * `right` dentro do campo, e num campo de 525px o "% off" ficava no extremo
 * oposto do numero -- dois textos distantes que nao se liam como um valor so.
 *
 * A correcao NAO e encolher o input por `field-sizing: content`: isso so
 * existe em Chrome/Edge recentes, e no Firefox e no Safari o sufixo voltaria
 * para a borda -- a maioria continuaria vendo o problema. MEDIDO no Chromium
 * do Playwright: o input ficou com 469px e o sufixo encostado na direita,
 * exatamente o que se queria evitar.
 *
 * Tambem NAO e dar `max-width` ao campo: OLHADO NA TELA, o desconto virava um
 * toco de 176px ao lado de uma data de 625px, e a linha ficava torta.
 *
 * Quem estava errado era a COLUNA. O `.ao-form__duo` divide a linha 50/50, o
 * que serve para dois campos de texto e nao para "tres digitos" ao lado de uma
 * data. `.ao-form__duo--desconto` da a cada um a largura do seu conteudo, e o
 * campo continua preenchendo a propria coluna: as duas caixas terminam
 * alinhadas e o "% off" encosta no numero em qualquer navegador.
 *
 * A BORDA passa para o wrapper: mantida no input, desenharia um retangulo so
 * em volta do numero, com o "% off" solto do lado de fora.
 */
.ao-field__wrap:has(.ao-field__sufixo) {
	display: flex;
	align-items: center;
	/*
	 * A largura mora AQUI, e nao so na coluna do `.ao-form__duo`: o campo de
	 * fim de semana nasce sozinho, fora do duo, e sem isto voltava a ocupar os
	 * 1080px da linha -- com o "% off" de novo no extremo direito.
	 */
	width: 11rem;
	max-width: 100%;
	height: 51px;
	padding-right: var(--ao-space-5);
	border: 1px solid var(--ao-grey-30);
	border-radius: var(--ao-radius-btn);
}

.ao-input--com-sufixo {
	flex: 1 1 auto;
	min-width: 0;
	height: 100%;
	padding-right: var(--ao-space-2);
	border: 0;
	background: transparent;
	-moz-appearance: textfield;
	appearance: textfield;
}

.ao-field__sufixo {
	flex: 0 0 auto;
	pointer-events: none;
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	color: var(--ao-muted);
}

/* Spinners fora: empurrariam o sufixo a cada hover, e uma faixa de 1 a 100
   nao se navega de um em um. */
.ao-input--com-sufixo::-webkit-outer-spin-button,
.ao-input--com-sufixo::-webkit-inner-spin-button {
	margin: 0;
	-webkit-appearance: none;
	appearance: none;
}

/*
 * Foco e erro seguem a borda: com ela no wrapper, as regras que miram
 * `.ao-input` (`:focus-visible`, `.is-invalid`) passariam a desenhar o anel e
 * o vermelho em volta do numero, nao do campo. O `:has()` repete os dois
 * estados no lugar certo, e a especificidade ganha do `.ao-input`.
 */
.ao-input--com-sufixo:focus,
.ao-input--com-sufixo:focus-visible {
	outline: 0;
}

.ao-field__wrap:has(.ao-input--com-sufixo:focus-visible) {
	outline: 2px solid var(--ao-primary);
	outline-offset: 2px;
}

.ao-field.is-invalid .ao-input--com-sufixo,
.ao-input--com-sufixo[aria-invalid="true"] {
	border: 0;
}

.ao-field.is-invalid .ao-field__wrap:has(.ao-input--com-sufixo),
.ao-field__wrap:has(.ao-input--com-sufixo[aria-invalid="true"]) {
	border-color: var(--ao-danger);
}

.ao-field.is-invalid .ao-field__wrap:has(.ao-input--com-sufixo:focus-visible) {
	outline-color: var(--ao-danger);
}

/* --------------------------------------------------------------------------
   Campo de data — caixa com o icone do calendario

   O icone e um <button> que ABRE o calendario, entao ganha alvo de toque de
   40px, e nao os `pointer-events: none` de um enfeite. Mesma anatomia do olho
   de senha: a borda mora no `.ao-field__wrap` e o input interno fica sem borda,
   para o retangulo envolver campo e icone — nao so o texto.
   `[REF:paginas-conecta pc-components.css:2687]`
   -------------------------------------------------------------------------- */

.ao-field__wrap:has(.ao-input--com-icone) {
	position: relative;
	display: block;
	height: 51px;
	border: 1px solid var(--ao-grey-30);
	border-radius: var(--ao-radius-btn);
}

.ao-input--com-icone {
	height: 100%;
	/* Reserva o espaco do botao: sem isto a data digitada passa por baixo dele. */
	padding-right: var(--ao-space-10);
	border: 0;
	background: transparent;
}

.ao-field__icone-botao {
	position: absolute;
	top: 50%;
	right: var(--ao-space-2);
	transform: translateY(-50%);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: var(--ao-grey-30);
	cursor: pointer;
}

@media (hover: hover) {
	.ao-field__icone-botao:hover {
		color: var(--ao-primary);
	}
}

.ao-field__icone-botao:focus-visible {
	outline: 2px solid var(--ao-primary);
	outline-offset: 2px;
}

.ao-field__icone {
	display: block;
	width: 20px;
	height: 20px;
	/* O clique precisa chegar no <button>, nunca no <svg>. */
	pointer-events: none;
}

/*
 * Foco e erro seguem a borda, que agora mora no wrapper — pelo mesmo motivo do
 * campo com sufixo: as regras que miram `.ao-input` desenhariam o anel em volta
 * do texto, deixando o icone de fora.
 */
.ao-input--com-icone:focus,
.ao-input--com-icone:focus-visible {
	outline: 0;
}

.ao-field__wrap:has(.ao-input--com-icone:focus-visible) {
	outline: 2px solid var(--ao-primary);
	outline-offset: 2px;
}

.ao-field.is-invalid .ao-input--com-icone,
.ao-input--com-icone[aria-invalid="true"] {
	border: 0;
}

.ao-field.is-invalid .ao-field__wrap:has(.ao-input--com-icone),
.ao-field__wrap:has(.ao-input--com-icone[aria-invalid="true"]) {
	border-color: var(--ao-danger);
}

.ao-field.is-invalid .ao-field__wrap:has(.ao-input--com-icone:focus-visible) {
	outline-color: var(--ao-danger);
}

/* --------------------------------------------------------------------------
   O calendario (montado por ao-painel.js dentro da gaveta compartilhada)

   Nao e ancorado ao campo: fundo, Esc, arraste e animacao vem do `.ao-drawer`,
   que no celular e folha e no desktop vira modal. Aqui fica so o conteudo.
   `[REF:paginas-conecta pc-components.css:2745]`
   -------------------------------------------------------------------------- */

.ao-drawer--calendario .ao-drawer__corpo {
	padding-bottom: var(--ao-space-5);
}

.ao-calendario__cabecalho {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: var(--ao-space-2);
}

/*
 * Nas visoes de dias e meses o titulo e um <button> que sobe um nivel
 * (mes -> ano), como no seletor nativo; na visao de anos vira <span>, porque
 * nao ha nivel acima. As duas formas dividem esta regra.
 */
.ao-calendario__titulo {
	/* Nomes de mes tem larguras bem diferentes (maio x fevereiro); centralizar
	   num flex de 3 itens evita a seta "pular" de lugar ao navegar. */
	flex: 1;
	padding: var(--ao-space-2) var(--ao-space-1);
	border: 0;
	border-radius: var(--ao-radius-btn);
	background: transparent;
	font-family: inherit;
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-semibold);
	color: var(--ao-body);
	text-align: center;
	text-transform: capitalize;
}

button.ao-calendario__titulo {
	cursor: pointer;
}

@media (hover: hover) {
	button.ao-calendario__titulo:hover {
		background: var(--ao-page);
	}
}

/* 44px: alvo de toque cheio — navegar entre meses e o gesto mais repetido aqui. */
.ao-calendario__nav {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: var(--ao-muted);
	cursor: pointer;
}

@media (hover: hover) {
	.ao-calendario__nav:hover {
		background: var(--ao-page);
		color: var(--ao-body);
	}
}

/* A mesma seta do chevron (que aponta para baixo), girada para virar
   esquerda/direita. */
.ao-calendario__nav svg {
	width: 12px;
	height: 8px;
	transform: rotate(-90deg);
	pointer-events: none;
}

.ao-calendario__nav--anterior svg {
	transform: rotate(90deg);
}

.ao-calendario__semana,
.ao-calendario__grade {
	display: grid;
	grid-template-columns: repeat(7, 1fr);
	gap: var(--ao-space-1);
}

/* Meses e anos: 4 colunas (12 itens em 3 linhas). Os rotulos sao palavras
   ("set", "2027"), nao numeros de 2 digitos — 7 colunas nao caberiam. */
.ao-calendario__grade--meses {
	grid-template-columns: repeat(4, 1fr);
	gap: var(--ao-space-2);
}

/* Celula de mes/ano: pill larga, nao o circulo dos dias — o conteudo e texto. */
.ao-calendario__celula {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	padding: 0 var(--ao-space-1);
	border: 0;
	border-radius: var(--ao-radius-pill);
	background: transparent;
	font-family: inherit;
	font-size: var(--ao-fs-body-2);
	color: var(--ao-body);
	text-transform: capitalize;
	cursor: pointer;
}

@media (hover: hover) {
	.ao-calendario__celula:hover:not(:disabled) {
		background: var(--ao-page);
	}
}

.ao-calendario__semana {
	margin-bottom: var(--ao-space-1);
}

.ao-calendario__semana span {
	padding: 6px 0;
	font-size: 12px;
	font-weight: var(--ao-fw-semibold);
	color: var(--ao-muted);
	text-align: center;
}

.ao-calendario__dia {
	display: flex;
	align-items: center;
	justify-content: center;
	/* Quadrado que acompanha a coluna: mantem a grade regular em qualquer
	   largura de gaveta, sem cravar px. */
	aspect-ratio: 1;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	font-family: inherit;
	font-size: 15px;
	color: var(--ao-body);
	cursor: pointer;
}

@media (hover: hover) {
	.ao-calendario__dia:hover:not(:disabled) {
		background: var(--ao-page);
	}
}

/* Dias do mes vizinho ficam visiveis (a semana nao pode ter buraco), mas
   apagados para nao competirem com o mes atual. */
.ao-calendario__dia--fora {
	color: var(--ao-subtle);
}

.ao-calendario__dia--hoje {
	font-weight: var(--ao-fw-bold);
	box-shadow: inset 0 0 0 1px var(--ao-grey-30);
}

/* Vale para dia, mes e ano: tudo que ja passou e a oferta nao alcancaria. */
.ao-calendario__dia--indisponivel {
	color: var(--ao-grey-10);
	cursor: default;
}

.ao-calendario__dia.is-selecionado,
.ao-calendario__celula.is-selecionado {
	background: var(--ao-primary);
	color: var(--ao-white);
	font-weight: var(--ao-fw-semibold);
}

.ao-calendario__nav:focus-visible,
.ao-calendario__dia:focus-visible,
.ao-calendario__celula:focus-visible,
button.ao-calendario__titulo:focus-visible {
	outline: 2px solid var(--ao-primary);
	outline-offset: 2px;
}

.ao-input::placeholder {
	color: var(--ao-subtle);
}

.ao-select {
	appearance: none;
	padding-right: var(--ao-space-10);
	background-image: linear-gradient(45deg, transparent 50%, var(--ao-muted) 50%), linear-gradient(135deg, var(--ao-muted) 50%, transparent 50%);
	background-position: calc(100% - 20px) 50%, calc(100% - 15px) 50%;
	background-size: 5px 5px, 5px 5px;
	background-repeat: no-repeat;
}

.ao-coupon {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--ao-space-2);
	padding: var(--ao-space-10) var(--ao-space-7);
	background: var(--ao-page);
	border: 1px dashed var(--ao-primary);
	border-radius: var(--ao-radius-card);
	text-align: center;
}

.ao-coupon__label {
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-muted);
}

.ao-coupon__code {
	font-size: var(--ao-fs-h1);
	line-height: var(--ao-lh-h1);
	font-weight: var(--ao-fw-extrabold);
	color: var(--ao-primary);
	word-break: break-all;
}

.ao-coupon__offer {
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-body);
}

.ao-coupon__meta {
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-muted);
}

.ao-validate {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-8);
}

.ao-validate__form {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-2);
	padding: var(--ao-space-10);
	background: var(--ao-white);
	border-radius: var(--ao-radius-card);
}

.ao-validate__row {
	display: flex;
	align-items: center;
	gap: var(--ao-space-4);
	flex-wrap: wrap;
}

/*
 * A CAIXA do codigo — e ela que tem a borda, nao o <input>.
 *
 * O botao da camera mora dentro do campo, encostado a direita. Para que ele
 * pareca parte do controle (e nao um botao solto por cima), a borda e o fundo
 * migraram do input para este wrapper, e o input ficou transparente. O foco
 * acende a caixa inteira via `:focus-within`.
 */
.ao-validate__campo {
	position: relative;
	display: flex;
	align-items: center;
	/* No desktop a caixa divide a linha com o botao "Validar", como antes: o
	   `1 1 60%` era do input e passa para o wrapper, que agora e o filho
	   direto da `.ao-validate__row`. */
	flex: 1 1 60%;
	min-width: 0;

	/* Mesma moldura que o `.ao-input` desenhava (`:1048`), so que agora no
	   wrapper — o input a perde logo abaixo para nao duplicar. */
	background: var(--ao-white);
	border: 1px solid var(--ao-grey-10);
	border-radius: var(--ao-radius-btn);
}

.ao-validate__campo:focus-within {
	outline: 2px solid var(--ao-primary);
	outline-offset: 2px;
}

.ao-validate__input {
	flex: 1 1 auto;
	min-width: 0;
	height: var(--ao-btn-h);
	font-size: var(--ao-fs-h2);
	line-height: var(--ao-lh-h2);
	font-weight: var(--ao-fw-bold);
	letter-spacing: 4px;
	text-transform: uppercase;

	/*
	 * A borda agora e do wrapper. O input perde a propria para nao desenhar
	 * uma segunda moldura por dentro, e perde o outline de foco porque quem
	 * mostra o foco e a caixa (`:focus-within` acima).
	 */
	background: transparent;
	border: 0;
}

.ao-validate__input:focus,
.ao-validate__input:focus-visible {
	outline: 0;
	box-shadow: none;
}

/*
 * O botao da camera. 44x44 — o alvo de toque minimo; abaixo disso o dedo
 * erra, e este botao fica a milimetros do campo de texto.
 *
 * Nasce `hidden` no PHP e so aparece quando o JS confirma camera disponivel,
 * entao nao ha estado "botao morto".
 */
.ao-validate__camera {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	margin-inline-end: var(--ao-space-2);
	padding: 0;
	background: none;
	border: 0;
	border-radius: 50%;
	color: var(--ao-primary);
	cursor: pointer;
}

.ao-validate__camera:hover {
	background: var(--ao-grey-10);
}

.ao-validate__camera[hidden] {
	display: none;
}

.ao-validate__camera-icone {
	width: 22px;
	height: 22px;
}

/* ==========================================================================
   Leitor de QR code — camada sobre a tela
   Nao esta no Figma (o QR so aparece do lado do consumidor, `102942:2733`);
   e a contraparte de leitura que o usuario pediu em 20/09.
   `[DECISÃO:2026-09-20]`
   ========================================================================== */

.ao-scan {
	position: fixed;
	inset: 0;
	z-index: 1000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--ao-space-5);

	/* Preto quase opaco: a imagem da camera e o unico ponto de atencao, e o
	   contraste ajuda a enxergar a tela do celular do cliente. */
	background: rgba(0, 0, 0, .92);
}

.ao-scan[hidden] {
	display: none;
}

.ao-scan__janela {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-5);
	width: min(100%, 480px);
}

.ao-scan__topo {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--ao-space-4);
}

.ao-scan__titulo {
	margin: 0;
	color: var(--ao-white);
	font-size: var(--ao-fs-h3);
	line-height: var(--ao-lh-h3);
}

/* 44px de alvo, como o botao da camera — o dedo precisa achar o "fechar"
   sem mirar. */
.ao-scan__fechar {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	background: none;
	border: 0;
	color: var(--ao-white);
	font-size: 32px;
	line-height: 1;
	cursor: pointer;
}

/*
 * O palco tem proporcao quadrada: o QR tambem e, e assim a mira ocupa o
 * maximo da area util em qualquer orientacao, sem barra preta.
 */
.ao-scan__palco {
	position: relative;
	aspect-ratio: 1;
	overflow: hidden;
	background: #000;
	border-radius: var(--ao-radius-card);
}

.ao-scan__video {
	display: block;
	width: 100%;
	height: 100%;

	/* `cover` para a imagem preencher o quadrado; o recorte nao atrapalha
	   porque a mira ja pede o QR no centro. */
	object-fit: cover;
}

/*
 * A mira: um quadrado vazado no centro, so contorno. Serve de alvo para o
 * anunciante, nao de recorte — a leitura acontece no quadro inteiro, entao
 * um QR fora da mira tambem e lido. E orientacao, nao restricao.
 */
.ao-scan__mira {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 62%;
	aspect-ratio: 1;
	transform: translate(-50%, -50%);
	border: 3px solid var(--ao-white);
	border-radius: var(--ao-radius-card);

	/* O veu escurece o que esta FORA da mira, sem uma segunda caixa: uma
	   sombra gigante e solida faz o papel. */
	box-shadow: 0 0 0 9999px rgba(0, 0, 0, .45);
}

.ao-scan__dica {
	margin: 0;
	color: var(--ao-white);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	text-align: center;
}

/* O erro (camera negada, sem suporte) fala mais alto que a dica neutra. */
.ao-scan__dica--erro {
	color: var(--ao-danger);
	font-weight: var(--ao-fw-bold);
}

.ao-validate__result {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-4);
	padding: var(--ao-space-10);
	border-radius: var(--ao-radius-card);
	border-left: 8px solid transparent;
	background: var(--ao-white);
}

.ao-validate__result:focus-visible {
	outline: 2px solid var(--ao-primary);
	outline-offset: 2px;
}

.ao-validate__result--ok {
	border-left-color: var(--ao-success);
	background: var(--ao-success-bg);
}

.ao-validate__result--erro {
	border-left-color: var(--ao-danger);
}

.ao-validate__title {
	margin: 0;
	font-size: var(--ao-fs-h2);
	line-height: var(--ao-lh-h2);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-body);
}

.ao-validate__result--ok .ao-validate__title {
	color: var(--ao-success);
}

.ao-validate__result--erro .ao-validate__title {
	color: var(--ao-danger);
}

.ao-validate__text {
	margin: 0;
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	color: var(--ao-body);
}

.ao-validate__meta {
	display: flex;
	gap: var(--ao-space-10);
	margin: 0;
	flex-wrap: wrap;
}

.ao-validate__meta dt {
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-muted);
}

.ao-validate__meta dd {
	margin: 0;
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-ink);
}

/* O codigo e o que o operador cruza com o papel na mao: monospace para conferir
   caractere a caractere, sem 0/O nem 1/l se confundindo na Poppins. */
.ao-validate__historico-codigo {
	font-family: ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace;
	font-weight: var(--ao-fw-bold);
	letter-spacing: 1px;
}

/* ==========================================================================
   Cupom no modo historico — ja validado
   A mesma pagina do cupom, sem o que so serve para resgatar. O selo responde a
   pergunta que traz a pessoa aqui: foi aceito? quando? Ver D34 em `docs/09`.
   ========================================================================== */
.ao-cupom-historico {
	display: flex;
	align-items: flex-start;
	gap: var(--ao-space-4);
	padding: var(--ao-space-6) var(--ao-space-8);
	border-radius: var(--ao-radius-card);
	background: color-mix(in srgb, var(--ao-primary) 6%, var(--ao-white));
	border-left: 8px solid var(--ao-primary);
}

.ao-cupom-historico__icone {
	display: inline-flex;
	flex: none;
	color: var(--ao-primary);
}

.ao-cupom-historico__texto {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-1);
}

.ao-cupom-historico__titulo {
	margin: 0;
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-primary);
}

.ao-cupom-historico__meta {
	margin: 0;
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-muted);
}

/* O codigo perde o destaque: nao vale mais nada no balcao, e mante-lo em 48px
   navy convidaria a tentar usar de novo. */
.ao-coupon--historico .ao-coupon__code {
	color: var(--ao-muted);
}

/* Impresso, o modo historico nao e um voucher — e um comprovante. Sem o aviso
   de rodape que promete desconto. */
@media print {
	.ao-cupom-view--historico .ao-print-foot__aviso {
		display: none;
	}
}

/* Figma 102942:2091 / 102942:2092 — o titulo do painel e cinza, nao navy. */
.ao-panel__title {
	color: var(--ao-grey-70);
}

.ao-panel__lead {
	color: var(--ao-muted);
}

.ao-panel__lead strong {
	font-weight: var(--ao-fw-bold);
}

/* Figma 102942:2125 — a tabela mora dentro de um cartao branco com titulo. */
.ao-table-card {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-8);
	padding-block: var(--ao-space-7);
	background: var(--ao-white);
	border: 1px solid var(--ao-subtle);
	border-radius: var(--ao-radius-card);
}

.ao-table-card__title {
	margin: 0;
	padding-inline: var(--ao-space-7);
	font-size: var(--ao-fs-h3);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-grey-70);
}

/* .ao-visually-hidden e absoluta: sem contexto ela mede a partir da pagina e
   estica o documento no mobile. */
.ao-table th {
	position: relative;
}

.ao-table-card .ao-table-wrap {
	border-radius: 0;
}

.ao-table-card .ao-table thead th:first-child,
.ao-table-card .ao-table thead th:last-child {
	border-radius: 0;
}

/* Figma 102942:2137 — miniatura de 60 + nome e segmento empilhados. */
.ao-table__oferta {
	display: flex;
	align-items: center;
	gap: var(--ao-space-7);
}

.ao-table__thumb {
	flex: none;
	display: block;
	width: 60px;
	height: 60px;
	overflow: hidden;
	background: var(--ao-grey-10);
}

.ao-table__thumb img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.ao-table__oferta-text {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-3);
	min-width: 0;
}

.ao-table__oferta-nome {
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-regular);
	color: var(--ao-grey-70);
}

.ao-table__oferta-seg {
	font-size: var(--ao-fs-body-2);
	line-height: 1.5;
	font-weight: var(--ao-fw-bold);
	color: var(--ao-subtle);
}

.ao-root .ao-table__label {
	font-weight: var(--ao-fw-regular);
}

.ao-table__expira {
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	white-space: nowrap;
}

/*
 * [DECISÃO:2026-09-16] As tres acoes soltas de `102942:2146` viraram um menu de
 * tres pontos: a coluna passa a ter cabecalho "Acoes" visivel e um so alvo por
 * linha. O Figma nao desenha esse menu — ver D18/D29.
 */
.ao-table__acoes-col {
	width: 1%;
	white-space: nowrap;
	text-align: center;
}

.ao-table__actions {
	gap: var(--ao-space-8);
}

/* O painel e posicionado em relacao a celula. */
.ao-acoes {
	position: relative;
	display: inline-flex;
	justify-content: center;
}

.ao-acoes__toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 0;
	border-radius: var(--ao-radius-8, 8px);
	background: transparent;
	color: var(--ao-grey-70);
	cursor: pointer;
}

.ao-acoes__toggle:hover,
.ao-acoes[data-ao-dropdown-ready].is-open .ao-acoes__toggle {
	background: var(--ao-grey-10, #f2f4f7);
	color: var(--ao-primary);
}

.ao-acoes__icone {
	flex: none;
	width: 20px;
	height: 20px;
}

/*
 * `display: flex` numa regra de classe vence o `display: none` que o navegador
 * da ao [hidden] — sem isto os tres menus nascem abertos sobre a tabela.
 */
.ao-acoes[data-ao-dropdown-ready] .ao-acoes__painel[hidden] {
	display: none;
}

.ao-acoes__painel {
	position: absolute;
	top: calc(100% + 4px);
	right: 0;
	z-index: 20;
	display: flex;
	flex-direction: column;
	min-width: 168px;
	padding: var(--ao-space-2, 8px) 0;
	border: 1px solid var(--ao-grey-20, #e4e7ec);
	border-radius: var(--ao-radius-8, 8px);
	background: #fff;
	box-shadow: 0 12px 24px rgb(16 24 40 / 12%);
	text-align: left;
}

/*
 * Sem [data-ao-dropdown-ready] o JS nao rodou: o painel fica visivel pelo
 * proprio [hidden] do HTML e as acoes continuam alcancaveis.
 */
.ao-acoes[data-ao-dropdown-ready] .ao-acoes__painel {
	opacity: 0;
	transform: translateY(-4px);
	transition: opacity 160ms ease, transform 160ms ease;
}

.ao-acoes[data-ao-dropdown-ready].is-open .ao-acoes__painel {
	opacity: 1;
	transform: translateY(0);
}

.ao-root .ao-acoes__painel form {
	margin: 0;
}

.ao-acoes__item {
	display: block;
	width: 100%;
	padding: var(--ao-space-2, 8px) var(--ao-space-4, 16px);
	border: 0;
	background: transparent;
	color: var(--ao-grey-70);
	font-family: var(--ao-font);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	text-align: left;
	text-decoration: none;
	cursor: pointer;
}

.ao-acoes__item:hover,
.ao-acoes__item:focus-visible {
	background: var(--ao-grey-10, #f2f4f7);
	color: var(--ao-primary);
}

.ao-acoes__item--danger:hover,
.ao-acoes__item--danger:focus-visible {
	color: var(--ao-danger);
}

@media (prefers-reduced-motion: reduce) {
	.ao-acoes[data-ao-dropdown-ready] .ao-acoes__painel {
		transition: none;
	}
}

.ao-table__action {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 20px;
	height: 20px;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--ao-grey-70);
	font-family: var(--ao-font);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	text-decoration: none;
	cursor: pointer;
}

@media (hover: hover) {
	.ao-table__action:hover {
		color: var(--ao-accent);
	}
}

@media (hover: hover) {
	.ao-table__action--danger:hover {
		color: var(--ao-danger);
	}
}

/* o SVG do tema nao traz width: sem tamanho explicito ele ocupa a celula. */
.ao-table__action-icon {
	flex: none;
	width: 20px;
	height: 20px;
}

.ao-table__action-text {
	white-space: nowrap;
}

@media (max-width: 1023.98px) {
	.ao-panel__content {
		width: 100%;
		min-width: 0;
	}

	.ao-table-card {
		min-width: 0;
	}

	.ao-table-wrap {
		max-width: 100%;
	}

	/* a tabela rola dentro do wrap em vez de esticar o documento */
	.ao-table {
		min-width: 600px;
	}

	/*
	 * Aqui a tabela nao cabe (min-width 600) e PRECISA rolar: o `clip` do
	 * desktop deixaria as colunas da direita inalcancaveis. Volta o scroll —
	 * e com ele o recorte no eixo Y, que o JS libera com o menu aberto.
	 */
	.ao-table-wrap {
		overflow-x: auto;
		overflow-y: auto;
		overflow-clip-margin: 0;
	}

	.ao-table-wrap.has-menu-aberto {
		overflow: visible;
	}

	.ao-panel__inner {
		flex-direction: column;
	}

	.ao-panel__aside,
	.ao-auth__card,
	.ao-withdraw__card {
		flex-basis: auto;
		width: 100%;
	}

	/*
	 * Sem largura para as duas colunas de 680, o painel da marca vai para cima e o
	 * formulario ocupa a linha inteira — mantendo os 323px do Figma como teto.
	 */
	.ao-auth--split {
		min-height: 0;
		padding: var(--ao-space-6);
	}

	.ao-auth--split .ao-auth__inner {
		flex-direction: column-reverse;
	}

	.ao-auth--split .ao-auth__card {
		max-width: none;
		padding-block: var(--ao-space-10);
	}

	.ao-auth__art {
		flex-basis: auto;
		align-self: auto;
		min-height: 220px;
	}
}

/* ==========================================================================
   Mobile — 767.98px
   O Figma so desenha o desktop 1440 (lacuna A7), entao tudo daqui e decisao
   de implementacao. `[DECISÃO:2026-09-20]`
   ========================================================================== */

@media (max-width: 767.98px) {
	/*
	 * Abaixo de 768 a tabela de 600px de largura minima nao cabe em tela
	 * nenhuma, e rolar na horizontal escondia Status/Expira/Acoes — colunas que
	 * o anunciante precisa ver. Cada linha vira um cartao.
	 *
	 * A PRIMEIRA versao (20/09) empilhava as 4 celulas como pares
	 * rotulo/valor, copiando "Meus Cupons" (`.ao-vouchers__table`, bloco
	 * abaixo). Testado no aparelho, ficou ruim: tres linhas cheias para tres
	 * dados curtos, e "Acoes  ⋮" — um rotulo de 6 letras para anunciar UM
	 * botao de icone — era o pior deles. O padrao rotulo/valor serve quando ha
	 * muitas colunas de texto parecido (o caso dos cupons: codigo, oferta,
	 * data, estabelecimento); aqui sao dois fatos e um menu.
	 *
	 * O cartao agora tem cabecalho e rodape, e o grid faz todo o trabalho sem
	 * tocar no HTML — a `<tr>` vira um grid de 2 colunas e cada `<td>` e
	 * posicionado por `grid-area`:
	 *
	 *     ┌──────────────────────────┐
	 *     │ [img] Nome da oferta   ⋮ │   .ao-table__label     +  .ao-table__acoes-col
	 *     │       Restaurantes       │
	 *     │ ──────────────────────── │
	 *     │ ● Disponivel  Expira 04/11 │ (badge)               +  .ao-table__expira
	 *     └──────────────────────────┘
	 *
	 * `[DECISÃO:2026-09-20]` — o Figma nao desenha mobile (lacuna A7).
	 */
	/*
	 * Desmontar a tabela vale para AS DUAS do painel (ofertas e "Vouchers
	 * validados"): nenhuma cabe em 375px. O que muda entre elas e so o
	 * desenho do cartao, mais abaixo.
	 */
	.ao-table,
	.ao-table tbody,
	.ao-table tr,
	.ao-table td {
		display: block;
	}

	.ao-table {
		min-width: 0;
	}

	/* Sem colunas, o cabecalho nao tem o que rotular. */
	.ao-table thead {
		display: none;
	}

	/* Volta a recortar: sem tabela larga, o scroll horizontal so atrapalharia
	   o menu de acoes, que precisa transbordar. */
	.ao-table-wrap {
		overflow: visible;
	}

	/*
	 * CARTAO DENTRO DE CARTAO — o de fora se dissolve.
	 *
	 * `.ao-table-card` e a moldura branca da TABELA: no desktop ela enquadra
	 * as linhas e o cabecalho azul. No celular as linhas ja viraram cartoes
	 * individuais, e a moldura virou um segundo contorno em volta deles —
	 * branco sobre branco, com 1px cinza de cada lado. Pedido do usuario
	 * (20/09): as ofertas ficam soltas, cada uma no seu cartao.
	 * `[DECISÃO:2026-09-20]`
	 *
	 * So onde a tabela VIROU cartao. Em "Vouchers validados" o `.ao-table-card`
	 * carrega o titulo da secao e continua sendo a caixa dela.
	 *
	 * A distincao vem de uma classe no PHP (`--solto`) e nao de `:has()`: o
	 * markup e nosso, entao nao ha motivo para depender do suporte ao seletor
	 * — e um `:has()` que falha deixaria o cartao duplo de volta, sem aviso.
	 */
	.ao-table-card--solto {
		padding: 0;
		background: none;
		border: 0;
		border-radius: 0;
	}

	/*
	 * `tabela_ofertas()` tambem roda no painel-resumo, e la recebe titulo
	 * ("Minhas Ofertas"). Sem o recuo do cartao, o `<h2>` encostaria na borda
	 * da tela — o titulo perde a caixa, nao o alinhamento.
	 */
	.ao-table-card--solto > .ao-table-card__title {
		padding-inline: 0;
	}

	/*
	 * A OUTRA `.ao-table` do painel — "Vouchers validados"
	 * (`class-ao-front-validacao.php:279`) — continua no padrao rotulo/valor.
	 *
	 * Ali ele e o certo: tres colunas de texto parecido (codigo, oferta,
	 * data) que, sem rotulo, viram tres linhas indistinguiveis. O cartao de
	 * cabecalho/rodape das ofertas so funciona porque la ha uma miniatura, um
	 * badge colorido e um menu — tres formas diferentes, cada uma legivel
	 * sozinha. Por isso a reforma ficou escopada em `.ao-table--ofertas` e
	 * este bloco preserva o comportamento anterior, sem mudanca.
	 */
	.ao-table:not(.ao-table--ofertas) tbody tr {
		margin-bottom: var(--ao-space-5);
		padding: var(--ao-space-5);
		background: var(--ao-white);
		border: 1px solid var(--ao-grey-10);
		border-radius: var(--ao-radius-card);
	}

	.ao-table:not(.ao-table--ofertas) tbody tr:last-child {
		margin-bottom: 0;
	}

	.ao-table:not(.ao-table--ofertas) tbody td {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		justify-content: space-between;
		gap: var(--ao-space-4);
		height: auto;
		padding: 0;
		padding-block: var(--ao-space-2);
		text-align: right;
	}

	.ao-table:not(.ao-table--ofertas) tbody td::before {
		content: attr(data-rotulo);
		flex: 0 0 auto;
		font-weight: var(--ao-fw-bold);
		color: var(--ao-black);
		text-align: left;
	}

	/*
	 * A primeira celula e o titulo do cartao (no historico, o codigo do
	 * voucher): sem rotulo e com uma divisoria separando-a do resto.
	 */
	.ao-table:not(.ao-table--ofertas) tbody td.ao-table__label::before {
		display: none;
	}

	.ao-table:not(.ao-table--ofertas) tbody td.ao-table__label {
		margin-bottom: var(--ao-space-2);
		padding-bottom: var(--ao-space-4);
		border-bottom: 1px solid var(--ao-grey-10);
		text-align: left;
	}

	/*
	 * O `grid` reordena as celulas sem mexer na ordem do DOM (que continua
	 * sendo a ordem das colunas do desktop): a de acoes sobe para o topo e a
	 * de status desce para o rodape, ao lado da data.
	 *
	 * `auto` na primeira coluna deixa o miolo (nome/segmento) tomar o que
	 * sobra; a segunda encolhe ate o conteudo — o botao de 32px em cima, a
	 * data em baixo.
	 */
	/*
	 * O cartao e um grid de 2 colunas x 2 linhas, mas as duas linhas tem
	 * necessidades opostas de largura, e uma unica grade nao serve as duas:
	 *
	 *   - em cima, o NOME quer toda a largura e o menu e um botao de 32px;
	 *   - embaixo, a DATA precisa de ~130px e os badges ficam com o resto.
	 *
	 * Tentativa 1: status e data na MESMA area, separados por `justify-self`.
	 * Colidiram assim que a marca de banner entrou ao lado de "Disponivel" —
	 * "No banner" correu por cima de "Expira 04/11/2026". Compartilhar area so
	 * nao colide por sorte de largura.
	 *
	 * Tentativa 2: areas separadas na mesma grade. A coluna da direita passou
	 * a ser dimensionada pela DATA (a mais larga das duas celulas dela) e
	 * estrangulou o nome da oferta la em cima: "Rodizio de massas par…".
	 *
	 * Solucao: o rodape sai da grade. A linha de cima continua sendo o grid
	 * (nome + menu) e o rodape vira uma faixa de largura cheia, com os proprios
	 * `flex`. Assim nenhuma coluna e compartilhada entre linhas de necessidade
	 * diferente.
	 */
	.ao-table--ofertas tbody tr {
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto;
		grid-template-areas:
			'oferta acoes'
			'status status'
			'expira expira';
		align-items: start;
		column-gap: var(--ao-space-4);
		margin-bottom: var(--ao-space-4);
		padding: var(--ao-space-4);
		background: var(--ao-white);
		border: 1px solid var(--ao-grey-10);
		border-radius: var(--ao-radius-card);
	}

	/*
	 * COMPACTAR — pedido do usuario (20/09): "esta com muita linha".
	 *
	 * Medido em 390px: o cartao tinha 158px de altura, e tres deles ja nao
	 * cabiam numa tela com o header e a barra inferior. Os gastos eram a
	 * miniatura de 60px, o nome em duas linhas com entrelinha de titulo, e os
	 * respiros de 20px em cada junta.
	 *
	 * O nome fica em DUAS linhas no maximo: cortar na primeira esconderia
	 * ofertas cujo nome so se distingue no fim ("Almoco executivo de terca a
	 * sexta" x "... de sabado"). Duas linhas cobrem os nomes reais do seed.
	 */
	.ao-table--ofertas .ao-table__oferta {
		gap: var(--ao-space-4);
		align-items: center;
	}

	.ao-table--ofertas .ao-table__thumb {
		width: 48px;
		height: 48px;
		flex: 0 0 48px;
		border-radius: var(--ao-radius-btn);
		overflow: hidden;
	}

	.ao-table--ofertas .ao-table__oferta-nome {
		display: -webkit-box;
		-webkit-line-clamp: 2;
		-webkit-box-orient: vertical;
		overflow: hidden;
		font-size: var(--ao-fs-body-1);
		line-height: 1.35;
	}

	.ao-table--ofertas .ao-table__oferta-seg {
		font-size: var(--ao-fs-body-2);
		line-height: 1.3;
	}

	.ao-table--ofertas tbody tr:last-child {
		margin-bottom: 0;
	}

	/*
	 * `border: 0` — a `<td>` do tema tem borda inferior (`ao-components.css`,
	 * a divisoria entre linhas da tabela). No cartao ela virava um risco solto
	 * sob o segmento e sob a data, como se o texto estivesse sublinhado.
	 * Quem desenha divisoria aqui e o rodape, e so ele.
	 */
	.ao-table--ofertas tbody td {
		height: auto;
		padding: 0;
		border: 0;
	}

	/*
	 * O par rotulo/valor sai de cena: o nome e a miniatura se explicam, o
	 * badge de status se explica pela cor e pela palavra, e a data recebe um
	 * prefixo proprio mais abaixo (`data-prefixo`). Um `::before` com o
	 * `data-rotulo` em cada celula so repetiria o obvio.
	 *
	 * A excecao da data vem DEPOIS desta regra no arquivo — mesma
	 * especificidade, entao quem vem por ultimo vence.
	 */
	.ao-table--ofertas tbody td::before {
		content: none;
	}

	.ao-table--ofertas tbody td.ao-table__label {
		grid-area: oferta;
		min-width: 0;
	}

	/*
	 * O menu de tres pontinhos sobe para o canto superior direito, alinhado
	 * pelo topo com a miniatura — a posicao onde ele se le como "acoes DESTE
	 * cartao" sem precisar de rotulo. O `.ao-table__actions` e um flex de
	 * largura cheia no desktop (a coluna o enquadrava); aqui encolhe.
	 */
	.ao-table--ofertas tbody td.ao-table__acoes-col {
		grid-area: acoes;

		/* O botao de 32px encostava no nome da oferta. O recuo negativo
		   devolve ao icone o alinhamento optico com a borda do cartao: sem
		   ele o alvo de toque empurra o icone para dentro. */
		margin-inline-end: calc(var(--ao-space-2) * -1);
	}

	.ao-table__actions {
		flex: 0 0 auto;
		width: auto;
	}

	/*
	 * O RODAPE — status e data lado a lado.
	 *
	 * As duas celulas dividem a mesma `grid-area`, o que as empilharia uma
	 * sobre a outra. O que as separa e o `justify-self`: a de status ancora a
	 * esquerda, a de data a direita. Cada uma ocupa so a propria largura, e
	 * como nenhuma e larga o bastante para alcancar a outra, nao ha
	 * sobreposicao. Vantagem sobre dar duas colunas ao grid: o cabecalho
	 * acima nao fica amarrado a essa divisao.
	 *
	 * A linha divisoria vem no `padding-top` + borda da celula de status, que
	 * e `width: 100%` justamente para a borda atravessar o cartao inteiro; a
	 * de data pega o mesmo padding para alinhar pela base, sem repetir a
	 * borda.
	 */
	/*
	 * O RODAPE — status e data dividem a MESMA area de largura cheia.
	 *
	 * Voltam a compartilhar `grid-area`, como na primeira versao, mas agora
	 * sem depender de sorte de largura: a celula de status reserva no proprio
	 * `padding-inline-end` o espaco que a data ocupa, e a data se ancora a
	 * direita. Os badges quebram DENTRO do espaco que sobrou, nunca por baixo
	 * nem por cima dela.
	 *
	 * MEDIDO em 390px: a celula de status tem 300px de largura util. Dois
	 * badges (199px: "Disponível" 100 + "No banner" 99) mais a data (~124px)
	 * somam 323 — nao cabem numa linha, em nenhum arranjo. Reservar 140px
	 * para a data era pior ainda: sobravam 160 e o SEGUNDO BADGE quebrava,
	 * deixando um cartao de 180px quando o pedido era compactar.
	 *
	 * Entao a data sai da disputa: ela vira uma terceira faixa, de largura
	 * cheia, abaixo dos badges. Custa uma linha de 18px, e devolve aos badges
	 * os 300px inteiros — onde os dois cabem lado a lado. Quando nao ha marca
	 * de destaque (o caso comum), o rodape continua com um badge so e a data
	 * logo abaixo.
	 */
	.ao-table--ofertas tbody td.ao-table__status {
		grid-area: status;
		display: flex;
		flex-wrap: wrap;
		gap: var(--ao-space-2);
		margin-block-start: var(--ao-space-3);
		padding-block-start: var(--ao-space-3);
		border-block-start: 1px solid var(--ao-grey-10);
	}

	.ao-table--ofertas tbody td.ao-table__expira {
		grid-area: expira;
		margin-block-start: var(--ao-space-2);
		color: var(--ao-muted);
		font-size: var(--ao-fs-body-2);
		line-height: var(--ao-lh-body-2);
	}

	/*
	 * A data sozinha ("04/11/2026") perdeu o rotulo da coluna e viraria um
	 * numero sem contexto no canto. O prefixo devolve o sentido em duas
	 * silabas, sem gastar a linha inteira que o par rotulo/valor gastava.
	 * O texto vem do PHP (`data-prefixo`) para continuar traduzivel.
	 */
	/*
	 * `content: attr(...) ' '` NAO funciona: o espaco final de uma string em
	 * `content` e colapsado na renderizacao e sai "Expira04/11/2026". O que
	 * sobrevive e uma margem — ou um `\00a0`, que seria um espaco inquebravel
	 * e grudaria o prefixo na data ao fim de linha.
	 */
	.ao-table--ofertas tbody td.ao-table__expira::before {
		content: attr(data-prefixo);
		margin-inline-end: .3em;
	}

	/*
	 * O DROPDOWN NAO PODE ALARGAR A PAGINA.
	 *
	 * Bug medido em 390px: com `left: 0` o painel de 168px abria a partir da
	 * borda ESQUERDA do botao, que no cartao encosta na direita da tela — ele
	 * ia de `left: 316` a `right: 484` e levava o documento de 390 para
	 * **485px de scrollWidth**. O resultado e a pagina inteira deslizando na
	 * horizontal, que e exatamente o que um dropdown nao deve fazer.
	 *
	 * `left: 0` foi escrito para resolver o sintoma oposto (com `right: 0` o
	 * painel sangrava 16px para a ESQUERDA, `left: -16`), mas as duas
	 * ancoragens partem do botao, que e estreito e esta na borda — nenhuma
	 * das duas cabe.
	 *
	 * A correcao muda o ponto de ancoragem: o painel deixa de se pendurar no
	 * botao e passa a se alinhar pela DIREITA DO CARTAO, com um recuo. Como
	 * `.ao-acoes` e o `position: relative` (`:1552`) e ele esta na coluna
	 * estreita do grid, o ancestral posicionado util e a propria `<tr>` —
	 * entao o painel e fixado em relacao a ela.
	 */
	.ao-table--ofertas tbody tr {
		position: relative;
	}

	.ao-table--ofertas .ao-acoes {
		position: static;
	}

	.ao-table--ofertas .ao-acoes__painel {
		/* Ancorado pela direita do CARTAO: nunca ultrapassa a borda dele, logo
		   nunca ultrapassa a tela. O recuo acompanha o padding do cartao —
		   se um mudar sem o outro, o painel desalinha do botao. */
		right: var(--ao-space-4);
		left: auto;

		/* O topo tambem sai do botao e passa a ser o do cartao + a altura do
		   toggle, para o painel abrir logo abaixo dos tres pontinhos. */
		top: calc(var(--ao-space-4) + 32px + 4px);

		/* Ultima defesa: em qualquer largura o painel cabe no cartao. */
		max-width: calc(100% - var(--ao-space-4) * 2);
	}

	/*
	 * VALIDAR VOUCHER — o campo toma a linha, o botao toma a largura.
	 *
	 * No desktop campo e botao dividem a linha (`flex: 1 1 60%` + botao ao
	 * lado). Em 375px isso dava um campo curto para um codigo de 6 caracteres
	 * com `letter-spacing: 4px`, e um "Validar" espremido ao lado. Sao os dois
	 * unicos controles da tela: cada um merece a largura inteira, e o botao
	 * em largura total e o alvo de toque que a acao principal pede — o mesmo
	 * que ja se faz com `.ao-form__submit` (`:3783`). Pedido do usuario
	 * (20/09). `[DECISÃO:2026-09-20]`
	 */
	.ao-validate__campo {
		flex: 1 1 100%;
	}

	.ao-root .ao-validate__submit {
		width: 100%;
	}

	/* O cartao de 40px de recuo deixava pouco miolo para o campo. */
	.ao-validate__form {
		padding: var(--ao-space-7) var(--ao-space-6);
	}

	.ao-validate__result {
		padding: var(--ao-space-7) var(--ao-space-6);
	}

	/* O historico e um `.ao-table-card` e ja segue o cartao da tabela mobile
	   (bloco acima): nao tem recuo proprio a ajustar aqui. */

	/*
	 * A NAVEGACAO DO MOBILE E A BARRA INFERIOR, nao a sidebar.
	 *
	 * Historico: a sidebar empilhava acima do conteudo e o anunciante rolava
	 * 6 itens antes de ver os KPIs. Virou uma tira horizontal rolavel em
	 * 20/09, e a barra fixa foi descartada porque "os itens sao texto puro,
	 * sem icones: 'Validar Voucher' nao cabe num alvo de 70px". Testada no
	 * aparelho, a tira ficou ruim. Os dois impedimentos caem com icone +
	 * rotulo curto ("Validar"), e os 6 itens viraram 5 porque "Meu Plano" e
	 * "Sair" mudaram para dentro de Minha Conta. `[DECISÃO:2026-09-20]`
	 *
	 * Some o MENU, e com ele o NOME -- o header logo acima ja diz
	 * "Ola, <nome>", e repetido em corpo grande ele competia com o titulo da
	 * tela. O e-mail fica: e a unica vez que ele aparece fora do campo de
	 * Minha Conta, e serve para saber com qual conta se esta.
	 */
	.ao-panel__nav,
	.ao-panel__user-name {
		display: none;
	}

	.ao-panel__aside {
		gap: var(--ao-space-5);
	}

	.ao-panel__user-mail {
		font-size: var(--ao-fs-body-2);
		line-height: var(--ao-lh-body-2);
	}
}

/*
 * O Figma so especifica o desktop. Abaixo de 760 as cinco colunas nao cabem,
 * entao o cartao vira pares rotulo/valor e o cabecalho sai de cena.
 */
@media (max-width: 760px) {
	/* Sem as colunas, cada cupom vira um cartao proprio com pares rotulo/valor: a
	   tabela deixa de se comportar como tabela e o cabecalho sai de cena. */
	.ao-vouchers {
		background: none;
		border: 0;
		border-radius: 0;
		overflow: visible;
	}

	.ao-vouchers__table,
	.ao-vouchers__table tbody,
	.ao-vouchers__table tr,
	.ao-vouchers__table td {
		display: block;
	}

	.ao-vouchers__table thead {
		display: none;
	}

	.ao-vouchers__table tbody tr {
		margin-bottom: var(--ao-space-8);
		padding: var(--ao-space-7) var(--ao-space-5);
		background: var(--ao-white);
		border: 1px solid var(--ao-grey-10);
		border-radius: 12px;
	}

	/* A zebra nao faz sentido quando cada linha ja e um cartao separado. */
	.ao-vouchers__table tbody tr:nth-child(even) {
		background: var(--ao-white);
	}

	.ao-vouchers__table tbody tr:last-child {
		margin-bottom: 0;
	}

	.ao-vouchers__table td,
	.ao-vouchers__table td:first-child,
	.ao-vouchers__table td:last-child {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		justify-content: space-between;
		gap: var(--ao-space-4);
		padding: 0;
		padding-block: var(--ao-space-2);
		text-align: right;
	}

	.ao-vouchers__table td::before {
		content: attr(data-rotulo);
		flex: 0 0 auto;
		font-weight: var(--ao-fw-bold);
		color: var(--ao-black);
		text-align: left;
	}

	/* A celula de status tem so o badge (D37), e ele vai para a direita como os
	   demais valores do cartao. */
	.ao-vouchers__table td > .ao-badge-status {
		margin-left: auto;
	}

	.ao-vouchers__acoes {
		justify-content: space-between;
	}
}

/* ==========================================================================
   Cupom gerado — comemoracao
   O sucesso da retirada e o unico momento de ganho do consumidor no fluxo, e
   ate aqui chegava como mais uma tela estatica. O selo carimba, o cartao entra
   e o confete cai uma vez so; nada disso pisca de novo num refresh porque as
   animacoes rodam com `forwards` e sem repeticao.
   ========================================================================== */

.ao-withdraw--won {
	position: relative;
	overflow: hidden;
}

.ao-withdraw--won .ao-withdraw__card {
	animation: ao-won-card 520ms cubic-bezier(0.16, 0.84, 0.44, 1) both;
}

/*
 * `.ao-withdraw__card > *` estica os filhos para os 648 da coluna. O selo e a
 * excecao: a classe dupla tem especificidade maior e devolve a caixa de 72.
 */
.ao-withdraw--won .ao-withdraw__card > .ao-won__seal {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 72px;
	max-width: 72px;
	height: 72px;
	margin-inline: auto;
	color: var(--ao-success);
	animation: ao-won-seal 620ms cubic-bezier(0.2, 1.5, 0.4, 1) 120ms both;
}

/*
 * O `ao-` no nome nao e enfeite: o reset do tema encolhe para 1em todo svg sem
 * width e sem classe `ao-` (ao-components.css). Com a classe, o selo fica no
 * tamanho que a caixa pede.
 */
.ao-won__seal-svg {
	width: 72px;
	height: 72px;
}

/* 145 ~= perimetro do circulo de raio 23; 32 ~= comprimento do traco do check */
.ao-won__seal-ring {
	stroke-dasharray: 145;
	animation: ao-won-ring 560ms ease-out 140ms both;
}

.ao-won__seal-check {
	stroke-dasharray: 32;
	animation: ao-won-check 380ms ease-out 480ms both;
}

/*
 * Na confirmacao o cartao volta a ser uma pilha centrada: as tres colunas sao da
 * tela do cupom, que e larga. Aqui a coluna e estreita, e as colunas empilhavam
 * deixando a linha divisoria como um risco solto no meio.
 */
.ao-withdraw--won .ao-coupon {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--ao-space-5);
	text-align: center;
	animation: ao-won-coupon 520ms cubic-bezier(0.16, 0.84, 0.44, 1) 320ms both;
}

.ao-withdraw--won .ao-coupon__col {
	align-items: center;
	width: 100%;
	padding: 0;
	border: 0;
	text-align: center;
}

/* As acoes ficam lado a lado: sao dois botoes curtos numa coluna estreita. */
.ao-withdraw--won .ao-coupon__col--acoes {
	flex-direction: row;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--ao-space-4);
}

.ao-withdraw--won .ao-coupon__col--acoes .ao-cupom-view__acao {
	width: auto;
}

.ao-confetti {
	position: absolute;
	inset: 0;
	pointer-events: none;
	overflow: hidden;
}

/*
 * O confete usa uma variavel por peca (--ao-confetti-i, 1..18) para espalhar
 * posicao, atraso e giro sem escrever 18 regras.
 */
.ao-confetti__bit {
	position: absolute;
	top: -24px;
	left: calc(var(--ao-confetti-i) * 5.4%);
	width: 9px;
	height: 14px;
	background: var(--ao-accent);
	border-radius: 2px;
	opacity: 0;
	animation: ao-confetti-fall 2.4s cubic-bezier(0.3, 0.1, 0.5, 1) both;
	animation-delay: calc(var(--ao-confetti-i) * 70ms);
}

.ao-confetti__bit--1 {
	width: 10px;
	height: 10px;
	background: var(--ao-primary);
	border-radius: 50%;
}

.ao-confetti__bit--2 {
	width: 7px;
	height: 16px;
	background: var(--ao-success);
}

@keyframes ao-won-card {
	from {
		opacity: 0;
		transform: translateY(18px);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes ao-won-seal {
	from {
		opacity: 0;
		transform: scale(0.4);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes ao-won-ring {
	from {
		stroke-dashoffset: 145;
	}

	to {
		stroke-dashoffset: 0;
	}
}

@keyframes ao-won-check {
	from {
		stroke-dashoffset: 32;
	}

	to {
		stroke-dashoffset: 0;
	}
}

@keyframes ao-won-coupon {
	from {
		opacity: 0;
		transform: scale(0.92);
	}

	60% {
		transform: scale(1.03);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes ao-confetti-fall {
	0% {
		opacity: 0;
		transform: translate3d(0, 0, 0) rotate(0deg);
	}

	10% {
		opacity: 1;
	}

	100% {
		opacity: 0;
		transform: translate3d(calc(var(--ao-confetti-i) * 2px - 20px), 460px, 0) rotate(720deg);
	}
}

/* Movimento e enfeite aqui: quem pediu menos movimento ve a tela pronta. */
@media (prefers-reduced-motion: reduce) {
	.ao-confetti {
		display: none;
	}

	.ao-withdraw--won .ao-withdraw__card,
	.ao-withdraw--won .ao-coupon,
	.ao-won__seal,
	.ao-won__seal-ring,
	.ao-won__seal-check {
		animation: none;
		opacity: 1;
		stroke-dashoffset: 0;
		transform: none;
	}
}

/* ==========================================================================
   Meu cupom — a tela que se abre pelo "Visualizar" da lista
   Linha de cima: o codigo a esquerda e onde usar a direita, lado a lado, que
   e a pergunta seguinte de quem acabou de abrir o cupom. Embaixo, as regras
   ocupando a largura inteira — e a leitura mais longa da tela.
   ========================================================================== */

/*
 * Sem teto proprio: a largura vem do `.ao-panel__content`, a mesma das outras
 * telas do painel. Um `max-width` aqui centralizava o bloco e deixava sobra
 * lateral que nao existe em "Meus Cupons".
 */
.ao-cupom-view {
	display: flex;
	flex-direction: column;
	/* O respiro entre o codigo e o resto separa "o que eu mostro no balcao" do
	   que e informacao de apoio: pouco espaco funde os dois. */
	gap: var(--ao-space-9);
	width: 100%;
}

.ao-cupom-view__acao {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--ao-space-3);
	width: 100%;
	white-space: nowrap;
}

/* O verde confirma a copia sem tirar os olhos do codigo. */
.ao-cupom-view__acao.is-copiado {
	border-color: var(--ao-success);
	color: var(--ao-success);
}

/*
 * O "voltar" abre a tela do cupom, que nao tem titulo: sem o cabecalho acima, a
 * margem negativa que o colava nele so o empurraria para fora.
 */
.ao-panel__content > .ao-panel__back {
	align-self: flex-start;
}

/*
 * A box em tres colunas: o codigo (o que vale no balcao), a oferta/local e as
 * acoes. Empilhado, o codigo de 48px empurrava o resto para baixo e a caixa
 * virava uma pilha alta com muito vazio dos lados.
 */
.ao-cupom-view .ao-coupon {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
	align-items: center;
	gap: var(--ao-space-9);
	width: 100%;
	padding: var(--ao-space-9);
	background: var(--ao-white);
	text-align: left;
}

.ao-coupon__col {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-2);
	min-width: 0;
}

/* A coluna do codigo respira menos: rotulo, codigo e validade sao uma unidade. */
.ao-coupon__col--codigo {
	gap: var(--ao-space-1);
}

/* Uma linha vertical separa as colunas sem precisar de moldura por bloco. */
.ao-coupon__col--local {
	padding-left: var(--ao-space-9);
	border-left: 1px solid var(--ao-grey-30);
}

/* 280 e o que "Imprimir ou salvar PDF" pede para caber numa linha so. */
.ao-coupon__col--acoes {
	gap: var(--ao-space-4);
	width: 280px;
}

/* O tracejado e o gesto de "destaque" do cupom: sem fundo proprio ele sumia
   contra a pagina cinza. */
.ao-cupom-view .ao-coupon .ao-coupon__code {
	letter-spacing: 0.04em;
}

/* Na box em colunas o rotulo vira cabecalho de coluna, nao legenda solta. */
.ao-cupom-view .ao-coupon__label {
	font-size: var(--ao-fs-body-2);
	font-weight: var(--ao-fw-bold);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ao-muted);
}

/*
 * Regras e "Onde usar" sao as duas secoes de leitura da tela, uma embaixo da
 * outra e com a mesma diagramacao: linha de cima, titulo, conteudo alinhado a
 * esquerda. Centralizar uma lista de itens atrapalharia a leitura.
 */
.ao-cupom-view > .ao-offer__section,
.ao-cupom-view > .ao-loja {
	width: 100%;
	padding-top: var(--ao-space-7);
	border-top: 1px solid var(--ao-grey-30);
	text-align: left;
}

/* A tipografia vem do `.ao-h3`, igual ao titulo das regras. */
.ao-loja__titulo {
	margin: 0 0 var(--ao-space-4);
}

.ao-loja__nome {
	margin: 0 0 var(--ao-space-2);
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-body);
}

.ao-loja__tipo {
	font-weight: var(--ao-fw-regular);
	color: var(--ao-muted);
}

.ao-loja__linha {
	margin: 0 0 var(--ao-space-2);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-muted);
}

.ao-loja__linha:last-child {
	margin-bottom: 0;
}

.ao-panel__back {
	display: inline-flex;
	align-items: center;
	gap: var(--ao-space-2);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-primary);
	text-decoration: none;
}

.ao-panel__back:hover,
.ao-panel__back:focus-visible {
	color: var(--ao-accent);
	text-decoration: underline;
}

.ao-panel__back-icon {
	display: inline-flex;
	flex: none;
}

/*
 * Abaixo de 900 as duas colunas ficam estreitas demais — o codigo de 48px e o
 * endereco passam a quebrar em varias linhas. Empilha: cupom, onde usar, regras.
 */
/*
 * Estreito, os 260 dos botoes comem a largura do codigo de 48px: a faixa
 * empilha e as acoes passam a ocupar a linha inteira, embaixo do cartao.
 */
/*
 * Estreito, as tres colunas nao cabem: viram uma pilha, e a linha vertical que
 * separava a coluna do meio passa a ser horizontal.
 */
@media (max-width: 899.98px) {
	.ao-cupom-view .ao-coupon {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--ao-space-7);
	}

	.ao-coupon__col--local {
		padding-left: 0;
		padding-top: var(--ao-space-7);
		border-left: 0;
		border-top: 1px solid var(--ao-grey-30);
	}

	.ao-coupon__col--acoes {
		width: 100%;
	}
}

@media (max-width: 767.98px) {
	.ao-cupom-view .ao-coupon {
		padding-inline: var(--ao-space-5);
	}
}

/* --------------------------------------------------------------------------
   Copiar o codigo e imprimir o cupom
   O anunciante valida digitando o codigo (`docs/08`), e as regras da casa ja
   preveem "apresentar o voucher (impresso ou digital)" (`docs/05:122`) — mas a
   tela nao oferecia nenhum dos dois caminhos. Ver D31 em `docs/09`.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Formulario de oferta — `[FIGMA:tela 9]` (102942:2358)

   O desenho nao usa cartao branco: os campos ficam direto sobre a pagina
   (#F5F5F5), com a borda cinza e o rotulo encaixado nela. E por isso que o
   `.ao-field--float` pinta o fundo do rotulo com `--ao-page` — dentro de um
   cartao branco o entalhe apareceria cinza sobre branco.
   -------------------------------------------------------------------------- */

.ao-form--oferta {
	gap: var(--ao-space-5);
}

/*
 * Figma 102942:2380 — "Oferta*" e "Tempo da oferta*" dividem a linha em duas
 * colunas de 586px dentro dos 1196px do conteudo. Aqui a divisao e por fracao,
 * para acompanhar a largura real do painel, e colapsa numa coluna no celular.
 */
.ao-form__duo {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--ao-space-8);
	align-items: start;
}

/*
 * "Desconto" ao lado de "Tempo da oferta": 50/50 daria 525px para tres digitos.
 * A primeira coluna fica com o tamanho do seu conteudo (o proprio campo pede
 * ~11rem) e a data recebe o resto -- as duas caixas terminam alinhadas.
 */
.ao-form__duo--desconto {
	grid-template-columns: 11rem minmax(0, 1fr);
}

@media (max-width: 700px) {
	.ao-form__duo,
	.ao-form__duo--desconto {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--ao-space-5);
	}

	/* Empilhado, o campo acompanha a largura dos vizinhos: um toco de 11rem
	   sozinho na linha pareceria um erro de layout. */
	.ao-field__wrap:has(.ao-field__sufixo) {
		width: 100%;
	}
}

/* --------------------------------------------------------------------------
   Dropzone da foto — Figma 102942:2360

   327px de altura, raio 10px e o fundo `Escala de Cinza/10`. O input de arquivo
   fica visualmente escondido mas continua focavel pelo teclado: o label inteiro
   e a area de clique, e o foco precisa aparecer em algum lugar.
   -------------------------------------------------------------------------- */

.ao-dropzone {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-3);
}

.ao-dropzone__alvo {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 327px;
	padding: var(--ao-space-9);
	border-radius: var(--ao-radius-card);
	background: var(--ao-card-body);
	cursor: pointer;
	overflow: hidden;
	transition: background-color 120ms ease, outline-color 120ms ease;
}

@media (max-width: 700px) {
	.ao-dropzone__alvo {
		min-height: 180px;
	}
}

@media (hover: hover) {
	.ao-dropzone__alvo:hover {
		background: #DEDEDE;
	}
}

/* O foco vive no input escondido; o contorno precisa aparecer no alvo visivel. */
.ao-dropzone__input:focus-visible + .ao-dropzone__vazio,
.ao-dropzone__alvo:focus-within {
	outline: 2px solid var(--ao-primary);
	outline-offset: 2px;
}

.ao-dropzone.is-dragging .ao-dropzone__alvo {
	background: #DEDEDE;
	outline: 2px dashed var(--ao-primary);
	outline-offset: -8px;
}

/*
 * Nao use `display: none` no input: o campo sairia da ordem de tabulacao e o
 * teclado perderia o acesso ao upload.
 */
.ao-dropzone__input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

.ao-dropzone__vazio {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--ao-space-9);
	color: var(--ao-muted);
	text-align: center;
}

.ao-dropzone__icone {
	color: var(--ao-muted);
}

.ao-dropzone__texto {
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-regular);
}

.ao-dropzone__texto strong {
	font-weight: var(--ao-fw-bold);
}

.ao-dropzone__preview {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.ao-dropzone__remover {
	align-self: flex-start;
	padding: var(--ao-space-1) 0;
	border: 0;
	background: none;
	color: var(--ao-danger);
	font-family: inherit;
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	text-decoration: underline;
	cursor: pointer;
}

.ao-dropzone__remover[hidden] {
	display: none;
}

/* --------------------------------------------------------------------------
   Preview do preco com desconto — anotacao de Dev Mode em 103011:2:
   "ao colocar a % o campo de valor total mostra um preview".
   -------------------------------------------------------------------------- */

.ao-preview {
	display: flex;
	align-items: baseline;
	gap: var(--ao-space-2);
	margin: calc(var(--ao-space-2) * -1) 0 0;
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
}

.ao-preview[hidden] {
	display: none;
}

.ao-preview__rotulo {
	color: var(--ao-muted);
}

.ao-preview__valor {
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-accent);
}

/* --------------------------------------------------------------------------
   Listas do formulario — "O que está incluso:" (102942:2405) e
   "Regras e condições:" (102942:2416).

   O Figma desenha os dois grupos com o titulo em 14px cinza e as linhas em duas
   colunas. As regras trazem um icone dentro do campo.
   -------------------------------------------------------------------------- */

.ao-lista {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-5);
	margin: 0;
	padding: 0;
	border: 0;
}

.ao-lista__titulo {
	padding: 0;
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	font-weight: var(--ao-fw-regular);
	color: var(--ao-subtle);
}

.ao-lista__linhas {
	display: grid;
	gap: var(--ao-space-4);
}

.ao-lista__linhas--duo {
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--ao-space-4) var(--ao-space-8);
}

@media (max-width: 700px) {
	.ao-lista__linhas--duo {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* Duas listas seguidas ("regras fixas" + "regras livres") respiram como uma so. */
.ao-lista__linhas + .ao-lista__linhas {
	margin-top: calc(var(--ao-space-4) * -1 + var(--ao-space-4));
}

.ao-lista__linha {
	position: relative;
	display: flex;
	align-items: center;
}

.ao-lista__linha .ao-input {
	height: 51px;
	border-color: var(--ao-grey-30);
	background: transparent;
}

.ao-lista__linha .ao-input::placeholder {
	color: var(--ao-subtle);
}

/* O icone fica dentro do campo, entao o texto comeca depois dele. */
.ao-lista__linha--icone .ao-input {
	padding-left: calc(var(--ao-space-5) + 18px + var(--ao-space-3));
}

.ao-lista__icone {
	position: absolute;
	left: var(--ao-space-5);
	color: var(--ao-subtle);
	pointer-events: none;
}

.ao-lista__add {
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	gap: var(--ao-space-2);
	padding: 0;
	border: 0;
	background: none;
	color: var(--ao-primary);
	font-family: inherit;
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	font-weight: var(--ao-fw-bold);
	cursor: pointer;
}

.ao-lista__add[hidden] {
	display: none;
}

@media (hover: hover) {
	.ao-lista__add:hover {
		color: var(--ao-accent);
	}
}

/* --------------------------------------------------------------------------
   "Voltar para painel geral" — Figma 102942:2544. Antes era um botao terciario
   no rodape; no desenho e um link azul com chevron, acima do conteudo.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Secoes do formulario de oferta

   O Figma desenha uma coluna unica sem titulos, mas a tela real ficou longa
   demais para isso: com "Valor total", as duas listas e o preco de fim de
   semana, tudo passa a ter o mesmo peso visual. Os grupos separam o que se
   decide junto. Pedido do usuario, 17/09.
   -------------------------------------------------------------------------- */

/*
 * `display: flex` num <fieldset> tira o <legend> do fluxo em Chrome e Safari: ele
 * vira o primeiro item flex e passa a se sobrepor ao que vem depois. O fieldset
 * fica em `block` e quem organiza a coluna e o .ao-secao__campos.
 */
/* --------------------------------------------------------------------------
   Checkbox do painel

   O <input type="checkbox"> nativo nao aceita cor de borda nem raio: ao lado dos
   campos de texto, que tem 1px cinza e canto de 6px, ele aparecia como um quadrado
   azul do sistema. Aqui o nativo fica invisivel mas focavel, e quem se desenha e a
   marca ao lado — o estado continua sendo o do input, entao teclado, leitor de tela
   e o `checked` do PHP seguem funcionando.
   -------------------------------------------------------------------------- */

.ao-check {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-1);
}

.ao-check__label {
	display: inline-flex;
	align-items: center;
	gap: var(--ao-space-3);
	font-size: var(--ao-fs-body-1);
	line-height: var(--ao-lh-body-1);
	color: var(--ao-body);
	cursor: pointer;
}

/*
 * `opacity: 0` em vez de `display: none`: escondido de verdade, o input sairia da
 * ordem de tabulacao e o checkbox viraria inalcancavel pelo teclado.
 */
.ao-check__input {
	position: absolute;
	width: 20px;
	height: 20px;
	margin: 0;
	opacity: 0;
	cursor: pointer;
}

.ao-check__marca {
	flex: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	border: 1px solid var(--ao-grey-30);
	border-radius: var(--ao-radius-badge);
	background: var(--ao-white);
	color: transparent;
	transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

@media (hover: hover) {
	.ao-check__label:hover .ao-check__marca {
		border-color: var(--ao-primary);
	}
}

.ao-check__input:checked + .ao-check__marca {
	border-color: var(--ao-primary);
	background: var(--ao-primary);
	color: var(--ao-on-dark);
}

/* O foco vive no input invisivel; o anel precisa aparecer na marca visivel. */
.ao-check__input:focus-visible + .ao-check__marca {
	outline: 2px solid var(--ao-primary);
	outline-offset: 2px;
}

.ao-check__hint {
	margin: 0;
	padding-left: calc(20px + var(--ao-space-3));
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-muted);
}

.ao-secao {
	display: block;
	margin: 0;
	padding: 0;
	border: 0;
}

/*
 * O divisor mora no topo da secao seguinte, nao no rodape da anterior: assim a
 * primeira nao nasce com um traco solto acima dela.
 */
.ao-secao + .ao-secao {
	margin-top: var(--ao-space-4);
	padding-top: var(--ao-space-9);
	border-top: 1px solid var(--ao-grey-10);
}

.ao-secao__titulo {
	float: left;
	width: 100%;
	margin: 0;
	padding: 0;
	font-size: var(--ao-fs-h3);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-primary);
}

/*
 * O <legend> flutuado sai do fluxo, entao quem vier depois precisa limpar — senao
 * a descricao sobe e imprime por cima do titulo.
 */
.ao-secao__titulo + * {
	clear: both;
}

.ao-secao__descricao {
	margin: var(--ao-space-1) 0 0;
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-muted);
}

.ao-secao__campos {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-5);
	margin-top: var(--ao-space-5);
	clear: both;
}

/* --------------------------------------------------------------------------
   Foto do estabelecimento — o mesmo dropzone da oferta, em circulo de 122px
   (Figma 102942:2620, onde havia so um circulo azul decorativo).
   -------------------------------------------------------------------------- */

.ao-dropzone--avatar {
	align-items: flex-start;
	margin-bottom: var(--ao-space-7);
}

/* O preview tambem precisa ser redondo, senao a foto vaza os cantos do circulo. */
.ao-dropzone--avatar .ao-dropzone__preview {
	border-radius: 50%;
}

.ao-dropzone--avatar .ao-dropzone__alvo {
	width: 122px;
	min-height: 122px;
	height: 122px;
	padding: var(--ao-space-4);
	border-radius: 50%;
	background: var(--ao-primary);
	color: var(--ao-on-dark);
}

@media (hover: hover) {
	.ao-dropzone--avatar .ao-dropzone__alvo:hover {
		background: #001a99;
	}
}

.ao-dropzone--avatar .ao-dropzone__icone {
	width: 28px;
	height: 28px;
	color: inherit;
}

.ao-dropzone--avatar .ao-dropzone__vazio {
	gap: var(--ao-space-2);
	color: inherit;
}

.ao-dropzone--avatar .ao-dropzone__texto {
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
}

/*
 * No Figma o link abre a tela, acima de tudo. Ele e impresso depois do cabecalho
 * porque `FrontPainel::abrir()` ja fechou o <header>; `order` o traz para cima sem
 * duplicar marcacao — `.ao-panel__content` e uma coluna flex.
 */
.ao-back {
	order: -1;
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	gap: var(--ao-space-4);
	color: var(--ao-primary);
	font-size: var(--ao-fs-body-2);
	line-height: 1.5;
	font-weight: var(--ao-fw-bold);
	text-decoration: none;
}

@media (hover: hover) {
	.ao-back:hover {
		color: var(--ao-accent);
	}
}

.ao-back__icone {
	flex: none;
}

/*
 * Cabecalho e rodape exclusivos da impressao: na tela o header e o footer do
 * site ja cumprem esse papel. Precisam vir ANTES do `@media print` — com a mesma
 * especificidade, a ultima regra ganha, e o bloco de impressao e quem deve
 * mandar no papel.
 */
/*
 * O cabecalho de marca, o rodape legal e o QR so fazem sentido no papel: na tela
 * o header e o footer do site ja cumprem esse papel, e o QR e para o anunciante
 * escanear o voucher impresso. "Onde usar" fica nos dois — impresso ou na tela,
 * a pessoa precisa saber onde resgatar.
 */
.ao-print-head,
.ao-print-foot,
.ao-print-qr {
	display: none;
}

/*
 * Impressao: o voucher vira documento. Sem isto a folha saia com o cupom solto,
 * sem marca e sem dizer de onde veio — quem recebe no balcao precisa reconhecer
 * a origem. O navegador oferece "Salvar como PDF" na mesma caixa, entao isto
 * cobre o PDF sem biblioteca no servidor. Ver D31 em `docs/09`.
 */
@media print {
	@page {
		size: A4;
		margin: 14mm;
	}

	.ao-header,
	.ao-footer,
	.ao-panel__aside,
	.ao-panel__back,
	.ao-panel__head,
	.ao-cupom-view__acoes,
	.ao-toast,
	.ao-toasts {
		display: none !important;
	}

	body {
		background: #fff;
		color: #111;
	}

	.ao-panel {
		padding-block: 0;
	}

	.ao-panel > .ao-container,
	.ao-panel__inner,
	.ao-panel__content,
	.ao-cupom-view {
		display: block;
		width: auto;
		max-width: none;
		margin: 0;
		padding: 0;
	}

	/* --- cabecalho da folha: marca de um lado, natureza do documento do outro --- */
	.ao-print-head {
		display: flex;
		align-items: flex-end;
		justify-content: space-between;
		gap: 12mm;
		padding-bottom: 4mm;
		/* A faixa azul-marinho e o unico fundo colorido da folha: sem ela o
		   documento nao se identifica a distancia. */
		border-bottom: 2px solid #00126b;
	}

	.ao-print-head__logo {
		width: auto;
		height: 16mm;
	}

	.ao-print-head__nome {
		font-size: 16pt;
		font-weight: 800;
		color: #00126b;
	}

	.ao-print-head__meta {
		display: flex;
		flex-direction: column;
		align-items: flex-end;
		gap: 1mm;
		text-align: right;
	}

	.ao-print-head__tipo {
		font-size: 11pt;
		font-weight: 700;
		letter-spacing: 0.08em;
		text-transform: uppercase;
		color: #00126b;
	}

	.ao-print-head__emissao {
		font-size: 9pt;
		color: #555;
	}

	/* --- o cupom --- */
	/*
	 * No papel o cupom volta a ser uma pilha centrada: as tres colunas da tela
	 * espalhariam o codigo, e os botoes nao existem impressos.
	 */
	.ao-cupom-view .ao-coupon {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 2mm;
		max-width: none;
		margin-top: 6mm;
		padding: 8mm;
		border: 2px dashed #00126b;
		border-radius: 3mm;
		background: none;
		text-align: center;
		break-inside: avoid;
	}

	.ao-coupon__col {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 1mm;
		width: auto;
		padding: 0;
		border: 0;
	}

	.ao-coupon__col--acoes {
		display: none;
	}

	.ao-coupon__label {
		font-size: 9pt;
		letter-spacing: 0.06em;
		text-transform: uppercase;
		color: #555;
	}

	/* O codigo e o que vale no balcao: e o maior elemento da folha. */
	.ao-coupon__code {
		font-size: 30pt;
		letter-spacing: 0.12em;
		color: #00126b;
	}

	.ao-coupon__offer {
		font-size: 13pt;
		color: #111;
	}

	.ao-coupon__meta {
		font-size: 10pt;
		color: #444;
	}

	/* --- regras --- */
	.ao-cupom-view > .ao-offer__section {
		max-width: none;
		margin-top: 6mm;
		padding-top: 4mm;
		border-top: 1px solid #ccc;
		break-inside: avoid;
	}

	.ao-cupom-view > .ao-offer__section .ao-h3 {
		font-size: 12pt;
		color: #00126b;
	}

	.ao-list__item {
		font-size: 10pt;
		color: #222;
		break-inside: avoid;
	}

	/* Laranja da marca no icone: o unico respiro de cor no corpo da folha. */
	.ao-list__icon {
		color: #ff4900;
	}

	/* --- rodape: aviso que evita mal-entendido no caixa + identificacao legal --- */
	.ao-print-foot {
		display: block;
		margin-top: 6mm;
		padding-top: 4mm;
		border-top: 1px solid #ccc;
		break-inside: avoid;
	}

	.ao-print-foot__aviso {
		margin: 0 0 2mm;
		font-size: 9pt;
		font-weight: 700;
		color: #111;
	}

	.ao-print-foot__marca {
		margin: 0;
		font-size: 8pt;
		color: #666;
	}

	/* --- QR de validacao: o anunciante aponta a camera e cai na tela certa --- */
	.ao-print-qr {
		display: flex;
		align-items: center;
		gap: 5mm;
		margin-top: 6mm;
		padding: 3mm 4mm;
		border: 1px solid #ccc;
		border-radius: 2mm;
		break-inside: avoid;
	}

	.ao-print-qr__img {
		flex: none;
		width: 30mm;
		height: 30mm;
	}

	.ao-print-qr__legenda {
		font-size: 9pt;
		font-weight: 700;
		color: #00126b;
	}

	/*
	 * Onde usar: impresso, o papel e a unica referencia que a pessoa leva. A
	 * moldura branca da tela vira tinta a toa no papel — aqui so a linha de cima
	 * separa o bloco das regras.
	 */
	.ao-cupom-view > .ao-loja {
		display: block;
		margin-top: 6mm;
		padding: 4mm 0 0;
		border: 0;
		border-top: 1px solid #ccc;
		background: none;
		break-inside: avoid;
	}

	.ao-loja__titulo {
		margin: 0 0 2mm;
		font-size: 12pt;
		color: #00126b;
	}

	.ao-loja__nome {
		margin: 0 0 1mm;
		font-size: 11pt;
		font-weight: 700;
		color: #111;
	}

	.ao-loja__tipo {
		font-weight: 400;
		color: #555;
	}

	.ao-loja__linha {
		margin: 0 0 1mm;
		font-size: 10pt;
		color: #333;
	}

	/* Fundos e cores chapadas so saem se o usuario deixar imprimir graficos. */
	.ao-print-head,
	.ao-print-head__tipo,
	.ao-coupon__code,
	.ao-list__icon {
		-webkit-print-color-adjust: exact;
		print-color-adjust: exact;
	}
}

/* ==========================================================================
   Meu Plano — o que o anunciante assinou e como resolver
   [DECISÃO:2026-09-18] · anatomia `[REF:paginas-conecta]`. Sem Figma: as 12
   telas da fonte nao incluem esta. Os cartoes reaproveitam `ao-table-card` e o
   CTA e o botao do design system — nada de linguagem visual nova. Se o cliente
   pedir desenho proprio, o ajuste e aqui, e nao na logica.

   A ordem e de LEITURA, nao estetica: selo de situacao -> nome -> preco ->
   frase do que acontece a seguir. Quem abre esta tela pergunta primeiro "em que
   situacao estou", nao "o que eu tenho".
   ========================================================================== */
.ao-meu-plano {
	align-items: flex-start;
	gap: var(--ao-space-4);
	padding-inline: var(--ao-space-7);
}

/* O selo vem antes do nome e por isso precisa de largura propria: `hug`, para
   "Aguardando pagamento" e "Ativa" nao virarem duas caixas do mesmo tamanho. */
.ao-meu-plano__selo {
	display: inline-flex;
	align-items: center;
	padding: var(--ao-space-1) var(--ao-space-4);
	border-radius: 999px;
	font-size: var(--ao-fs-body-2);
	font-weight: 700;
	line-height: var(--ao-lh-body-2);
}

/* Tres niveis de alarme, nao dois. `aguardando` e ambar de proposito: a
   cobranca esta em aberto mas as ofertas seguem no ar, entao o vermelho de
   `atrasada` seria mentira sobre o estado do produto. */
.ao-meu-plano__selo--ativa {
	background: var(--ao-success-bg);
	color: var(--ao-success);
}

.ao-meu-plano__selo--aguardando {
	background: #FEF3C7;
	color: #92400E;
}

.ao-meu-plano__selo--atrasada {
	background: var(--ao-danger);
	color: var(--ao-white);
}

.ao-meu-plano__selo--cancelada,
.ao-meu-plano__selo--expirada,
.ao-meu-plano__selo--sem_assinatura {
	background: var(--ao-grey-30);
	color: var(--ao-grey-50);
}

.ao-meu-plano__nome {
	margin: 0;
	padding-inline: 0;
	font-size: var(--ao-fs-h3);
	line-height: var(--ao-lh-body-1);
	color: var(--ao-ink);
}

/* O preco e o maior elemento da tela — e o que a pessoa veio conferir. */
.ao-meu-plano__preco {
	display: flex;
	align-items: baseline;
	gap: var(--ao-space-1);
	margin: 0;
	color: var(--ao-ink);
}

.ao-meu-plano__moeda {
	font-size: var(--ao-fs-body-1);
	font-weight: 700;
}

.ao-meu-plano__valor {
	font-size: var(--ao-fs-h2);
	font-weight: 700;
	line-height: 1.1;
}

.ao-meu-plano__ciclo {
	font-size: var(--ao-fs-body-1);
	color: var(--ao-muted);
}

.ao-meu-plano__resumo {
	margin: 0;
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-muted);
}

/* So aparece quando a consequencia ja aconteceu (estado `atrasada`). */
.ao-meu-plano__banner {
	width: 100%;
	margin: 0;
	padding: var(--ao-space-4) var(--ao-space-5);
	border-radius: var(--ao-radius-card);
	background: #FEF3C7;
	color: #92400E;
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
}

.ao-meu-plano__acao {
	width: 100%;
	margin-top: var(--ao-space-2);
}

/* CTA de largura cheia: e a acao principal da tela, nao uma entre varias. */
.ao-meu-plano__cta {
	width: 100%;
	justify-content: center;
}

/* Titulos de secao vivem FORA dos cartoes, como no resto do painel. */
.ao-meu-plano__secao {
	margin: var(--ao-space-8) 0 var(--ao-space-4);
	font-size: var(--ao-fs-body-1);
	font-weight: 700;
	line-height: var(--ao-lh-body-1);
	color: var(--ao-ink);
}

.ao-meu-plano__detalhes {
	gap: 0;
	padding-block: 0;
}

.ao-meu-plano__detalhes > div {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--ao-space-5);
	padding: var(--ao-space-5) var(--ao-space-7);
	border-bottom: 1px solid var(--ao-subtle);
}

.ao-meu-plano__detalhes > div:last-child {
	border-bottom: 0;
}

.ao-meu-plano__detalhes dt {
	font-size: var(--ao-fs-body-2);
	color: var(--ao-muted);
}

/* Valor a direita e em negrito: a coluna de rotulos fica escaneavel. */
.ao-meu-plano__detalhes dd {
	margin: 0;
	font-size: var(--ao-fs-body-2);
	font-weight: 700;
	text-align: right;
	color: var(--ao-ink);
}

.ao-meu-plano__beneficios {
	gap: var(--ao-space-4);
	margin: 0;
	padding: var(--ao-space-7);
	list-style: none;
}

.ao-meu-plano__beneficios li {
	position: relative;
	padding-left: var(--ao-space-7);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-ink);
}

.ao-meu-plano__beneficios li::before {
	content: "✓";
	position: absolute;
	left: 0;
	color: var(--ao-success);
	font-weight: 700;
}

/* Cancelar: presente e encontravel, sem competir com o CTA. Fora de cartao, no
   fim da pagina, como link — nunca como botao ao lado do de pagar. */
.ao-meu-plano__rodape {
	display: flex;
	justify-content: center;
	margin-top: var(--ao-space-9);
}

.ao-meu-plano__cancelar-link {
	padding: 0;
	border: 0;
	background: none;
	color: var(--ao-danger);
	font-family: inherit;
	font-size: var(--ao-fs-body-2);
	text-decoration: underline;
	cursor: pointer;
}

@media (hover: hover) {
	.ao-meu-plano__cancelar-link:hover {
		opacity: 0.8;
	}
}

.ao-meu-plano__mensagem {
	margin: 0 0 var(--ao-space-5);
	padding: var(--ao-space-4) var(--ao-space-5);
	border-radius: var(--ao-radius-card);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
}

.ao-meu-plano__mensagem--ok {
	background: var(--ao-success-bg);
	color: var(--ao-success);
}

.ao-meu-plano__mensagem--erro {
	background: var(--ao-white);
	border: 1px solid var(--ao-danger);
	color: var(--ao-danger);
}

@media (max-width: 640px) {
	/* Rotulo e valor empilham: lado a lado, "Próxima cobrança" e a data longa
	   disputam a mesma linha e a data quebra no meio. */
	.ao-meu-plano__detalhes > div {
		flex-direction: column;
		gap: var(--ao-space-1);
	}

	.ao-meu-plano__detalhes dd {
		text-align: left;
	}
}

/* --------------------------------------------------------------------------
   Meu Plano — tela de cancelamento
   Friccao construtiva `[REF:paginas-conecta]`: ate quando o acesso continua,
   o que se perde, e o motivo. Nesta ordem, e nunca num confirm() do navegador.
   -------------------------------------------------------------------------- */
.ao-meu-plano--cancelar {
	gap: var(--ao-space-7);
}

.ao-meu-plano__perdas {
	width: 100%;
	padding: var(--ao-space-5) var(--ao-space-7);
	border-radius: var(--ao-radius-card);
	background: var(--ao-grey-10, #F7F7FA);
}

.ao-meu-plano__perdas-titulo {
	margin: 0 0 var(--ao-space-4);
	font-size: var(--ao-fs-body-2);
	font-weight: 700;
	color: var(--ao-ink);
}

.ao-meu-plano__perdas-lista {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-2);
	margin: 0;
	padding-left: var(--ao-space-7);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-muted);
}

.ao-meu-plano__form-cancelar {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-5);
	width: 100%;
}

/* Empilhados, nao lado a lado: sao acoes opostas, e uma fileira horizontal as
   apresenta como um par equivalente — "escolha uma". Empilhado, cada botao e
   uma decisao propria, e o de cancelar (primeiro, vermelho) nao divide a linha
   com a saida. */
.ao-meu-plano__acoes-cancelar {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: var(--ao-space-4);
	margin-top: var(--ao-space-2);
}

.ao-meu-plano__acoes-cancelar > .ao-btn {
	width: 100%;
}

/* O peso visual fica com quem conserva a assinatura: "Manter" e botao cheio,
   no verde da paleta (--ao-success, o mesmo do selo "Ativa"), e o cancelamento
   desce para link vermelho. A acao destrutiva continua encontravel, mas parou
   de se parecer com o caminho comum. */
.ao-btn--sucesso {
	border-color: var(--ao-success);
	background: var(--ao-success);
	color: var(--ao-white);
}

@media (hover: hover) {
	.ao-btn--sucesso:hover {
		border-color: var(--ao-success);
		background: var(--ao-success);
		opacity: 0.9;
	}
}

/* O link de cancelar dentro do form e o mesmo do rodape do cartao, mas como
   <button>: precisa submeter. Centralizado para nao ficar solto sob um botao
   de largura cheia. */
.ao-meu-plano__acoes-cancelar > .ao-meu-plano__cancelar-link {
	align-self: center;
	font-family: inherit;
}


/* Banner principal do Premium (RN-56) — mesma anatomia do aviso de downgrade,
   que ja e o formato de "recado do sistema" desta tela. A cor da borda diz o
   estado sem depender do texto: verde no ar, laranja esperando, azul da marca
   para o direito ainda por usar. */
.ao-banner-status {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--ao-space-2);
	padding: var(--ao-space-7);
	background: var(--ao-white);
	border-radius: var(--ao-radius-card);
	border-left: 8px solid var(--ao-primary);
}

.ao-banner-status--no-ar {
	border-left-color: var(--ao-success);
}

.ao-banner-status--fila {
	border-left-color: var(--ao-accent);
}

.ao-banner-status__title {
	margin: 0;
	font-size: var(--ao-fs-h3);
	line-height: var(--ao-lh-body-1);
	font-weight: var(--ao-fw-bold);
	color: var(--ao-primary);
}

.ao-banner-status--no-ar .ao-banner-status__title {
	color: var(--ao-success);
}

.ao-banner-status--fila .ao-banner-status__title {
	color: var(--ao-accent);
}

.ao-banner-status__text {
	margin: 0;
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	color: var(--ao-body);
}

/* ==========================================================================
   Barra inferior do mobile e atalhos da conta          [DECISAO:2026-09-20]
   ========================================================================== */

/*
 * A lista de atalhos de "Minha Conta": Meu Plano e Sair, que sairam da
 * navegacao para caber a barra inferior em 5 itens.
 *
 * Formato do `paginas-conecta` (`pc-perfil__item`): linha em pill com rotulo
 * e chevron, uma por linha -- nao cartoes em grade. Vale nos dois tamanhos:
 * esconder no desktop faria a mesma pagina ter duas caras, e "Sair" sumiria
 * de quem rolou ate o fim.
 */
.ao-conta-menu {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-3);
	margin-top: var(--ao-space-7);
}

.ao-conta-menu__item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--ao-space-4);
	padding: var(--ao-space-5) var(--ao-space-6);
	border-radius: var(--ao-radius-card);
	background: var(--ao-white);
	border: 1px solid var(--ao-grey-10);
	color: var(--ao-primary);
	font-weight: var(--ao-fw-semibold);
	text-decoration: none;
}

@media (hover: hover) {
	.ao-conta-menu__item:hover {
		border-color: var(--ao-accent);
		color: var(--ao-accent);
	}
}

.ao-conta-menu__seta {
	width: 16px;
	height: 16px;
	flex: 0 0 auto;
}

/* Largura total e o padrao do `paginas-conecta` para a acao de sair. */
.ao-conta-menu__sair {
	justify-content: center;
	width: 100%;
}

/*
 * A BARRA INFERIOR. Fica fora de toda media query no HTML (o markup e o mesmo
 * nos dois tamanhos); quem a liga e a media query abaixo. No desktop ela nao
 * existe: a sidebar faz o trabalho.
 */
.ao-bottom-nav {
	display: none;
}

@media (max-width: 767.98px) {
	.ao-bottom-nav {
		display: block;
		position: fixed;
		inset-inline: 0;
		bottom: 0;
		z-index: 90;
		background: var(--ao-white);
		border-top: 1px solid var(--ao-grey-10);
		/*
		 * O aparelho do usuario mostra a faixa de gesto na base. Sem a
		 * safe-area os alvos ficam debaixo dela; nenhum outro ponto do
		 * projeto usava `env()` ate aqui.
		 */
		padding-bottom: env(safe-area-inset-bottom, 0px);
	}

	.ao-bottom-nav__lista {
		display: flex;
		margin: 0;
		padding: 0;
		list-style: none;
	}

	.ao-bottom-nav__item {
		flex: 1 1 0;
		min-width: 0;
	}

	.ao-bottom-nav__link {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		gap: 4px;
		/* 56px + safe-area: acima dos 44px minimos de alvo de toque. */
		min-height: 56px;
		padding: var(--ao-space-2) 2px;
		color: var(--ao-muted);
		text-decoration: none;
		text-align: center;
	}

	.ao-bottom-nav__icone {
		width: 22px;
		height: 22px;
		flex: 0 0 auto;
	}

	.ao-bottom-nav__rotulo {
		font-size: 11px;
		line-height: 1.2;
		/*
		 * "Validar" e o rotulo mais longo e cabe inteiro em 5 colunas de
		 * 360px. Cortar com reticencias seria pior que reduzir o corpo: um
		 * rotulo pela metade nao diz para onde o botao leva.
		 */
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
		max-width: 100%;
	}

	.ao-bottom-nav__item.is-active .ao-bottom-nav__link {
		color: var(--ao-accent);
		font-weight: var(--ao-fw-bold);
	}

	/*
	 * A barra flutua sobre o conteudo: sem esta reserva ela cobre o ultimo
	 * elemento da pagina. A reserva vai no `.ao-main` (o shell), nao no
	 * `.ao-panel`: os atalhos da conta (`.ao-conta-menu`) ficam FORA do painel,
	 * e com a reserva so nele o botao "Sair" nascia atras da barra -- medido,
	 * base do botao em 844 contra topo da barra em 787.
	 */
	.ao-main {
		padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px));
	}

	/*
	 * Na home o rodape fica ABAIXO do `.ao-main` e a reserva dele nao o
	 * alcanca: sem isto a barra cobriria as ultimas linhas do rodape, que e
	 * justamente onde moram CNPJ e contato.
	 */
	body.home .ao-main {
		padding-bottom: 0;
	}

	body.home .ao-footer {
		padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px));
	}

	/*
	 * Botao de acao em largura total: num alvo de polegar, meio botao alinhado
	 * a esquerda e mais dificil de acertar e nao parece a acao principal da
	 * tela. Pedido do usuario. Vale para "Salvar alteracoes" e para os demais
	 * submits do painel, que seguem o mesmo padrao.
	 */
	.ao-root .ao-form__submit {
		align-self: stretch;
		width: 100%;
	}
}

@media print {
	.ao-bottom-nav {
		display: none;
	}
}

/* ==========================================================================
   Gaveta (drawer) — folha no celular, modal no desktop
   Portada do `paginas-conecta` (`pc-components.css` + `pc-desktop.css`).
   Serve a escolha "Tirar foto / Escolher da galeria" do dropzone.
   [REF:paginas-conecta] `[DECISÃO:2026-09-20]`
   ========================================================================== */

/*
 * Fundo travado enquanto ha gaveta aberta (a classe entra pelo JS, que guarda
 * e devolve a posicao de rolagem).
 *
 * `position: fixed`, e nao so `overflow: hidden`: no iOS o overflow sozinho
 * nao segura o gesto e a pagina rola atras do painel assim mesmo. O fixed tira
 * o body do fluxo, por isso o `width: 100%` -- senao ele encolhe ao conteudo.
 */
body.ao-scroll-travado {
	position: fixed;
	width: 100%;
	overflow: hidden;
	/* O `top` negativo com a posicao de rolagem entra inline, via JS. */
}

.ao-drawer {
	position: fixed;
	inset: 0;
	z-index: 1000;
	display: none;
}

.ao-drawer.is-aberto {
	display: block;
}

.ao-drawer__fundo {
	position: absolute;
	inset: 0;
	background: rgba(0, 0, 0, .55);
	opacity: 0;
	transition: opacity .3s ease;

	/* O veu nao rola nada: sem isto o arraste sobre ele iria para a pagina
	   de tras. */
	overscroll-behavior: none;
	touch-action: none;
}

.ao-drawer.is-aberto.is-animando .ao-drawer__fundo {
	opacity: 1;
}

/*
 * A FOLHA sobe de baixo e ocupa so a altura do conteudo.
 * `dvh` e nao `vh`: no celular a barra do navegador entra e sai, e `vh` conta
 * a tela inteira -- a folha ficaria maior que o visivel.
 */
.ao-drawer__painel {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	display: flex;
	flex-direction: column;
	max-height: 85dvh;
	transform: translateY(100%);
	background: var(--ao-white);
	border-radius: var(--ao-radius-card) var(--ao-radius-card) 0 0;
	padding-bottom: env(safe-area-inset-bottom, 0px);
	transition: transform .3s ease;
}

/*
 * DUAS classes, nao uma: `is-aberto` so tira o `display: none`; `is-animando`
 * entra no frame seguinte e dispara o deslize. No mesmo frame o navegador
 * pintaria direto no estado final e nao haveria animacao.
 */
.ao-drawer.is-aberto.is-animando .ao-drawer__painel {
	transform: translateY(0);
}

/* Durante o arraste o JS escreve o transform inline; a transicao sai para o
   painel acompanhar o dedo, e volta ao soltar. */
.ao-drawer__painel.esta-arrastando {
	transition: none;
}

@media (prefers-reduced-motion: reduce) {
	.ao-drawer__painel,
	.ao-drawer__fundo {
		transition: none;
	}
}

/*
 * O cabecalho e a ALCA do arraste. `touch-action: none` e obrigatorio: sem
 * ele o navegador trata o gesto como rolagem e o `pointermove` nunca chega.
 */
.ao-drawer__cabecalho {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--ao-space-4);
	flex-shrink: 0;
	padding: var(--ao-space-8) var(--ao-space-6) var(--ao-space-4);
	touch-action: none;
	cursor: grab;
}

.ao-drawer__cabecalho:active {
	cursor: grabbing;
}

/* Puxador: a afordancia de folha que sobe, no lugar do X. */
.ao-drawer__cabecalho::before {
	content: '';
	position: absolute;
	top: 10px;
	left: 50%;
	width: 36px;
	height: 4px;
	transform: translateX(-50%);
	border-radius: 2px;
	background: var(--ao-grey-10);
}

.ao-drawer__titulo {
	margin: 0;
	font-size: var(--ao-fs-h3);
	line-height: var(--ao-lh-h3);
}

/* No celular o X sai: puxador, arraste, fundo e Esc ja fecham. */
.ao-drawer__fechar {
	display: none;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	background: none;
	border: 0;
	color: var(--ao-body);
	font-size: 28px;
	line-height: 1;
	cursor: pointer;
}

.ao-drawer__corpo {
	flex: 0 1 auto;
	min-height: 0;
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;

	/* Sem isto, ao chegar ao fim da rolagem interna o gesto CONTINUA na
	   pagina de tras e a gaveta parece empurrar o fundo. */
	overscroll-behavior: contain;
	padding: 0 var(--ao-space-6) var(--ao-space-8);
}

/* --------------------------------------------------------------------------
   Origem da foto: camera ou galeria
   -------------------------------------------------------------------------- */

.ao-origem-foto {
	display: flex;
	flex-direction: column;
	gap: var(--ao-space-4);
}

.ao-origem-foto__opcao {
	display: flex;
	align-items: center;
	gap: var(--ao-space-5);
	width: 100%;
	padding: var(--ao-space-5);
	background: var(--ao-white);
	border: 1px solid var(--ao-grey-10);
	border-radius: var(--ao-radius-card);
	text-align: left;
	font-family: inherit;
	color: var(--ao-body);
	cursor: pointer;
}

.ao-origem-foto__opcao:hover,
.ao-origem-foto__opcao:focus-visible {
	border-color: var(--ao-primary);
}

.ao-origem-foto__icone {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	background: color-mix(in srgb, var(--ao-primary) 10%, var(--ao-white));
	color: var(--ao-primary);
}

.ao-origem-foto__icone svg {
	width: 22px;
	height: 22px;
}

.ao-origem-foto__texto {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.ao-origem-foto__texto strong {
	font-size: var(--ao-fs-body-1);
	font-weight: var(--ao-fw-bold);
}

.ao-origem-foto__texto small {
	font-size: var(--ao-fs-body-2);
	color: var(--ao-muted);
}

/*
 * O input de camera fica escondido como o principal: e o botao da gaveta que
 * o aciona. `visually-hidden` e nao `display:none` -- um input de arquivo
 * oculto por display nao abre o seletor em alguns navegadores.
 */
.ao-dropzone__input[data-ao-dropzone-camera] {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
}

/* ==========================================================================
   Desktop — a gaveta vira modal centrado (>= 768px)
   "Fade + scale em 180ms e vocabulario de dialogo centrado; o slide de 300ms
   e de gaveta." [REF:paginas-conecta pc-desktop.css:1678]
   ========================================================================== */

@media (min-width: 768px) {
	.ao-drawer__painel {
		inset: auto;
		left: 50%;
		top: 50%;
		bottom: auto;
		width: min(480px, 92vw);
		max-height: 85vh;
		transform: translate(-50%, -50%) scale(.98);
		opacity: 0;
		border-radius: var(--ao-radius-card);
		padding-bottom: 0;
		transition: opacity .18s ease, transform .18s ease;
	}

	.ao-drawer.is-aberto.is-animando .ao-drawer__painel {
		opacity: 1;
		transform: translate(-50%, -50%) scale(1);
	}

	/* O X volta: sem o gesto de arraste, a caixa ficaria sem afordancia de
	   fechar visivel. */
	.ao-drawer__fechar {
		display: flex;
	}

	/* Puxador e cursor de arraste saem: no mouse nao ha gesto. O handler do
	   JS continua registrado e fica inerte -- so dispara em `pointerdown`
	   sobre o cabecalho. */
	.ao-drawer__cabecalho {
		padding-top: var(--ao-space-6);
		touch-action: auto;
		cursor: default;
	}

	.ao-drawer__cabecalho::before {
		content: none;
	}
}

/* --------------------------------------------------------------------------
   Minha Conta dividida em paginas (21/09)
   No celular a Minha Conta e um indice; cada bloco do formulario abre em
   pagina propria, com este link de volta. `[DECISÃO:2026-09-21]`
   -------------------------------------------------------------------------- */

.ao-conta-voltar {
	margin: 0 0 var(--ao-space-6);
}

.ao-conta-voltar__link {
	display: inline-flex;
	align-items: center;
	gap: var(--ao-space-2);

	/* O alvo de toque precisa dos 44px, mas o texto nao pode descolar do
	   titulo logo abaixo: o padding vertical cresce sem mover a linha de base
	   porque a margem do <p> ja o compensa. */
	padding-block: var(--ao-space-3);
	color: var(--ao-primary);
	font-size: var(--ao-fs-body-2);
	line-height: var(--ao-lh-body-2);
	font-weight: var(--ao-fw-semibold);
	text-decoration: none;
}

@media (hover: hover) {
	.ao-conta-voltar__link:hover {
		color: var(--ao-accent);
	}
}

.ao-conta-voltar__seta {
	width: 16px;
	height: 16px;
	flex: 0 0 auto;
}

/* --------------------------------------------------------------------------
   Desktop: o que e so do indice mobile nao aparece aqui
   -------------------------------------------------------------------------- */

/*
 * O que e do INDICE DO CELULAR nao aparece no desktop.
 *
 * O retrato, o "voltar" e os atalhos da conta nasceram com a Minha Conta em
 * lista (21/09), que so existe no mobile. No desktop o formulario continua na
 * propria tela: o retrato duplicaria a foto do upload logo abaixo, o "voltar
 * para Minha Conta" apontaria para a tela em que a pessoa ja esta, e os
 * atalhos repetiriam a sidebar -- inclusive "Sair", que ela tem.
 *
 * TUDO DENTRO DA MEDIA QUERY. A primeira versao escondeu sem media e deixou a
 * camada mobile reexibir; como `ao-painel.css` carrega DEPOIS de
 * `ao-mobile.css`, a reexibicao perdeu a cascata e sumiu no celular tambem.
 * Escondendo so onde se quer esconder, nao ha o que reexibir.
 */
@media (min-width: 768px) {
	.ao-conta-retrato,
	.ao-conta-voltar,
	.ao-conta-menu {
		display: none;
	}
}
