html, body {
    font-family: Roboto, 'Helvetica Neue', Helvetica, Arial, sans-serif;
    background-color: var(--mud-palette-background, #F8F9FB);
}

.validation-message {
    color: var(--mud-palette-error);
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred.";
    }

.admin-media-row-pending {
    background-color: color-mix(in srgb, var(--mud-palette-warning) 12%, transparent);
}

.admin-media-card-pending {
    border-left: 3px solid var(--mud-palette-warning);
}

.admin-media-dropzone {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem 1.5rem;
    border: 2px dashed var(--mud-palette-lines-default);
    border-radius: var(--mud-default-borderradius);
    transition: border-color 0.2s, background-color 0.2s;
    cursor: pointer;
    text-align: center;
}

.admin-media-dropzone:hover,
.admin-media-dropzone--active {
    border-color: var(--mud-palette-primary);
    background-color: color-mix(in srgb, var(--mud-palette-primary) 6%, transparent);
}

/* Editor de tabela da aula: table-layout fixo faz o cabeçalho e as linhas usarem a mesma
   largura de coluna, inclusive na faixa de botões, que só existe no cabeçalho e no fim da linha. */
.lesson-table-editor {
    overflow-x: auto;
}

.lesson-table-editor table {
    table-layout: fixed;
    width: max-content;
    border-collapse: separate;
    border-spacing: 8px 4px;
}

.lesson-table-editor th,
.lesson-table-editor td {
    width: 170px;
    padding: 0;
    vertical-align: middle;
}

.lesson-table-editor .lesson-table-editor-actions {
    width: 88px;
    white-space: nowrap;
    text-align: right;
}

/* Faixa do cabeçalho no editor de tabela. O app pinta a primeira linha com fundo próprio; o
   editor faz o mesmo para que a regra se veja antes de salvar, e não só no aviso ao lado.
   Só cor e canto: mexer em padding aqui desalinharia as colunas, que é o defeito que o
   table-layout fixo acima existe para evitar. */
.lesson-table-editor thead th.lesson-table-editor-head {
    background-color: color-mix(in srgb, var(--mud-palette-primary) 8%, transparent);
    border-radius: 8px;
}

.admin-media-dropzone-input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}

#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 10000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

.admin-login-page {
    /* dvh e não vh: no Safari do iPhone a barra de endereço entra na conta de 100vh e o cartão
       fica cortado — sobretudo com o painel instalado como PWA. */
    min-height: 100dvh;
    background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
    --mud-palette-text-primary: #1A1D29;
    --mud-palette-text-secondary: #6B7280;
    --mud-palette-text-disabled: #9CA3AF;
    --mud-palette-lines-inputs: #E5E7EB;
    --mud-palette-surface: #FFFFFF;
    --mud-palette-background: #F8F9FB;
    --mud-palette-action-default: #6B7280;
}

.admin-login-shell {
    width: 100%;
    max-width: 420px;
    padding: 24px;
    box-sizing: border-box;
}

.admin-login-card {
    background: #FFFFFF;
    border: 1px solid #E5E7EB;
    border-radius: 16px;
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.08), 0 8px 10px -6px rgba(0, 0, 0, 0.04);
}

.admin-login-field {
    margin-bottom: 20px;
}

.admin-login-label {
    display: block;
    font-size: 0.875rem;
    font-weight: 400;
    color: #1A1D29;
    margin-bottom: 8px;
}

.admin-login-textfield.mud-input-control {
    margin-top: 0;
}

.admin-login-textfield legend {
    width: 0 !important;
    max-width: 0 !important;
}

.admin-login-textfield .mud-input-label-outlined,
.admin-login-textfield .mud-input-label-inputcontrol {
    display: none !important;
}

.admin-login-textfield .mud-input-outlined-border {
    border-color: #E5E7EB !important;
    border-radius: 8px !important;
}

.admin-login-textfield .mud-input-outlined:hover .mud-input-outlined-border {
    border-color: #4F7CFF !important;
}

.admin-login-textfield .mud-input-outlined.mud-input-outlined-focus .mud-input-outlined-border {
    border-color: #4F7CFF !important;
    border-width: 2px !important;
}

.admin-login-textfield .mud-input {
    color: #1A1D29 !important;
}

.admin-login-textfield .mud-input > input.mud-input-root,
.admin-login-textfield .mud-input-slot {
    background-color: #FFFFFF !important;
    color: #1A1D29 !important;
}

.admin-login-textfield .mud-input > input.mud-input-root {
    min-height: 48px;
}

.admin-login-textfield .mud-input > input.mud-input-root::placeholder,
.admin-login-textfield .mud-input > input.mud-input-root::-webkit-input-placeholder,
.admin-login-textfield .mud-input > input.mud-input-root::-moz-placeholder,
.admin-login-textfield .mud-input > input.mud-input-root:-ms-input-placeholder {
    color: #9CA3AF !important;
    opacity: 1 !important;
}

/* Autofill do Chrome/Edge: o navegador pinta o campo com um background-image próprio, marcado
   como !important no user-agent stylesheet — nenhum background-color nosso vence isso. O truque
   que funciona é cobrir a caixa com uma sombra interna sólida e forçar a cor do texto. A transição
   absurda existe para o caso de o navegador reaplicar a pintura depois de um clique. */
.admin-login-textfield input:-webkit-autofill,
.admin-login-textfield input:-webkit-autofill:hover,
.admin-login-textfield input:-webkit-autofill:focus,
.admin-login-textfield input:-webkit-autofill:active {
    -webkit-box-shadow: inset 0 0 0 1000px #FFFFFF !important;
    box-shadow: inset 0 0 0 1000px #FFFFFF !important;
    -webkit-text-fill-color: #1A1D29 !important;
    caret-color: #1A1D29;
    transition: background-color 9999s ease-in-out 0s;
}

.admin-login-remember {
    margin-top: 4px;
    margin-left: -8px;
}

.admin-login-textfield .mud-input-adornment .mud-icon-root {
    color: #9CA3AF;
}

.admin-login-submit {
    height: 48px;
    font-weight: 600;
    text-transform: none;
    border-radius: 8px;
    box-shadow: 0 10px 15px -3px rgba(79, 124, 255, 0.25);
}

.admin-login-back-link {
    color: #6B7280 !important;
    text-decoration: none !important;
}

.admin-login-back-link:hover {
    color: #1A1D29 !important;
}

/* ---------------------------------------------------------------------------
   Enfase em texto corrido.

   Titulo tem peso pelo tema (Typography no AdminThemes). Estas duas existem
   para body2 e caption, que o tema NAO pode pintar: engrossaria todo o texto
   corrido do painel, e o peso ali e para destacar um valor dentro da linha.
   --------------------------------------------------------------------------- */
.admin-strong {
    font-weight: 600;
}

.admin-medium {
    font-weight: 500;
}

/* ---------------------------------------------------------------------------
   Agenda do dia no dashboard.

   A lista tem uma linha por aluno com aula hoje (a chave composta do banco
   garante uma aula por aluno por dia), entao ela cresce junto com a turma. Sem
   teto, o cartao esticava a linha inteira do grid: com 50 alunos passava de
   2.800px ao lado de um grafico de 260px, empurrando o resto do dashboard para
   fora da tela. Com teto, o cartao para em ~6 linhas e rola por dentro.
   --------------------------------------------------------------------------- */
.admin-agenda-do-dia {
    max-height: 22rem;
    overflow-y: auto;
}

/* ---------------------------------------------------------------------------
   A licao dentro de um celular -- que e onde ela se edita.

   O editor anterior mostrava a aula com a tipografia do painel. Ele respondia
   "o markup esta certo?", mas nao "como isto fica no celular?" -- que e a
   pergunta de quem escreve a aula: quanto texto cabe, onde a tabela estoura,
   em quantas linhas o titulo quebra.

   Os valores abaixo sao os do app (TeacherApp.App/Features/Lesson: LessonPage.xaml
   e LessonBlocksView.cs), e estao em variaveis por um motivo pratico: a
   identidade visual do app esta sendo refeita, e quando a tela de licao for
   redesenhada isto aqui se atualiza trocando token, nao reescrevendo regra.

   1dp = 1px: o app roda a 393dp de largura num Redmi 9, e e essa a largura da
   tela desenhada aqui.
   --------------------------------------------------------------------------- */
/* Os tokens valem tambem para .app-drag-fantasma: durante o arrasto o SortableJS
   poe o clone como filho do <body> (fallbackOnBody), fora de .app-phone. Sem isto
   o bloco em voo sai com Roboto e a cor do painel, e o professor ve uma coisa
   arrastando e outra pousando. */
.app-phone,
.app-drag-fantasma {
    /* Cores: espelho de TeacherApp.App/Resources/Styles/Colors.xaml (rampa clara). */
    --app-bg: #FDF2E0;
    --app-card: #FFFDFC;
    --app-card-alt: #FCF8F3;
    --app-border: #E6DCCE;
    --app-track: #EFE7DC;
    --app-text: #1A1D29;
    --app-text-accent: #4A32B8;
    --app-text-muted: #545B67;
    --app-text-dim: #6E747E;
    --app-success: #059669;
    --app-error: #DC2626;
    /* A tela de exercicio usa quatro fundos que a de aula nao tem: o afundado da
       bandeja, o balao da direita e as duas faixas de resultado. As duas ultimas
       repetem os valores de --app-examples-* de proposito: no app sao a mesma
       cor (FeedbackSuccessBg/FeedbackErrorBg) usada em dois lugares, e um nome
       por lugar e o que deixa claro onde cada uma pinta. */
    --app-surface-sunken: #F8F5F0;
    --app-bubble-right: #F1E8DA;
    --app-feedback-ok-bg: #D4EDDA;
    --app-feedback-ok-fg: #155724;
    --app-feedback-erro-bg: #F8D7DA;
    --app-feedback-erro-fg: #721C24;
    /* Sem par escuro no app: sao cores cheias, usadas atras de branco. */
    --app-accent: #7C5DF7;
    --app-on-accent: #FFFFFF;
    --app-acao-ok: #10B981;
    --app-acao-erro: #F44336;

    /* Caixa de exemplos: fundo pastel + texto escuro da mesma familia (Feedback* de
       Colors.xaml / GamifiedTheme). O selo e cor CHEIA (ActionSuccess/ActionError) com o
       glifo branco. O neutro usa o lilas da pilula da trilha: sobre o fundo rabiscado o
       creme do CardAlt some e a caixa deixa de parecer uma caixa. */
    --app-examples-bg-positive: #D4EDDA;
    --app-examples-bg-negative: #F8D7DA;
    --app-examples-bg-neutral: #EDE5FD;
    --app-examples-text-positive: #155724;
    --app-examples-text-negative: #721C24;
    --app-badge-success: #10B981;
    --app-badge-error: #F44336;

    /* Geometria (LessonPage.xaml / LessonBlocksView.cs). */
    /* Redmi 9: 1080x2340 px a 2.75x = 393x851 dp. A altura importa tanto quanto a
       largura -- e ela que responde "cabe na primeira tela?". */
    --app-screen-width: 393px;
    --app-screen-height: 851px;
    --app-bezel: 14px;
    --app-card-radius: 16px;
    --app-card-pad: 20px;
    --app-box-radius: 12px;
    --app-examples-radius: 16px;
    --app-cta-height: 54px;
    --app-cta-radius: 14px;

    font-family: 'Open Sans', Roboto, system-ui, sans-serif;
    color: var(--app-text);
}

.app-phone {
    display: flex;
    justify-content: center;
}

.app-phone.app-dark,
body.app-arrastando-escuro .app-drag-fantasma {
    --app-bg: #090D20;
    --app-card: #1A1F27;
    --app-card-alt: #232935;
    --app-border: #2B323D;
    --app-track: #262C36;
    --app-text: #FFFFFF;
    --app-text-accent: #C4B8FF;
    --app-text-muted: #9AA3B2;
    --app-text-dim: #6B7280;
    --app-success: #34D399;
    --app-error: #F87171;
    --app-examples-bg-positive: #142A22;
    --app-examples-bg-negative: #2A1620;
    --app-examples-bg-neutral: #262040;
    --app-examples-text-positive: #34D399;
    --app-examples-text-negative: #F87171;
    --app-surface-sunken: #171B22;
    --app-bubble-right: #2B3240;
    --app-feedback-ok-bg: #142A22;
    --app-feedback-ok-fg: #34D399;
    --app-feedback-erro-bg: #2A1620;
    --app-feedback-erro-fg: #F87171;
}

.app-phone * {
    box-sizing: border-box;
}

/* Aparelho. A altura e fixa e a rolagem acontece DENTRO da tela: sem isso a
   aula inteira esticaria o dialogo e a moldura deixaria de significar algo. */
.app-phone-frame {
    width: calc(var(--app-screen-width) + 2 * var(--app-bezel));
    height: calc(var(--app-screen-height) + 2 * var(--app-bezel));
    padding: var(--app-bezel);
    border-radius: 40px;
    background: #0B0B0F;
    /* O anel claro e para o aparelho nao sumir no fundo quando o painel esta no
       tema escuro -- a moldura preta encostava num fundo quase preto. */
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .14), 0 12px 32px rgba(0, 0, 0, .35);
    display: flex;
    flex-direction: column;
}

.app-phone-statusbar {
    height: 32px;
    flex: none;
    background-color: var(--app-bg);
    border-radius: 26px 26px 0 0;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    padding: 0 18px;
    font-size: 13px;
    font-weight: 600;
    color: var(--app-text);
}

.app-phone-hole {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #000;
    justify-self: center;
}

.app-phone-signal {
    justify-self: end;
    font-size: 11px;
    letter-spacing: 2px;
}

/* Sem barra de rolagem: o aparelho nao tem uma fixa, e a do navegador comia
   8px da largura util -- o texto quebrava antes do ponto em que quebra no
   celular, que e justamente o que esta tela existe para mostrar. */
.app-phone-screen {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    background-color: var(--app-bg);
    scrollbar-width: none;
}

.app-phone-screen::-webkit-scrollbar {
    width: 0;
    height: 0;
}

/* Barra de abas do Shell: a aula abre dentro dela, entao ela cobre o fim da pagina
   e tira 68dp da altura util. Sem rotulo -- os nomes estao mudando na identidade
   nova, e o que ela representa aqui e o espaco que ocupa. */
.app-tabbar {
    height: 68px;
    flex: none;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    align-items: center;
    justify-items: center;
    background-color: var(--app-card-alt);
    border-top: 1px solid var(--app-border);
}

.app-tab {
    display: inline-flex;
    color: var(--app-text-muted);
}

.app-tab-ativa {
    color: var(--app-accent);
}

/* Navegacao do sistema (tres botoes), que no Redmi tambem come tela. */
.app-phone-nav {
    height: 47px;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 64px;
    background-color: var(--app-card-alt);
    border-radius: 0 0 26px 26px;
    color: var(--app-text-muted);
}

.app-phone-nav-quadrado,
.app-phone-nav-circulo,
.app-phone-nav-triangulo {
    width: 12px;
    height: 12px;
    background-color: currentColor;
    opacity: .75;
}

.app-phone-nav-circulo {
    border-radius: 50%;
}

.app-phone-nav-triangulo {
    clip-path: polygon(100% 0, 100% 100%, 0 50%);
}

/* Cabecalho da aula. */
.app-header {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 16px 20px 12px;
}

.app-back {
    align-self: flex-start;
    display: inline-flex;
    color: var(--app-text);
}

.app-title-box {
    display: flex;
    gap: 12px;
    padding: 12px 14px;
    border: 1px solid var(--app-border);
    border-radius: var(--app-card-radius);
    background-color: var(--app-card);
}

.app-title-bar {
    flex: none;
    width: 4px;
    border-radius: 2px;
    background-color: var(--app-accent);
}

.app-title-text {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    min-width: 0;
}

.app-eyebrow {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 1.5px;
    color: var(--app-text-accent);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Duas linhas e corta, como o MaxLines do app: e aqui que se ve que o titulo
   longo nao cabe -- no painel ele cabia numa linha e ninguem percebia. */
.app-title {
    font-size: 22px;
    font-weight: 700;
    color: var(--app-text);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.app-title-vazio {
    color: var(--app-text-muted);
}

.app-page {
    display: flex;
    flex-direction: column;
    gap: 20px;
    padding: 12px 16px 32px;
}

.app-cards {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.app-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: var(--app-card-pad);
    border: 1px solid var(--app-border);
    border-radius: var(--app-card-radius);
    background-color: var(--app-card);
}

.app-card-title {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 18px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--app-text-accent);
    overflow-wrap: anywhere;
}

.app-card-emoji {
    flex: none;
    font-size: 20px;
    line-height: 1.2;
}

.app-blocks {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

/* Blocos (LessonBlocksView.cs). */
.app-heading {
    margin-top: 6px;
    font-size: 18px;
    font-weight: 700;
    color: var(--app-text);
}

.app-paragraph {
    margin: 0;
    font-size: 15px;
    line-height: 1.35;
    color: var(--app-text);
}

.app-note {
    padding: 14px;
    border-radius: var(--app-box-radius);
    background-color: var(--app-card-alt);
    font-size: 14px;
    line-height: 1.35;
    color: var(--app-text);
}

/* Sem borda: quem separa a caixa do cartao e o fundo tingido. */
.app-examples {
    display: flex;
    gap: 12px;
    padding: 14px;
    border-radius: var(--app-examples-radius);
    background-color: var(--app-examples-bg);
}

.app-examples-positive {
    --app-variant: var(--app-examples-text-positive);
    --app-examples-bg: var(--app-examples-bg-positive);
    --app-badge: var(--app-badge-success);
}

.app-examples-negative {
    --app-variant: var(--app-examples-text-negative);
    --app-examples-bg: var(--app-examples-bg-negative);
    --app-badge: var(--app-badge-error);
}

/* Neutro nao tem selo, entao nao tem --app-badge: a coluna da esquerda nem existe. */
.app-examples-neutral {
    --app-variant: var(--app-text-accent);
    --app-examples-bg: var(--app-examples-bg-neutral);
}

.app-examples-badge {
    flex: none;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background-color: var(--app-badge);
    color: var(--app-on-accent);
    font-size: 15px;
    font-weight: 700;
    /* line-height = altura: centra o glifo sem flex, que arrastaria o circulo na coluna. */
    line-height: 30px;
    text-align: center;
}

.app-examples-body {
    display: flex;
    flex-direction: column;
    gap: 5px;
    min-width: 0;
}

/* A primeira linha e o destaque: negrito, na cor da variante. */
.app-examples-title {
    font-size: 16px;
    font-weight: 700;
    line-height: 1.25;
    color: var(--app-variant);
}

.app-examples-item {
    font-size: 14.5px;
    line-height: 1.35;
    color: var(--app-text);
}

/* Tabela sem linhas internas: o app desenha so a faixa do cabecalho e a borda
   de fora. Com linhas, a previa sugeria uma grade que o aluno nao ve. */
.app-table {
    border: 1px solid var(--app-border);
    border-radius: var(--app-box-radius);
    background-color: var(--app-card);
    overflow: hidden;
}

.app-table table {
    width: 100%;
    border-collapse: collapse;
}

.app-table thead {
    background-color: var(--app-card-alt);
}

.app-table th,
.app-table td {
    border: 0;
    padding: 8px 10px;
    text-align: center;
}

.app-table th {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .6px;
    color: var(--app-text-muted);
}

.app-table td {
    font-size: 14px;
    line-height: 1.35;
    color: var(--app-text);
}

.app-transform {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid var(--app-border);
    border-radius: var(--app-box-radius);
    background-color: var(--app-card);
}

.app-transform-base,
.app-transform-result {
    font-size: 16px;
    color: var(--app-text);
}

.app-transform-result {
    font-weight: 700;
}

.app-transform-arrow {
    font-size: 16px;
    color: var(--app-text-muted);
}

/* Figura solta: 4/3 reservado, contain — a mesma geometria do RemoteImage no app.
   AspectFill (cover) recortaria figura didatica, que pode cortar o que se ensina. */
.app-figure img,
.app-figure .app-thumb {
    aspect-ratio: 4 / 3;
    object-fit: contain;
}

.app-figure-caption {
    margin-top: 6px;
    font-size: 13px;
    text-align: center;
    color: var(--app-text-muted);
}

/* Grade de vocabulario: duas colunas fixas, como o Grid do app. Contagem impar deixa a
   segunda coluna vazia de proposito. */
.app-vocab-title {
    font-size: 15px;
    font-weight: 700;
    color: var(--app-text);
    margin-bottom: 8px;
}

.app-vocab {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}

.app-vocab-card {
    padding: 10px;
    border-radius: 14px;
    background-color: var(--app-card-alt);
}

.app-vocab-card img,
.app-vocab-card .app-thumb {
    aspect-ratio: 1;
    object-fit: cover;
    border-radius: 10px;
}

.app-vocab-word {
    margin-top: 4px;
    font-size: 15px;
    font-weight: 700;
    text-align: center;
    color: var(--app-text);
}

.app-vocab-translation {
    font-size: 13px;
    text-align: center;
    color: var(--app-text-muted);
}

/* "Completar as frases": uma linha por frase, um espaco por lacuna, e as pecas embaixo. */
.app-ex-frases {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.app-ex-frase {
    margin: 0;
    font-size: 17px;
    line-height: 1.8;
    color: var(--app-text);
}

/* Nome proprio, e nao .app-ex-pecas: aquela ja e do "ordenar palavras", e os testes a usam
   para identificar o miolo daquele tipo. O visual da peca e o mesmo de proposito. */
.app-ex-preenchimentos {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
}

.app-ex-preenchimento {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 11px 18px;
    border: 1px solid var(--app-border);
    border-radius: 14px;
    background-color: var(--app-card);
    color: var(--app-text-accent);
    font-size: 16px;
}

/* Figura do exercicio: teto de 200 dp, como no app. A conta e o orcamento vertical do
   Redmi 9 -- figura a 4:3 daria 265 dp e, com mascote, player e pecas, empurraria o botao
   Enviar para baixo da dobra. No exercicio a figura e adereco, nao a materia. */
.app-ex-figura img,
.app-ex-figura .app-thumb {
    max-height: 200px;
    object-fit: contain;
}

/* Player parado: diz que o card tem audio e quanto espaco ele ocupa. */
.app-audio {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px;
    border: 1px solid var(--app-border);
    border-radius: var(--app-box-radius);
    background-color: var(--app-card-alt);
}

.app-audio-play {
    flex: none;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background-color: var(--app-accent);
    color: var(--app-on-accent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.app-audio-mid {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.app-audio-label {
    font-size: 13px;
    color: var(--app-text-muted);
}

.app-audio-track {
    display: block;
    height: 4px;
    border-radius: 2px;
    background-color: var(--app-track);
}

.app-audio-time {
    flex: none;
    font-size: 12px;
    color: var(--app-text-muted);
}

.app-empty {
    margin: 8px 0;
    font-size: 14px;
    text-align: center;
    color: var(--app-text-muted);
}

/* Desabilitado sem apagar: o botao esta aqui para ocupar o espaco que ocupa no
   aparelho, nao para ser tocado. */
.app-cta {
    width: 100%;
    height: var(--app-cta-height);
    margin-top: 8px;
    border: 0;
    border-radius: var(--app-cta-radius);
    background-color: var(--app-accent);
    color: var(--app-on-accent);
    font-family: inherit;
    font-size: 16px;
    font-weight: 700;
    box-shadow: 0 4px 12px rgba(124, 93, 247, .3);
    cursor: default;
}

.app-cta:disabled {
    opacity: 1;
}

/* Destaque ==assim==. A classe existe para a pele decidir a cor: dentro do
   celular e o roxo do app, e nao o azul do painel, que era o que a previa
   antiga pintava com estilo inline. O fallback serve a qualquer uso fora daqui. */
.app-hl {
    color: var(--mud-palette-primary);
    font-weight: 600;
}

.app-phone .app-hl {
    color: var(--app-accent);
    font-weight: 700;
}

.app-phone strong {
    font-weight: 700;
}

/* ---------------------------------------------------------------------------
   A tela de exercicio dentro do celular -- que e onde ela se monta.

   Medidas de TeacherApp.App/Features/Exercise/Views/ExercisePage.xaml e dos
   controles em Features/Exercise/Controls/. Como na aula, 1dp = 1px.
   --------------------------------------------------------------------------- */
/* O exercicio respira mais que a aula: Spacing=18, Padding="20,8,20,24". */
.app-page.app-page-ex {
    gap: 18px;
    padding: 8px 20px 24px;
}

.app-ex-pagina {
    display: flex;
    flex-direction: column;
    gap: 18px;
}

/* Cabecalho: fechar a esquerda, progresso no centro. O X e os segmentos sao do
   app; aqui nao fazem nada, estao para dar a medida do que sobra ao conteudo. */
.app-ex-topbar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 16px 6px;
    color: var(--app-text-muted);
}

.app-ex-progresso {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    /* O X ocupa 20px a esquerda; a margem a direita recentra o progresso. */
    margin-right: 20px;
}

.app-ex-segmentos {
    display: flex;
    gap: 4px;
}

.app-ex-segmento {
    width: 30px;
    height: 6px;
    border-radius: 3px;
    background-color: var(--app-track);
}

.app-ex-segmento-atual {
    background-color: var(--app-accent);
}

.app-ex-questao {
    font-size: 12px;
    color: var(--app-text-muted);
}

/* O que se pede, no idioma da interface -- separado do enunciado, que e materia
   de estudo em ingles. */
.app-ex-instrucao {
    font-size: 15px;
    color: var(--app-text-muted);
}

.app-ex-apoio {
    background-color: var(--app-card);
    border-radius: 16px;
    padding: 14px 16px;
}

.app-ex-apoio-linha {
    margin: 0;
    font-size: 16px;
}

.app-ex-apoio-linha + .app-ex-apoio-linha {
    margin-top: 6px;
}

/* Balao de fala. O rabo e um triangulo em ::after, como o Polygon do
   SpeechBubbleView do app. */
.app-ex-balao {
    position: relative;
    max-width: 320px;
    padding: 10px 14px;
    border-radius: 18px;
    font-size: 15px;
    background-color: var(--app-track);
    /* O enunciado pode ter varias linhas (o tipo "Completar as frases" tem uma frase por
       linha). Sem isto o 
 vira espaco e a previa mente sobre o que o aluno ve. pre-line
       colapsa runs de espaco e honra a quebra, entao e seguro para os enunciados antigos. */
    white-space: pre-line;
}

.app-ex-balao + .app-ex-balao {
    margin-top: 8px;
}

.app-ex-balao-esq::after,
.app-ex-balao-dir::after {
    content: "";
    position: absolute;
    top: 12px;
    border: 10px solid transparent;
}

.app-ex-balao-esq::after {
    left: -11px;
    border-right: 12px solid var(--app-track);
}

.app-ex-balao-dir {
    margin-left: auto;
    background-color: var(--app-bubble-right);
}

.app-ex-balao-dir::after {
    right: -11px;
    border-left: 12px solid var(--app-bubble-right);
}

/* A pergunta: a raposa a esquerda e o balao ao lado, como na tela do aluno. */
.app-ex-pergunta {
    display: flex;
    align-items: flex-start;
    gap: 6px;
}

.app-ex-mascote {
    flex: none;
    width: 72px;
    height: 72px;
    background-image: url("mascot_fox.svg");
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
}

.app-ex-pergunta .app-ex-balao {
    flex: 1;
    min-width: 0;
    max-width: none;
    font-size: 17px;
    background-color: var(--app-card);
}

.app-ex-pergunta .app-ex-balao-esq::after {
    border-right-color: var(--app-card);
}

/* A lacuna: largura da conta do InlineBlankText, com a regua embaixo. */
.app-blank {
    display: inline-block;
    vertical-align: bottom;
    height: 22px;
    border-bottom: 2px solid var(--app-text-accent);
}

/* Palavra com traducao no glossario: tracejado que convida ao toque. */
.app-gloss {
    border-bottom: 1.6px dashed var(--app-text-accent);
}

/* Alternativas. Em chip quando preenchem uma lacuna (leem-se dentro da frase),
   em lista quando sao a resposta inteira. */
.app-ex-opcoes {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.app-ex-opcoes-chips {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
}

.app-ex-opcao {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 14px 16px;
    border: 2px solid var(--app-border);
    border-radius: 14px;
    background-color: var(--app-card);
    font-size: 16px;
}

.app-ex-opcoes-chips .app-ex-opcao {
    padding: 12px 20px;
    font-size: 17px;
}

.app-ex-opcao-texto {
    flex: 1;
    min-width: 0;
}

.app-ex-certa {
    flex: none;
    display: inline-flex;
    color: var(--app-success);
}

/* Ordenar palavras: a bandeja vazia em cima, as pecas embaralhadas embaixo. */
.app-ex-bandeja {
    min-height: 64px;
    border: 1px solid var(--app-border);
    border-radius: 14px;
    background-color: var(--app-surface-sunken);
}

.app-ex-pecas {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.app-ex-peca {
    padding: 11px 18px;
    border: 1px solid var(--app-border);
    border-radius: 14px;
    background-color: var(--app-card);
    color: var(--app-text-accent);
    font-size: 16px;
}

/* Combinar pares: no app as duas colunas vem embaralhadas, aqui os dois lados
   ficam na mesma linha -- e o que deixa o par visivel para quem escreve. */
.app-ex-pares {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.app-ex-par {
    display: flex;
    gap: 12px;
}

.app-ex-par-lado {
    flex: 1;
    min-width: 0;
    padding: 16px 14px;
    border: 2px solid var(--app-border);
    border-radius: 14px;
    background-color: var(--app-card);
    font-size: 15px;
    text-align: center;
}

.app-ex-palavras {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.app-ex-palavra {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 11px 18px;
    border: 2px solid var(--app-border);
    border-radius: 14px;
    background-color: var(--app-card);
    font-size: 16px;
}

.app-ex-falas {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.app-ex-fala-modo {
    display: block;
    margin-top: 2px;
    font-size: 11px;
    color: var(--app-text-dim);
}

/* Campo de resposta proprio, quando nao ha lacuna na frase. */
.app-ex-resposta {
    padding: 14px 12px;
    border: 1px solid var(--app-border);
    border-radius: 16px;
    background-color: var(--app-card);
    color: var(--app-text-dim);
    font-size: 16px;
}

.app-ex-dica {
    border: 1px solid var(--app-border);
    border-radius: 16px;
    background-color: var(--app-card);
    overflow: hidden;
}

.app-ex-dica-cabeca {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 16px;
    font-size: 15px;
}

.app-ex-dica-rotulo {
    flex: 1;
    color: var(--app-text-accent);
}

.app-ex-dica-seta {
    display: inline-flex;
    color: var(--app-text-muted);
}

/* Aberta no editor, fechada no app: o professor precisa ler o que escreveu. */
.app-ex-dica-corpo {
    margin: 0;
    padding: 12px 16px;
    background-color: var(--app-surface-sunken);
    color: var(--app-text-muted);
    font-size: 14px;
}

/* A faixa de resultado, que no app sobe de baixo depois da resposta. */
.app-ex-feedback {
    border-radius: 20px;
    padding: 16px 20px;
    background-color: var(--app-feedback-ok-bg);
    color: var(--app-feedback-ok-fg);
}

.app-ex-feedback-marca {
    font-size: 19px;
    font-weight: 700;
}

.app-ex-feedback-texto {
    margin: 6px 0 0;
    font-size: 14px;
}

.app-ex-feedback-aviso {
    display: block;
    margin-top: 8px;
    font-size: 11px;
    opacity: .75;
}

.app-ex-rodape {
    margin: -8px 0 0;
    font-size: 12px;
    color: var(--app-text-muted);
    text-align: center;
}

.app-ex-depois {
    margin: 8px 0 0;
    font-size: 12px;
    color: var(--app-text-muted);
}

/* Campo ainda em branco: diz o que sera, em vez de abrir um vao. */
.app-ex-vazio {
    color: var(--app-text-dim);
    font-style: italic;
}

/* ---------------------------------------------------------------------------
   "Nova versao": montar a licao arrastando blocos para dentro do celular.

   Tres colunas -- paleta, aparelho, painel do selecionado -- num dialogo de tela
   cheia. O aparelho e o mesmo .app-phone da previa; o que muda e o chrome de
   edicao, que entra pela classe .app-canvas e usa tokens PROPRIOS (azul) para
   nao se confundir com o roxo do app: contorno azul e coisa do editor, roxo e
   coisa que o aluno ve.
   --------------------------------------------------------------------------- */

/* O .mud-dialog-fullscreen e overflow-y:hidden e o .mud-dialog-content rola;
   aqui quem rola e cada coluna, senao as tres rolam juntas e a paleta sobe
   junto com o celular. */
.mud-dialog-content.lesson-canvas-dialogo {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 8px 16px 12px;
}

.lesson-canvas {
    flex: 1;
    min-height: 0;
    display: grid;
    grid-template-columns: 260px minmax(0, 1fr) 380px;
    gap: 16px;
}

.lesson-canvas-paleta,
.lesson-canvas-inspector {
    min-width: 0;
    overflow-y: auto;
    padding-right: 4px;
}

.lesson-canvas-aparelho {
    min-width: 0;
    overflow: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 4px;
    outline: none;
}

.lesson-canvas-barra {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: calc(var(--app-screen-width) + 2 * var(--app-bezel));
}

.lesson-canvas-sem-selecao {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    text-align: center;
    padding: 32px 16px;
}

@media (max-width: 1199px) {
    .lesson-canvas {
        grid-template-columns: 220px minmax(0, 1fr) 320px;
        gap: 12px;
    }
}

@media (max-width: 959px) {
    .lesson-canvas {
        grid-template-columns: 1fr;
        overflow-y: auto;
    }

    .lesson-canvas-paleta .lesson-paleta-lista {
        flex-direction: row;
        flex-wrap: wrap;
    }
}

/* Tela baixa: o aparelho tem 879px de moldura e nao cabe em notebook de 768px de
   altura. zoom encolhe tudo junto; transform NAO serve -- criaria um containing
   block e o fantasma do arrasto (position:fixed) passaria a se posicionar em
   relacao ao celular, indo parar longe do ponteiro. */
@media (max-height: 920px) {
    .lesson-canvas-aparelho .app-phone {
        zoom: .85;
    }
}

/* Notebook de 768/800px de altura: com .85 o aparelho ainda passa da area util e
   a barra de abas fica abaixo da dobra -- justo a parte que responde "cabe na
   primeira tela?". Em .72 o celular inteiro aparece. */
@media (max-height: 860px) {
    .lesson-canvas-aparelho .app-phone {
        zoom: .72;
    }
}

/* ----- paleta (fora do celular: MudBlazor a vontade) ----- */

.lesson-paleta-lista {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 8px;
}

.lesson-paleta-item {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 10px;
    background-color: var(--mud-palette-surface);
    cursor: grab;
    user-select: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.lesson-paleta-item:hover,
.lesson-paleta-item:focus-visible {
    border-color: var(--mud-palette-primary);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--mud-palette-primary) 14%, transparent);
    outline: none;
}

.lesson-paleta-item:active {
    cursor: grabbing;
}

.lesson-paleta-texto {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.lesson-paleta-rotulo {
    font-size: .875rem;
    font-weight: 600;
    line-height: 1.3;
}

.lesson-paleta-dica {
    font-size: .75rem;
    line-height: 1.3;
    color: var(--mud-palette-text-secondary);
}

/* ----- chrome de edicao DENTRO do celular ----- */

.app-phone.app-canvas {
    --app-canvas-sel: #2F6FED;
    --app-canvas-sel-fraco: rgba(47, 111, 237, .18);
    --app-canvas-chrome: #111827;
    --app-canvas-chrome-fg: #FFFFFF;
}

.app-phone.app-canvas.app-dark {
    --app-canvas-sel: #7AA7FF;
    --app-canvas-sel-fraco: rgba(122, 167, 255, .22);
    --app-canvas-chrome: #F3F4F6;
    --app-canvas-chrome-fg: #111827;
}

/* user-select:none porque clicar e arrastar no corpo do bloco selecionaria o
   texto da licao, e o arrasto pareceria falhado. */
/* Peca selecionavel do editor -- vale para qualquer coisa que o professor
   escolhe dentro do celular. Bloco e card da licao tem regras proprias por
   causa da geometria; o resto do editor usa esta. */
.app-canvas .app-sel {
    position: relative;
    cursor: pointer;
    user-select: none;
    border-radius: 12px;
    transition: box-shadow .12s ease;
}

.app-canvas .app-sel:hover {
    box-shadow: 0 0 0 2px var(--app-canvas-sel-fraco);
}

.app-canvas .app-sel.app-sel-ativo {
    box-shadow: 0 0 0 2px var(--app-canvas-sel);
}

.app-canvas .app-sel:hover > .app-block-grip,
.app-canvas .app-sel-ativo > .app-block-grip {
    opacity: 1;
}

.app-canvas .app-block {
    position: relative;
    border-radius: 8px;
    cursor: pointer;
    user-select: none;
}

.app-canvas .app-block:hover {
    box-shadow: 0 0 0 2px var(--app-canvas-sel-fraco);
}

.app-canvas .app-block.app-block-selecionado {
    box-shadow: 0 0 0 2px var(--app-canvas-sel);
}

.app-canvas .app-card {
    position: relative;
    cursor: pointer;
}

.app-canvas .app-card.app-card-selecionado {
    border-color: var(--app-canvas-sel);
    box-shadow: 0 0 0 2px var(--app-canvas-sel-fraco);
}

.app-canvas .app-card-nome {
    min-width: 0;
}

.app-canvas .app-card-aviso {
    margin: 0;
    font-size: 12px;
    line-height: 1.3;
    color: var(--app-text-muted);
}

/* min-height para a zona existir mesmo entre blocos coladinhos: sem altura, o
   SortableJS nao tem onde soltar. */
.app-canvas .app-blocks {
    min-height: 24px;
}

.app-canvas .app-blocks-vazia,
.app-canvas .app-pagina-vazia {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    border: 2px dashed var(--app-border);
    border-radius: var(--app-box-radius);
    color: var(--app-text-muted);
}

.app-canvas .app-blocks-vazia {
    min-height: 72px;
}

.app-canvas .app-blocks-vazia::after {
    content: "Arraste um bloco aqui";
    font-size: 13px;
}

.app-canvas .app-pagina-vazia {
    min-height: 160px;
    padding: 20px;
    font-size: 14px;
    border-radius: var(--app-card-radius);
}

/* Durante o arrasto todas as zonas se anunciam: sem isto, soltar dentro de um
   card cheio e' mira as cegas. */
body.app-arrastando .app-canvas .app-blocks,
body.app-arrastando .app-canvas .app-pagina-vazia {
    outline: 2px dashed var(--app-canvas-sel-fraco);
    outline-offset: 4px;
}

/* ----- SortableJS ----- */

/* O vao que fica na lista, mostrando onde o bloco vai cair. */
.app-canvas .app-sortable-ghost {
    opacity: .35;
    outline: 2px dashed var(--app-canvas-sel);
    outline-offset: 2px;
}

/* O clone que segue o ponteiro. Vive no <body>, entao precisa da largura do card
   escrita aqui -- solto, ele esticaria ate a largura da janela. */
.app-drag-fantasma {
    opacity: .92;
    box-shadow: 0 12px 28px rgba(0, 0, 0, .28);
    transform: rotate(1.5deg);
    pointer-events: none;
    cursor: grabbing;
}

.app-drag-fantasma.app-block {
    width: calc(var(--app-screen-width) - 2 * var(--app-card-pad) - 2px);
    background-color: var(--app-card);
    border-radius: 8px;
    padding: 4px;
}

.app-drag-fantasma.app-card {
    width: calc(var(--app-screen-width) - 32px);
}

/* ----- alcas e barra flutuante (dentro do celular: nada de MudBlazor) ----- */

.app-block-grip,
.app-card-grip {
    display: inline-flex;
    align-items: center;
    cursor: grab;
    opacity: 0;
    transition: opacity .12s ease;
}

.app-canvas .app-block:hover .app-block-grip,
.app-canvas .app-block-selecionado .app-block-grip,
.app-canvas .app-card:hover .app-card-grip,
.app-canvas .app-card-selecionado .app-card-grip {
    opacity: 1;
}

.app-block-grip:active,
.app-card-grip:active {
    cursor: grabbing;
}

.app-card-grip {
    margin-left: auto;
    color: var(--app-text-muted);
    flex: none;
}

.app-block-grip {
    position: absolute;
    top: -12px;
    left: 6px;
    z-index: 2;
    padding: 2px;
    border-radius: 6px;
    background-color: var(--app-canvas-chrome);
    color: var(--app-canvas-chrome-fg);
}

/* A barra fica DENTRO do quadro do celular, colada no bloco: assim rola junto
   com ele. Como overlay do painel, precisaria medir a posicao a cada rolagem. */
.app-block-tools {
    position: absolute;
    top: -12px;
    right: 6px;
    z-index: 2;
    display: flex;
    gap: 2px;
    padding: 2px;
    border-radius: 8px;
    background-color: var(--app-canvas-chrome);
    color: var(--app-canvas-chrome-fg);
    box-shadow: 0 2px 8px rgba(0, 0, 0, .3);
}

.app-block-tool {
    all: unset;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 6px;
    cursor: pointer;
}

.app-block-tool:hover {
    background-color: color-mix(in srgb, var(--app-canvas-chrome-fg) 18%, transparent);
}

.app-block-tool:focus-visible {
    outline: 2px solid var(--app-canvas-sel);
    outline-offset: 1px;
}

.app-block-tool:disabled {
    opacity: .35;
    cursor: default;
}

.app-block-tool-perigo:hover {
    background-color: rgba(220, 38, 38, .35);
}

/* ── Figuras da biblioteca de mídias ───────────────────────────────────────────
   O .app-thumb é usado DENTRO do .app-phone-frame (prévia da lição e do
   exercício) e também fora dele, no seletor e na lista de mídias. Por isso ele
   só define forma, e quem o usa dá o tamanho: no celular a figura tem de
   obedecer ao card; no painel, ao cartão da grade. */
.app-thumb {
    display: block;
    width: 100%;
    object-fit: contain;
    border-radius: var(--app-box-radius);
    background: var(--app-track);
}

/* Enquanto a figura não resolve (ou não resolveu): o mesmo espaço, em cinza.
   Sem texto de erro — é o editor, o professor sabe o que pôs ali. */
.app-thumb-vazio {
    aspect-ratio: 4 / 3;
}

/* Galeria da aba "Fotos": aqui a figura É o card, e não um adorno de 56px ao lado do nome.
   Nome de arquivo de imagem não identifica nada ("img_2847.jpg"), então a miniatura precisa ser
   o conteúdo — foi por isso que a aba se separou da lista de áudio. */
.admin-foto-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 16px;
}

.admin-foto-card {
    display: flex;
    flex-direction: column;
}

/* Proporção fixa, como a caixa da lição: sem ela o card salta de altura quando cada figura
   resolve, e a grade inteira reflui uma vez por miniatura. */
.admin-foto-figura {
    aspect-ratio: 4 / 3;
    overflow: hidden;
    background: var(--mud-palette-background-grey, #f5f5f5);
}

/* Recorta em vez de encaixar: aqui a miniatura é identificação, e a faixa vazia do AspectFit
   desalinharia a grade. A tela do aluno é que decide o enquadramento de verdade. */
.admin-foto-figura .app-thumb {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 0;
}

.admin-foto-figura .app-thumb-vazio {
    aspect-ratio: auto;
}

.admin-foto-pendente {
    display: flex;
    width: 100%;
    height: 100%;
    align-items: center;
    justify-content: center;
}

.admin-foto-legenda {
    min-width: 0;
    padding: 8px 12px 0;
}

/* Enquanto o navegador reamostra a foto. É rápido (algumas centenas de ms numa de 12 MP), mas
   sem sinal nenhum a tela fica parada entre escolher o arquivo e o upload começar. */
.admin-media-dropzone:has(input[data-resizing]) {
    cursor: progress;
}

.admin-media-dropzone:has(input[data-resizing])::after {
    content: "Preparando a imagem...";
    display: block;
    margin-top: 8px;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary, #757575);
}

/* Seletor de figura: grade de miniaturas, porque nome de arquivo não identifica
   uma imagem. */
.admin-image-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 12px;
    max-height: 360px;
    overflow-y: auto;
    padding: 2px;
}

.admin-image-card {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 8px;
    border: 1px solid var(--mud-palette-lines-default, #0001);
    border-radius: 10px;
    background: transparent;
    cursor: pointer;
    text-align: left;
    font: inherit;
    color: inherit;
}

.admin-image-card:hover,
.admin-image-card:focus-visible {
    border-color: var(--mud-palette-primary, #594ae2);
    background: var(--mud-palette-action-default-hover, #0000000a);
}

.admin-image-card-thumb {
    aspect-ratio: 1;
    object-fit: cover;
}

.admin-image-card-nome {
    font-size: 12px;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.admin-image-card-tamanho {
    font-size: 11px;
    opacity: 0.7;
}

/* Conferência dentro do campo: a figura escolhida, pequena o bastante para não
   empurrar o resto do inspetor para fora da tela. */
.admin-image-preview {
    margin-top: 8px;
    max-height: 160px;
    object-fit: contain;
}
