/**
 * meeting.css
 * Estilos da PÁGINA do portal de convidados: fundo, ecrã de entrada e os
 * cartões de transição (contagem decrescente, despedida, erro).
 *
 * O ecrã da reunião NÃO está aqui: é o componente partilhado MeetUI, que traz a
 * sua própria folha (Shared/Components/MeetUI/styles/meet-ui.css). Esta
 * separação é o que permite ao CRM e ao portal mostrarem o mesmo ecrã.
 */

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

html {
    scrollbar-width: none;
    -ms-overflow-style: none;
}
html::-webkit-scrollbar { width: 0; height: 0; }

html, body {
    /* Inter, a família única do projeto. */
    font-family: 'Inter', sans-serif;
    color: #e6edf3;
    font-size: 15px;
    line-height: 1.5;
}
html { background: #0d1117; }
body { background: transparent; }

/* ─── Fundo ÚNICO da página, igual em todas as fases ───
   Gradiente animado, sem véu por cima. O ecrã da reunião é transparente de
   propósito para o herdar: é o mesmo fundo do início ao fim. */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
    background-size: 400% 400%;
    animation: meeting-gradient 12s ease infinite;
    z-index: -1;
}
@keyframes meeting-gradient {
    0%   { background-position: 0% 50%; }
    50%  { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}

/* Scrollbar fino nos elementos internos, nunca o nativo do SO. Mesma lógica do
   Pilot/base.css: Chrome e Safari via ::-webkit-scrollbar; scrollbar-width só
   no Firefox (@supports que só ele cumpre); rede de segurança que força auto no
   Chrome (o antigo `*{scrollbar-width:thin}` ativava o nativo no Chrome 121+). */
::-webkit-scrollbar          { width: 8px; height: 8px; }
::-webkit-scrollbar-button   { display: none; height: 0; width: 0; }
::-webkit-scrollbar-track    { background: transparent; }
::-webkit-scrollbar-thumb    { background: rgba(255, 255, 255, .20); border-radius: 0; }
::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, .38); }
@supports not selector(::-webkit-scrollbar) {
    * { scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .20) transparent; }
}
@supports selector(::-webkit-scrollbar) {
    * { scrollbar-width: auto !important; scrollbar-color: auto !important; }
}

/* ─── Layout: a mesma estrutura do /login ───
   O ecrã ocupa a altura toda e o conteúdo fica ao centro. O rodapé vive ABAIXO
   dessa altura, e chega-se a ele a rolar, como no login do CRM. */
body {
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
}

/* A mesma centragem do /login: o contentor tem a altura toda e o conteúdo fica
   no meio dela. O `padding` era simétrico e assim o cartão descia: os 90px do
   topo, que existiam para o cabeçalho, empurravam-no para baixo do centro. */
#meeting-app {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 100dvh;
    padding: 40px 16px;
}
/* A página inicial fica ao centro como o resto do portal. Quando é mais alta do
   que o ecrã, o `safe-center` deixa-a crescer para baixo sem cortar o topo, que
   é o que o `center` faz a um filho maior do que o contentor. */
#meeting-app:has(.meeting-home) {
    justify-content: safe center;
    padding-block: 48px;
}
/* O cabeçalho é fixo e passa por cima do que estiver ao centro. O espaço dele
   sai por MARGEM e não por padding: o padding entra na caixa que se está a
   centrar e puxava tudo para baixo, deixando mais espaço em cima do que em
   baixo. Com margem, o contentor começa abaixo do cabeçalho e centra no que
   sobra, que é o que se quer. */
body.meeting-portal.tem-sessao #meeting-app {
    margin-top: var(--meeting-header-h);
    min-height: calc(100dvh - var(--meeting-header-h));
}

/* ANTES da chamada o cabeçalho não aparece (decisão do Jorge, 2026-09-03): quem
   chega aqui vem para uma reunião, e a página é um cartão ao centro de um ecrã
   vazio, como o /login. O cabeçalho entra quando a reunião entra.

   O rodapé é o contrário: está lá desde o início e sai quando o ecrã de reunião
   monta, ou ficava por baixo dele, misturado com a barra de dispositivos.

   O `meetui-open` é posto no body pelo MeetUI. As regras do cabeçalho levam a
   classe `.meeting-portal`, que só este portal tem: o offers carrega esta mesma
   folha e ficaria sem cabeçalho nenhum. */
/* ANTES da chamada o cabeçalho não aparece a quem chega de fora: a página é um
   cartão ao centro de um ecrã vazio, como o /login, e um cabeçalho por cima
   dela era um menu para uma casa onde essa pessoa não entra.

   Quem tem sessão vê-o sempre (decisão do Jorge, 2026-09-04): a página inicial
   é uma página do CRM como as outras, e a partir dela navega-se. */
body.meeting-portal #main-header { display: none; }
body.meeting-portal.meetui-open #main-header,
body.meeting-portal.tem-sessao #main-header { display: flex; }
body.meetui-open .main-footer { display: none; }

/* ─── O cabeçalho não se sobrepõe à reunião ───
   O ecrã de reunião nasce em `inset: 0` e o cabeçalho é fixo no topo: ocupavam
   a mesma faixa, com a marca do MeetUI por baixo do logótipo. Aqui a reunião
   começa abaixo do cabeçalho e a marca do MeetUI sai. */
body.meeting-portal {
    /* As mesmas medidas do `--main-header-height` (main-header.css), repetidas
       aqui porque lá vivem dentro do `#main-header` e não chegam a quem está
       fora dele. Mudar uma sem a outra deixa uma frincha ou uma sobreposição. */
    --meeting-header-h: 50px;
}
@media (min-width: 992px) {
    body.meeting-portal { --meeting-header-h: 70px; }
}
body.meeting-portal.meetui-open .meetui:not(.meetui-prejoin) {
    top: var(--meeting-header-h);
    grid-template-rows: 0 minmax(0, 1fr) var(--meet-bar-h);
}
/* `display: none` tira o elemento do grid e faz subir tudo o que vem a seguir:
   o vídeo passava a ocupar a linha de zero e a barra ia parar ao meio do ecrã.
   O item fica, com altura zero e escondido de toda a gente, incluindo de quem
   navega por teclado. */
body.meeting-portal.meetui-open .meetui:not(.meetui-prejoin) .meetui-brand {
    visibility: hidden;
    overflow: hidden;
    min-height: 0;
    padding: 0;
    border: 0;
}

/* ─── O gradiente cala-se durante a reunião ───
   Desfocado e por baixo de um véu escuro: o movimento continua nas margens, e o
   contraste todo fica para o vídeo e para as caras. */
body.meeting-portal.meetui-open .meetui:not(.meetui-prejoin) {
    background: rgba(0, 0, 0, .62);
    backdrop-filter: blur(22px);
    -webkit-backdrop-filter: blur(22px);
}
/* O cabeçalho assenta no mesmo escuro, para a faixa do topo não ficar a ser a
   única janela para o gradiente. */
body.meeting-portal.meetui-open:has(.meetui:not(.meetui-prejoin)) #main-header {
    background: rgba(0, 0, 0, .62);
    backdrop-filter: blur(22px);
    -webkit-backdrop-filter: blur(22px);
}



/* ─── Ecrã de entrada (código da reunião) ───
   Mesmo cartão do /login do CRM: claro sobre o fundo, largura contida, sombra
   de elevação e a mesma entrada suave. É a peça a que se chega sem link nas
   mãos, e é para onde vai parar quem tentou um código que já não serve. */
.meeting-entry {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: center;
    width: min(380px, calc(100vw - 48px));
    padding: 32px;
    background-color: #ffffff;
    color: #171717;
    border-radius: 8px;
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, .3), 0 4px 6px -4px rgba(0, 0, 0, .3);
    text-align: center;
    animation: meeting-card-in .9s cubic-bezier(.33, 0, .2, 1) both;
}
@keyframes meeting-card-in {
    from { opacity: 0; transform: translateY(18px) scale(.985); }
    to   { opacity: 1; transform: none; }
}

/* Texto que só os leitores de ecrã leem. O nome é o canónico do projeto
   (base.css do CMS), repetido aqui porque o portal não carrega essa folha. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Logótipo e nome da aplicação, com a anatomia do cartão de /login: a marca
   identifica a casa, a linha por baixo diz em que aplicação se está. */
.meeting-entry-logo {
    display: flex;
    justify-content: center;
    align-self: center;
    padding: 4px;
    color: #171717;
    border-radius: 4px;
}
.meeting-entry-logo:focus-visible { outline: 2px solid #737373; outline-offset: 2px; }
.meeting-entry-logo svg { width: 120px; height: auto; display: block; }

.meeting-entry-app {
    display: block;
    margin: 0 0 26px;
    font-size: 12px;
    font-weight: 500;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: #737373;
    text-decoration: none;
}
.meeting-entry-app:hover { color: #171717; }
.meeting-entry-app:focus-visible { outline: 2px solid #737373; outline-offset: 2px; border-radius: 2px; }

.meeting-entry-title {
    font-size: 20px;
    font-weight: 600;
    color: #171717;
    margin-bottom: 6px;
}
.meeting-entry-error {
    margin-bottom: 18px;
    padding: 10px 14px;
    border-radius: 6px;
    background: #fdecec;
    border: 1px solid #f5c2c0;
    color: #b42318;
    font-size: 13.5px;
    line-height: 1.5;
}
/* Tudo ao centro, como no cartão do /login: é um cartão estreito com um campo
   só, e o alinhamento à esquerda dava três eixos diferentes de leitura. */
.meeting-entry-form {
    display: flex;
    flex-direction: column;
    gap: 7px;
    text-align: center;
}
.meeting-entry-label {
    font-size: 13px;
    font-weight: 500;
    color: #525252;
}
/* Monoespaçado e com as letras afastadas: um código lê-se caractere a
   caractere, e é assim que se confere o que se escreveu contra o convite. */
.meeting-entry-input {
    width: 100%;
    padding: 11px 14px;
    border: 1px solid #d4d4d4;
    border-radius: 6px;
    background: #fff;
    color: #171717;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 17px;
    letter-spacing: .09em;
    text-align: center;
    transition: border-color .15s;
}
.meeting-entry-input::placeholder { color: #a3a3a3; letter-spacing: .09em; }
.meeting-entry-input:focus { outline: none; border-color: #737373; }
.meeting-entry-input:focus-visible {
    outline: 2px solid #737373;
    outline-offset: 2px;
    border-color: #737373;
}
.meeting-entry-hint {
    font-size: 12px;
    color: #737373;
    margin-bottom: 8px;
}
/* Sem sublinhado em repouso, como o "Esqueceu-se da palavra-passe?" do /login:
   o sublinhado aparece ao passar por cima e ao chegar pelo teclado. */
.meeting-entry-back {
    display: inline-block;
    margin-top: 20px;
    color: #737373;
    font-size: 13px;
    text-decoration: none;
}
.meeting-entry-back:hover,
.meeting-entry-back:focus-visible {
    color: #171717;
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* Mensagens do Validation.js.
   O componente escreve `.error-messages > .error-message` e conta com o CSS do
   CMS, que este portal não carrega: sem isto o erro saía como texto solto, na
   cor do corpo e colado ao campo. O desenho é o do CMS, transposto para os
   valores desta caixa clara. */
/* O Validation acrescenta a caixa da mensagem no FIM do formulário, e ela saía
   por baixo do botão, longe do campo que estava errado. O `order` põe-na no
   sítio: label, campo, erro, dica, botão. */
.meeting-entry-form > .meeting-entry-label { order: 1; }
.meeting-entry-form > .meeting-entry-input { order: 2; }
.meeting-entry-form > .error-messages      { order: 3; }
.meeting-entry-form > .meeting-entry-hint  { order: 4; }
.meeting-entry-form > .meeting-btn-primary { order: 5; }

.meeting-entry .error-messages {
    display: block;
    padding-top: 4px;
    line-height: 1.35;
    pointer-events: none;
}
.meeting-entry .error-message {
    display: block;
    margin: 0;
    padding: 0;
    color: #b42318;
    font-size: 12px;
    line-height: 1.35;
}
/* O campo com erro fica marcado a vermelho: a mensagem diz o que falta e a
   borda diz onde. */
.meeting-entry .validation-error,
.meeting-entry-input.validation-error {
    border-color: #d92d20;
}
.meeting-entry .validation-error:focus-visible {
    outline-color: #d92d20;
    border-color: #d92d20;
}

/* ─── Página inicial (quem tem sessão do CRM) ───
   Cartão claro sobre o gradiente, como o da caixa do código, mas largo: aqui há
   uma lista e um formulário de nove escolhas, e a medida do cartão de login
   apertava tudo numa coluna. */
.meeting-home {
    width: min(760px, calc(100vw - 32px));
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding: 32px;
    background: #fff;
    color: #171717;
    border-radius: 12px;
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, .3), 0 4px 6px -4px rgba(0, 0, 0, .3);
    animation: meeting-card-in .9s cubic-bezier(.33, 0, .2, 1) both;
}

.meeting-home-head h1 { font-size: 22px; font-weight: 600; margin-bottom: 4px; }
.meeting-home-head p  { font-size: 14px; color: #737373; }

.meeting-home-actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.meeting-home-actions .meeting-btn-primary { width: auto; }
.meeting-home-join { display: flex; gap: 8px; flex: 1; min-width: 240px; }
.meeting-home-join input {
    flex: 1;
    min-width: 0;
    padding: 11px 14px;
    border: 1px solid #d4d4d4;
    border-radius: 6px;
    font: inherit;
    font-size: 14px;
    color: #171717;
    background: #fff;
}
.meeting-home-join input:focus-visible { outline: 2px solid #737373; outline-offset: 2px; border-color: #737373; }

.meeting-btn-ghost {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 11px 16px;
    border: 1px solid #d4d4d4;
    border-radius: 6px;
    background: #fff;
    color: #171717;
    font: inherit;
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
}
.meeting-btn-ghost:hover { background: #f5f5f5; border-color: #a3a3a3; }
.meeting-btn-ghost:focus-visible { outline: 2px solid #737373; outline-offset: 2px; }

/* ── O formulário de criação ── */
.meeting-new,
.meeting-done,
.meeting-list { border-top: 1px solid #e5e5e5; padding-top: 18px; }
.meeting-new h2,
.meeting-done h2,
.meeting-list h2 { font-size: 15px; font-weight: 600; margin-bottom: 14px; }
.meeting-new[hidden], .meeting-done[hidden] { display: none; }

/* Duas colunas onde cabem, uma onde não cabem. Sem media query: o `auto-fit`
   com uma medida mínima faz a decisão pela largura real do cartão. */
.mh-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 12px;
    margin-bottom: 16px;
}
.mh-field { display: flex; flex-direction: column; gap: 5px; }
.mh-field > span { font-size: 13px; font-weight: 500; color: #525252; }
.mh-field small { font-size: 12px; color: #737373; }
.mh-field input,
.mh-field select,
.mh-field textarea {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid #d4d4d4;
    border-radius: 6px;
    background: #fff;
    color: #171717;
    font: inherit;
    font-size: 14px;
    resize: vertical;
}
.mh-field input:focus-visible,
.mh-field select:focus-visible,
.mh-field textarea:focus-visible { outline: 2px solid #737373; outline-offset: 1px; border-color: #737373; }
.mh-field[hidden] { display: none; }

.mh-opts {
    border: 1px solid #e5e5e5;
    border-radius: 8px;
    padding: 12px 14px 14px;
    margin-bottom: 14px;
}
.mh-opts legend { padding: 0 6px; font-size: 12.5px; font-weight: 500; color: #525252; }
.mh-check { display: flex; align-items: center; gap: 8px; font-size: 13.5px; padding: 4px 0; }
/* A caixa real: no CMS o global esconde-a, e este portal não carrega esse CSS,
   mas o reset do topo desta folha zera-lhe a margem. */
.mh-check input[type="checkbox"] {
    position: static;
    width: 15px;
    height: 15px;
    margin: 0;
    opacity: 1;
    clip: auto;
    accent-color: #171717;
    cursor: pointer;
}
.mh-check input[type="checkbox"]:focus-visible { outline: 2px solid #737373; outline-offset: 2px; }

.mh-form-acts { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; }
.mh-form-acts .meeting-btn-primary { width: auto; }

.mh-msg { margin-top: 12px; font-size: 13.5px; color: #525252; }
.mh-msg.is-error { color: #b42318; }
.mh-msg[hidden] { display: none; }

/* ── O código, depois de criada ──
   Grande e monoespaçado: é para se ler de longe e ditar ao telefone, que é o
   caso para que este código existe. */
.meeting-done { text-align: center; }
.mh-done-sub { font-size: 13.5px; color: #737373; margin-bottom: 14px; }
.mh-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 30px;
    letter-spacing: .1em;
    color: #171717;
    padding: 14px;
    background: #f5f5f5;
    border-radius: 8px;
    margin-bottom: 16px;
    user-select: all;
}
.mh-done-acts { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
.mh-done-acts .meeting-btn-primary { width: auto; }
.mh-done-invites { margin-top: 12px; font-size: 13px; color: #525252; }
.mh-done-invites[hidden] { display: none; }

/* ── A lista ── */
.meeting-list-empty { font-size: 13.5px; color: #737373; }
.meeting-list-items { list-style: none; display: flex; flex-direction: column; }
.meeting-item {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 0;
    border-bottom: 1px solid #f0f0f0;
    flex-wrap: wrap;
}
.meeting-item:last-child { border-bottom: 0; }
.meeting-item-body { flex: 1; min-width: 180px; }
.meeting-item-name { font-size: 14px; font-weight: 500; }
.meeting-item-meta {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 3px;
    font-size: 12.5px;
    color: #737373;
}
.meeting-item-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    letter-spacing: .04em;
    color: #171717;
}
.meeting-item-live { color: #138643; font-weight: 500; }
.meeting-item-acts { display: flex; gap: 8px; flex-wrap: wrap; }
.meeting-item-acts .meeting-btn-primary { width: auto; padding: 9px 14px; font-size: 13.5px; }
.meeting-item-acts .meeting-btn-ghost { padding: 9px 14px; font-size: 13.5px; }

@media (prefers-reduced-motion: reduce) {
    .meeting-home { animation: none; }
}

/* ─── Cartão de transição (contagem decrescente, despedida) ─── */
.meeting-card {
    background: #161b22;
    border: 1px solid #30363d;
    border-radius: 12px;
    padding: 32px;
    width: 100%;
    max-width: 460px;
    box-shadow: 0 16px 48px rgba(0, 0, 0, .5);
    text-align: center;
}
.meeting-card-title {
    font-size: 20px;
    font-weight: 600;
    margin-bottom: 6px;
}
.meeting-card-subtitle {
    font-size: 14px;
    color: #8b949e;
    margin-bottom: 20px;
    line-height: 1.6;
}
.meeting-card-subtitle strong { color: #e6edf3; }

.meeting-btn-primary {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    padding: 12px 16px;
    background: #171717;
    color: #fff;
    border: none;
    border-radius: 6px;
    font-family: inherit;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s;
}
/* Serve <button> e <a>: um link com o desenho de botão não leva sublinhado. */
.meeting-btn-primary { text-decoration: none; }
.meeting-btn-primary:hover { background: #404040; }
.meeting-btn-primary:focus-visible { outline: 2px solid #737373; outline-offset: 2px; }
.meeting-btn-primary:disabled { opacity: .55; cursor: not-allowed; }

/* O cartão de transição é escuro: o botão lá dentro não pode ser o preto da
   caixa clara, ou desaparecia no fundo. */
.meeting-card .meeting-btn-primary { background: #e6edf3; color: #161b22; }
.meeting-card .meeting-btn-primary:hover { background: #fff; }

/* ─── Contagem decrescente ─── */
.meeting-countdown-wrap {
    display: flex;
    gap: 10px;
    justify-content: center;
    flex-wrap: wrap;
    margin: 4px 0 0;
}
.meeting-countdown-unit {
    background: #0d1117;
    border: 1px solid #30363d;
    border-radius: 8px;
    padding: 10px 14px;
    min-width: 60px;
    text-align: center;
}
.meeting-countdown-value {
    display: block;
    font-size: 26px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: #e6edf3;
}
.meeting-countdown-label {
    display: block;
    margin-top: 3px;
    font-size: 10px;
    color: #8b949e;
    text-transform: uppercase;
    letter-spacing: .05em;
}

/* ─── Ecrã de erro ─── */
.meeting-error-screen {
    position: relative;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    overflow: hidden;
}
.meeting-error-content {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
    padding: 32px 24px;
    max-width: 480px;
    text-align: center;
    color: #fff;
    text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
}
.meeting-error-icon { opacity: .9; flex-shrink: 0; }
.meeting-error-msg  { font-size: 22px; font-weight: 600; line-height: 1.4; }
.meeting-error-back {
    color: #fff;
    font-size: 15px;
    font-weight: 500;
    text-decoration: none;
    border: 2px solid rgba(255, 255, 255, .75);
    border-radius: 8px;
    padding: 10px 28px;
    transition: background .2s, border-color .2s;
}
.meeting-error-back:hover {
    background: rgba(255, 255, 255, .18);
    border-color: #fff;
}

@media (prefers-reduced-motion: reduce) {
    body::before { animation: none; }
    .meeting-entry { animation: none; }
}

/* ─── Rodapé ───
   O mesmo do /login (modules/login/assets/css/login.css), por decisão do Jorge
   a 2026-09-04: este portal é a porta de entrada da casa, não uma landing de
   campanha. A faixa anima `transform` e não `background-position`, para a GPU
   compor sem um único repaint. */
.main-footer {
    display: flex;
    position: relative;
    margin: 0;
    padding: 20px 0;
    /* O pseudo-elemento é maior do que o rodapé: sem isto assomava para fora e
       dava scroll horizontal à página inteira. */
    overflow: hidden;
    /* Contexto próprio, para o `z-index: -1` do pseudo ficar atrás do texto e
       nunca escapar para trás do gradiente da página. */
    isolation: isolate;
    background-color: #101010;
}
.main-footer::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 400%;
    z-index: -1;
    background-image: linear-gradient(-60deg, #111, #333, #666, #333);
    background-size: 100% 100%;
    animation: meeting-footer-drift 4s ease-in-out infinite alternate;
    will-change: transform;
}
@keyframes meeting-footer-drift {
    from { transform: translate3d(0, 0, 0); }
    /* -75% de 400% são três larguras de rodapé, o percurso do original. */
    to   { transform: translate3d(-75%, 0, 0); }
}
.main-footer .copyright-area {
    margin: 0 auto;
    padding: 3px 0;
}
.main-footer .copyright-text {
    margin: 0;
    font-size: 13px;
    font-weight: 400;
    color: #ffffff;
    text-align: center;
}
@media (prefers-reduced-motion: reduce) {
    /* O gradiente fica; o movimento é que não. */
    .main-footer::before { animation: none; will-change: auto; }
}

/* Eliminar uma reunião: discreto ao lado do que se usa todos os dias, e claro
   quando se lá chega. */
.meeting-btn-danger {
    padding: 8px 14px;
    border: 1px solid rgba(220, 38, 38, .35);
    border-radius: 8px;
    background: transparent;
    color: #dc2626;
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}
.meeting-btn-danger:hover { background: rgba(220, 38, 38, .08); border-color: #dc2626; }
.meeting-btn-danger:focus-visible { outline: 2px solid #dc2626; outline-offset: 2px; }

/* O corpo do modal de confirmação. Os modais deste portal seguem o tema escuro
   do site público (assets/css/default/modal.css), por isso as cores vêm dos
   tokens dele e não das da página, que é clara. */
.mh-modal-body { padding: 20px 24px 8px; }
.mh-modal-body p {
    margin: 0 0 10px;
    color: var(--modal-text, #e8e4e0);
    font-size: 14px;
    line-height: 1.55;
}
.mh-modal-body p:last-child { color: var(--modal-text-muted, #888888); }

/* Administração: as reuniões de outra pessoa e o registo do que se apagou.
   Fica no fim da página, discreto, porque é o que se procura de propósito e
   nunca o que se vem cá fazer. */
.meeting-admin {
    margin-top: 28px;
    padding-top: 22px;
    border-top: 1px solid #e5e5e5;
}
.meeting-admin h2 {
    margin: 0 0 14px;
    font-size: 15px;
    font-weight: 600;
    color: #525252;
}
.meeting-admin-list { margin-top: 10px; }
.meeting-admin-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 10px 0;
    border-bottom: 1px solid #f0f0f0;
}
.meeting-admin-row:last-child { border-bottom: 0; }
.meeting-admin-log { margin-top: 18px; }
.meeting-admin-log summary {
    cursor: pointer;
    font-size: 13px;
    color: #525252;
}
.meeting-admin-log summary:hover { color: #171717; }
.meeting-admin-log summary:focus-visible { outline: 2px solid #737373; outline-offset: 2px; }
