﻿/* Contratos - central premium de aceites e planos */
.contracts-workspace {
  gap: 1rem;
}

/* ═══════════════════════════════════════════════════════════════════════
   [19.3] CONTRATOS — A LISTA.

   Saíram: o hero com "Aceites digitais e planos", os três contadores
   (Pendentes / Assinados / Próx. vencimentos), o cartão "Lista de contratos"
   e o cartão do contrato com avatar de 54px, selo colorido, linha de
   vencimento com ícone e três botões no rodapé. Ficou: o cabeçalho da
   Biblioteca (título 22px/700 + linha de fatos 13px apagada), a busca de
   44px, a fileira de pílulas de 34px e uma linha de 68px por contrato.
   ═══════════════════════════════════════════════════════════════════════ */
.library-hero.contratos-hero h2 {
  font-size: 22px !important;
  font-weight: 700 !important;
  line-height: 1.15 !important;
}

/* [19.3 D] A busca é a barra de todas as telas, na altura do desenho. */
.contratos-busca .pattern-search-field {
  min-height: 44px;
}

.contratos-busca .pattern-search-field input {
  min-height: 42px;
}

.contratos-lista {
  display: grid;
  gap: 0;
}

.contrato-linha {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.7rem;
  min-height: 68px;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--borda);
}

.contratos-lista .contrato-linha:last-child { border-bottom: 0; }

/* [19.3 E] O CÍRCULO DA INICIAL: 32px, fundo a 12% da cor do tema. No
   encerrado ele é cinza — o contrato acabou, e a cor do tema é para o que
   ainda está em jogo. */
.contrato-inicial {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: rgba(var(--brand-rgb), 0.12);
  color: var(--brand-strong);
  font-size: var(--t-fato);
  font-weight: 700;
  line-height: 1;
}

.contrato-inicial.is-encerrado {
  background: rgba(255, 255, 255, 0.06);
  color: var(--muted);
}

.contrato-linha-texto {
  display: grid;
  gap: 0.15rem;
  min-width: 0;
}

.contrato-linha-nome {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}

.contrato-linha-nome strong {
  overflow: hidden;
  color: var(--ink);
  font-size: var(--t-corpo);
  font-weight: 600;
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.contrato-linha-fatos {
  overflow: hidden;
  color: var(--dim);
  font-size: var(--t-fato);
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* [18.3 E] "1 aluno sem acesso aguardando assinatura", agora como linha de
   fato acima da lista — o cartão que o segurava saiu. */
.contratos-sem-acesso {
  margin: 0 0 0.35rem !important;
}

/* [21.1] O PAINEL "FILTRAR" SAIU (details/summary, selects de Status /
   Aluno / Plano). `.filter-chevron` FICA: a seta que gira é usada também
   pelo histórico recolhível do Financeiro (financeiro.css) e pelo
   index.html. */
.filter-chevron {
  margin-left: auto;
  width: 1.1rem;
  height: 1.1rem;
  flex-shrink: 0;
  stroke: var(--muted);
  transition: transform 200ms ease;
}

.new-contract-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.8rem;
  width: 100%;
  min-height: 5.4rem;
  padding: 0.86rem 1rem;
  border: 1px dashed rgb(from var(--brand-soft) r g b / 0.55);
  border-radius: 0.92rem;
  background: rgb(from var(--brand-soft) r g b / 0.035);
  color: var(--brand-strong);
  text-align: left;
}

.new-contract-card:hover {
  border-color: rgb(from var(--brand-soft) r g b / 0.82);
  background: rgb(from var(--brand-soft) r g b / 0.075);
}

.new-contract-icon {
  display: inline-grid;
  width: 3rem;
  height: 3rem;
  place-items: center;
  border: 1px solid rgb(from var(--brand-soft) r g b / 0.72);
  border-radius: 999px;
  color: var(--brand-strong);
}

.new-contract-card svg {
  width: 1.3rem;
  height: 1.3rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.1;
}

.new-contract-card strong {
  display: block;
  color: var(--brand-strong);
  font-size: 1.04rem;
  line-height: 1.1;
}

.new-contract-card small {
  display: block;
  margin-top: 0.22rem;
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.25;
}

.contract-detail {
  display: grid;
  gap: 0.85rem;
}

.contract-detail-hero {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.78rem;
  padding: 0.78rem;
  border: 1px solid var(--line);
  border-radius: 0.9rem;
  background: rgb(from var(--ink) r g b / 0.045);
}

.contract-detail-hero .entity-avatar {
  width: 4.2rem;
  height: 4.2rem;
}

.contract-detail-title {
  display: grid;
  gap: 0.24rem;
  min-width: 0;
}

.contract-detail-title strong {
  color: var(--ink);
  font-size: 1.22rem;
  line-height: 1.12;
}

.contract-detail-title span {
  color: var(--muted);
  font-size: 0.86rem;
}

.contract-detail-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.55rem;
}

.contract-detail-grid article {
  display: grid;
  gap: 0.2rem;
  min-width: 0;
  padding: 0.7rem;
  border: 1px solid rgb(from var(--ink) r g b / 0.09);
  border-radius: 0.78rem;
  background: rgb(from var(--ink) r g b / 0.038);
}

.contract-detail-grid span {
  color: var(--muted);
  font-size: 0.75rem;
  line-height: 1.15;
}

.contract-detail-grid strong {
  color: var(--ink);
  font-size: 0.94rem;
  line-height: 1.25;
}

.contract-detail-section {
  display: grid;
  gap: 0.65rem;
  padding: 0.75rem;
  border: 1px solid var(--line);
  border-radius: 0.9rem;
  background: rgb(from var(--ink) r g b / 0.032);
}

.contract-detail-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.65rem;
}

@media (max-width: 68rem) {
  .contract-detail-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 57.99rem) {
  .contract-detail-hero {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .contract-detail-hero > .badge {
    grid-column: 2;
    justify-self: start;
  }

  .contract-detail-actions {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 28rem) {
  .contract-detail-grid {
    grid-template-columns: 1fr;
  }

  .new-contract-card {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .new-contract-card > svg {
    display: none;
  }
}

/* ─── Contract Form Sheet ─────────────────────────────────────────────────── */

/* O formulário reusa .ns-form (compartilhado com a tela de aluno), mas aqui ele
   vive dentro do .ex-sheet-body do sheet, cujo rodapé (.ex-sheet-footer) é um
   elemento SEPARADO fora da rolagem. Então, ao contrário da tela de aluno, não
   precisa do padding inferior de ~5rem que libera um rodapé sticky interno — só
   precisa de respiro lateral (o .ex-sheet-body não tem padding) e um respiro
   final curto. Dois IDs vencem o .ns-form sem !important. */
#contractFormSheet #contractSheetForm {
  padding: 0.85rem 1.1rem calc(1rem + var(--safe-bottom, 0px));
}

/* O espaçador do rodapé sticky da tela de aluno é inútil aqui (rodapé separado);
   zera para não somar espaço morto no fim da rolagem. */
#contractFormSheet #contractSheetForm .ns-footer-spacer {
  height: 0;
}

.cfs-student-field {
  position: relative;
}

.cfs-student-search {
  display: block;
  width: 100%;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  padding: 0.62rem 0.88rem;
  color: var(--ink);
  font-size: 0.95rem;
  outline: none;
  transition: border-color 0.15s;
}

.cfs-student-search:focus-visible {
  border-color: rgba(var(--brand-rgb), 0.5);
  box-shadow: 0 0 0 3px rgb(from var(--brand-soft) r g b / 0.3);
}

.cfs-student-results {
  display: flex;
  flex-direction: column;
  margin-top: 0.35rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  overflow: hidden;
}

.cfs-student-results[hidden] { display: none; }

.cfs-student-result {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0.88rem;
  background: transparent;
  border: none;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  transition: background 0.1s;
}

.cfs-student-result:hover,
.cfs-student-result:focus-visible {
  background: rgb(from var(--ink) r g b / 0.06);
}

.cfs-result-avatar {
  display: inline-grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  font-size: 0.72rem;
  font-weight: 700;
  flex-shrink: 0;
}

.cfs-no-results {
  color: var(--muted);
  font-size: 0.85rem;
  padding: 0.6rem 0.88rem;
}

/* ═══════════════════════════════════════════════════════════════════════
   [19.5] "EDITAR CONTRATO". Saíram: a caixa de pré-visualização do aluno
   (avatar + nome + objetivo), o "Plano / Serviço" desenhado como campo, o
   campo "Parcelas", o cartão do aviso do PDF e os rótulos em caixa-alta na
   cor do tema. O aluno é uma linha de 56px em caixa de campo; o plano é
   texto com "não muda"; os rótulos são 12px apagados acima do campo.
   ═══════════════════════════════════════════════════════════════════════ */
.cf-aluno {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-height: 56px;
  padding: 0 0.88rem;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  background: var(--card);
}

.cf-aluno-texto {
  display: grid;
  gap: 0.1rem;
  min-width: 0;
}

.cf-aluno-texto strong {
  overflow: hidden;
  color: var(--ink);
  font-size: var(--t-corpo);
  font-weight: 600;
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cf-aluno-texto span {
  overflow: hidden;
  color: var(--dim);
  font-size: var(--t-fato);
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* [19.5 B] O PLANO NÃO PARECE CAMPO: texto, sem caixa, e "não muda" à direita. */
.cf-plano {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  min-height: 44px;
  padding: 0 0.2rem;
}

.cf-plano-nome {
  overflow: hidden;
  color: var(--ink);
  font-size: var(--t-corpo);
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cf-nao-muda {
  flex: 0 0 auto;
  color: var(--dim);
  font-size: 12px;
}

/* [19.5 C] RÓTULOS de 12px apagados, acima do campo — vencem o `.field span`
   (0.88rem/750 na cor da tinta) do base.css. */
#contractFormSheet .cf-campo > .cf-rotulo {
  color: var(--dim);
  font-size: 12px;
  font-weight: 500;
}

/* [19.5 C] O CALENDÁRIO NÃO É AÇÃO: sem cor do tema. */
#contractFormSheet .ns-date-icon {
  stroke: var(--dim);
}

/* [19.5 E] "valor mensal" ocupa a largura; "início" e "fim" dividem a linha. */
.cf-termos {
  gap: 0.9rem;
}

/* [19.5 F] A frase do PDF e os avisos do formulário: 13px na cor fraca. */
.cf-aviso {
  margin: 0;
  color: var(--dim);
  font-size: var(--t-fato);
  line-height: 1.4;
}

.cf-aviso-pdf {
  margin-top: 1.4rem;
}

/* [20.2 D] O motivo ao lado do botão desligado: 13px na cor fraca, com o
   atalho para o perfil em texto. */
.cf-rodape-motivo {
  margin: 0;
  width: 100%;
  color: var(--dim);
  font-size: var(--t-fato);
  line-height: 1.4;
  text-align: center;
}

.ex-sheet-footer .primary-action[disabled] {
  opacity: 0.5;
  cursor: default;
}

/* ═══════════════════════════════════════════════════════════════════════
   [19.4] A FOLHA DO CONTRATO (professor). O componente é o da folha do
   compromisso (`.det-sheet` / `.det-panel`, em alunos.css): sobe de baixo,
   para na altura do conteúdo, um rolador só. Daqui é só o que muda: as
   linhas de dado têm 52px (rótulo 13px apagado à esquerda, valor 15px/500 à
   direita, com uma segunda linha de 13px quando há CPF), e a linha de fato
   do envio.
   ═══════════════════════════════════════════════════════════════════════ */
.contrato-folha-painel .ct-linha {
  min-height: 52px;
  align-items: center;
}

.contrato-folha-painel .ct-rotulo {
  color: var(--dim);
  font-size: var(--t-fato);
}

.contrato-folha-painel .ct-valor {
  display: grid;
  justify-items: end;
  gap: 0.1rem;
  min-width: 0;
  color: var(--ink);
  font-size: var(--t-corpo);
  font-weight: 500;
  text-align: right;
}

.contrato-folha-painel .ct-valor-texto {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.contrato-folha-painel .ct-valor-segunda {
  display: block;
  color: var(--dim);
  font-size: var(--t-fato);
  font-weight: 400;
}

.contrato-folha-envio {
  margin: 0;
  color: var(--dim);
  font-size: var(--t-fato);
  line-height: 1.35;
}

/* O visor do PDF revelado por "Ver contrato" respira do que vem antes. */
.contrato-folha-painel .ct-visor {
  margin-top: 0.4rem;
}

/* ═══════════════════════════════════════════════════════════════════════
   [19.6] "CONTRATO ENVIADO". A frase em 15px com o e-mail em 600; o aviso
   em 13px na cor fraca; o link como linha de 52px cortado pelo COMEÇO; o
   âmbar do WhatsApp com o ícone de conversa.
   ═══════════════════════════════════════════════════════════════════════ */
.ce-frase {
  margin: 0;
  color: var(--ink);
  font-size: var(--t-corpo);
  font-weight: 400;
  line-height: 1.4;
}

.ce-frase strong {
  font-weight: 600;
}

.ce-nota {
  margin: 0;
  color: var(--dim);
  font-size: var(--t-fato);
  line-height: 1.4;
}

/* `min-width: 0`: a linha é filha de uma grade, e sem isso ela cresceria
   até o tamanho do endereço em vez de cortá-lo. */
.contrato-enviado-painel .ce-link {
  min-width: 0;
  min-height: 52px;
  border-top: 1px solid var(--borda);
}

.ce-link-rotulo {
  color: var(--dim);
  font-size: var(--t-fato);
}

/* CORTADO PELO COMEÇO: a caixa é da direita para a esquerda, então o que
   transborda some pela esquerda e as reticências ficam no começo; o <bdi>
   mantém o endereço na ordem normal de leitura. */
.ce-link-endereco {
  min-width: 0;
  overflow: hidden;
  direction: rtl;
  text-align: left;
  color: var(--ink);
  font-size: var(--t-fato);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ce-link-endereco bdi {
  unicode-bidi: isolate;
}

.ce-whatsapp {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}

.ce-whatsapp svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

/* ─── Contract View Sheet (ALUNO) ─────────────────────────────────────────── */

.contract-view-hero {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.contract-view-hero-info {
  flex: 1;
  min-width: 0;
}

.contract-view-hero-info strong {
  display: block;
  color: var(--ink);
  font-size: 1rem;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.contract-view-hero-info span {
  color: var(--muted);
  font-size: 0.84rem;
}

/* O corpo do sheet (.ex-sheet-body) não tem padding; o conteúdo do detalhe pede
   respiro lateral e inferior (safe-area) para não colar nas bordas da tela. */
.contract-view-content {
  padding: 1rem 1.1rem calc(1.2rem + var(--safe-bottom, 0px));
}

/* ─── Cartão "Documento" (entrada para Visualizar / Baixar) ──────────────────── */

.contract-doc-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0.18rem 0.85rem;
  padding: 0.85rem 0.95rem;
  border: 1px solid var(--borda);
  border-radius: 0.9rem;
  background: var(--card);
}

.contract-doc-card-icon {
  grid-row: span 2;
  display: inline-grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 0.7rem;
  background: rgb(from var(--brand-soft) r g b / 0.1);
  color: var(--brand-strong);
}

.contract-doc-card-icon svg {
  width: 1.45rem;
  height: 1.45rem;
  stroke: currentColor;
  fill: none;
}

.contract-doc-card-text strong {
  display: block;
  color: var(--ink);
  font-size: 0.95rem;
  line-height: 1.2;
}

.contract-doc-card-text span {
  color: var(--muted);
  font-size: 0.8rem;
}

.contract-doc-card-actions {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.55rem;
}

.contract-doc-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.42rem;
  flex: 1 1 8rem;
  min-height: 2.5rem;
  padding: 0 0.8rem;
  border: 1px solid var(--line);
  border-radius: 0.7rem;
  background: rgb(from var(--ink) r g b / 0.04);
  color: var(--ink);
  font-size: 0.86rem;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease, color 150ms ease;
}

.contract-doc-btn svg {
  width: 1.02rem;
  height: 1.02rem;
  stroke: currentColor;
  fill: none;
  flex-shrink: 0;
}

.contract-doc-btn:hover {
  border-color: rgb(from var(--brand-soft) r g b / 0.55);
  color: var(--brand-strong);
}

.contract-doc-btn.is-brand {
  border-color: rgb(from var(--brand-soft) r g b / 0.45);
  background: rgb(from var(--brand-soft) r g b / 0.08);
  color: var(--brand-strong);
}

.contract-doc-btn.is-brand:hover {
  border-color: rgb(from var(--brand-soft) r g b / 0.75);
  background: rgb(from var(--brand-soft) r g b / 0.14);
}

.contract-doc-btn:disabled {
  opacity: 0.55;
  pointer-events: none;
}

/* ─── "Cara do PDF": folha branca formatada (revelada por Visualizar) ────────── */

.contract-paper-reveal {
  margin-top: 0.9rem;
}

.contract-paper-reveal[hidden] {
  display: none;
}

.cpaper-meta {
  margin: 0.7rem 0 0;
  text-align: center;
}

.contract-paper {
  --paper-ink: #1f2430;
  position: relative;
  max-width: 40rem;
  margin: 0 auto;
  padding: 2.4rem 2.1rem 2rem;
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 0.5rem;
  background: #fff;
  color: var(--paper-ink);
  font-family: Georgia, "Times New Roman", "Times", serif;
  box-shadow: 0 10px 30px rgb(0 0 0 / 0.18);
}

.contract-paper.is-empty {
  padding: 1.6rem;
  text-align: center;
  color: #6b7280;
  box-shadow: none;
}

.contract-paper .contract-doc-logo {
  padding: 0 0 1rem;
}

.contract-paper .contract-doc-logo-img {
  max-height: 2.8rem;
}

.cpaper-title {
  margin: 0 0 1.3rem;
  color: var(--paper-ink);
  font-family: inherit;
  font-size: 1.04rem;
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: 0.01em;
  text-align: center;
  text-transform: uppercase;
}

.cpaper-body {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.cpaper-body > p,
.cpaper-parties p,
.cpaper-sig p {
  margin: 0;
}

.cpaper-text,
.cpaper-clause {
  font-size: 0.9rem;
  line-height: 1.7;
  text-align: justify;
}

.cpaper-clause strong {
  font-weight: 700;
}

.cpaper-parties {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.cpaper-parties p {
  font-size: 0.9rem;
  line-height: 1.55;
}

.cpaper-parties strong {
  font-weight: 700;
}

.cpaper-sig {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin-top: 0.6rem;
  padding-top: 1rem;
  border-top: 1px solid rgb(0 0 0 / 0.14);
}

.cpaper-sig p {
  font-size: 0.86rem;
  line-height: 1.55;
}

.cpaper-sig-title {
  letter-spacing: 0.04em;
}

.cpaper-sig-note {
  color: #6b7280;
  font-size: 0.78rem;
}

.cpaper-footer {
  margin: 1.4rem 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid rgb(0 0 0 / 0.1);
  color: #6b7280;
  font-family: -apple-system, "Segoe UI", system-ui, sans-serif;
  font-size: 0.78rem;
  text-align: center;
}

@media (max-width: 28rem) {
  .contract-paper {
    padding: 1.7rem 1.25rem 1.5rem;
  }
}

.contract-timeline {
  display: flex;
  flex-direction: column;
  padding-left: 0.45rem;
}

.contract-tl-item {
  display: flex;
  align-items: flex-start;
  gap: 0.88rem;
  position: relative;
  padding-bottom: 1.1rem;
}

.contract-tl-item:last-child {
  padding-bottom: 0;
}

.contract-tl-item:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 0.38rem;
  top: 0.85rem;
  bottom: 0;
  width: 1px;
  background: var(--line);
}

.contract-tl-dot {
  width: 0.82rem;
  height: 0.82rem;
  border-radius: 50%;
  border: 2px solid var(--muted);
  background: var(--bg);
  flex-shrink: 0;
  margin-top: 0.1rem;
}

.contract-tl-item.is-done .contract-tl-dot {
  border-color: var(--ok);
  background: var(--ok);
}

.contract-tl-text {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.contract-tl-text > span {
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.contract-tl-text > strong {
  color: var(--ink);
  font-size: 0.88rem;
  font-weight: 500;
}

.contract-doc-logo {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0.5rem 0 0.75rem;
}

.contract-doc-logo-img {
  max-height: 3.25rem;
  max-width: 60%;
  object-fit: contain;
}

.contract-doc-body {
  white-space: pre-wrap;
  color: var(--ink);
  font-size: 0.88rem;
  line-height: 1.65;
  background: rgb(from var(--ink) r g b / 0.03);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  padding: 1rem;
  margin-top: 0.5rem;
  max-height: 24rem;
  overflow-y: auto;
}

.contract-doc-loading {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 1.25rem 1rem;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  margin-top: 0.5rem;
  color: var(--muted);
  font-size: 0.88rem;
}

.contract-doc-loading-spinner {
  display: inline-block;
  width: 1.1rem;
  height: 1.1rem;
  border: 2px solid var(--line);
  border-top-color: var(--brand);
  border-radius: 50%;
  flex-shrink: 0;
  animation: contract-doc-spin 0.8s linear infinite;
}

@keyframes contract-doc-spin {
  to { transform: rotate(360deg); }
}

/* ─── Contract PDF Upload (form) ─────────────────────────────────────────────── */

.contract-pdf-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 9rem;
  padding: 1.5rem;
  border: 2px dashed rgb(from var(--brand-soft) r g b / 0.38);
  border-radius: 0.88rem;
  background: rgb(from var(--brand-soft) r g b / 0.025);
  cursor: pointer;
  text-align: center;
  transition: border-color 150ms ease, background 150ms ease;
}

.contract-pdf-dropzone input[type="file"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 0;
  height: 0;
}

.contract-pdf-dropzone:hover,
.contract-pdf-dropzone.is-dragging {
  border-color: rgb(from var(--brand-soft) r g b / 0.75);
  background: rgb(from var(--brand-soft) r g b / 0.055);
}

.contract-pdf-dropzone.is-uploading {
  opacity: 0.55;
  pointer-events: none;
}

.contract-pdf-dropzone svg {
  width: 2.6rem;
  height: 2.6rem;
  stroke: var(--brand-strong);
  stroke-width: 1.6;
  fill: none;
  margin-bottom: 0.1rem;
}

.contract-pdf-dropzone strong {
  color: var(--brand-strong);
  font-size: 0.97rem;
  font-weight: 720;
}

.contract-pdf-dropzone span {
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.3;
}

.contract-pdf-attached {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.82rem 1rem;
  border: 1px solid rgb(from var(--success) r g b / 0.28);
  border-radius: 0.82rem;
  background: rgb(from var(--success) r g b / 0.04);
}

.contract-pdf-attached[hidden] { display: none; }

.contract-pdf-attached > svg {
  width: 2rem;
  height: 2rem;
  stroke: var(--ok);
  stroke-width: 1.8;
  fill: none;
  flex-shrink: 0;
}

.contract-pdf-file-meta {
  flex: 1;
  min-width: 0;
}

.contract-pdf-file-meta strong {
  display: block;
  color: var(--ink);
  font-size: 0.9rem;
  font-weight: 680;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.contract-pdf-file-meta span {
  color: var(--muted);
  font-size: 0.78rem;
}

.contract-pdf-remove-btn {
  flex-shrink: 0;
  padding: 0.34rem 0.72rem;
  border: 1px solid var(--line);
  border-radius: 0.5rem;
  background: transparent;
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 150ms ease, color 150ms ease;
}

.contract-pdf-remove-btn:hover {
  border-color: rgb(from var(--danger) r g b / 0.55);
  color: var(--danger);
}

/* ─── Geração automática de PDF a partir de modelo (form) ────────────────────── */

.cfs-doc-block {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  margin-top: 0.7rem;
}

.cfs-doc-block[hidden] { display: none; }

.cfs-generate-btn {
  width: 100%;
  justify-content: center;
  border-color: rgb(from var(--brand-soft) r g b / 0.45);
  color: var(--brand-strong);
}

.cfs-generate-btn:disabled {
  opacity: 0.55;
  pointer-events: none;
}

.cfs-pdf-status {
  margin: 0;
  font-size: 0.8rem;
  color: var(--ok);
}

.cfs-pdf-status.is-error { color: var(--danger); }

.cfs-pdf-status[hidden] { display: none; }

.cfs-pdf-preview .contract-pdf-doc {
  height: min(48vh, 30rem);
}

/* ─── Contract PDF Viewer (view sheet) ────────────────────────────────────────── */

.contract-pdf-viewer-wrap {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin-top: 0.3rem;
}

/* Host do PDF.js: rola TODAS as páginas (canvas empilhados) na vertical. Em iOS o
   scroll por toque precisa do momentum (-webkit-overflow-scrolling). */
.contract-pdf-doc {
  width: 100%;
  height: min(72vh, 52rem);
  min-height: 16rem;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  background: rgb(from var(--ink) r g b / 0.03);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem;
  scroll-behavior: smooth;
}

/* Cada página: fit-to-width (100% do host) e altura proporcional. O buffer interno
   do canvas é renderizado em alta resolução (DPR) no app.js; aqui só escalamos. */
.contract-pdf-page {
  display: block;
  width: 100%;
  height: auto;
  background: #fff;
  border-radius: 0.35rem;
  box-shadow: 0 1px 6px rgb(0 0 0 / 0.18);
}

.contract-pdf-doc-status {
  margin: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 1.5rem 1rem;
  text-align: center;
  color: var(--muted);
  font-size: 0.85rem;
}

.contract-pdf-doc-status.is-error { color: var(--danger); }

.contract-pdf-actions {
  display: flex;
  gap: 0.5rem;
}

.contract-pdf-open-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.44rem;
  flex: 1;
  justify-content: center;
  padding: 0.52rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: 0.6rem;
  background: rgb(from var(--ink) r g b / 0.04);
  color: var(--muted);
  font-size: 0.84rem;
  font-family: inherit;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 150ms ease, color 150ms ease, background 150ms ease;
}

.contract-pdf-open-btn:hover {
  border-color: rgb(from var(--brand-soft) r g b / 0.5);
  color: var(--brand-strong);
}

.contract-pdf-open-btn.is-download {
  border-color: rgb(from var(--brand-soft) r g b / 0.4);
  background: rgb(from var(--brand-soft) r g b / 0.06);
  color: var(--brand-strong);
}

.contract-pdf-open-btn.is-download:hover {
  border-color: rgb(from var(--brand-soft) r g b / 0.75);
  background: var(--brand-soft);
}

.contract-pdf-open-btn svg {
  width: 0.92rem;
  height: 0.92rem;
  stroke: currentColor;
  fill: none;
  flex-shrink: 0;
}

/* ─── Contract Consent Block (aceite jurídico) ───────────────────────────────── */

.contract-consent-block {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  width: 100%;
  padding: 1rem 1.1rem;
  border-top: 1px solid var(--line);
  background: var(--surface);
}

.contract-consent-check-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  cursor: pointer;
  padding: 0.7rem 0.9rem;
  border: 1px solid rgb(from var(--brand-soft) r g b / 0.28);
  border-radius: 0.65rem;
  background: rgb(from var(--brand-soft) r g b / 0.04);
  transition: border-color 120ms ease, background 120ms ease;
}

.contract-consent-check-row:hover {
  border-color: rgb(from var(--brand-soft) r g b / 0.55);
  background: rgb(from var(--brand-soft) r g b / 0.08);
}

.contract-consent-check-row input[type="checkbox"] {
  flex-shrink: 0;
  width: 1.1rem;
  height: 1.1rem;
  accent-color: var(--brand-strong);
  cursor: pointer;
}

.contract-consent-check-row span {
  font-size: 0.9rem;
  font-weight: 580;
  color: var(--ink);
  line-height: 1.3;
}

.contract-consent-block .primary-action:disabled {
  opacity: 0.38;
  cursor: not-allowed;
  pointer-events: none;
}

.contract-consent-block .small-text {
  font-size: 0.75rem;
  color: var(--muted);
  text-align: center;
  line-height: 1.4;
  margin: 0;
}

.contract-gate-error {
  margin: 0;
  padding: 0.6rem 0.8rem;
  border-radius: 0.6rem;
  border: 1px solid rgb(from var(--danger) r g b / 0.32);
  background: rgb(from var(--danger) r g b / 0.08);
  color: var(--danger);
  font-size: 0.82rem;
  font-weight: 600;
  line-height: 1.35;
}

.contract-gate-error[hidden] {
  display: none;
}

/* ─── Tela de assinatura premium (gate do aluno): menos blocos, mais respiro ─ */
.contract-gate--premium {
  gap: 1.1rem;
}

/* Cabeçalho: logo + nome do professor */
.gate-brand-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.3rem;
  padding: 1.65rem 1.25rem 1.5rem;
  border-radius: var(--radius);
  background: #1A1A1A;
  border-left: 3px solid var(--brand-strong);
  color: #f0ece0;
  box-shadow: var(--shadow);
}

.gate-brand-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 0.45rem;
}

.gate-brand-logo-img {
  max-height: 3.5rem;
  max-width: 64%;
  object-fit: contain;
}

.gate-brand-eyebrow {
  margin: 0;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand-strong);
}

.gate-brand-name {
  margin: 0;
  font-size: clamp(1.3rem, 6vw, 1.7rem);
  line-height: 1.12;
  color: #f0ece0;
}

.gate-brand-sub {
  margin-top: 0.2rem;
  max-width: 30rem;
  font-size: 0.85rem;
  line-height: 1.45;
  color: #9ca3af;
}

/* UM card do plano (plano + valor + fidelidade) */
.plan-gate-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.4rem;
  padding: 1.4rem 1.25rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
}

.plan-gate-eyebrow {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}

.plan-gate-title {
  font-size: 1.18rem;
  line-height: 1.2;
  color: var(--ink);
}

.pay-gate-value {
  margin-top: 0.45rem;
  font-size: 2.8rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--accent);
}

.pay-gate-methods {
  text-align: center;
  margin-top: 0.9rem;
}

.gate-link-action {
  display: block;
  width: 100%;
  background: none;
  border: 0;
  padding: 0.7rem;
  text-align: center;
  text-decoration: none;
  font-weight: 800;
  font-size: 0.95rem;
  color: var(--brand);
  cursor: pointer;
}

.gate-link-action--muted {
  color: var(--muted);
  font-weight: 500;
  font-size: 0.85rem;
}

.plan-gate-rows {
  display: flex;
  flex-direction: column;
  margin: 0.4rem 0 0;
}

.plan-gate-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.62rem 0;
  border-top: 1px solid var(--line);
}

.plan-gate-row dt {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--muted);
}

.plan-gate-row dd {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--ink);
  text-align: right;
}

.plan-gate-row dd small {
  margin-left: 0.15rem;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--muted);
}

/* Painel do documento (prévia do PDF real) */
.gate-doc-panel {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: 1.1rem 1.1rem 1.25rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
}

.gate-doc-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}

.gate-doc-head h4 {
  margin: 0;
  font-size: 1rem;
  color: var(--ink);
}

/* Painel de consentimentos + identidade */
.gate-sign-panel {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.gate-sign-panel .contract-consent-block {
  border-top: none;
  padding: 1.25rem 1.25rem 0.6rem;
}

.gate-sign-panel .form-actions {
  padding: 0.4rem 1.25rem 1.1rem;
}

.gate-sign-panel a.primary-action {
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  font-family: inherit;
}


/* ═══ [40.9]+[40.10] A TELA DE ACEITE, NOS DOIS LADOS ══════════════════════
   Tudo aqui vale para o professor e para o aluno: e a mesma casca e o mesmo
   painel de aceite ([40.0 A]). */

/* [40.10 B] O cabecalho do documento em DUAS linhas: o que e, e em que pe
   esta. O selo "Versão N" solto a direita saiu. */
.gate-doc-head--duas-linhas {
  display: grid;
  gap: 0.12rem;
  justify-content: start;
}

.gate-doc-sub {
  font-size: 0.8rem;
  color: var(--muted);
}

/* [40.10 E] A linha juridica encolhe e perde "identificação técnica", que
   ninguem sabe o que e. O seletor e longo de proposito: ela mora dentro do
   `.contract-consent-block`, que tem regra propria para `.small-text`.

   [41.15] item 1 — ELA MUDOU DE CASA, E A REGRA TEVE DE IR JUNTO. A barra
   fixa tirou o botão e esta linha de dentro do `.contract-consent-block`;
   o seletor antigo deixou de casar e o tamanho voltou para os 13,44px que
   `.small-text` herda. Os dois lugares estão listados aqui, na mesma regra,
   para que os 10,5px sejam UM fato só e não dois que possam divergir. */
.contract-consent-block .small-text.contract-linha-juridica,
.gate-barra-fixa .small-text.contract-linha-juridica {
  font-size: 10.5px;
  line-height: 1.35;
}

/* [40.9 A] Quando o cadastro do professor nao tem o que confirmar a
   identidade dele, o formulario de aceite NAO EXISTE: no lugar dele, o que
   falta e o caminho para preencher. */
.contract-sem-identidade .contract-gate-group-title {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--ink);
}

.contract-sem-identidade .contract-gate-list {
  margin: 0;
  padding-left: 1.1rem;
  display: grid;
  gap: 0.2rem;
  font-size: 0.85rem;
  color: var(--ink);
}

/* ═══════════════════════════════════════════════════════════════
   [41.15] item 1 — A BARRA DE CONFIRMAR, PRESA EMBAIXO, NOS DOIS LADOS.

   O botão de confirmar estava no FIM DA ROLAGEM. Numa tela que tem o
   documento inteiro em cima, chegar até ele é rolar quatro páginas de
   contrato — e é exatamente o que o [30.2]C proíbe: nenhuma ação principal
   depende de rolar.

   Ela é `fixed` e não `sticky` porque o que ela tem de acompanhar é a TELA,
   não o painel: o painel de aceite tem altura própria e rola junto. E ela
   sobe com o teclado (`--teclado`), porque os dois campos que ela confirma —
   nome e CPF — ficam logo acima dela.
   ═══════════════════════════════════════════════════════════════ */
.gate-barra-fixa {
  position: fixed;
  /* [54.2] a barra se APOIA na área segura (o mesmo desenho da barra de ação
     do kit: bottom = o que existe embaixo), em vez de engolir a área segura
     como padding — assim a medida "fundo da barra → fundo da tela" é SÓ a
     área segura, nas portas e nas telas de dentro, com uma conta só. */
  inset: auto 0 calc(var(--teclado, 0px) + var(--safe-bottom, 0px)) 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.7rem var(--goteira, 20px);
  background: var(--bg, #0D0D0D);
  border-top: 1px solid var(--line);
}

.gate-barra-fixa .primary-action {
  width: 100%;
  min-height: 50px;
}

.gate-barra-fixa .contract-linha-juridica {
  margin: 0;
  text-align: center;
}

/* O espaço que a barra ocupa: sem ele, ela cobre o fim do painel de aceite —
   que é justamente o campo de CPF.

   `.assin-aceite` saiu desta lista: o bloco de aceite embutido em "Minha
   assinatura" não existe mais ([41.15] item 2), e regra de CSS sem dono é o
   que o [41.12] mandou apagar.

   E o `:has` NÃO é enfeite. A classe `.contract-gate--premium` veste TRÊS
   telas: esta, o gate de pagamento (`renderPaymentGateShell`) e o beco do
   professor sem plano (`renderProfessorSemPlanoGate`). Só a primeira tem
   barra fixa; sem o `:has`, as outras duas ganhavam 112px de vão morto no
   fim da rolagem por causa de uma barra que elas não têm. */
.contract-gate--premium:has(.gate-barra-fixa) {
  padding-bottom: calc(112px + var(--safe-bottom, 0px));
}
