/* ===== moldura e primitivas =====
   Uma regra entra aqui quando serve mais do que uma área; se só serve uma, vive no ficheiro dela. */

/* As duas colunas do ecrã principal chegam ao fundo, para as duas listas terem espaço para
   crescer. `min-height` e não `height`: quando o conteúdo passa do ecrã, a página cresce. */
#dashboardApp {
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
}

/* O tecto de leitura entra aqui e não no `container-fluid`: a moldura continua de ponta a
   ponta e é o conteúdo que para. */
.dashboard-main {
    max-width: var(--content-max);
}

/* Empilhado, a atividade sobe para debaixo da identidade e os cartões de telemetria descem; a
   coluna do aparelho desfaz-se para os seus cartões poderem ser ordenados. */
@media (max-width: 991.98px) {
    /* A régua entrega a telemetria com um respiro -- sem ele a etiqueta da secção fica
       colada aos separadores --, e o `g-3` da linha anula a margem do primeiro cartão. */
    .device-screen {
        padding-top: .625rem;
    }

    /* A lista é a excepção: vai de bordo a bordo e encostada à régua, como um ecrã e não
       como uma folha pousada. Os 12px são o enchimento do `container-fluid`. */
    .device-screen > #detailColumn > .card {
        margin-top: -.625rem;
        margin-inline: -12px;
        border-inline-width: 0;
        border-top-width: 0;
        border-radius: 0;
    }

    .device-screen > #deviceColumn {
        display: contents;
    }

    .device-screen > #deviceColumn > * {
        width: 100%;
        margin-top: var(--bs-gutter-y);
        padding-inline: calc(.5 * var(--bs-gutter-x));
    }

    .device-screen > #detailColumn {
        order: 1;
    }

    .device-screen > #deviceColumn > #requestCardsCard,
    .device-screen > #deviceColumn > #ncsEventSection {
        order: 2;
    }

    /* A banda do topo diz o que diz o cartão da identidade, sempre à vista. */
    .device-screen > #deviceColumn > .card:has(#selectedDevicePanel:not(.d-none)) {
        display: none;
    }

    /* Os três separadores: a telemetria são os cartões do aparelho, e as outras duas são o
       cartão da atividade inteiro -- com a busca e os filtros que só ali fazem sentido. */
    [data-device-tab="telemetry"] .device-screen > #detailColumn {
        display: none;
    }

    [data-device-tab="activity"] .device-screen > #deviceColumn > #requestCardsCard,
    [data-device-tab="activity"] .device-screen > #deviceColumn > #ncsEventSection {
        display: none;
    }
}

/* ===== primitivas do sistema ===== */

/* A barra de navegação é o navy da marca, separado do `--brand`, que no escuro sobe para se
   ver como botão enquanto a barra fica em baixo. */
.dashboard-navbar {
    background-color: var(--brand-bar);
}

/* No telemóvel a barra leva a marca e três alvos em 390px, e os botões respiram com menos
   enchimento. O nome da conta esconde-se na marcação, com o `d-none d-lg-inline`. */
@media (max-width: 991.98px) {
    .dashboard-navbar .btn {
        --bs-btn-padding-x: .5rem;
        --bs-btn-padding-y: .3125rem;
    }
}

/* Sem dispositivo escolhido, o botão do cabeçalho e o do meio do cartão abrem o mesmo
   selector a cem pixéis um do outro. Fica o do meio, que é onde a frase leva o olho. */
.card:has(#deviceSelectionEmptyState:not(.d-none)) #openDeviceSelectorBtn {
    display: none;
}

/* A banda do aparelho, abaixo do `lg`: a mesma superfície da barra, e rola com a página --
   a identidade lê-se uma vez, e os separadores é que se usam sempre. */
.device-band {
    background-color: var(--brand-bar);
    color: var(--brand-on);
}

.device-band-btn {
    width: 38px;
    height: 38px;
    border-radius: .625rem;
}

/* A identidade é o selector: toca-se nela para trocar de aparelho, e a seta di-lo. Um
   `⋮` ao lado diria «mais opções», que é outra coisa. */
.device-band-identity {
    padding: .25rem .5rem .25rem .25rem;
    border: 0;
    border-radius: .625rem;
    background-color: transparent;
    color: inherit;
}

.device-band-identity:hover,
.device-band-identity:focus-visible {
    background-color: rgba(var(--brand-on-rgb), .1);
}

.device-band-caret {
    font-size: .6875rem;
    color: rgba(var(--brand-on-rgb), .62);
}

/* A imagem do modelo, a mesma do selector: diz de que aparelho se trata antes de se ler
   o IMEI. Sobre o navy precisa de fundo claro, senão os contornos escuros somem-se. */
.device-band-thumb {
    width: 34px;
    height: 34px;
    background-color: rgba(var(--brand-on-rgb), .1);
}

.device-band-thumb img {
    width: 26px;
    height: 26px;
}

.device-band-title {
    font-size: 1.03125rem;
    letter-spacing: -.01em;
}

.device-band-meta {
    font-size: var(--fs-label);
    color: rgba(var(--brand-on-rgb), .62);
}

/* A régua cola debaixo da barra de navegação, e por isso é a banda que sai ao rolar. O
   `z-index` fica abaixo do da barra e acima do conteúdo, que vem depois na página. */
.device-tabs {
    --bs-nav-link-padding-y: .75rem;
    --bs-nav-link-padding-x: 0;
    --bs-nav-link-color: rgba(var(--brand-on-rgb), .62);
    --bs-nav-link-hover-color: var(--brand-on);
    position: sticky;
    top: var(--navbar-height, 3.5rem);
    z-index: 1019;
    background-color: var(--brand-bar);
    text-align: center;
}

.device-tabs .nav-link {
    border-bottom: 2.5px solid transparent;
    border-radius: 0;
    font-size: var(--fs-sm);
    font-weight: 600;
}

.device-tabs .nav-link.active {
    border-bottom-color: var(--brand-on);
    color: var(--brand-on);
}

/* Com `overflow-y: auto` o eixo x passa a `auto` e a goteira negativa de um `.row` vira barra
   horizontal; o `clip` corta-a. */
.device-modal-content {
    overflow-x: clip;
}

/* A contagem é texto ao lado do nome, e não uma pastilha: aqui o nome já é curto. */
.device-tab-count {
    margin-left: .35rem;
    font-size: var(--fs-label);
    font-weight: 400;
    font-variant-numeric: tabular-nums;
}

.device-tab-count:empty {
    display: none;
}

/* Dentro da barra, os `btn-dark` pedem a cor à própria barra: o quase-preto do Bootstrap
   sobre o navy da marca lê-se como um segundo escuro. */
.dashboard-navbar .btn-dark,
.device-band .btn-dark {
    --bs-btn-color: var(--brand-on);
    --bs-btn-bg: rgba(var(--brand-on-rgb), .08);
    --bs-btn-border-color: rgba(var(--brand-on-rgb), .18);
    --bs-btn-hover-color: var(--brand-on);
    --bs-btn-hover-bg: rgba(var(--brand-on-rgb), .16);
    --bs-btn-hover-border-color: rgba(var(--brand-on-rgb), .28);
    --bs-btn-active-color: var(--brand-on);
    --bs-btn-active-bg: rgba(var(--brand-on-rgb), .22);
    --bs-btn-active-border-color: rgba(var(--brand-on-rgb), .32);
}

/* Uma elevação só: a página é cinzenta e o cartão branco. O contorno do cartão é mais claro que
   as linhas interiores, para não competir com as divisórias. */
.card {
    /* O `secondary-bg` é um degrau mais claro que o `border-color` das linhas, e vira com o tema. */
    --bs-card-border-color: var(--bs-secondary-bg);
}

/* No escuro o `secondary-bg` fica por baixo da superfície do cartão e dilui a aresta em vez
   de a marcar: a moldura passa a um degrau curto acima dele. */
[data-bs-theme="dark"] .card {
    --bs-card-border-color: #202b42;
}

/* A linha vertical é o que diz que um filho pertence ao cabeçalho acima. As margens
   negativas valem o `p-3` do `card-body`, para a linha atravessar o cartão de lado a lado. */
/* O `gap` fica aqui: `.75rem` não é um degrau do Bootstrap. */
.tree-row {
    margin: .75rem -1rem 0;
    padding: .75rem 1rem 0 2rem;
    border-top: 1px solid var(--bs-border-color-translucent);
    gap: .75rem;
}

.tree-row+.tree-row {
    margin-top: .5rem;
    padding-top: .5rem;
}

/* A curva que liga o filho ao cabeçalho acima dele. */
.tree-row::before {
    content: "";
    position: absolute;
    left: 1rem;
    top: 0;
    bottom: 50%;
    width: 1px;
    background: var(--bs-border-color);
}

.tree-row::after {
    content: "";
    position: absolute;
    left: 1rem;
    top: 50%;
    width: .5rem;
    height: 1px;
    background: var(--bs-border-color);
}

.tree-field-id {
    width: 8rem;
}

.tree-field-name {
    min-width: 12rem;
}

@media (max-width: 575.98px) {
    .tree-row {
        padding-left: 1.5rem;
    }

    .tree-row::before,
    .tree-row::after {
        left: .625rem;
    }

    /* O formulário das credenciais sai da indentação e toma o cartão de lado a lado; o fundo
       separa-o da licença a que pertence. */
    .radar-credentials-row {
        padding: 1rem;
        background: var(--bs-tertiary-bg);
    }

    .radar-credentials-row::before,
    .radar-credentials-row::after {
        display: none;
    }
}

/* A folha do catálogo abre a ficha do modelo. É um `<button>`: larga como a linha, e sem a
   moldura nem o fundo do navegador. */
.catalog-model {
    width: calc(100% + 2rem);
    border-width: 1px 0 0;
    background-color: transparent;
    color: inherit;
    text-align: start;
    cursor: pointer;
}

.catalog-model:hover,
.catalog-model:focus-visible {
    background: var(--bs-tertiary-bg);
}

.catalog-model-image {
    width: 28px;
    height: 28px;
}

/* A chapa acompanha a fotografia no escuro, como as chapas pequenas do `modals.css`; o raio
   torna-a uma chapa e não um rectângulo do tamanho da imagem. */
[data-bs-theme="dark"] .catalog-model-image:has(img) {
    background: #fff;
    border-radius: .375rem;
    filter: brightness(.84);
}

.catalog-caret {
    font-size: var(--fs-sm);
    transition: transform .15s ease;
}

[aria-expanded="false"] .catalog-caret {
    transform: rotate(-90deg);
}

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

/* Identificadores e valores em coluna alinham dígito a dígito. Um IMEI de 15 dígitos numa
   tabela de vinte linhas lê-se por comparação, e sem isto cada linha começa noutro sítio. */
.tabular-nums {
    font-variant-numeric: tabular-nums;
}

/* Sem isto um filho de flex não encolhe abaixo do conteúdo, e o `text-truncate` do irmão
   nunca corta -- transborda. O Bootstrap não traz utilitário de `min-width`. */
.min-w-0 {
    min-width: 0;
}

/* O mesmo para a altura: com `min-height: auto` uma lista alta empurra a coluna e o
   `overflow-auto` nunca chega a ter o que rolar. O Bootstrap também não traz utilitário. */
.min-h-0 {
    min-height: 0;
}

/* O Bootstrap 5 não traz utilitário de cursor: num `input[type=file]` invisível o ponteiro é
   a única pista de que a zona se clica. */
.cursor-pointer {
    cursor: pointer;
}

/* Medida mínima, a do "13" com `px-1`, para as treze caixas não se lerem desalinhadas; o
   `flex-fill` mantém a base de cada uma. */
.pagination .page-link {
    min-width: 1.5rem;
}

/* Num ecrã de toque o botão mede o mínimo que um dedo acerta. Acima de `md` volta à medida
   do rato, que é onde catorze números fazem sentido lado a lado. */
@media (max-width: 767.98px) {
    .pagination .page-link-touch {
        min-width: 2.75rem;
        min-height: 2.75rem;
    }
}

/* A divisória entre blocos de um cartão vai de bordo a bordo, como a linha de uma tabela, para
   não parecer outra caixa dentro do cartão. */
.card-section {
    margin-inline: calc(-1 * var(--bs-card-spacer-x, 1rem));
    padding-inline: var(--bs-card-spacer-x, 1rem);
}

/* O contador ao lado da etiqueta, e não no extremo oposto do cartão: "Leituras" e "12" são
   a mesma informação, e a meio metro de distância deixam de o ser. */
/* O fundo e a cor ficam aqui: o `count-chip-strong` troca-os. A forma também, como no
   `.count-number` abaixo. */
.count-chip {
    font-size: var(--fs-label);
    line-height: 1.45;
    font-weight: 600;
    padding-inline: .5rem;
    border-radius: var(--bs-border-radius-pill);
    font-variant-numeric: tabular-nums;
    background: var(--bs-tertiary-bg);
    color: var(--bs-secondary-color);
}

/* Sem contagem não há pastilha: vazia, é um rectângulo cinzento de 6px ao lado do título. */
.count-chip:empty {
    display: none;
}

/* Um número ao lado de uma etiqueta, sem pastilha: o mosaico de tipos, as opções de filtro e
   as pastilhas de secção. */
.count-number {
    font-size: var(--fs-label);
    color: var(--bs-secondary-color);
    font-variant-numeric: tabular-nums;
}

/* No botão de filtros a pastilha diz quantos estão ligados, e é a única cor do painel. */
.count-chip-strong {
    background: var(--bs-primary);
    color: var(--brand-on);
}

/* A pastilha de um filtro aplicado é neutra, porque o filtro não é um estado do sistema; a
   forma é a das pastilhas de estado, porque também é uma condição ligada. */
/* O `bg-body-secondary` na marcação e não o terciário: a um tom do branco do cartão a
   pastilha não se lê como pastilha, é texto em maiúsculas com um ponto à frente. */
.filter-chip {
    gap: .35rem;
    font-size: var(--fs-label);
    letter-spacing: .04em;
    padding: .15rem .3rem .15rem .55rem;
}

.filter-chip::before {
    content: "";
    width: 6px;
    height: 6px;
    flex: none;
    border-radius: 50%;
    background: currentcolor;
}

.filter-chip-remove {
    width: 15px;
    height: 15px;
    background: transparent;
    color: inherit;
    font-size: var(--fs-micro);
}

/* O fundo do realce é mais escuro que o da pastilha, que já é o `secondary-bg`. */
.filter-chip-remove:hover,
.filter-chip-remove:focus-visible {
    background: var(--bs-tertiary-color);
    color: var(--bs-body-bg);
}

/* O cabeçalho de secção dentro de um cartão: o título do ecrã não pode competir com um h5
   em cada bloco. */
.section-label,
.selected-device-facts dt,
.wizard-trail .wizard-badge-key {
    font-size: var(--fs-label);
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--bs-secondary-color);
}

/* Como etiqueta de um campo leva sempre a linha toda e o mesmo espaço por baixo. */
label.section-label {
    display: block;
    margin-bottom: .25rem;
}

/* ===== a linguagem de selecção =====
   Os quatro estados das caixas que se escolhem; a geometria fica no ficheiro de cada área. */
.device-type-tile,
.device-card,
.capability-section-chip,
.gateway-card,
.wizard-card {
    border: 1px solid var(--bs-border-color);
    background: var(--bs-body-bg);
    cursor: pointer;
    transition: border-color .12s ease, background-color .12s ease;
}

.device-type-tile:hover,
.device-card:hover,
.capability-section-chip:hover,
.gateway-card:hover,
.wizard-card:hover {
    border-color: var(--bs-primary-border-subtle);
    background: var(--bs-tertiary-bg);
}

/* O anel do browser tem 1px e não conhece a cor da marca. O do gateway pendura-se na caixa
   de marcar, que é o que lá dentro recebe o foco. */
.device-type-tile:focus-visible,
.device-card:focus-visible,
.capability-section-chip:focus-visible,
.wizard-card:focus-visible,
.gateway-card:has(.gateway-card-check:focus-visible) {
    outline: 2px solid var(--bs-primary);
    outline-offset: 2px;
}

.device-type-tile.selected,
.device-card.selected,
.capability-section-chip.selected,
.wizard-card.selected,
.gateway-card:has(.gateway-card-check:checked) {
    border-color: var(--bs-primary);
    background: var(--bs-primary-bg-subtle);
}

@media (prefers-reduced-motion: reduce) {
    .device-type-tile,
    .device-card,
    .capability-section-chip,
    .gateway-card,
    .wizard-card {
        transition: none;
    }
}
