/* Sidebar — icon rail with stacked icon + label. Layout dimensions live as
   CSS custom properties on .console-shell so the sidebar, context panel, and
   console-main margin all read from the same source. */

.console-shell {
  --sidebar-width: 112px;
  --context-panel-width: 200px;
  --footer-height: 32px;

  /* Estrutura do shell em CSS explícito (não depender só das utilities
     `flex flex-col` do layout): se a utility não aplicar — build do
     Tailwind defasado ou corrida de carregamento — o shell cairia para
     `row` e o rodapé (último filho) colapsaria numa faixa estreita no topo
     à direita. Fixar a coluna aqui mantém o footer full-width embaixo. */
  display: flex;
  flex-direction: column;
}

/* Portal shares the footer with the console. It only needs --footer-height (no
   sidebar/context-panel rail vars — the portal sidebar is its own component) and
   the explicit column so the footer stays full-width at the bottom even if the
   Tailwind `flex flex-col` utilities race on load (same rationale as above). */
.portal-shell {
  --footer-height: 32px;

  display: flex;
  flex-direction: column;
}

.sidebar {
  flex-shrink: 0;
  z-index: 100;
  width: var(--sidebar-width);
  min-width: var(--sidebar-width);
  height: 100%;
  background: #0f1120;
  color: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding-top: 1rem;
  padding-bottom: 1rem;
}

.sidebar-top {
  flex: 1 1 0%;
  min-height: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.sidebar-bottom {
  width: 100%;
  flex-shrink: 0;
}

.sidebar nav {
  display: flex;
  flex: 1 1 0%;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 100%;
  padding: 0 0.5rem;
  overflow-y: auto;
  min-height: 0;
}

.nav-icon-btn {
  width: 96px;
  padding: 8px 4px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  /* Raio comum dos controles (ver --radius-control no tema). */
  border-radius: var(--radius-control, 0.25rem);
  color: rgba(255, 255, 255, 0.6);
  font-size: 11px;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  position: relative;
  text-decoration: none;
}

.nav-icon-btn:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

.nav-icon-btn.active {
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
}

.nav-icon-btn.active::before {
  content: "";
  position: absolute;
  left: -10px;
  top: 8px;
  bottom: 8px;
  width: 3px;
  background: var(--color-primary, #4b6bfb);
  border-radius: 0 3px 3px 0;
}

/* Bolinha de "há notificação não vista" no botão do sino. O bloco contenedor
   é o próprio `.nav-icon-btn` (position: relative, 96px de largura, padding
   8px 4px), e o ícone tem 20px centrado — ou seja, a borda direita do ícone
   cai a 38px da direita do botão e o topo dele a 8px do topo. `right: 34px` +
   `top: 4px` põem a bolinha montada nesse canto (metade fora, metade sobre o
   ícone), que é como um badge é lido. Medido no browser (system test do sino):
   com `right: 22px` ela flutuava 8px à direita do ícone e parecia um ponto
   solto no rail, não um marcador daquele botão. */
.notifications-dot {
  position: absolute;
  top: 4px;
  right: 34px;
  width: 8px;
  height: 8px;
  border-radius: 9999px;
  background: var(--color-error, #ef4444);
  /* O anel imita o fundo do rail, que é fixo (`.sidebar`), não o tema. */
  box-shadow: 0 0 0 2px #0f1120;
}

.nav-group {
  position: relative;
  width: 100%;
  display: flex;
  justify-content: center;
}

/* Hidden flyout — used as a data source by the context panel.
   The Stimulus controller reads its items and renders them in #context-panel.
   The profile flyout (outside <nav>) keeps the original popup behavior below. */
.flyout {
  position: absolute;
  left: 100%;
  top: 0;
  margin-left: 4px;
  min-width: 220px;
  background: #161829;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  padding: 8px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
  opacity: 0;
  visibility: hidden;
  transform: translateX(-4px);
  transition: opacity 0.15s, transform 0.15s, visibility 0.15s;
  z-index: 200;
}

.flyout::before {
  content: "";
  position: absolute;
  left: -8px;
  top: 0;
  bottom: 0;
  width: 8px;
}

.nav-group:hover .flyout,
.nav-group:focus-within .flyout,
.flyout:hover {
  opacity: 1;
  visibility: visible;
  transform: translateX(0);
}

/* Section flyouts feed the context panel — never show as popups. */
nav .flyout {
  display: none !important;
}

.flyout-title {
  padding: 8px 12px 6px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  /* 0.55 ≈ 4.7:1 over #161829 — passes WCAG AA for normal text. */
  color: rgba(255, 255, 255, 0.55);
}

.flyout-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  /* Raio comum dos controles (ver --radius-control no tema). */
  border-radius: var(--radius-control, 0.25rem);
  font-size: 13px;
  color: rgba(255, 255, 255, 0.75);
  cursor: pointer;
  text-decoration: none;
}

.flyout-item:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

.flyout-item.disabled {
  /* 0.5 keeps visual "disabled" affordance while keeping WCAG AA contrast. */
  opacity: 0.5;
  cursor: not-allowed;
}

.flyout-item.disabled:hover {
  background: transparent;
  color: rgba(255, 255, 255, 0.75);
}

.flyout-badge {
  margin-left: auto;
}

/* Group dividers inside a flyout — paired subtitle + separator are how nav
   sections (e.g. accounts) split clickable items into named buckets. The
   styles below cover both the (hidden) source flyout and the rendered
   context-panel clones; keeping them visually identical means the JS clone
   path doesn't need a separate look. */
.flyout-subtitle,
.context-subtitle {
  padding: 8px 12px 4px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: rgba(255, 255, 255, 0.55);
}

.flyout-separator,
.context-separator {
  height: 1px;
  margin: 6px 8px;
  background: rgba(255, 255, 255, 0.08);
}

/* Context panel — the secondary nav that shows the section's items. */
.context-panel {
  position: fixed;
  left: var(--sidebar-width);
  top: 0;
  bottom: var(--footer-height);
  width: var(--context-panel-width);
  background: #161829;
  color: #fff;
  z-index: 99;
  border-right: 1px solid rgba(255, 255, 255, 0.06);
  transform: translateX(-100%);
  transition: transform 0.18s ease;
  display: flex;
  flex-direction: column;
  padding: 12px 0;
  box-shadow: 8px 0 24px rgba(0, 0, 0, 0.25);
}

.context-panel.open {
  transform: translateX(0);
}

html.sidebar-pinned .context-panel {
  transform: translateX(0);
  box-shadow: none;
}

html.sidebar-pinned .console-main {
  margin-left: var(--context-panel-width);
}

.context-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 16px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  margin-bottom: 8px;
}

.context-panel-title {
  font-size: 14px;
  font-weight: 600;
  color: #fff;
}

.context-panel-pin {
  cursor: pointer;
  padding: 4px;
  border-radius: 6px;
  color: rgba(255, 255, 255, 0.55);
  background: transparent;
  border: 0;
  display: flex;
  align-items: center;
  transition: background 0.15s, color 0.15s;
}

.context-panel-pin:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

/* Show only the icon that matches the current pin state. Toggling via CSS
   instead of mutating innerHTML keeps lucide-rails as the single source of
   truth for the icon SVG. */
html:not(.sidebar-pinned) .pin-icon-when-pinned,
html.sidebar-pinned .pin-icon-when-unpinned {
  display: none;
}

.context-panel-pin .pin-icon-when-unpinned,
.context-panel-pin .pin-icon-when-pinned {
  display: inline-flex;
  align-items: center;
}

/* Unpinned: pin button is the call-to-action — bright primary bg + white icon. */
html:not(.sidebar-pinned) .context-panel-pin {
  background: var(--color-primary, #4b6bfb);
  color: #fff;
}

html:not(.sidebar-pinned) .context-panel-pin:hover {
  /* Static fallback for browsers without color-mix() (Safari <16.4, Chrome <111). */
  background: #3f5bd4;
  background: color-mix(in oklab, var(--color-primary, #4b6bfb) 85%, black);
}

.context-items {
  flex: 1;
  overflow-y: auto;
  padding: 0 8px;
}

.context-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  /* Raio comum dos controles (ver --radius-control no tema). */
  border-radius: var(--radius-control, 0.25rem);
  font-size: 13px;
  color: rgba(255, 255, 255, 0.75);
  cursor: pointer;
  text-decoration: none;
  margin-bottom: 2px;
}

.context-item:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

.context-item.active {
  background: var(--color-primary, #4b6bfb);
  color: #fff;
}

.context-item .ctx-badge {
  margin-left: auto;
}

/* Profile flyout (anchors at bottom, opens upward). */
.profile-flyout {
  top: auto;
  bottom: 0;
  min-width: 260px;
}

/* Notifications bell flyout (sits right above the profile block) — same
   bottom-anchored, opens-upward behavior as the profile flyout. Slightly
   wider so notification titles get room before truncating. */
.notifications-flyout {
  top: auto;
  bottom: 0;
  min-width: 300px;
}

.profile-flyout-header {
  padding: 10px 12px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  margin-bottom: 4px;
}

.profile-flyout-name {
  font-size: 13px;
  font-weight: 500;
  color: #fff;
}

.profile-flyout-email {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.6);
}

/* Respect user's reduced-motion preference (WCAG 2.3.3 / vestibular disorder). */
@media (prefers-reduced-motion: reduce) {
  .nav-icon-btn,
  .flyout,
  .context-panel,
  .context-panel-pin,
  .console-main {
    transition: none;
  }
}

/* Mobile nav drawer (< lg): mesma identidade escura do icon rail (#0f1120) para
   consistência de cor entre desktop e mobile. O `menu` do daisyUI é claro por
   padrão (texto base-content escuro), então re-tematizamos texto/hover/ativo aqui
   — espelhando o rail (texto branco translúcido, hover branco, ativo primary).
   Escopado a #console-mobile-nav; CSS de componente (unlayered) vence as utilities
   layered do daisyUI. */
#console-mobile-nav {
  background: #0f1120;
  color: #fff;
}

#console-mobile-nav .menu :where(li > a),
#console-mobile-nav .menu :where(li > details > summary) {
  /* Mesmas métricas do .context-item (menu normal do desktop): 13px, gap 10px,
     padding 8px 12px, raio 8px — consistência de fonte/espaçamento mobile↔desktop. */
  color: rgba(255, 255, 255, 0.75);
  font-size: 13px;
  gap: 10px;
  padding: 8px 12px;
  /* Raio comum dos controles (ver --radius-control no tema). */
  border-radius: var(--radius-control, 0.25rem);
}

#console-mobile-nav .menu :where(li > a:hover),
#console-mobile-nav .menu :where(li > details > summary:hover) {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

#console-mobile-nav .menu :where(li > a.menu-active),
#console-mobile-nav .menu :where(li > a[aria-current="page"]) {
  background: var(--color-primary, #4b6bfb);
  color: #fff;
}

/* Below lg (<1024px, matching Tailwind's `lg:` min-width:1024px) the desktop
   icon rail + hover context-panel are replaced by the accordion drawer
   (Sidebar::MobileNav, shown via lg:hidden). Hide the desktop chrome here.
   !important + a same-file media query is required because `.sidebar { display:flex }`
   is unlayered component CSS that would otherwise beat Tailwind utilities.
   Neutralizing the pinned margin is load-bearing, not just defensive: the
   sidebar--component controller lives on the turbo-permanent aside, so it still
   runs connect() on mobile and reapplies `html.sidebar-pinned` from localStorage —
   without this, a pinned desktop session would push mobile content 200px right
   with no visible panel. */
@media (max-width: 1023.98px) {
  .sidebar,
  .context-panel {
    display: none !important;
  }

  html.sidebar-pinned .console-main {
    margin-left: 0;
  }
}
