/* =========================================================================
   SurfApp - Portal do aluno
   -------------------------------------------------------------------------
   CSS escrito a mao, sem framework e sem build: o projeto nao depende de Node.
   Mobile first. Toda regra de layout maior comeca em min-width, de modo que a
   base ja e a versao de celular e o desktop apenas acrescenta colunas.
   ========================================================================= */

:root {
    /* --brand-primary e --brand-secondary chegam do <head>, injetadas por
       App\Support\Brand::cssVariables(). Os valores abaixo sao apenas a reserva
       da plataforma para quando a escola nao personalizou a marca.

       OS NOMES SAO HISTORICOS, e ler `--navy` como "azul-marinho" ja custou
       defeito neste arquivo. A traducao e esta, e vale para o arquivo inteiro:

           --navy, --navy-700, --navy-500 ....... a cor PRINCIPAL da escola
           --turquoise, --turquoise-600/050 ..... a cor SECUNDARIA da escola

       QUAL PAPEL CABE A CADA UMA (a regra que este arquivo passou a seguir):

           principal ... identidade. O cabecalho e os titulos. Uma faixa fina no
                         topo e a cor do texto dos titulos — nada de area grande
                         no meio da pagina.
           secundaria .. acao e apoio. Botao, link, selo, chip de horario, item
                         de menu sob o cursor.

       O que mudou e por que: o painel do portal abria com o cabecalho E o
       cartao de boas-vindas pintados da MESMA cor principal, colados um no
       outro — ~260px de cor chapada antes de qualquer conteudo. E o que parecia
       ser a secundaria no corpo da pagina (link, chip, selo) era um turquesa
       fixo que escola nenhuma escolheu. Ver `.hero` e os dois tokens da
       secundaria adiante. */
    --navy: var(--brand-primary, #0A2638);

    /*
       Os dois tons abaixo eram valores FIXOS, e isso quebrava o unico lugar que
       usa cada um. O `.hero` era um degrade de `--navy` ate `--navy-500`: com a
       cor principal vinda da escola e a segunda ponta fixa, nenhuma cor de texto
       servia para o cartao inteiro — marca clara dava 12,7 de contraste no
       comeco e 1,5 no fim. (Aquele degrade nao existe mais; ver `.hero`.)

       O segundo tom e calculado no servidor (`ReadableColor::shade()`) porque a
       DIRECAO depende da cor: sobre marca escura o degrade escurece, sobre marca
       clara ele clareia. Um `color-mix` fixo aqui no CSS nao da conta — foi a
       primeira tentativa, e ela derrubava `#1a828e` de 10,5 para 3,4.

       Os valores literais ficam como reserva para quando nao ha escola no
       contexto, e sao exatamente os tons que o portal sempre desenhou.
    */
    --navy-700: var(--brand-primary-shade, #0F3549);
    --navy-500: var(--brand-primary-shade, #17435C);

    /*
       A SECUNDARIA NOS TRES PAPEIS QUE ELA PRECISA TER.

       `--turquoise-600` e `--turquoise-050` eram literais — `#1a828e` e
       `#e4f1f0` —, e por isso o link do portal, o chip de horario e o selo
       "Confirmada" saiam turquesa em TODA escola, inclusive nas que escolheram
       vermelho ou ambar. Era o motivo real de "a secundaria a gente quase nao
       usa": ela estava na tela, mas era a da plataforma.

       Alem de errado como marca, era ilegivel: `#1a828e` mede 3,95:1 sobre
       `--bg` e 3,92:1 dentro do chip — abaixo dos 4,5 da WCAG, em todas as
       escolas ao mesmo tempo. `--brand-secondary-ink` e calculado
       (`ReadableColor::ink()` contra o mais escuro dos dois fundos) e o pior
       caso das 216 cores varridas passou a ser 4,51:1.

       `--brand-secondary-surface` e a secundaria com 12% de tinta sobre branco.
       Texto escuro por cima mede no minimo 11,81:1 na mesma varredura.
    */
    --turquoise: var(--brand-secondary, #4AA5A6);
    --turquoise-600: var(--brand-secondary-ink, #1a828e);
    --turquoise-050: var(--brand-secondary-surface, #e4f1f0);
    --accent: #c08a3e;
    --accent-050: #f7eedf;

    --bg: #f2efe8;
    --surface: #ffffff;
    --line: #e6e1d7;
    --line-strong: #d5cfc3;

    --ink: #0a2638;
    --ink-soft: #4f6472;
    --ink-faint: #8a9aa4;

    --danger: #c0503f;
    --danger-050: #f7e3df;
    --success: #1f7a5c;
    --success-050: #dcefe7;
    --warning: #c08a3e;
    --warning-050: #f7eedf;
    /* Ambar escuro de TEXTO sobre `--warning-050` (4,90:1, passa em AA). O
       valor ja existia escrito a mao em `.alert--warning` e em
       `.card--warning .card__title`; virou token quando a faixa de "sistema em
       validacao" precisou dele pela terceira vez. */
    --warning-700: #8a5f14;
    --info: #1a828e;
    --info-050: #e4f1f0;

    --radius: 14px;
    --radius-sm: 9px;
    --radius-pill: 999px;

    --shadow: 0 1px 2px rgba(10, 38, 56, .06), 0 6px 20px rgba(10, 38, 56, .07);
    --shadow-sm: 0 1px 2px rgba(10, 38, 56, .07);
    --shadow-lg: 0 10px 40px rgba(10, 38, 56, .14);

    --header-h: 60px;
    --maxw: 1120px;
}

/* -------------------------------------------------------------------------
   Base
   ------------------------------------------------------------------------- */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: 16px;
    line-height: 1.55;
    /* Nenhum filho pode empurrar a pagina para os lados no celular. */
    overflow-x: hidden;
}

img,
svg,
canvas {
    max-width: 100%;
    height: auto;
}

a {
    color: var(--turquoise-600);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

h1, h2, h3, h4 {
    margin: 0 0 .4rem;
    color: var(--brand-ink, var(--navy));
    line-height: 1.25;
    font-weight: 650;
}

h1 { font-size: 1.5rem; }
h2 { font-size: 1.2rem; }
h3 { font-size: 1.03rem; }
h4 { font-size: .95rem; }

p { margin: 0 0 .75rem; }

hr {
    border: 0;
    border-top: 1px solid var(--line);
    margin: 1.25rem 0;
}

.muted { color: var(--ink-soft); }
.faint { color: var(--ink-faint); }
.small { font-size: .84rem; }
.tiny { font-size: .76rem; }
.strong { font-weight: 650; }
.nowrap { white-space: nowrap; }
.center { text-align: center; }
.right { text-align: right; }
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: .5rem; }
.mt-2 { margin-top: 1rem; }
.mt-3 { margin-top: 1.5rem; }
.mb-0 { margin-bottom: 0; }
.mb-1 { margin-bottom: .5rem; }
.mb-2 { margin-bottom: 1rem; }
.mb-3 { margin-bottom: 1.5rem; }

/* Visivel para leitor de tela, invisivel na tela. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* -------------------------------------------------------------------------
   Estrutura
   ------------------------------------------------------------------------- */

.portal-shell {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.portal-main {
    flex: 1;
    width: 100%;
    max-width: var(--maxw);
    margin: 0 auto;
    /* A folga que antes liberava a barra inferior agora fica no rodape, que e o
       ultimo elemento da pagina. Sem isso o portal ganharia espaco vazio duas
       vezes no celular. */
    padding: 1rem 1rem 1.5rem;
}

@media (min-width: 900px) {
    .portal-main {
        padding: 1.75rem 1.5rem 2rem;
    }
}

/* -------------------------------------------------------------------------
   Cabecalho
   ------------------------------------------------------------------------- */

/*
    `--navy` e a cor PRINCIPAL da escola (ver o topo do arquivo), entao toda
    regra que a usa como fundo tem de tirar a cor do texto de
    `--brand-on-primary` — calculada por luminancia — em vez de fixar branco.
    Escola com primaria clara ficava com o cabecalho inteiro ilegivel.
*/
/*
    O CABECALHO E AGORA A UNICA SUPERFICIE GRANDE COM A COR DA ESCOLA — o cartao
    de boas-vindas deixou de ser a segunda (ver `.hero`). Isso torna a borda de
    baixo obrigatoria, e nao decorativa: com primaria clara (a escola real tem
    `#e0e0d2`) a faixa e o fundo bege da pagina ficam a uma distancia de
    contraste de 1,1 e o cabecalho perde a forma — vira um borrao no topo.

    O fio de baixo sai de `currentColor`, que aqui e `--brand-on-primary`: a cor
    que o `ReadableColor` ja escolheu como a que se ve sobre esta faixa. Por
    isso ele funciona nas duas pontas da paleta, escurecendo sob marca clara e
    clareando sob marca escura, sem uma segunda variavel para injetar.

    A linha `rgba` antes do `color-mix` e a reserva para navegador sem suporte,
    e reproduz exatamente o que o portal desenhava antes.
*/
.portal-header {
    position: sticky;
    top: 0;
    z-index: 30;
    background: var(--navy);
    color: var(--brand-on-primary, #fff);
    box-shadow: 0 1px 0 rgba(255, 255, 255, .06), var(--shadow-sm);
    box-shadow: 0 1px 0 color-mix(in srgb, currentColor 16%, transparent), var(--shadow-sm);
}

.portal-header__inner {
    max-width: var(--maxw);
    margin: 0 auto;
    min-height: var(--header-h);
    padding: .5rem 1rem;
    display: flex;
    align-items: center;
    gap: 1rem;
}

.brand {
    display: flex;
    align-items: center;
    gap: .6rem;
    /* Herda do cabecalho: quem decide claro ou escuro e a marca da escola. */
    color: inherit;
    font-weight: 700;
    letter-spacing: .01em;
    min-width: 0;
}

.brand:hover { text-decoration: none; }

/* O monograma de texto que ficava aqui saiu de cena: o cabecalho agora exibe a
   logomarca da escola ou o simbolo do SurfApp (ver o bloco "Marca" no fim). */

.brand__text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.brand__name {
    font-size: .98rem;
    line-height: 1.15;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.brand__sub {
    font-size: .7rem;
    font-weight: 500;
    /* Mesma cor do cabecalho, so que apagada — funciona nas duas paletas. */
    color: currentColor;
    opacity: .62;
    line-height: 1.2;
}

/* A barra `.portal-nav` fica entre a marca e este bloco, na mesma linha — ver o
   bloco "Do menu sanduiche para a barra" adiante. O `margin-left: auto` e o que
   joga a conta para a direita nas duas larguras: no celular ela sobra depois da
   marca, no desktop depois da barra. Havia aqui um `margin-left: .75rem` para
   900px que ANULAVA o auto; fazia sentido enquanto a barra morava numa segunda
   linha, e com ela de volta a linha deixava a conta grudada no menu. */

.portal-account {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: .5rem;
    flex: 0 0 auto;
}

.avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    /* O veu translucido segue a cor do texto do cabecalho, e nao branco fixo:
       sobre cabecalho claro um veu branco sumia junto com as iniciais. */
    background: rgba(255, 255, 255, .14);
    background: color-mix(in srgb, currentColor 14%, transparent);
    color: inherit;
    display: grid;
    place-items: center;
    font-size: .8rem;
    font-weight: 700;
    flex: 0 0 auto;
}

.avatar:hover { text-decoration: none; }

.logout-btn {
    background: transparent;
    border: 1px solid rgba(255, 255, 255, .22);
    border-color: color-mix(in srgb, currentColor 22%, transparent);
    color: currentColor;
    opacity: .85;
    border-radius: var(--radius-pill);
    padding: .34rem .7rem;
    font-size: .8rem;
    font-family: inherit;
    cursor: pointer;
}

.logout-btn:hover {
    background: rgba(255, 255, 255, .1);
    background: color-mix(in srgb, currentColor 10%, transparent);
    opacity: 1;
}

/* -------------------------------------------------------------------------
   Menu sanduiche
   -------------------------------------------------------------------------
   O QUE ELE SUBSTITUIU: uma `tabbar` fixa no rodape, com cinco colunas de
   largura igual, imitando a barra de um aplicativo instalado. O portal e um
   site no navegador: aquela barra disputava espaco com a barra do Chrome no
   celular, colidia com o gesto de voltar do sistema e prometia uma navegacao
   que o resto da tela nao cumpria. E, com as secoes dependendo do vinculo da
   pessoa, uma grade de cinco colunas fixas deixou de comportar a lista.

   SEM JAVASCRIPT: e um <details>/<summary>. Abre, fecha, recebe foco e responde
   a Enter e Espaco sem uma linha de script — o portal nao tem build, nao carrega
   CDN e a CSP nao deixaria passar script externo.

   O `name` compartilhado com `.school-switch` faz os dois menus do cabecalho
   serem um acordeao exclusivo, resolvido pelo navegador. Ver o partial.
   ------------------------------------------------------------------------- */

.portal-menu {
    flex: 0 0 auto;
}

.portal-menu__toggle {
    display: flex;
    align-items: center;
    gap: .45rem;
    /* Alvo de toque de 40px de altura: a recomendacao e 44, e o cabecalho tem
       60 — os 10px de folga em volta completam a area clicavel sem esticar a
       barra. */
    min-height: 40px;
    padding: .34rem .7rem;
    border: 1px solid rgba(255, 255, 255, .22);
    border-radius: var(--radius-pill);
    color: rgba(255, 255, 255, .9);
    font-size: .82rem;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    list-style: none;
    user-select: none;
}

/* O triangulo padrao do <summary> sai de cena nos dois motores. */
.portal-menu__toggle::-webkit-details-marker { display: none; }
.portal-menu__toggle::marker { content: ''; }

.portal-menu__toggle:hover {
    background: rgba(255, 255, 255, .1);
    color: #fff;
}

/* Foco VISIVEL, e nao o contorno padrao que some sobre o cabecalho escuro.
   Quem navega por teclado precisa enxergar onde esta antes de apertar Enter. */
.portal-menu__toggle:focus-visible,
.school-switch__toggle:focus-visible,
.portal-menu__item:focus-visible {
    outline: 2px solid var(--turquoise);
    outline-offset: 2px;
}

/* As tres barras, desenhadas em CSS: sem arquivo, sem icone de fonte externa
   (a CSP nao carregaria) e sem emoji, que muda de desenho a cada sistema.
   A do meio e o proprio elemento; as outras duas sao ::before e ::after. */
.portal-menu__bars,
.portal-menu__bars::before,
.portal-menu__bars::after {
    display: block;
    width: 18px;
    height: 2px;
    border-radius: 2px;
    background: currentColor;
}

.portal-menu__bars {
    position: relative;
}

.portal-menu__bars::before,
.portal-menu__bars::after {
    content: '';
    position: absolute;
    left: 0;
}

.portal-menu__bars::before { top: -6px; }
.portal-menu__bars::after { top: 6px; }

/* Aberto, as tres barras viram um X. E a unica pista de estado que o botao
   consegue dar sem script, e ela importa: o painel pode ficar fora do campo de
   visao em tela pequena. */
.portal-menu[open] .portal-menu__bars {
    background: transparent;
}

.portal-menu[open] .portal-menu__bars::before {
    top: 0;
    transform: rotate(45deg);
}

.portal-menu[open] .portal-menu__bars::after {
    top: 0;
    transform: rotate(-45deg);
}

/* A regra que mostrava a palavra "Menu" a partir de 560px saiu junto com o
   proprio rotulo: o botao e so o icone. As tres barras ja dizem o que ele faz,
   e a palavra disputava espaco com o nome da escola justamente na largura em
   que o botao existe. O `aria-label` do <summary> cobre o leitor de tela. */

/*
   O PAINEL.

   No celular ele e uma folha que ocupa a largura inteira, ancorada no
   CABECALHO (que e `position: sticky`, e portanto o bloco de contencao do
   `absolute`). A partir de 900px vira um menu suspenso preso ao botao — por
   isso `.portal-menu` so ganha `position: relative` naquela largura.
*/
.portal-menu__panel {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 50;
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - var(--header-h) - 1rem);
    overflow-y: auto;
    padding: .5rem;
    background: var(--surface);
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow-lg);
}

.portal-menu__group {
    margin: .6rem .55rem .25rem;
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

.portal-menu__group:first-child { margin-top: .1rem; }

.portal-menu__item {
    display: block;
    width: 100%;
    /* .7rem de altura de cada lado + a linha do texto passa dos 44px de alvo de
       toque, que e o que a barra inferior dava de graca e um menu de links
       precisa reconquistar. */
    padding: .7rem .55rem;
    border-radius: var(--radius-sm);
    color: var(--ink);
    font-size: .95rem;
    font-weight: 550;
    text-align: left;
}

.portal-menu__item:hover {
    background: var(--turquoise-050);
    text-decoration: none;
}

/*
    O item ativo usava `--turquoise-600` sobre `--turquoise-050`: 3,92 de
    contraste, abaixo dos 4,5 da WCAG. A correcao foi escurecer o texto — a
    tinta do fundo ja identifica qual secao esta aberta, e a cor do texto nao
    precisa repetir o recado ao custo da leitura.

    ATUALIZACAO: as duas cores DEIXARAM de ser fixas da plataforma (o comentario
    antigo dizia que eram) e hoje saem da secundaria da escola. `--ink` sobre a
    superficie de apoio mede 11,81:1 no pior caso das 216 cores varridas, entao
    a escolha de escurecer o texto continua valendo — agora para qualquer
    paleta, e nao so para o turquesa que estava escrito aqui.
*/
.portal-menu__item.is-active {
    background: var(--turquoise-050);
    color: var(--ink);
    font-weight: 700;
}

/* "Sair" e um <button> dentro de um <form> POST: o reset abaixo o faz parecer
   um item da lista sem deixar de ser um botao. */
.portal-menu__item--button {
    background: transparent;
    border: 0;
    font-family: inherit;
    cursor: pointer;
    color: var(--danger);
}

.portal-menu__item--button:hover {
    background: var(--danger-050);
}

/*
    "Comprar pacote" — o unico item de menu que e ACAO, e nao lugar.

    Ele fica no topo do painel, fora dos grupos, porque nao pertence a um
    vinculo so: o aluno sem cadastro de pagador tambem alcanca a vitrine (e para
    la que a agenda e as fotos o mandam quando falta pacote). Sem marca visual
    ele viraria "mais um link" no meio de sete, e o item que a escola mais
    precisa que seja achado seria o mais dificil de achar.

    A tinta e ambar da PLATAFORMA, e nao da escola, por dois motivos: distingue
    o item do estado ativo (turquesa) sem competir com ele, e nao depende de uma
    cor que a escola escolhe — `--warning-700` sobre `--accent-050` da 4,90:1 e
    passa em AA em qualquer marca. `.is-active` continua vencendo por
    especificidade quando a vitrine e a tela aberta: dentro dela o item volta a
    ser "onde voce esta", que e a informacao mais util naquele momento.
*/
.portal-menu__item--cta {
    background: var(--accent-050);
    color: var(--warning-700);
    font-weight: 700;
}

.portal-menu__item--cta:hover {
    background: #f0e2c9;
}

/* -------------------------------------------------------------------------
   Do menu sanduiche para a barra de navegacao, a partir de 900px
   -------------------------------------------------------------------------
   Sanduiche e um recurso de tela estreita: esconder a navegacao atras de um
   toque so se justifica quando ela nao cabe. A partir de 900px ela cabe, e fica
   a vista na MESMA linha da marca e do avatar.

   O que fez caber esta em `nav.blade.php`: "Meu cadastro" e "Sair" foram para o
   menu do avatar, "Inicio" virou o clique na marca, e o que sobrou foi agrupado
   por frequencia de uso. Os doze itens antigos davam 1033px numa linha que
   oferece ~692px; agora o caso mais cheio da ~560px.

   Sao DOIS blocos no HTML — o <details> do sanduiche e a `.portal-nav` —
   alternados por media query. Um markup so, deitado por CSS, foi medido e NAO
   funciona: o conteudo de um <details> fechado aceita `display` e ocupa caixa no
   layout, mas o navegador nao o pinta; sem botao para abrir, no desktop o menu
   ficaria invisivel para sempre.
   ------------------------------------------------------------------------- */

/* Abaixo de 900px quem navega e o sanduiche. */
.portal-nav { display: none; }

/* O sanduiche fica por ULTIMO na linha do celular, depois do seletor de escola
   e do avatar. No HTML ele vem antes, porque no desktop a barra se le entre a
   marca e a conta; aqui a ordem visual e outra e o flex resolve sem duplicar
   markup. */
.portal-menu { order: 3; }

@media (min-width: 900px) {
    /* O botao sanduiche inteiro sai de cena, e com ele o painel suspenso. */
    .portal-menu { display: none; }

    .portal-nav {
        display: flex;
        flex-direction: row;
        align-items: center;
        gap: .1rem;
        /* Encolhe antes da marca em janela apertada: o nome da escola diz onde
           a pessoa esta, e some com reticencias so depois. */
        min-width: 0;
    }

    .portal-nav .portal-menu__item {
        width: auto;
        padding: .45rem .6rem;
        /* Herda a cor do cabecalho — que ja e calculada contra a marca da
           escola (ver `--brand-on-primary`). Fixar `--ink` aqui repetiria o
           defeito de contraste que o resto do arquivo corrige. */
        color: inherit;
        font-size: .87rem;
        font-weight: 550;
        white-space: nowrap;
    }

    .portal-nav .portal-menu__item:hover {
        background: rgba(255, 255, 255, .12);
        background: color-mix(in srgb, currentColor 14%, transparent);
    }

    .portal-nav .portal-menu__item.is-active {
        background: rgba(255, 255, 255, .18);
        background: color-mix(in srgb, currentColor 20%, transparent);
        color: inherit;
        font-weight: 700;
    }

    /*
        A vitrine na barra: contorno, e nao tinta.

        Aqui o fundo e a cor PRINCIPAL DA ESCOLA, entao o ambar do menu do
        celular nao serve — sobre marca amarela ele sumiria, sobre marca escura
        gritaria. O contorno sai de `currentColor`, que ja e a cor calculada
        contra a marca (`--brand-on-primary`): o item se destaca dos vizinhos em
        qualquer paleta sem que nenhuma cor precise ser escolhida aqui.

        O `rgba` acima do `color-mix` e a reserva para navegador que nao suporta
        a funcao — ela cai para um branco translucido, que e o caso da maioria
        das marcas.
    */
    .portal-nav .portal-menu__item--cta {
        margin-left: .35rem;
        padding: .38rem .75rem;
        border: 1px solid rgba(255, 255, 255, .45);
        border: 1px solid color-mix(in srgb, currentColor 45%, transparent);
        border-radius: var(--radius-pill);
        background: transparent;
        color: inherit;
        font-weight: 700;
    }

    .portal-nav .portal-menu__item--cta:hover,
    .portal-nav .portal-menu__item--cta.is-active {
        background: rgba(255, 255, 255, .18);
        background: color-mix(in srgb, currentColor 20%, transparent);
    }
}

/*
    A FAIXA APERTADA: de 900px, onde a barra aparece, ate 1100px.

    O cabecalho e uma linha so, e ela nao quebra: quando o conteudo passa da
    largura, o bloco da conta e empurrado para fora e o avatar encavala o ultimo
    item. Media dos rotulos reais, com os DOIS vinculos e o nome de escola que
    trunca: em 900px a barra deixava ~110px livres antes de "Comprar pacote"
    existir, e a vitrine custa ~116px com a margem. Faltavam ~20px, e o defeito
    aparecia justamente no notebook de 13", que e onde a escola trabalha.

    A compressao devolve ~45px sem tirar nada da linha: o `gap` sai (a barra ja
    tem respiro no padding de cada item) e o padding lateral encolhe de .6rem
    para .42rem. Acima de 1100px nada disso vale e o espacamento continua o que
    era — apertar uma linha que tem folga so deixaria os itens grudados.

    Encolher a FONTE foi medido e descartado: economizava 12px e fazia a barra
    inteira mudar de tamanho no meio do redimensionamento, o que se le como
    defeito. O que muda aqui e so o ar em volta dos rotulos.
*/
@media (min-width: 900px) and (max-width: 1099px) {
    .portal-nav { gap: 0; }

    .portal-nav .portal-menu__item { padding: .45rem .42rem; }

    .portal-nav .portal-menu__item--cta {
        margin-left: .3rem;
        padding: .34rem .62rem;
    }
}

/* -------------------------------------------------------------------------
   Grupos da barra ("Progresso", "Responsavel")
   ------------------------------------------------------------------------- */

.portal-nav__group {
    position: relative;
    flex: 0 0 auto;
}

.portal-nav__group-toggle {
    display: flex;
    align-items: center;
    gap: .3rem;
    cursor: pointer;
    list-style: none;
    user-select: none;
}

.portal-nav__group-toggle::-webkit-details-marker { display: none; }
.portal-nav__group-toggle::marker { content: ''; }

.portal-nav__group-toggle:focus-visible {
    outline: 2px solid var(--turquoise);
    outline-offset: 2px;
}

/* O grupo que contem a tela aberta fica marcado, senao entrar em "Avaliacoes"
   apagaria a barra inteira e a pessoa perderia a referencia de onde esta. */
.portal-nav__group.is-active > .portal-nav__group-toggle {
    background: rgba(255, 255, 255, .18);
    background: color-mix(in srgb, currentColor 20%, transparent);
    font-weight: 700;
}

/* A setinha, desenhada em CSS: sem arquivo, sem fonte de icone (a CSP nao
   carregaria) e sem emoji, que muda de desenho a cada sistema. */
.portal-nav__caret {
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 4px solid currentColor;
    opacity: .7;
    transition: transform .12s ease;
}

.portal-nav__group[open] .portal-nav__caret { transform: rotate(180deg); }

.portal-nav__submenu {
    position: absolute;
    top: calc(100% + .4rem);
    left: 0;
    z-index: 50;
    min-width: 190px;
    display: flex;
    flex-direction: column;
    padding: .35rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}

/* Dentro do painel branco valem as cores de painel, e nao as do cabecalho: a
   regra da barra pede `color: inherit`, que aqui viraria texto claro sobre
   fundo claro. */
.portal-nav .portal-nav__submenu .portal-menu__item {
    width: 100%;
    padding: .55rem .6rem;
    color: var(--ink);
    font-size: .9rem;
    white-space: nowrap;
}

.portal-nav .portal-nav__submenu .portal-menu__item:hover {
    background: var(--turquoise-050);
}

.portal-nav .portal-nav__submenu .portal-menu__item.is-active {
    background: var(--turquoise-050);
    color: var(--ink);
    font-weight: 700;
}

/* -------------------------------------------------------------------------
   Menu da conta (o avatar)
   -------------------------------------------------------------------------
   "Meu cadastro" e "Sair" sairam da navegacao e vieram para ca, em TODAS as
   larguras: sao acoes sobre a conta, e nao lugares do portal, e e no proprio
   avatar que todo mundo procura por elas.
   ------------------------------------------------------------------------- */

.account-menu {
    position: relative;
    flex: 0 0 auto;
}

.account-menu__toggle {
    display: block;
    cursor: pointer;
    list-style: none;
    border-radius: 50%;
}

.account-menu__toggle::-webkit-details-marker { display: none; }
.account-menu__toggle::marker { content: ''; }

.account-menu__toggle:focus-visible {
    outline: 2px solid var(--turquoise);
    outline-offset: 2px;
}

.account-menu[open] .avatar,
.account-menu__toggle:hover .avatar {
    background: rgba(255, 255, 255, .26);
    background: color-mix(in srgb, currentColor 26%, transparent);
}

.account-menu__panel {
    position: absolute;
    top: calc(100% + .5rem);
    right: 0;
    z-index: 50;
    min-width: 210px;
    display: flex;
    flex-direction: column;
    padding: .35rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}

/* Quem esta logado, antes das acoes: e a pergunta que o avatar levanta, e a
   resposta nao cabe num circulo de 34px. */
.account-menu__who {
    display: flex;
    flex-direction: column;
    margin: .2rem .6rem .45rem;
    padding-bottom: .45rem;
    border-bottom: 1px solid var(--line);
}

.account-menu__name {
    color: var(--ink);
    font-size: .92rem;
    font-weight: 700;
    line-height: 1.25;
}

.account-menu__role {
    color: var(--ink-soft);
    font-size: .78rem;
}

/* No painel branco os itens voltam as cores de painel. */
.account-menu__panel .portal-menu__item {
    width: 100%;
    padding: .55rem .6rem;
    color: var(--ink);
    font-size: .92rem;
}

.account-menu__panel .portal-menu__item:hover {
    background: var(--turquoise-050);
}

.account-menu__panel .portal-menu__item--button {
    color: var(--danger);
}

.account-menu__panel .portal-menu__item--button:hover {
    background: var(--danger-050);
}

/* -------------------------------------------------------------------------
   Cartoes
   ------------------------------------------------------------------------- */

.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 1.1rem;
    margin-bottom: 1rem;
}

.card--flat {
    box-shadow: none;
}

.card--accent {
    border-left: 4px solid var(--turquoise);
}

.card__header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    flex-wrap: wrap;
    margin-bottom: .85rem;
}

.card__title {
    margin: 0;
    font-size: 1.02rem;
    font-weight: 650;
    color: var(--brand-ink, var(--navy));
}

.card__link {
    font-size: .82rem;
    font-weight: 600;
}

/* -------------------------------------------------------------------------
   Boas-vindas do painel (`.hero`)
   -------------------------------------------------------------------------
   ELE NAO CARREGA MAIS A COR DA ESCOLA, e esse e o ponto.

   O QUE ERA: um cartao de ~190px pintado com a cor principal, logo abaixo do
   cabecalho — que e da MESMA cor. Os dois colados davam ~260px de cor chapada
   antes de o painel comecar, e nas duas paletas que fotografamos o resultado
   era ruim por motivos opostos: com primaria clara (`#e0e0d2`) o cartao sumia
   dentro do fundo bege da pagina e o topo do portal virava um borrao sem forma;
   com primaria escura (`#122a5c`), um bloco navy dominava a dobra inteira e
   empurrava para baixo o que a pessoa veio ver — a proxima aula e o saldo.

   O QUE E AGORA: uma SAUDACAO, e nao um cartao. Sem fundo, sem sombra e sem
   caixa. O que restou de marca aqui e a cor do titulo, que ja e `--brand-ink` —
   a principal escurecida ate passar em 4,5:1 sobre `--bg` (ver `ReadableColor`
   e `Brand::cssVariables`). A escola continua presente na saudacao; ela so
   deixou de ser o fundo de um bloco de 190px.

   POR QUE NAO VIRAR UM CARTAO BRANCO como os outros: porque ele nao e um
   cartao. Nao tem titulo de secao, nao tem "ver todos", nao agrupa uma lista —
   e uma frase e quatro numeros. Com moldura branca, o painel abria com duas
   caixas em sequencia dizendo a mesma coisa. Sem moldura, a frase se le como
   cabecalho da pagina, que e o que ela sempre foi.

   Contrastes medidos (formula da WCAG, ver `Brand::secondaryInk` para o metodo):
     titulo `--brand-ink` sobre `--bg`  — 12,10:1 na paleta escura testada,
                                          4,67:1 na clara, 4,51:1 no pior caso
                                          possivel (o `ink()` para de escurecer
                                          assim que cruza 4,5);
     apoio  `--ink-soft` sobre `--bg`   — 5,38:1 (valor fixo, nao depende da
                                          escola).
   ------------------------------------------------------------------------- */
.hero {
    background: transparent;
    color: var(--ink);
    border: 0;
    border-radius: 0;
    padding: 0;
    box-shadow: none;
    /* Um pouco maior do que o 1rem dos cartoes: sem moldura, o respiro e a
       unica coisa que separa a saudacao do que vem depois. No painel de quem so
       paga, onde nao ha a faixa de numeros no meio, sem isto o "Bom dia" e o
       titulo "Quem voce paga" ficavam colados. */
    margin-bottom: 1.25rem;
}

/* O titulo volta a ser um titulo do portal: mesma tinta de "Proximas aulas" e
   "Meus pacotes". Antes era `inherit` porque o pai e que decidia claro ou
   escuro conforme a cor de fundo — sem fundo, quem decide e o `--brand-ink`. */
.hero h1 {
    color: var(--brand-ink, var(--navy));
    font-size: 1.35rem;
    margin-bottom: .2rem;
}

/* `--ink-soft` no lugar de `currentColor` com `opacity: .78`: a opacidade so
   funcionava porque havia um fundo conhecido embaixo. Sobre `--bg` ela daria um
   cinza sem contraste garantido; o token e medido (5,38:1). */
.hero p {
    color: var(--ink-soft);
    margin: 0;
    font-size: .9rem;
}

/* Sem a faixa de numeros: e o topo do painel de quem so paga, e nao ha
   "creditos" nem "frequencia" para contar ali. Continua existindo como
   modificador porque o painel do pagador o usa, mas sem caixa nao ha mais
   espacamento proprio para reduzir. */
.hero--compact {
    padding: 0;
}

.hero__stats {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .6rem;
    margin-top: .9rem;
}

@media (min-width: 620px) {
    .hero__stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/*
   Os numeros sairam de dentro do bloco colorido e viraram quatro fichas sobre a
   pagina, iguais aos demais cartoes do portal.

   O fundo era `color-mix(in srgb, currentColor 9%, transparent)` — um veu da
   propria cor do texto, que so fazia sentido enquanto havia um fundo de marca
   embaixo. Sobre `--bg` ele viraria um cinza de baixissimo contorno; a
   superficie e a linha explicitas dao a mesma leitura em qualquer paleta,
   porque nao dependem de paleta nenhuma.

   Contrastes medidos: `--ink` sobre `--surface` 15,59:1 (o numero) e
   `--ink-soft` sobre `--surface` 6,18:1 (o rotulo).
*/
.hero__stat {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: .6rem .7rem;
}

.hero__stat b {
    display: block;
    font-size: 1.3rem;
    line-height: 1.2;
    color: var(--ink);
}

.hero__stat span {
    font-size: .72rem;
    color: var(--ink-soft);
}

/* -------------------------------------------------------------------------
   Grades
   ------------------------------------------------------------------------- */

.grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
}

@media (min-width: 780px) {
    .grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .grid--sidebar { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
}

@media (min-width: 560px) {
    .grid--stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 940px) {
    .grid--stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.stat {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    padding: .9rem 1rem;
}

.stat__value {
    font-size: 1.55rem;
    font-weight: 700;
    color: var(--brand-ink, var(--navy));
    line-height: 1.2;
}

.stat__label {
    font-size: .78rem;
    color: var(--ink-soft);
    text-transform: uppercase;
    letter-spacing: .04em;
    font-weight: 600;
}

.stat__hint {
    font-size: .78rem;
    color: var(--ink-faint);
}

/* -------------------------------------------------------------------------
   Titulos de secao
   ------------------------------------------------------------------------- */

.page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.page-head p {
    margin: .15rem 0 0;
    color: var(--ink-soft);
    font-size: .9rem;
}

/* -------------------------------------------------------------------------
   Botoes
   ------------------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    padding: .58rem 1.05rem;
    font-family: inherit;
    font-size: .88rem;
    font-weight: 650;
    line-height: 1.2;
    cursor: pointer;
    text-align: center;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.btn:hover { text-decoration: none; }

.btn:disabled,
.btn.is-disabled {
    opacity: .55;
    cursor: not-allowed;
}

/*
    A cor do texto vem calculada da luminancia do fundo (ver `ReadableColor`),
    e nao escrita aqui. `#04262b` era um escuro pensado para o turquesa claro
    do padrao: a escola que escolhesse uma secundaria escura ficava com
    "Marcar uma aula" invisivel dentro do proprio botao — contraste 1,02.
    O valor de reserva mantem a aparencia antiga quando nao ha escola no
    contexto e nenhuma variavel foi injetada.
*/
.btn--primary {
    background: var(--turquoise);
    color: var(--brand-on-secondary, #04262b);
}

/*
   O hover era `background: var(--turquoise-600); color: #fff` com os dois
   valores FIXOS: o botao de acao de toda escola trocava a cor dela por um
   turquesa da plataforma no instante em que o cursor encostava. Agora ele so
   muda de TOM — `ReadableColor::shade()` sobre a propria secundaria, que anda
   para longe do texto, entao o botao sob o cursor nunca le pior do que parado
   (garantia varrida em `BrandContrastTest`).

   A reserva reproduz o comportamento antigo quando nao ha escola no contexto:
   `#1a828e` com texto claro da 4,54:1, que e o que o portal sempre desenhou.
*/
.btn--primary:hover:not(:disabled) {
    background: var(--brand-secondary-shade, #1a828e);
    color: var(--brand-on-secondary, #fff);
}

.btn--navy {
    background: var(--navy);
    color: var(--brand-on-primary, #fff);
}

.btn--navy:hover:not(:disabled) { background: var(--navy-700); }

.btn--ghost {
    background: transparent;
    border-color: var(--line-strong);
    color: var(--brand-ink, var(--navy));
}

.btn--ghost:hover:not(:disabled) { background: #eef3f8; }

.btn--danger {
    background: transparent;
    border-color: #f0c2c2;
    color: var(--danger);
}

.btn--danger:hover:not(:disabled) { background: var(--danger-050); }

.btn--accent {
    background: var(--accent);
    color: #4a2c0a;
}

.btn--accent:hover:not(:disabled) { background: #e78f47; }

.btn--sm {
    padding: .38rem .8rem;
    font-size: .8rem;
}

.btn--block {
    display: flex;
    width: 100%;
}

/*
    Cancela o `--block` quando a tela deixa de ser estreita.

    Serve ao botao que FECHA um fluxo — "Ir para o pagamento" — onde no celular
    a largura toda e o alvo certo e no desktop um botao de 1120px seria
    grotesco. Sozinho o modificador nao faz nada: ele existe so ao lado de
    `--block`, e por isso o seletor exige os dois.
*/
@media (min-width: 560px) {
    /* `display` junto: `--block` troca para `flex`, que e de nivel de bloco —
       so devolver `width: auto` deixaria o botao ocupando a linha do mesmo
       jeito. */
    .btn--block.btn--auto {
        display: inline-flex;
        width: auto;
    }
}

.btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

/* -------------------------------------------------------------------------
   Selos
   ------------------------------------------------------------------------- */

.badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    border-radius: var(--radius-pill);
    padding: .16rem .6rem;
    font-size: .74rem;
    font-weight: 650;
    line-height: 1.5;
    white-space: nowrap;
}

.badge--primary   { background: var(--info-050);      color: var(--info); }
.badge--success   { background: var(--success-050);   color: var(--success); }
.badge--danger    { background: var(--danger-050);    color: var(--danger); }
.badge--warning   { background: var(--warning-050);   color: var(--warning); }
.badge--info      { background: var(--turquoise-050); color: var(--turquoise-600); }
.badge--secondary { background: #eef2f6;              color: var(--ink-soft); }
.badge--dark      { background: #e3e8ee;              color: var(--brand-ink, var(--navy)); }

/* -------------------------------------------------------------------------
   Alertas
   ------------------------------------------------------------------------- */

.alert {
    display: flex;
    gap: .6rem;
    border-radius: var(--radius-sm);
    padding: .8rem .95rem;
    margin-bottom: 1rem;
    font-size: .9rem;
    border: 1px solid transparent;
}

.alert__icon { flex: 0 0 auto; font-size: 1rem; line-height: 1.45; }
.alert__body { min-width: 0; }
.alert p:last-child { margin-bottom: 0; }

.alert ul {
    margin: .25rem 0 0;
    padding-left: 1.1rem;
}

.alert--success { background: var(--success-050); border-color: #bfe3cc; color: #1f6b3c; }
.alert--error   { background: var(--danger-050);  border-color: #f2c4c4; color: #9c2b2b; }
.alert--warning { background: var(--warning-050); border-color: #eddcb4; color: #8a5f14; }
.alert--info    { background: var(--info-050);    border-color: #c5daf0; color: #1f5288; }

/* -------------------------------------------------------------------------
   Formularios
   ------------------------------------------------------------------------- */

.field {
    margin-bottom: .95rem;
}

.field > label,
.field-label {
    display: block;
    font-size: .82rem;
    font-weight: 650;
    color: var(--brand-ink, var(--navy));
    margin-bottom: .3rem;
}

.input,
.select,
.textarea {
    width: 100%;
    max-width: 100%;
    background: #fff;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    padding: .6rem .75rem;
    font-family: inherit;
    font-size: .95rem;
    color: var(--ink);
    appearance: none;
}

.textarea {
    min-height: 96px;
    resize: vertical;
}

.select {
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath fill='%2355657a' d='M1.4 0 7 5.6 12.6 0 14 1.4 7 8.4 0 1.4Z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .7rem center;
    padding-right: 2rem;
}

.input:focus,
.select:focus,
.textarea:focus {
    outline: none;
    border-color: var(--turquoise);
    box-shadow: 0 0 0 3px rgba(74, 165, 166, .18);
}

.input.is-invalid,
.select.is-invalid,
.textarea.is-invalid {
    border-color: var(--danger);
}

.field__error {
    display: block;
    color: var(--danger);
    font-size: .78rem;
    margin-top: .28rem;
}

.field__hint {
    display: block;
    color: var(--ink-faint);
    font-size: .78rem;
    margin-top: .28rem;
}

.check {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    font-size: .88rem;
    margin-bottom: .45rem;
    cursor: pointer;
}

.check input {
    margin-top: .22rem;
    width: 17px;
    height: 17px;
    accent-color: var(--turquoise);
    flex: 0 0 auto;
}

/* -------------------------------------------------------------------------
   Linha de pacote a venda (`.offer`)
   -------------------------------------------------------------------------
   Uma estrutura, dois usos: a lista de precos que o aluno sem cadastro de
   pagador ve (so leitura) e o rotulo do radio de quem compra. As duas mostram
   exatamente os mesmos campos, e escreve-las com marcacoes diferentes faria a
   vitrine parecer duas telas conforme quem entra.

   NOME E PRECO NA PRIMEIRA LINHA, o resto embaixo. Antes era uma frase corrida
   — "Pacote 5 aulas — R$ 500,00 · 5 aulas · 60 dias de validade" — que em
   375px virava um bloco de tres linhas em que nada saltava. O preco e
   justamente o que se compara entre um pacote e outro, e ele precisa estar
   sempre no mesmo lugar do olho.

   O `flex-basis: 100%` do meta e o que garante a quebra: ele ocupa a linha
   inteira sempre, tambem no desktop, e a coluna do meio nunca comprime o
   preco.

   ESCRITO NA PROPRIEDADE LONGA DE PROPOSITO. A forma curta equivalente (o
   `flex` de tres valores com base de 100%) esta proibida no arquivo inteiro
   por `PortalUnifiedTest`, que a procura como texto: era ela que jogava a
   barra de navegacao para uma segunda linha e levava o cabecalho de 60px a
   146px. Uma sentinela por texto tambem pega quem nao tem nada com o assunto,
   e ainda assim o teste esta certo em existir — melhor a propriedade longa
   aqui do que enfraquecer a guarda la.
   ------------------------------------------------------------------------- */

.offer {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: .1rem .75rem;
    min-width: 0;
}

.offer__name {
    font-weight: 650;
    color: var(--brand-ink, var(--navy));
}

.offer__price {
    font-weight: 700;
    white-space: nowrap;
}

.offer__meta {
    flex-basis: 100%;
    color: var(--ink-soft);
    font-size: .8rem;
}

/* Linhas direto no cartao: a lista so de leitura. */
.card > .offer {
    padding: .7rem 0;
    border-bottom: 1px solid var(--line);
}

.card > .offer:first-child { padding-top: 0; }

.card > .offer:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

/* A mesma linha, agora como rotulo de radio. O alvo de toque e a linha inteira
   e passa dos 44px pelo proprio padding — o radio de 17px nunca precisa ser
   acertado. */
.check--offer {
    align-items: center;
    gap: .65rem;
    margin-bottom: 0;
    padding: .75rem .1rem;
    border-bottom: 1px solid var(--line);
    font-size: .95rem;
}

.check--offer:first-child { padding-top: 0; }

.check--offer:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

/* O deslocamento existe para alinhar o radio a PRIMEIRA linha de um texto
   corrido; com a linha centrada ele desalinha. */
.check--offer input { margin-top: 0; }

.check--offer .offer {
    flex: 1 1 auto;
}

/* -------------------------------------------------------------------------
   Quantos pacotes (`.offer-qty` + `.stepper`)
   -------------------------------------------------------------------------
   A pergunta "quantos" era um cartao inteiro depois da lista, com rotulo,
   `<input class="input">` de largura total e dica embaixo — tres linhas de
   tela para uma resposta que quase sempre e "1". Ela virou a ultima linha do
   MESMO cartao da selecao, no formato que o dono do produto pediu: menos,
   numero, mais.

   A linha se le da esquerda para a direita como uma frase — "Quantos pacotes"
   de um lado, o controle do outro — e quebra em duas no celular estreito, que
   e o que `flex-wrap` garante sem media query.
   ------------------------------------------------------------------------- */

.offer-qty {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem .75rem;
    padding-top: .75rem;
}

.offer-qty__label {
    /* Nao usa `.field > label`: ali o rotulo e bloco, com margem embaixo, e
       aqui ele divide a linha com o controle. */
    margin: 0;
    font-size: .95rem;
    font-weight: 650;
    color: var(--brand-ink, var(--navy));
}

/* A moldura mora no CONJUNTO, e nao no campo: os tres elementos formam um
   controle so, e um contorno em volta de cada um viraria tres caixas. */
.stepper {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    background: #fff;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-pill);
}

/* O foco tambem e do conjunto: quem chega de teclado ao campo do meio precisa
   ver o controle inteiro destacado, e nao um retangulo interno. Mesmo halo de
   `.input:focus`, para o portal nao ter dois jeitos de mostrar foco. */
.stepper:focus-within {
    border-color: var(--turquoise);
    box-shadow: 0 0 0 3px rgba(74, 165, 166, .18);
}

/* 40px de lado: alvo de toque confortavel sem transformar a linha num bloco.
   Sao `<button type="button">` no HTML — dentro do formulario de compra, um
   botao sem tipo e `submit`, e o "+" enviaria o pedido. */
.stepper__btn {
    width: 40px;
    height: 40px;
    flex: 0 0 auto;
    border: 0;
    background: transparent;
    color: var(--brand-ink, var(--navy));
    font-family: inherit;
    font-size: 1.15rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    border-radius: var(--radius-pill);
}

.stepper__btn:hover {
    background: rgba(10, 38, 56, .06);
    background: color-mix(in srgb, currentColor 8%, transparent);
}

.stepper__btn:focus-visible {
    outline: 2px solid var(--turquoise);
    outline-offset: -3px;
}

/* Chega do JS quando o proximo passo sairia do intervalo do campo. O apagado e
   consequencia do `disabled`, e nao um substituto dele: o clique ja esta
   impedido de verdade. */
.stepper__btn:disabled {
    opacity: .3;
    cursor: not-allowed;
    background: transparent;
}

/* Continua sendo um `<input type="number">`; o que o CSS faz e tirar a moldura
   dele, que agora e do conjunto. */
.stepper__input {
    width: 2.6rem;
    border: 0;
    background: transparent;
    padding: .5rem 0;
    text-align: center;
    font-family: inherit;
    font-size: .95rem;
    font-weight: 700;
    color: var(--ink);
    /* As setinhas nativas saem porque os botoes de 40px fazem o mesmo trabalho
       com alvo de toque decente; o TECLADO continua com as setas, que nao
       dependem do desenho. */
    appearance: textfield;
    -moz-appearance: textfield;
}

.stepper__input::-webkit-outer-spin-button,
.stepper__input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* O halo ja e desenhado pelo conjunto, em `.stepper:focus-within`. */
.stepper__input:focus { outline: none; }

.form-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 1rem;
}

@media (min-width: 640px) {
    .form-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* CEP, cidade e UF numa linha so: sao tres campos que se leem juntos, e um
       CEP ocupando meia tela ao lado de um complemento vazio e o que faz o
       endereco parecer um formulario mais longo do que e. */
    .form-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .55rem;
    margin-top: .5rem;
}

/* Barra de filtros */
.filters {
    display: grid;
    grid-template-columns: 1fr;
    gap: .7rem;
    align-items: end;
}

@media (min-width: 640px) {
    .filters { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 980px) {
    .filters { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.filters .field { margin-bottom: 0; }

/* -------------------------------------------------------------------------
   Tabs
   ------------------------------------------------------------------------- */

.tabs {
    display: flex;
    gap: .35rem;
    border-bottom: 1px solid var(--line);
    margin-bottom: 1rem;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.tabs a {
    flex: 0 0 auto;
    padding: .55rem .85rem;
    font-size: .88rem;
    font-weight: 650;
    color: var(--ink-soft);
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    white-space: nowrap;
}

.tabs a:hover { color: var(--brand-ink, var(--navy)); text-decoration: none; }

.tabs a.is-active {
    color: var(--turquoise-600);
    border-bottom-color: var(--turquoise);
}

/* -------------------------------------------------------------------------
   Listas de aulas / reservas
   ------------------------------------------------------------------------- */

.day-group {
    margin-bottom: 1.35rem;
}

.day-group__title {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    font-size: .82rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--ink-soft);
    margin-bottom: .55rem;
}

.day-group__title b { color: var(--brand-ink, var(--navy)); }

.slot-list {
    display: grid;
    grid-template-columns: 1fr;
    gap: .65rem;
}

@media (min-width: 700px) {
    .slot-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.slot {
    display: flex;
    gap: .85rem;
    align-items: center;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    padding: .8rem .9rem;
    color: inherit;
}

.slot:hover {
    text-decoration: none;
    border-color: var(--turquoise);
    box-shadow: var(--shadow);
}

.slot__time {
    flex: 0 0 auto;
    width: 62px;
    text-align: center;
    background: var(--turquoise-050);
    color: var(--turquoise-600);
    border-radius: var(--radius-sm);
    padding: .4rem .2rem;
}

.slot__time b {
    display: block;
    font-size: 1.02rem;
    line-height: 1.2;
    color: var(--brand-ink, var(--navy));
}

.slot__time span { font-size: .66rem; }

.slot__body {
    min-width: 0;
    flex: 1;
}

.slot__title {
    font-weight: 650;
    color: var(--brand-ink, var(--navy));
    font-size: .95rem;
    overflow: hidden;
    text-overflow: ellipsis;
}

.slot__meta {
    font-size: .8rem;
    color: var(--ink-soft);
    overflow: hidden;
    text-overflow: ellipsis;
}

.slot__side {
    flex: 0 0 auto;
    text-align: right;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: .25rem;
}

/* -------------------------------------------------------------------------
   Barra de progresso
   ------------------------------------------------------------------------- */

.progress {
    height: 9px;
    background: #e6ecf2;
    border-radius: var(--radius-pill);
    overflow: hidden;
}

.progress__bar {
    height: 100%;
    background: linear-gradient(90deg, var(--turquoise) 0%, var(--turquoise-600) 100%);
    border-radius: var(--radius-pill);
}

.progress__bar--warning { background: linear-gradient(90deg, #f0b96f 0%, var(--accent) 100%); }
.progress__bar--danger  { background: linear-gradient(90deg, #e88585 0%, var(--danger) 100%); }

.progress-legend {
    display: flex;
    justify-content: space-between;
    font-size: .78rem;
    color: var(--ink-soft);
    margin-top: .35rem;
}

/* Medidor circular simples usado na nota geral. */
.gauge {
    display: flex;
    align-items: center;
    gap: .9rem;
}

.gauge__circle {
    flex: 0 0 auto;
    width: 84px;
    height: 84px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: conic-gradient(var(--turquoise) calc(var(--value, 0) * 1%), #e6ecf2 0);
}

.gauge__inner {
    width: 66px;
    height: 66px;
    border-radius: 50%;
    background: var(--surface);
    display: grid;
    place-items: center;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--brand-ink, var(--navy));
}

/* -------------------------------------------------------------------------
   Tabelas (rolam sozinhas, nunca a pagina)
   ------------------------------------------------------------------------- */

.table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin: 0 -.25rem;
    padding: 0 .25rem;
}

.table {
    width: 100%;
    min-width: 520px;
    border-collapse: collapse;
    font-size: .88rem;
}

.table th,
.table td {
    padding: .6rem .55rem;
    text-align: left;
    border-bottom: 1px solid var(--line);
    vertical-align: top;
}

.table th {
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--ink-soft);
    font-weight: 700;
    white-space: nowrap;
}

.table tbody tr:last-child td { border-bottom: 0; }

.table td.num,
.table th.num { text-align: right; white-space: nowrap; }

.amount-in  { color: var(--success); font-weight: 650; }
.amount-out { color: var(--danger);  font-weight: 650; }

/* Lista chave/valor */
.dl {
    display: grid;
    grid-template-columns: 1fr;
    gap: .55rem;
    margin: 0;
}

@media (min-width: 560px) {
    .dl--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.dl div { min-width: 0; }

.dl dt {
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--ink-faint);
    font-weight: 700;
}

.dl dd {
    margin: 0;
    font-size: .93rem;
    color: var(--ink);
    overflow-wrap: anywhere;
}

/* -------------------------------------------------------------------------
   Estado vazio
   ------------------------------------------------------------------------- */

.empty {
    text-align: center;
    padding: 2rem 1rem;
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius);
    background: #fbfdff;
}

/* O icone contextual e a marca d'agua ocupam a mesma celula da grade, um sobre
   o outro, para que o estado vazio continue com uma unica figura no topo. */
.empty__icon {
    display: grid;
    place-items: center;
    width: 64px;
    height: 64px;
    margin: 0 auto .5rem;
    font-size: 2rem;
    line-height: 1;
}

.empty__icon > * {
    grid-area: 1 / 1;
}

.empty__watermark {
    width: 64px;
    height: auto;
    object-fit: contain;
    opacity: .15;
}

.empty__glyph {
    line-height: 1;
}

.empty__title {
    font-weight: 650;
    color: var(--brand-ink, var(--navy));
    margin-bottom: .25rem;
}

.empty__text {
    color: var(--ink-soft);
    font-size: .89rem;
    margin: 0 auto .9rem;
    max-width: 46ch;
}

/* -------------------------------------------------------------------------
   Graficos
   ------------------------------------------------------------------------- */

.chart {
    width: 100%;
    min-height: 260px;
}

.chart--tall { min-height: 330px; }

/* -------------------------------------------------------------------------
   Paginacao
   ------------------------------------------------------------------------- */

.pagination {
    display: flex;
    flex-wrap: wrap;
    gap: .3rem;
    list-style: none;
    padding: 0;
    margin: 1.25rem 0 0;
    justify-content: center;
}

.pagination a,
.pagination span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 36px;
    height: 36px;
    padding: 0 .55rem;
    border-radius: var(--radius-sm);
    border: 1px solid var(--line);
    background: var(--surface);
    color: var(--ink-soft);
    font-size: .85rem;
    font-weight: 600;
}

.pagination a:hover {
    text-decoration: none;
    border-color: var(--turquoise);
    color: var(--turquoise-600);
}

.pagination .is-active span,
.pagination span[aria-current] {
    background: var(--navy);
    border-color: var(--brand-ink, var(--navy));
    color: var(--brand-on-primary, #fff);
}

.pagination .is-disabled span {
    opacity: .45;
}

/* -------------------------------------------------------------------------
   Telas de visitante (login, senha)
   ------------------------------------------------------------------------- */

.guest {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 1.5rem 1rem 2.5rem;
    background:
        radial-gradient(1100px 520px at 50% -12%, rgba(74, 165, 166, .30) 0%, transparent 62%),
        linear-gradient(180deg, #0a2638 0%, #2e6a79 46%, #f2efe8 46%, #f2efe8 100%);
}

.guest__card {
    width: 100%;
    max-width: 420px;
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 1.5rem 1.35rem;
}

.guest__brand {
    /* Mesma largura do cartao: sem uma largura definida o `max-width` do
       logotipo se resolveria contra a largura da propria imagem e acabaria
       encolhendo a marca. */
    width: 100%;
    max-width: 420px;
    text-align: center;
    color: #fff;
    margin-bottom: 1.25rem;
}

.guest__brand p {
    color: rgba(255, 255, 255, .72);
    font-size: .85rem;
    margin: 0;
}

.guest__foot {
    text-align: center;
    font-size: .82rem;
    color: var(--ink-soft);
    margin-top: 1.1rem;
}

.guest__legal {
    text-align: center;
    font-size: .76rem;
    color: var(--ink-faint);
    margin-top: 1.25rem;
}

/* -------------------------------------------------------------------------
   Impressao
   ------------------------------------------------------------------------- */

@media print {
    .portal-header,
    .portal-footer,
    .portal-menu,
    .btn-row,
    .no-print { display: none !important; }

    body { background: #fff; }
    .card { box-shadow: none; border-color: #ccc; }
}

/* =========================================================================
   Marca
   -------------------------------------------------------------------------
   Regras de exibicao das imagens de marca, comuns ao cabecalho, ao rodape e
   as telas de visitante.

   Tres cuidados valem para toda imagem daqui:

     1. altura fixa e `width: auto`, para o logotipo nunca esticar;
     2. `object-fit: contain`, porque a logomarca enviada pela escola pode ter
        qualquer proporcao e nao pode ser cortada;
     3. em fundo escuro entra o arquivo REVERSO, gerado no kit. Clarear com
        filtro CSS distorceria as cores do simbolo e esta proibido.
   ========================================================================= */

/* Simbolo do SurfApp no cabecalho, quando a escola nao subiu logomarca. */
.brand__mark-img {
    flex: 0 0 auto;
    height: 32px;
    width: auto;
    object-fit: contain;
}

/* Logomarca da escola, direto sobre o cabecalho.

   A cor de fundo vem de `--brand-logo-plate`, injetada por escola no `<style>`
   do layout (ver `Brand::cssVariables()` e o enum `LogoBackground`). Ela existe
   por um motivo real: PNG transparente com tracos claros, ou a versao reversa
   que muita escola usa nas redes, some por completo num cabecalho da cor da
   propria escola, e sem esse fundo nao ha como a escola corrigir a tela.

   O QUE SAIU DAQUI FOI A MOLDURA, e nao a protecao. Havia um respiro de
   `.3rem .5rem` mais um contorno de 1px em volta: os dois juntos estendiam a
   placa PARA FORA do desenho e fechavam um retangulo, entao ate a logomarca que
   ja traz fundo proprio aparecia dentro de um cartao branco que ninguem pediu —
   foi exatamente essa borda branca que o dono do produto viu no portal.

   Sem respiro e sem contorno o fundo passa a ter EXATAMENTE o tamanho da arte
   (`height: 32px` + `width: auto` com `contain` no `img`), e os dois casos se
   resolvem sozinhos:

     - logomarca com fundo proprio cobre esse fundo inteiro, entao a marca fica
       limpa sobre o cabecalho;
     - logomarca transparente continua desenhada sobre o fundo que a escola
       escolheu, que e o unico jeito de ela nao sumir.

   O `border-radius` fica SEM `overflow: hidden` de proposito: arredondar o
   fundo e desejavel, recortar o canto da marca nao — `contain` preserva a
   proporcao justamente para a arte nunca perder um pedaco.

   A reserva do fundo virou `transparent`, e nao `#fff`: `--brand-logo-plate` so
   falta onde nao ha escola no contexto, e ali nao ha logomarca de escola para
   desenhar tampouco. Um branco fixo de reserva seria a moldura voltando em
   qualquer tela que esquecesse de injetar a variavel. */
.brand__logo {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--brand-logo-plate, transparent);
    border-radius: var(--radius-sm);
    max-width: 148px;
}

.brand__logo-img {
    height: 32px;
    width: auto;
    max-width: 100%;
    /* `contain` e nao `cover`: marca cortada e marca errada. Prefiro sobrar
       espaco na placa a perder um pedaco do desenho. */
    object-fit: contain;
    display: block;
}

/* -------------------------------------------------------------------------
   Assinatura da plataforma no rodape do portal
   -------------------------------------------------------------------------
   O portal e white label: a escola lidera a tela. O SurfApp assina aqui, baixo
   e discreto.

   A folga extra no fim da pagina saiu junto com a barra inferior fixa: ela
   existia so para o ultimo elemento nao ficar debaixo dela. Sem barra, o
   espaco vazio seria espaco vazio.
   ------------------------------------------------------------------------- */

.portal-footer {
    text-align: center;
    padding: .25rem 1rem 1.75rem;
}

.portal-footer__link {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    color: var(--ink-faint);
    font-size: .76rem;
    font-weight: 600;
    letter-spacing: .01em;
    opacity: .85;
}

.portal-footer__link:hover {
    color: var(--ink-soft);
    text-decoration: none;
    opacity: 1;
}

.portal-footer__mark {
    height: 18px;
    width: auto;
    object-fit: contain;
}

/* -------------------------------------------------------------------------
   Marca nas telas de visitante
   -------------------------------------------------------------------------
   O topo da tela de login e um degrade escuro, entao aqui a assinatura vertical
   e sempre a versao reversa.
   ------------------------------------------------------------------------- */

.guest__logo-wrap {
    margin: 0 0 .6rem;
    line-height: 1;
}

/* A assinatura passou de VERTICAL para HORIZONTAL LIMPA (ver o comentário em
   `portal/layouts/guest.blade.php`). A altura desce junto: a arte horizontal é
   ~3,3x mais larga que alta, e mantê-la em 110px a faria ocupar quase toda a
   largura do cartão no celular. 56px é a mesma altura que o painel usa na tela
   de login dele, o que deixa as duas portas de entrada do produto com a marca
   no mesmo tamanho. */
.guest__logo {
    height: 56px;
    width: auto;
    max-width: 82%;
    object-fit: contain;
}

.guest__tagline {
    color: rgba(255, 255, 255, .78);
    font-size: .78rem;
    letter-spacing: .04em;
    margin: 0;
}

.guest__subtitle {
    color: rgba(255, 255, 255, .72);
    font-size: .85rem;
    margin: .35rem 0 0;
}

/* ---------------------------------------------------------------------------
   Fotos e videos
   ---------------------------------------------------------------------------
   Grade fluida com `auto-fill`: a mesma marcacao serve do celular ao desktop
   sem media query, e o numero de colunas acompanha a largura disponivel.
--------------------------------------------------------------------------- */

.gallery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 1rem;
}

.gallery-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    color: inherit;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    text-decoration: none;
    transition: box-shadow .15s ease, transform .15s ease;
}

.gallery-card:hover {
    box-shadow: var(--shadow);
    transform: translateY(-2px);
}

.gallery-card__cover {
    aspect-ratio: 4 / 3;
    background: var(--turquoise-050);
    display: block;
    position: relative;
}

.gallery-card__cover img {
    height: 100%;
    object-fit: cover;
    width: 100%;
}

.gallery-card__placeholder {
    align-items: center;
    display: flex;
    font-size: 2rem;
    height: 100%;
    justify-content: center;
    opacity: .5;
}

.gallery-card__count {
    background: rgba(10, 38, 56, .78);
    border-radius: var(--radius-pill);
    bottom: .5rem;
    color: #fff;
    font-size: .72rem;
    padding: .12rem .5rem;
    position: absolute;
    right: .5rem;
}

.gallery-card__body {
    display: block;
    padding: .7rem .85rem .9rem;
}

.gallery-card__title {
    display: block;
    font-weight: 600;
    line-height: 1.3;
}

.gallery-card__meta {
    color: var(--ink-faint);
    display: block;
    font-size: .78rem;
    margin-top: .2rem;
}

/* Grade das midias dentro de uma galeria. Colunas menores que as da lista de
   galerias: aqui o objetivo e varrer muitas fotos de uma vez. */
.media-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: .6rem;
}

.media-tile {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    margin: 0;
    overflow: hidden;
}

.media-tile__open {
    background: var(--turquoise-050);
    border: 0;
    cursor: zoom-in;
    display: block;
    padding: 0;
    position: relative;
    width: 100%;
}

.media-tile__open img {
    aspect-ratio: 1;
    display: block;
    object-fit: cover;
    width: 100%;
}

.media-tile__badge {
    align-items: center;
    background: rgba(10, 38, 56, .6);
    border-radius: 50%;
    color: #fff;
    display: flex;
    font-size: .9rem;
    height: 34px;
    justify-content: center;
    left: 50%;
    position: absolute;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 34px;
}

.media-tile__duration {
    background: rgba(10, 38, 56, .78);
    border-radius: var(--radius-pill);
    bottom: .35rem;
    color: #fff;
    font-size: .68rem;
    padding: .1rem .4rem;
    position: absolute;
    right: .35rem;
}

.media-tile__foot {
    border-top: 1px solid var(--line);
    display: flex;
    justify-content: center;
    padding: .35rem;
}

.btn--xs {
    font-size: .72rem;
    padding: .22rem .55rem;
}

/* Sobreposicao de visualizacao. Escrita a mao: o portal nao carrega nada de
   CDN, e uma lightbox com uma imagem nao justifica uma dependencia. */
.lightbox {
    align-items: center;
    background: rgba(10, 38, 56, .92);
    display: flex;
    inset: 0;
    justify-content: center;
    padding: 1.2rem;
    position: fixed;
    z-index: 60;
}

.lightbox[hidden] { display: none; }

.lightbox__stage {
    max-height: 92vh;
    max-width: 96vw;
}

.lightbox__stage img,
.lightbox__stage video {
    border-radius: var(--radius-sm);
    max-height: 92vh;
    max-width: 96vw;
    object-fit: contain;
}

.lightbox__close {
    background: transparent;
    border: 0;
    color: #fff;
    cursor: pointer;
    font-size: 2rem;
    line-height: 1;
    padding: .3rem .6rem;
    position: absolute;
    right: .8rem;
    top: .6rem;
}

/* -------------------------------------------------------------------------
   Area do responsavel (portal/responsavel)
   -------------------------------------------------------------------------
   Acrescimo, nunca alteracao: todos os seletores abaixo sao nomes NOVOS, usados
   apenas pelas telas do pagador. O portal do aluno nao referencia nenhum deles,
   entao esta secao nao pode mudar a aparencia de nada que ja existia.

   `.section` e `.section__title` ja estavam no HTML do painel do pagador desde
   que a area nasceu, mas nunca existiram na folha de estilo: os titulos saiam
   com o tamanho padrao do h1/h2 e sem respiro entre os blocos.
   ------------------------------------------------------------------------- */

.section {
    margin-bottom: 1.5rem;
}

.section__title {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    flex-wrap: wrap;
    margin: 0 0 .7rem;
    font-size: 1.05rem;
    font-weight: 650;
    color: var(--brand-ink, var(--navy));
}

/* Numero grande do bloco de destaque (valor em aberto). */
.card__value {
    margin: .1rem 0 .35rem;
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--brand-ink, var(--navy));
    line-height: 1.1;
}

/* Cartao de aviso: usado quando ha valor em aberto. A tarja lateral carrega o
   alerta sem pintar o cartao inteiro, que ficaria gritando na tela toda. */
.card--warning {
    border-left: 4px solid var(--warning);
    background: var(--warning-050);
}

.card--warning .card__title { color: #8a5a12; }

/* Cartao inteiro clicavel (um dependente da lista). O <a> vira bloco e herda a
   cor do texto: sem isso o cartao inteiro sairia azul e sublinhado. */
.card--link {
    display: block;
    color: inherit;
}

.card--link:hover {
    border-color: var(--turquoise);
    text-decoration: none;
}

.card--link .card__title { color: var(--brand-ink, var(--navy)); }

/* Lista simples dentro de um cartao (parcelas de uma cobranca). */
.list {
    margin: .6rem 0 0;
    padding-left: 1.1rem;
}

.list li { margin-bottom: .25rem; }

.list--compact {
    font-size: .84rem;
    color: var(--ink-soft);
}

.list--compact li:last-child { margin-bottom: 0; }

/* -------------------------------------------------------------------------
   Troca de escola (cabecalho)
   -------------------------------------------------------------------------
   So existe na tela de quem tem mais de um vinculo provado na sessao; para
   todo mundo mais o HTML nem chega a ser renderizado.

   Abre e fecha com <details>/<summary>, sem uma linha de JavaScript: o portal
   nao tem build, nao carrega CDN e a CSP nao deixaria passar script externo.
   ------------------------------------------------------------------------- */

.school-switch {
    position: relative;
    flex: 0 1 auto;
    min-width: 0;
}

.school-switch__toggle {
    display: flex;
    align-items: center;
    gap: .3rem;
    max-width: 42vw;
    padding: .34rem .6rem;
    border: 1px solid rgba(255, 255, 255, .22);
    border-radius: var(--radius-pill);
    color: rgba(255, 255, 255, .9);
    font-size: .8rem;
    line-height: 1.2;
    cursor: pointer;
    list-style: none;
    user-select: none;
}

/* O triangulo padrao do <summary> sai de cena nos dois motores. */
.school-switch__toggle::-webkit-details-marker { display: none; }
.school-switch__toggle::marker { content: ''; }

.school-switch__toggle:hover {
    background: rgba(255, 255, 255, .1);
    color: #fff;
}

.school-switch__current {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.school-switch__caret {
    flex: 0 0 auto;
    font-size: .7rem;
    opacity: .75;
}

.school-switch[open] .school-switch__caret { transform: rotate(180deg); }

.school-switch__menu {
    position: absolute;
    top: calc(100% + .45rem);
    right: 0;
    z-index: 40;
    /* No celular o menu nao pode ser mais largo que a tela: 100vw menos a
       folga das duas margens do cabecalho. */
    width: max-content;
    min-width: 232px;
    max-width: min(320px, calc(100vw - 2rem));
    padding: .5rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}

.school-switch__title {
    margin: .1rem .35rem .4rem;
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

.school-switch__item {
    display: flex;
    align-items: center;
    gap: .55rem;
    width: 100%;
    padding: .45rem .35rem;
    background: transparent;
    border: 0;
    border-radius: var(--radius-sm);
    font-family: inherit;
    font-size: .86rem;
    text-align: left;
    color: var(--ink);
    cursor: pointer;
}

.school-switch__item:hover {
    background: var(--turquoise-050);
}

/* A escola atual aparece, mas nao e um destino: fica desabilitada no HTML. */
.school-switch__item[disabled] {
    cursor: default;
    background: var(--bg);
}

.school-switch__logo {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: var(--navy);
    color: var(--brand-on-primary, #fff);
    font-size: .72rem;
    font-weight: 700;
    overflow: hidden;
}

.school-switch__logo img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #fff;
}

.school-switch__text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1 1 auto;
}

.school-switch__name {
    font-weight: 600;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.school-switch__meta {
    font-size: .72rem;
    color: var(--ink-soft);
    line-height: 1.25;
}

.school-switch__badge {
    flex: 0 0 auto;
    padding: .1rem .4rem;
    border-radius: var(--radius-pill);
    background: var(--turquoise-050);
    color: var(--turquoise-600);
    font-size: .65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.school-switch__foot {
    margin: .45rem .35rem .1rem;
    font-size: .68rem;
    line-height: 1.35;
    color: var(--ink-faint);
}

@media (min-width: 900px) {
    .school-switch__toggle { max-width: 220px; }
}

/* =========================================================================
   Aviso de sistema em validacao (faixa beta)

   Primeiro item da `.portal-shell`, antes do cabecalho: a faixa fala do
   AMBIENTE, nao da escola nem da pagina. Sangra de ponta a ponta e nao tem
   borda em cima nem embaixo — com moldura ela viraria um `.alert` dentro do
   conteudo, que e outra coisa.

   COR FIXA, E NAO A DA ESCOLA. Todo o resto do cabecalho e white label
   (`--navy` vem de `--brand-primary`), mas este aviso e da plataforma: pintar
   com a cor da escola sugeriria que a escola esta avisando algo, e ainda
   jogaria o contraste na sorte da paleta enviada.

   O par de superficie de aviso do portal: `--warning-050` (#f7eedf, amarelo
   pastel) com texto em `--warning-700` (#8a5f14, o mesmo ambar escuro dos
   `.alert--warning`). Contraste medido: 4,90:1, acima do 4,5:1 da AA.

   O token SOLIDO `--warning` (#c08a3e) foi tentado como fundo e reprovado:
   e tom de icone e filete, e como faixa larga fica pesado e derruba o
   contraste do texto.

   O QUE SEGURA A LEITURA DE "AVISO" com fundo suave e sem borda: o triangulo
   de atencao antes da frase e o peso 600. Sem eles, um retangulo pastel de
   ponta a ponta passa por faixa informativa neutra.

   A mesma regra, com os tokens de cada casa, esta em public/css/site.css e
   public/css/admin/surfapp-admin.css. As tres folhas sao independentes de
   proposito.

   NADA A COMPENSAR: `.portal-header` e `position: sticky`, ou seja, esta no
   fluxo. A faixa o empurra para baixo em vez de ficar atras dele, e ao rolar o
   cabecalho gruda no topo como sempre.
   ========================================================================= */

.beta-aviso {
    /* Triangulo de atencao. MASCARA, e nao imagem: quem pinta e
       `currentColor`, entao o icone acompanha a cor do texto e nao ha uma
       segunda definicao de cor para manter em dia. `fill-rule='evenodd'` vaza
       a barra e o ponto de exclamacao. */
    --beta-icone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' fill-rule='evenodd' d='M12 2.5 22.5 21 1.5 21 Z M10.9 9 h2.2 v6.5 h-2.2 Z M10.9 17.2 h2.2 v2 h-2.2 Z'/%3E%3C/svg%3E");

    /* Sem `max-width`, sem margem lateral: de x=0 a 100%. */
    width: 100%;
    padding: .5rem 1rem;
    /* O requisito e explicito: sem filete em cima nem embaixo. */
    border: 0;
    background: var(--warning-050);
    color: var(--warning-700);
    text-align: center;
}

.beta-aviso__texto {
    margin: 0;
    font-size: .875rem;
    line-height: 1.4;
    font-weight: 600;
}

/* No `::before` do texto, e nao no da faixa: assim o icone e a primeira linha
   andam juntos quando a frase quebra no celular. */
.beta-aviso__texto::before {
    content: "";
    display: inline-block;
    width: 1.05em;
    height: 1.05em;
    margin-right: .45em;
    vertical-align: -.16em;
    background-color: currentColor;
    -webkit-mask: var(--beta-icone) center / contain no-repeat;
    mask: var(--beta-icone) center / contain no-repeat;
}


/* Os campos de senha (olho, medidor, divergência) moram em
   `public/css/shared/password.css`, carregado à parte: as mesmas regras servem
   ao cadastro público do site, e uma folha só evita que a correção feita aqui
   falte lá. */


/* =========================================================================
   NAVEGACAO POR SEMANA (agenda e remarcacao)
   -------------------------------------------------------------------------
   A agenda passou a abrir so na semana corrente, e o dono do produto pediu que
   a tela DIGA isso: "precisamos sempre informar este detalhe na tela para ficar
   de simples navegacao para o cliente / aluno".

   Sao tres celulas numa linha: voltar, o periodo, avancar. O periodo fica no
   MEIO e centralizado porque e a informacao — as setas sao o controle, e num
   controle a posicao previsivel vale mais que o destaque.

   No celular a linha vira duas: as setas dividem a largura e o rotulo vai para
   cima delas. A alternativa (encolher tudo numa linha so) espremia "Semana
   anterior" a ponto de quebrar a palavra no meio.

   O passo desabilitado (semana ja no passado) e um <span>, e nao um <a>: link
   para lugar nenhum e pior que ausencia. `.is-disabled` ja existe neste arquivo
   para os botoes, e e reaproveitado aqui de proposito.
   ========================================================================= */

.week-nav {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: .5rem;
    margin-bottom: .5rem;
}

/* O rotulo do periodo. `min-width: 0` para que o texto encolha em vez de
   empurrar as setas para fora da tela em telefone estreito. */
.week-nav__label {
    margin: 0;
    min-width: 0;
    text-align: center;
    font-size: .9rem;
    color: var(--ink-soft);
}

.week-nav__label b {
    color: var(--brand-ink, var(--navy));
    font-variant-numeric: tabular-nums;
}

/* O selo de "esta semana" cai na linha de baixo quando nao cabe, e nao encolhe
   a data ao lado. */
.week-nav__label .badge {
    margin-left: .35rem;
    vertical-align: .05em;
}

.week-nav__step {
    white-space: nowrap;
}

/* A explicacao de por que so ha uma semana na tela. `margin-top` negativo
   nenhum: ela e paragrafo, e paragrafo respira. */
.week-nav__hint {
    margin: 0 0 1rem;
}

@media (max-width: 559px) {
    .week-nav {
        grid-template-columns: 1fr 1fr;
    }

    /* O rotulo ocupa a linha inteira, acima das duas setas. */
    .week-nav__label {
        grid-column: 1 / -1;
        order: -1;
    }
}

/* Campo de busca que ocupa a linha inteira da grade de filtros: o termo livre e
   a primeira coisa que se digita, e um campo de texto na largura de um <select>
   de datas nao cabe "escolinha da praia do foguete". */
@media (min-width: 640px) {
    .filters .field--wide { grid-column: 1 / -1; }
}


/* =========================================================================
   O COMPROVANTE DE COMPRA, EM FORMA DE CANHOTO
   -------------------------------------------------------------------------
   "Minhas compras" mostrava cartoes comuns. O dono do produto pediu o
   comprovante: "mostrar uma imagem simulando um comprovante, como o exemplo a
   imagem que e gerada da compra na pagina de pagamento".

   A tal imagem e o `.site-checkout__cupom` de `public/css/site.css` — o canhoto
   serrilhado da tela de pagamento. ESTE ARQUIVO REPETE O DESENHO, E NAO IMPORTA
   O OUTRO: as duas folhas sao independentes de proposito (nao ha build, nao ha
   `@import`, e trazer uma para a outra arrastaria o tema inteiro do site para
   dentro do portal). O que viaja e a tecnica; os tokens sao os daqui.

   TUDO E DECORACAO, e decoracao nao pode custar leitura:
     - nenhum texto mora em pseudo-elemento; le-se o mesmo <h2>, o mesmo valor
       e o mesmo <dl>;
     - o picote e o unico elemento a mais, vazio e com `aria-hidden`;
     - o contraste e o mesmo do `.card` que estava aqui antes.

   E NAO USA IMAGEM NENHUMA — a CSP do portal nao deixaria buscar uma, e um
   recorte assim nao vale um pedido de rede. Serrilhado por mascara de gradiente
   conico, picote por borda tracejada, entalhes por dois circulos da cor da
   pagina.
   ========================================================================= */

.recibo {
    /* As tres medidas do recorte concordam entre si: o dente e cortado por
       mascara e o entalhe e desenhado por pseudo-elemento. Mudar uma sozinha
       desalinha o serrilhado. */
    --recibo-passo: 16px;    /* largura de cada dente do serrilhado */
    --recibo-dente: 8px;     /* profundidade do serrilhado */
    --recibo-entalhe: 9px;   /* raio do entalhe lateral */
    --recibo-respiro: 1.1rem;

    /* Monoespacada do sistema. Sem @font-face e sem download, como todo o resto
       deste arquivo: numero de comprovante alinhado nao vale um pedido de rede
       nem um furo na CSP. */
    --recibo-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
                   "Liberation Mono", "Courier New", monospace;

    display: block;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    /* O respiro passa para cada metade do canhoto: o picote precisa atravessar
       de ponta a ponta, e nao parar na borda interna do padding. */
    padding: 0;
    margin-bottom: 1rem;
}

/* Compra esperando pagamento: a mesma tarja lateral do `.card--warning`, sem o
   fundo ambar. O fundo pintaria o canhoto inteiro e faria a compra pendente
   parecer um aviso de erro, quando ela e so uma compra por terminar. */
.recibo--pendente {
    border-left: 4px solid var(--warning);
}

/* O cabecalho: de quem e, o que e, e quanto e. */
.recibo__topo {
    display: flex;
    flex-direction: column;
    gap: .2rem;
    /* O dente entra na conta do respiro de cima: sem isso o nome da escola
       encostaria no serrilhado quando a mascara esta ativa. */
    padding: calc(var(--recibo-respiro) + var(--recibo-dente)) var(--recibo-respiro) var(--recibo-respiro);
}

/* O nome da escola, em cima e pequeno: e o cabecalho de um comprovante, e nao o
   titulo da tela. */
.recibo__escola {
    margin: 0;
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    font-weight: 700;
    color: var(--ink-faint);
}

.recibo__item {
    margin: 0;
    font-size: 1.02rem;
    font-weight: 650;
    color: var(--brand-ink, var(--navy));
}

.recibo__valor {
    margin: .15rem 0 0;
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--brand-ink, var(--navy));
    font-family: var(--recibo-mono);
    font-variant-numeric: tabular-nums;
}

/* O PICOTE — "destaque aqui". Linha de altura zero: quem ocupa espaco sao os
   respiros das duas metades. */
.recibo__picote {
    position: relative;
    height: 0;
    margin: 0 var(--recibo-respiro);
    border-top: 2px dashed var(--line-strong);
}

/* O corpo. Mesma grade do `.dl`, escrita aqui para o canhoto nao depender de
   duas classes no markup. */
.recibo__linhas {
    display: grid;
    grid-template-columns: 1fr;
    gap: .55rem;
    margin: 0;
    padding: var(--recibo-respiro);
}

/* O dente do serrilhado entra na conta do respiro de baixo — mas so de quem
   fecha o canhoto, que pode ser a lista de linhas ou o rodape. Somar o dente
   as duas abriria um buraco no meio do comprovante que so aparece quando ha
   rodape, e e o tipo de folga que ninguem relaciona a causa depois. */
.recibo > :last-child {
    padding-bottom: calc(var(--recibo-respiro) + var(--recibo-dente));
}

@media (min-width: 560px) {
    .recibo__linhas { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.recibo__linhas div { min-width: 0; }

.recibo__linhas dt {
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--ink-faint);
    font-weight: 700;
}

.recibo__linhas dd {
    margin: 0;
    font-size: .93rem;
    color: var(--ink);
    overflow-wrap: anywhere;
}

/* O NUMERO da compra em monoespacada, como o valor. Rotulo e texto corrido
   ficam na fonte do portal — monoespacada em frase encompridaria o nome do
   aluno sem ganhar nada. */
.recibo__numero {
    font-family: var(--recibo-mono);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0;
}

/* O rodape: o que a compra liberou e o botao de terminar o pagamento. Separado
   por filete, e nao por um segundo picote: dois picotes no mesmo canhoto
   sugeririam que ha duas partes a destacar. */
.recibo__rodape {
    /* A margem lateral alinha o filete com o picote, que tambem e recuado do
       respiro: dois riscos horizontais no mesmo canhoto com larguras diferentes
       leriam como desalinho. */
    margin: 0 var(--recibo-respiro);
    padding-top: .8rem;
    border-top: 1px solid var(--line);
}

.recibo__rodape > :last-child { margin-bottom: 0; }

/* =========================================================================
   O RECORTE, e por que ele mora inteiro num `@supports`.

   A mascara e o que transforma o retangulo em canhoto — e e tambem o que obriga
   a tirar borda, canto arredondado e sombra: mascara corta o pixel, e uma borda
   de 1px viraria um risco reto atravessando os dentes.

   Onde a mascara nao existe (Safari antigo, sobretudo), NADA disso acontece: a
   compra continua sendo o cartao branco de borda fina que ela sempre foi, com o
   picote tracejado por cima. Perde-se o enfeite e nao se perde informacao —
   que e a degradacao certa num comprovante.

   AS TRES CAMADAS da mascara se somam (composicao `add`, o padrao):
     1. dentes apontando para cima, presos no topo;
     2. dentes apontando para baixo, presos na base;
     3. o retangulo do meio, encolhido de um dente em cada ponta.
   Cada dente e o setor de +-45 graus de um gradiente conico: num ladrilho de
   16x8 esse setor e exatamente o triangulo de base 16 e altura 8, e por isso as
   duas medidas nao podem ser escolhidas separadamente.
   ========================================================================= */
@supports (mask-image: conic-gradient(#000, #fff)) {
    .recibo {
        border: 0;
        border-radius: 0;
        box-shadow: none;
        -webkit-mask:
            conic-gradient(from 135deg at top, transparent, #000 1deg 89deg, transparent 90deg)
                0 0 / var(--recibo-passo) var(--recibo-dente) repeat-x,
            conic-gradient(from -45deg at bottom, transparent, #000 1deg 89deg, transparent 90deg)
                0 100% / var(--recibo-passo) var(--recibo-dente) repeat-x,
            linear-gradient(#000 0 0) 0 50% / 100% calc(100% - 2 * var(--recibo-dente)) no-repeat;
        mask:
            conic-gradient(from 135deg at top, transparent, #000 1deg 89deg, transparent 90deg)
                0 0 / var(--recibo-passo) var(--recibo-dente) repeat-x,
            conic-gradient(from -45deg at bottom, transparent, #000 1deg 89deg, transparent 90deg)
                0 100% / var(--recibo-passo) var(--recibo-dente) repeat-x,
            linear-gradient(#000 0 0) 0 50% / 100% calc(100% - 2 * var(--recibo-dente)) no-repeat;
    }

    /* A tarja da compra pendente sobreviveria a mascara como um risco reto
       atravessando os dentes da esquerda. Vira faixa de fundo, presa a borda
       esquerda e cortada pela propria mascara junto com o resto. */
    .recibo--pendente {
        border-left: 0;
        background:
            linear-gradient(var(--warning) 0 0) 0 0 / 4px 100% no-repeat,
            var(--surface);
    }

    /* OS ENTALHES LATERAIS, na altura do picote: dois circulos da cor da pagina
       centrados nas bordas do canhoto — o truque do bilhete de cinema. So
       funcionam porque o portal tem um fundo so (`--bg`) atras do conteudo;
       sobre qualquer outro fundo eles apareceriam como duas bolas.

       Ficam dentro do `@supports` de proposito: sem a mascara o canhoto ainda
       tem borda e canto arredondado, e meio circulo por cima disso leria como
       defeito, e nao como entalhe. */
    .recibo__picote::before,
    .recibo__picote::after {
        content: "";
        position: absolute;
        top: 50%;
        width: calc(var(--recibo-entalhe) * 2);
        height: calc(var(--recibo-entalhe) * 2);
        transform: translateY(-50%);
        border-radius: 50%;
        background: var(--bg);
    }

    /* O picote esta recuado do respiro; o centro do circulo tem de cair na
       borda do canhoto, um raio mais para fora. */
    .recibo__picote::before {
        left: calc(-1 * (var(--recibo-respiro) + var(--recibo-entalhe)));
    }

    .recibo__picote::after {
        right: calc(-1 * (var(--recibo-respiro) + var(--recibo-entalhe)));
    }
}


/* =========================================================================
   BUSCA DENTRO DE UM SELETOR LONGO  (.combo)
   -------------------------------------------------------------------------
   Pedido do dono do produto: "caso o select fique longo, podemos usar um outro
   componente que melhor trabalhe com isto". O caso é o cliente `company` — a
   pousada, a escola parceira — com dezenas de alunos vinculados no "Para quem é
   a aula?".

   ESTE BLOCO NÃO ESCONDE NADA SOZINHO. A classe `.combo__native` é aplicada por
   `public/js/shared/surfapp-select-search.js`, e só depois que o widget está
   montado: sem script — ou com o script barrado pela CSP — nenhuma destas
   regras encontra elemento nenhum, e o `<select>` nativo continua sendo a tela.
   Abaixo do limiar o arquivo nem é carregado (ver `schedule/actor-picker`).
   ========================================================================= */

.combo {
    position: relative;
}

/* O nativo continua no DOM, e continua sendo quem o formulário envia:
   `display: none` esconde da tela sem tirar o campo do envio (só `disabled`
   faria isso). */
.combo__native {
    display: none;
}

/* O botão "Trocar" some quando escolher já navega. Precisa desta regra porque
   `.form-actions` declara `display: flex`, e qualquer `display` de autor vence
   o `[hidden] { display: none }` da folha do navegador — o atributo ficaria no
   HTML sem efeito nenhum na tela. */
.form-actions[hidden] {
    display: none;
}

/* Espaço para a seta do `.select`, que aqui não existe: o campo é de texto. */
.combo__input {
    padding-right: .75rem;
}

.combo__list {
    position: absolute;
    z-index: 40;
    top: calc(100% + .25rem);
    left: 0;
    right: 0;
    /* Teto duplo: 45vh impede a lista de cobrir a tela do celular, e 320px
       impede que num monitor alto ela vire uma coluna de trinta nomes. */
    max-height: min(45vh, 320px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    margin: 0;
    padding: .25rem;
    list-style: none;
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow);
}

.combo__option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    /* 44px é o alvo mínimo de toque, e a lista longa é justamente a que será
       usada no celular — com o polegar, no estacionamento da praia. */
    min-height: 44px;
    padding: .5rem .6rem;
    border-radius: var(--radius-sm);
    font-size: .95rem;
    line-height: 1.35;
    color: var(--ink);
    cursor: pointer;
}

/* `is-active` é o item que o teclado está percorrendo (o mesmo que
   `aria-activedescendant` aponta). O fundo turquesa claro mantém o texto em
   `--ink` acima de 4,5:1. */
.combo__option.is-active {
    background: var(--turquoise-050);
}

@media (hover: hover) {
    .combo__option:hover {
        background: var(--turquoise-050);
    }
}

/* Quem está ESCOLHIDO agora — pergunta diferente de "quem está em foco", e por
   isso marca diferente: peso e um visto, não fundo. */
.combo__option[aria-selected="true"] {
    font-weight: 650;
}

.combo__option[aria-selected="true"]::after {
    content: "\2713";
    color: var(--turquoise-600);
    font-weight: 700;
}

.combo__empty {
    padding: .6rem;
    color: var(--ink-faint);
    font-size: .88rem;
}
