/* Material Design 3 Components: Cards, Tables, Buttons, Chips, Forms, Dialogs, Inlines */

/* Prevent Cumulative Layout Shift (CLS) & FOUT during Material Symbols Icon Font loading */
.material-symbols-outlined,
.material-symbols,
.material-icons,
.md-icon {
  font-family: 'Material Symbols Outlined', sans-serif;
  font-weight: normal;
  font-style: normal;
  font-size: 24px;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  max-width: 24px;
  max-height: 24px;
  overflow: hidden;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-feature-settings: 'liga';
  vertical-align: middle;
  user-select: none;
  flex-shrink: 0;
}

/* Icon Size Standard Classes */
.md-icon-xs {
  font-size: 16px !important;
  width: 16px !important;
  height: 16px !important;
  max-width: 16px !important;
  max-height: 16px !important;
}

.md-icon-sm {
  font-size: 18px !important;
  width: 18px !important;
  height: 18px !important;
  max-width: 18px !important;
  max-height: 18px !important;
}

.md-icon-md {
  font-size: 24px !important;
  width: 24px !important;
  height: 24px !important;
  max-width: 24px !important;
  max-height: 24px !important;
}

.md-icon-lg {
  font-size: 32px !important;
  width: 32px !important;
  height: 32px !important;
  max-width: 32px !important;
  max-height: 32px !important;
}

.md-icon-xl {
  font-size: 48px !important;
  width: 48px !important;
  height: 48px !important;
  max-width: 48px !important;
  max-height: 48px !important;
}

/* Icon Button */
.m3-icon-button {
  background: transparent;
  border: none;
  color: inherit;
  width: 40px;
  height: 40px;
  border-radius: var(--md-shape-corner-full);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: var(--md-transition-standard);
}

.m3-icon-button:hover {
  background-color: var(--md-sys-color-surface-container-highest);
}

/* Arredondamento pequeno, de propósito — não o "full" pílula que o M3 usa por
   padrão. Um botão de texto curto ("Salvar", "Adicionar") em pílula soa bem
   no Material puro, mas numa tela cheia de outros elementos com cantos
   discretos (cartão, tabela, campo) o botão pílula destoa: parece de outro
   sistema de design. */
.m3-btn,
input[type="submit"].m3-btn,
button.m3-btn,
a.m3-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 24px;
  border-radius: var(--md-shape-corner-s);
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  border: none;
  text-decoration: none !important;
  transition: var(--md-transition-standard);
  white-space: nowrap;
}

.m3-btn-filled,
a.m3-btn-filled,
button.m3-btn-filled,
input[type="submit"].m3-btn-filled {
  background-color: var(--md-sys-color-primary) !important;
  color: var(--md-sys-color-on-primary) !important;
}

.m3-btn-filled *,
a.m3-btn-filled *,
button.m3-btn-filled * {
  color: var(--md-sys-color-on-primary) !important;
}

.m3-btn-filled:hover,
a.m3-btn-filled:hover,
button.m3-btn-filled:hover,
input[type="submit"].m3-btn-filled:hover {
  box-shadow: var(--md-elevation-1);
  opacity: 0.92;
  color: var(--md-sys-color-on-primary) !important;
}

/* Botão tonal: a variante do M3 entre o preenchido e o de contorno. Serve
   para a ação que fecha um passo sem ser a ação principal da página — aqui,
   "Pronto" no editor do item: o que salva de verdade é o botão do formulário. */
.m3-btn-tonal,
a.m3-btn-tonal,
button.m3-btn-tonal {
  background-color: var(--md-sys-color-secondary-container) !important;
  color: var(--md-sys-color-on-secondary-container) !important;
  border: 0 !important;
}

.m3-btn-tonal *,
a.m3-btn-tonal *,
button.m3-btn-tonal * {
  color: var(--md-sys-color-on-secondary-container) !important;
}

.m3-btn-tonal:hover,
a.m3-btn-tonal:hover,
button.m3-btn-tonal:hover {
  box-shadow: var(--md-elevation-1);
  filter: brightness(0.96);
  color: var(--md-sys-color-on-secondary-container) !important;
}

.m3-btn-outlined,
a.m3-btn-outlined,
button.m3-btn-outlined,
input[type="submit"].m3-btn-outlined {
  background-color: transparent !important;
  border: 1px solid var(--md-sys-color-outline) !important;
  color: var(--md-sys-color-primary) !important;
}

.m3-btn-outlined:hover,
a.m3-btn-outlined:hover,
button.m3-btn-outlined:hover,
input[type="submit"].m3-btn-outlined:hover {
  background-color: var(--md-sys-color-surface-container-high) !important;
}

/* M3 Expressive Cards - Signature Large Rounded Shape (16px - 28px) */
.m3-card {
  background-color: var(--md-sys-color-surface-container-low);
  border-radius: var(--md-shape-corner-l);
  padding: 20px;
  border: 1px solid var(--md-sys-color-outline-variant);
  box-shadow: var(--md-elevation-1);
  transition: var(--md-transition-standard);
  margin-bottom: 20px;
}

.m3-card:hover {
  box-shadow: var(--md-elevation-2);
}

.m3-card-title {
  font-size: 1.1rem;
  font-weight: 600;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Data Tables & Overflow Fixes - Rounded Container Shape */
.m3-table-container {
  background-color: var(--md-sys-color-surface-container-lowest);
  border-radius: var(--md-shape-corner-l);
  border: 1px solid var(--md-sys-color-outline-variant);
  box-shadow: var(--md-elevation-1);
  margin-top: 16px;
  margin-bottom: 32px;
  overflow-x: auto;
  overflow-y: visible; /* Prevents dropdown menu clipping */
}

.m3-table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}

/* Header cells ONLY in thead get header background (Prevents tbody th vertical gray column) */
.m3-table thead th,
#result_list thead th {
  background-color: var(--md-sys-color-surface-container-high) !important;
  color: var(--md-sys-color-on-surface) !important;
  font-weight: 600;
  font-size: 0.85rem;
  padding: 14px 16px;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
  vertical-align: middle;
}

.m3-table tbody td,
.m3-table tbody th,
#result_list tbody td,
#result_list tbody th {
  padding: 14px 16px;
  font-size: 0.9rem;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
  color: var(--md-sys-color-on-surface);
  font-weight: normal;
  vertical-align: middle;
}

/* Table Row Links - Enforces M3 Primary Link Styling for tbody th and tbody td */
#result_list tbody th a:not(.m3-btn):not(.m3-chip),
#result_list tbody td a:not(.m3-btn):not(.m3-chip),
.m3-table tbody th a:not(.m3-btn):not(.m3-chip),
.m3-table tbody td a:not(.m3-btn):not(.m3-chip),
.field-display a:not(.m3-btn):not(.m3-chip),
th.field-display a:not(.m3-btn):not(.m3-chip) {
  color: var(--md-sys-color-primary) !important;
  text-decoration: none !important;
  font-weight: 500 !important;
}

#result_list tbody th a:not(.m3-btn):not(.m3-chip):hover,
#result_list tbody td a:not(.m3-btn):not(.m3-chip):hover,
.m3-table tbody th a:not(.m3-btn):not(.m3-chip):hover,
.m3-table tbody td a:not(.m3-btn):not(.m3-chip):hover,
.field-display a:not(.m3-btn):not(.m3-chip):hover,
th.field-display a:not(.m3-btn):not(.m3-chip):hover {
  color: var(--md-sys-color-primary) !important;
  text-decoration: underline !important;
  opacity: 0.88;
}

/* Table Rows & Alternating Stripe Fixes (Overrides legacy Django .row1/.row2 gray backgrounds) */
.m3-table tbody tr,
#result_list tbody tr,
tr.row1, tr.row2 {
  background-color: var(--md-sys-color-surface-container-lowest) !important;
}

.m3-table tbody tr:nth-child(even),
#result_list tbody tr:nth-child(even) {
  background-color: var(--md-sys-color-surface-container-low) !important;
}

.m3-table tbody tr td,
.m3-table tbody tr th,
#result_list tbody tr td,
#result_list tbody tr th,
tr.row1 td, tr.row1 th,
tr.row2 td, tr.row2 th {
  background-color: transparent !important;
  color: var(--md-sys-color-on-surface);
}

.m3-table tbody tr:hover,
.m3-table tbody tr:hover td,
.m3-table tbody tr:hover th,
#result_list tbody tr:hover,
#result_list tbody tr:hover td,
#result_list tbody tr:hover th {
  background-color: var(--md-sys-color-surface-container-high) !important;
}

.m3-table tr:last-child td,
.m3-table tr:last-child th {
  border-bottom: none;
}

/* M3 Chips - Rounded Pill Shape */
.m3-chip-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.m3-chip,
a.m3-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border-radius: var(--md-shape-corner-full);
  background-color: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface-variant) !important;
  font-size: 0.82rem;
  font-weight: 500;
  border: 1px solid var(--md-sys-color-outline-variant);
  text-decoration: none !important;
  transition: var(--md-transition-standard);
  white-space: nowrap;
  flex-shrink: 0;
}

.m3-chip.active,
a.m3-chip.active {
  background-color: var(--md-sys-color-secondary-container) !important;
  color: var(--md-sys-color-on-secondary-container) !important;
  border-color: transparent;
}

.m3-chip.active *,
a.m3-chip.active * {
  color: var(--md-sys-color-on-secondary-container) !important;
}

/* Legacy .badge and .label overrides for M3 Chips */
.badge, .label, .badge.label {
  display: inline-flex !important;
  align-items: center !important;
  gap: 4px !important;
  padding: 4px 10px !important;
  border-radius: var(--md-shape-corner-full) !important;
  background-color: var(--md-sys-color-secondary-container) !important;
  color: var(--md-sys-color-on-secondary-container) !important;
  font-size: 0.78rem !important;
  font-weight: 500 !important;
  float: none !important;
  border: none !important;
  box-shadow: none !important;
  margin: 0 4px !important;
  white-space: nowrap !important;
}

/* Search Box - Rounded Shape */
.m3-search-box {
  display: flex;
  align-items: center;
  gap: 8px;
  background-color: var(--md-sys-color-surface-container-high);
  border-radius: var(--md-shape-corner-full);
  padding: 8px 16px;
  border: 1px solid var(--md-sys-color-outline-variant);
  width: 100%;
  max-width: 380px;
}

.m3-search-box input {
  border: none;
  background: transparent;
  outline: none;
  color: var(--md-sys-color-on-surface);
  width: 100%;
  font-size: 0.9rem;
}

/* Form Controls & Widgets (Django Change Form Inputs & Widgets) */
.m3-field-group label,
.form-row label,
fieldset label {
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--md-sys-color-on-surface-variant);
  margin-bottom: 6px;
  display: block;
}

/* M3 Outlined Text Fields, Selects, Textareas & Widgets */
.m3-field-group input[type="text"]:not(.jscolor):not(.colorfield_field),
.m3-field-group input[type="password"],
.m3-field-group input[type="email"],
.m3-field-group input[type="number"],
.m3-field-group input[type="url"],
.m3-field-group input[type="date"],
.m3-field-group input[type="datetime-local"],
.m3-field-group input[type="time"],
.m3-field-group select:not([multiple]),
.m3-field-group textarea,
.form-row input[type="text"]:not(.jscolor):not(.colorfield_field),
.form-row input[type="password"],
.form-row input[type="email"],
.form-row input[type="number"],
.form-row input[type="url"],
.form-row input[type="date"],
.form-row input[type="datetime-local"],
.form-row input[type="time"],
.form-row select:not([multiple]),
.form-row textarea,
.vTextField:not(.jscolor):not(.colorfield_field),
.vIntegerField,
.vURLField,
.vDateField,
.vTimeField,
.vLargeTextField,
.vSelectField,
.m3-input,
.m3-select,
fieldset input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="file"]):not([type="image"]):not(.jscolor):not(.colorfield_field),
fieldset select:not([multiple]),
fieldset textarea {
  width: 100%;
  max-width: 100%;
  padding: 12px 16px;
  border-radius: var(--md-shape-corner-m);
  border: 1px solid var(--md-sys-color-outline);
  background-color: var(--md-sys-color-surface-container-lowest) !important;
  color: var(--md-sys-color-on-surface) !important;
  font-family: var(--md-font-family);
  font-size: 0.92rem;
  outline: none;
  transition: var(--md-transition-standard);
  box-sizing: border-box;
  box-shadow: none;
}

/* Colorfield Widget (jscolor) - Preserves dynamic color preview swatch */
.colorfield_field,
.jscolor,
input.colorfield_field,
input.jscolor {
  border-radius: var(--md-shape-corner-m) !important;
  border: 1px solid var(--md-sys-color-outline) !important;
  padding: 12px 16px !important;
  font-family: var(--md-font-family);
  font-size: 0.92rem;
  font-weight: 600;
  outline: none;
  transition: var(--md-transition-standard);
  box-sizing: border-box;
  box-shadow: var(--md-elevation-1);
}

.colorfield_field:focus,
.jscolor:focus,
input.colorfield_field:focus,
input.jscolor:focus {
  border-color: var(--md-sys-color-primary) !important;
  box-shadow: 0 0 0 3px var(--md-sys-color-secondary-container) !important;
}

/* Focus State - M3 Clean Non-shifting Focus */
.m3-field-group input:not(.jscolor):not(.colorfield_field):focus,
.m3-field-group select:focus,
.m3-field-group textarea:focus,
.form-row input:not(.jscolor):not(.colorfield_field):focus,
.form-row select:focus,
.form-row textarea:focus,
.vTextField:not(.jscolor):not(.colorfield_field):focus,
.vIntegerField:focus,
.vSelectField:focus,
.vLargeTextField:focus,
.m3-input:focus,
.m3-select:focus,
fieldset input:not(.jscolor):not(.colorfield_field):focus,
fieldset select:focus,
fieldset textarea:focus {
  /* No M3 o campo com contorno responde ao foco com um traço de 2px em
     `primary` — não com um halo em volta, que é idioma de outra biblioteca.
   *
   * Mas engrossar a BORDA de verdade obriga a compensar no `padding`, e um
   * `padding` com `!important` aqui atropela o `padding` que cada campo define
   * para si: o do login reserva 44px à esquerda para o ícone, o de data reserva
   * 42px à direita para o botão do calendário. Ao focar, o texto ia parar
   * debaixo do ícone.
   *
   * `box-shadow: inset` desenha o segundo traço POR DENTRO, sem ocupar espaço:
   * a borda parece de 2px, nada no layout se move, e o `padding` de cada campo
   * fica intacto. */
  border-color: var(--md-sys-color-primary) !important;
  box-shadow: inset 0 0 0 1px var(--md-sys-color-primary) !important;
  background-color: var(--md-sys-color-surface-container-lowest) !important;
}

/* ==========================================
   M3 FILE UPLOAD FIELD & CONTAINER
   ========================================== */
.m3-file-upload-zone,
.file-upload,
p.file-upload,
.vFileInputField {
  display: flex !important;
  align-items: center !important;
  gap: 16px !important;
  padding: 16px 20px !important;
  border: 2px dashed var(--md-sys-color-outline) !important;
  border-radius: var(--md-shape-corner-l) !important;
  background-color: var(--md-sys-color-surface-container-low) !important;
  transition: var(--md-transition-standard) !important;
  margin-top: 6px !important;
  flex-wrap: wrap !important;
}

.m3-file-upload-zone:hover,
p.file-upload:hover,
.vFileInputField:hover {
  border-color: var(--md-sys-color-primary) !important;
  background-color: var(--md-sys-color-surface-container-high) !important;
}

.file-upload a,
p.file-upload a {
  display: inline-flex !important;
  align-items: center !important;
  gap: 6px !important;
  padding: 6px 14px !important;
  border-radius: var(--md-shape-corner-full) !important;
  background-color: var(--md-sys-color-secondary-container) !important;
  color: var(--md-sys-color-on-secondary-container) !important;
  font-size: 0.85rem !important;
  font-weight: 500 !important;
  text-decoration: none !important;
}

input[type="file"] {
  padding: 8px 14px;
  background: var(--md-sys-color-surface-container-high) !important;
  border-radius: var(--md-shape-corner-m);
  font-size: 0.88rem;
  cursor: pointer;
}

/* Checkbox & Radio Buttons */
input[type="checkbox"]:not(.m3-switch input) {
  width: 20px;
  height: 20px;
  accent-color: var(--md-sys-color-primary);
  border-radius: 4px;
  cursor: pointer;
  vertical-align: middle;
}

input[type="radio"] {
  width: 20px;
  height: 20px;
  accent-color: var(--md-sys-color-primary);
  cursor: pointer;
  vertical-align: middle;
}

/* ==========================================
   M3 MANY-TO-MANY SELECTOR (FILTER_HORIZONTAL & FILTER_VERTICAL)
   ========================================== */
.selector {
  display: flex !important;
  align-items: center;
  gap: 16px;
  width: 100% !important;
  margin-top: 8px;
  flex-wrap: wrap;
}

.selector-available,
.selector-chosen {
  flex: 1;
  min-width: 260px;
  background-color: var(--md-sys-color-surface-container-low) !important;
  border-radius: var(--md-shape-corner-l) !important;
  border: 1px solid var(--md-sys-color-outline-variant) !important;
  padding: 16px !important;
  box-shadow: var(--md-elevation-1);
}

.selector-available h2,
.selector-chosen h2 {
  font-size: 0.85rem !important;
  font-weight: 700 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.6px !important;
  color: var(--md-sys-color-primary) !important;
  background: transparent !important;
  padding: 0 0 10px 0 !important;
  margin: 0 !important;
  border-bottom: 1px solid var(--md-sys-color-outline-variant) !important;
}

.selector-filter {
  padding: 10px 0 !important;
  background: transparent !important;
  border: none !important;
}

.selector-filter input {
  width: 100% !important;
  padding: 8px 14px !important;
  border-radius: var(--md-shape-corner-full) !important;
  border: 1px solid var(--md-sys-color-outline) !important;
  background-color: var(--md-sys-color-surface-container-lowest) !important;
  color: var(--md-sys-color-on-surface) !important;
  font-size: 0.85rem !important;
  outline: none !important;
}

.selector select[multiple] {
  width: 100% !important;
  height: 220px !important;
  border-radius: var(--md-shape-corner-m) !important;
  border: 1px solid var(--md-sys-color-outline-variant) !important;
  background-color: var(--md-sys-color-surface-container-lowest) !important;
  color: var(--md-sys-color-on-surface) !important;
  padding: 8px !important;
  font-size: 0.88rem !important;
  outline: none !important;
}

.selector select[multiple] option {
  padding: 8px 12px !important;
  border-radius: var(--md-shape-corner-s) !important;
  margin-bottom: 2px !important;
  font-size: 0.88rem !important;
  cursor: pointer;
}

.selector select[multiple] option:checked {
  background-color: var(--md-sys-color-secondary-container) !important;
  color: var(--md-sys-color-on-secondary-container) !important;
  font-weight: 600;
}

/* M3 Chooser Action Buttons between Available and Chosen */
.selector-chooser {
  display: flex !important;
  flex-direction: column !important;
  gap: 8px !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 0 !important;
  margin: 0 !important;
  list-style: none !important;
}

.selector-chooser li {
  list-style: none !important;
  margin: 0 !important;
  padding: 0 !important;
}

.selector-chooser li a,
.selector-add,
.selector-remove {
  width: 40px !important;
  height: 40px !important;
  border-radius: var(--md-shape-corner-full) !important;
  background-color: var(--md-sys-color-surface-container-high) !important;
  color: var(--md-sys-color-primary) !important;
  border: 1px solid var(--md-sys-color-outline-variant) !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  text-decoration: none !important;
  font-weight: bold !important;
  cursor: pointer !important;
  transition: var(--md-transition-standard) !important;
  box-shadow: var(--md-elevation-1);
}

.selector-chooser li a:hover,
.selector-add:hover,
.selector-remove:hover {
  background-color: var(--md-sys-color-primary) !important;
  color: var(--md-sys-color-on-primary) !important;
  box-shadow: var(--md-elevation-2);
}

/* ==========================================
   M3 RELATED LOOKUP & INLINE ACTIONS (ADD/EDIT/DELETE)
   ========================================== */
.related-widget-wrapper {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: 100%;
}

.related-widget-wrapper select {
  flex: 1;
}

/* Campo M2M (`<select multiple>`, ex.: EmentaConteudo em AvaliacaoEmenta) é
   uma caixa alta -- `align-items: center` do wrapper acima centraliza o
   botao "+" no meio dela, flutuando longe do topo da lista e parecendo
   desalinhado. Alinhar pelo topo e descer o botao pra bater com a borda do
   select resolve sem quebrar o caso comum do <select> de FK, que continua
   centralizado (a regra so entra quando ha `multiple`). */
.related-widget-wrapper:has(select[multiple]) {
  align-items: flex-start;
}

.related-widget-wrapper:has(select[multiple]) .related-lookup,
.related-widget-wrapper:has(select[multiple]) .add-related,
.related-widget-wrapper:has(select[multiple]) .change-related,
.related-widget-wrapper:has(select[multiple]) .delete-related {
  margin-top: 2px;
}

.related-lookup,
.add-related,
.change-related,
.delete-related {
  width: 36px !important;
  height: 36px !important;
  border-radius: var(--md-shape-corner-full) !important;
  background-color: var(--md-sys-color-surface-container-high) !important;
  color: var(--md-sys-color-primary) !important;
  border: 1px solid var(--md-sys-color-outline-variant) !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  text-decoration: none !important;
  transition: var(--md-transition-standard) !important;
  flex-shrink: 0;
  font-size: 1.1rem;
}

.related-lookup:hover,
.add-related:hover,
.change-related:hover {
  background-color: var(--md-sys-color-primary) !important;
  color: var(--md-sys-color-on-primary) !important;
}

.delete-related {
  color: var(--md-sys-color-error) !important;
}

.delete-related:hover {
  background-color: var(--md-sys-color-error) !important;
  color: var(--md-sys-color-on-error) !important;
}

.related-lookup img,
.add-related img,
.change-related img,
.delete-related img {
  display: none !important;
}

.add-related:after {
  content: "+";
  font-size: 1.2rem;
  font-weight: 600;
}

.change-related:after {
  content: "✎";
  font-size: 1.1rem;
}

.delete-related:after {
  content: "✕";
  font-size: 1.1rem;
  font-weight: 600;
}

.related-lookup:after {
  content: "🔍";
  font-size: 0.95rem;
}

/* Bulk Action Select Styling */
.m3-action-select-wrapper select,
.actions-container select,
select[name="action"] {
  width: 100%;
  padding: 10px 16px;
  border-radius: var(--md-shape-corner-full);
  border: 1px solid var(--md-sys-color-outline);
  background-color: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
  font-size: 0.88rem;
  font-weight: 500;
  outline: none;
  cursor: pointer;
  transition: var(--md-transition-standard);
}

.m3-action-select-wrapper select:focus,
.actions-container select:focus,
select[name="action"]:focus {
  border-color: var(--md-sys-color-primary);
  box-shadow: 0 0 0 2px var(--md-sys-color-primary);
}

.m3-field-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 16px;
}

/* M3 Switch Input */
.m3-switch {
  position: relative;
  display: inline-block;
  width: 52px;
  height: 32px;
}

.m3-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.m3-switch-slider {
  position: absolute;
  cursor: pointer;
  top: 0; left: 0; right: 0; bottom: 0;
  background-color: var(--md-sys-color-surface-container-highest);
  border: 2px solid var(--md-sys-color-outline);
  border-radius: var(--md-shape-corner-full);
  transition: var(--md-transition-standard);
}

.m3-switch-slider:before {
  position: absolute;
  content: "";
  height: 16px;
  width: 16px;
  left: 6px;
  bottom: 6px;
  background-color: var(--md-sys-color-outline);
  border-radius: 50%;
  transition: var(--md-transition-standard);
}

.m3-switch input:checked + .m3-switch-slider {
  background-color: var(--md-sys-color-primary);
  border-color: var(--md-sys-color-primary);
}

.m3-switch input:checked + .m3-switch-slider:before {
  transform: translateX(20px);
  background-color: var(--md-sys-color-on-primary);
  height: 20px;
  width: 20px;
  left: 4px;
  bottom: 4px;
}

/* Submit Line M3 Card */
.m3-submit-line {
  background-color: var(--md-sys-color-surface-container-low) !important;
  border: 1px solid var(--md-sys-color-outline-variant) !important;
  border-radius: var(--md-shape-corner-l) !important;
}

/* Fieldset Cards - M3 Rounded Shape */
fieldset.m3-fieldset {
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-shape-corner-l);
  padding: 20px;
  background-color: var(--md-sys-color-surface-container-low);
  margin-bottom: 24px;
}

fieldset.m3-fieldset legend {
  padding: 0 12px;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--md-sys-color-primary);
}

/* ============================================================================
   Campos de relacionamento — chips (M2M) e menu com busca (FK)
   ----------------------------------------------------------------------------
   Desenhados por `m3-relations.js` por cima do `<select>` do Django, que
   continua no DOM e continua postando. Só tokens aqui, então o tema escuro
   acompanha sem uma linha a mais.
   ========================================================================== */

/* O select nativo sai da tela mas NÃO do formulário: ele é quem posta. */
.m3-rel-nativo {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0 !important;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  border: 0 !important;
}

.m3-rel {
  flex: 1;
  min-width: 0;
}

.m3-rel-field {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  min-height: 46px;
  padding: 7px 8px 7px 14px;
  border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-shape-corner-m);
  background-color: var(--md-sys-color-surface-container-lowest);
  cursor: text;
  transition: var(--md-transition-standard);
}

.m3-rel-field:hover {
  border-color: var(--md-sys-color-on-surface);
}

/* Foco e erro NÃO mexem na espessura da borda.
 *
 * Engrossar de 1px para 2px e compensar no padding parece equivalente, mas o
 * arredondamento do navegador em telas não inteiras deixa meio pixel sobrando —
 * e o campo estremece a cada foco. `box-shadow` desenha por cima, sem ocupar
 * espaço: a borda parece de 2px e nada no layout se move.
 */
.m3-rel-field:focus,
.m3-rel-field:focus-visible,
.m3-rel-field.is-open {
  border-color: var(--md-sys-color-primary);
  box-shadow: inset 0 0 0 1px var(--md-sys-color-primary);
  outline: none;
}

.m3-rel-field.has-error {
  border-color: var(--md-sys-color-error);
  box-shadow: inset 0 0 0 1px var(--md-sys-color-error);
}

.m3-rel-chips {
  display: contents;
}

/* Input chip do M3: o rótulo e o × moram no mesmo contêiner arredondado. */
.m3-rel-chip {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  max-width: 100%;
  padding: 4px 4px 4px 12px;
  border-radius: var(--md-shape-corner-s);
  background-color: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  font-size: 0.82rem;
  line-height: 1.3;
}

.m3-rel-chip-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.m3-rel-chip-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 0;
  border-radius: var(--md-shape-corner-full);
  background: transparent;
  color: inherit;
  cursor: pointer;
  opacity: 0.7;
  transition: var(--md-transition-standard);
}

.m3-rel-chip-remove:hover {
  opacity: 1;
  background-color: rgba(0, 0, 0, 0.1);
}

.m3-rel-chip-remove .material-symbols-outlined {
  font-size: 15px;
}

/* Cresce para ocupar a linha, mas cede espaço aos chips quando eles chegam.
 *
 * A especificidade alta é obrigatória, não capricho: o tema veste TODO
 * `input[type="text"]` dentro de `.form-row` com borda, fundo, raio de 12px e
 * `padding: 12px 16px`, e aquele seletor
 * (`.form-row input[type="text"]:not(.jscolor):not(.colorfield_field)`) tem
 * especificidade 0-4-1 — um `.m3-rel-search` simples (0-1-0) perde mesmo com
 * `!important`. O resultado era uma segunda caixa desenhada dentro do campo,
 * empurrando o layout ao focar. Este seletor chega a 0-5-1. */
.m3-rel[data-multiple] .m3-rel-field > input.m3-rel-search[type="text"] {
  flex: 1 1 90px;
  width: auto !important;
  min-width: 90px;
  min-height: 0 !important;
  height: auto !important;
  margin: 0 !important;
  padding: 3px 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  background-color: transparent !important;
  color: var(--md-sys-color-on-surface) !important;
  font-family: var(--md-font-family);
  font-size: 0.92rem;
  outline: none !important;
  box-shadow: none !important;
}

/* Sem o que filtrar, o campo continua igual aos outros mas não convida a
   digitar: o cursor é de clique, como num select. */
.m3-rel[data-multiple] .m3-rel-field > input.m3-rel-search.is-readonly {
  cursor: pointer;
}

.m3-rel-search::placeholder {
  color: var(--md-sys-color-outline);
}

.m3-rel-arrow {
  color: var(--md-sys-color-outline);
  font-size: 22px;
  pointer-events: none;
  transition: var(--md-transition-standard);
}

.m3-rel-field.is-open .m3-rel-arrow {
  transform: rotate(180deg);
  color: var(--md-sys-color-primary);
}

/* `fixed` porque o menu vive no <body>: dentro do formulário o primeiro
   ancestral com overflow o recortaria. O JS posiciona e reposiciona. */
.m3-rel-list {
  overflow-y: auto;
  flex: 1;
  min-height: 0;
  padding: 6px;
}

.m3-rel-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  border-radius: var(--md-shape-corner-s);
  color: var(--md-sys-color-on-surface);
  font-size: 0.9rem;
  cursor: pointer;
}

/* `is-active` é a navegação por teclado; hover é o mouse. Mesma aparência de
   propósito: são a mesma ideia por meios diferentes. */
.m3-rel-option:hover,
.m3-rel-option.is-active {
  background-color: var(--md-sys-color-surface-container-high);
}

.m3-rel-option.is-selected {
  color: var(--md-sys-color-on-secondary-container);
  font-weight: 600;
}

.m3-rel-option-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.m3-rel-check {
  flex-shrink: 0;
  font-size: 19px;
  color: var(--md-sys-color-outline);
}

.m3-rel-option.is-selected .m3-rel-check {
  color: var(--md-sys-color-primary);
}

.m3-rel-empty {
  padding: 10px 12px;
  color: var(--md-sys-color-outline);
  font-size: 0.85rem;
  font-style: italic;
}

/* O anel de foco pertence ao CAMPO, não ao input de busca que mora dentro
   dele. O tema veste todo `input` de `.form-row` com borda primária e halo de
   3px no `:focus`, e aquele seletor
   (`.form-row input:not(.jscolor):not(.colorfield_field):focus`) é mais
   específico que um `.m3-rel-search` simples — o resultado eram dois anéis
   aninhados. A especificidade exagerada abaixo é para desfazer, não decorar. */
.m3-rel[data-multiple] .m3-rel-field > input.m3-rel-search[type="text"]:focus,
.m3-rel[data-multiple] .m3-rel-field > input.m3-rel-search[type="text"]:focus-visible {
  border: 0 !important;
  outline: none !important;
  box-shadow: none !important;
  background: transparent !important;
}

/* ============================================================================
   Campo de arquivo — área de soltar e cartão do anexo
   ----------------------------------------------------------------------------
   O `<input type="file">` continua sendo quem posta; isto é a casca.
   ========================================================================== */

.m3-file {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
}

/* O input nativo sai da tela mas NÃO do formulário. */
.m3-file .m3-file-input,
.m3-file .m3-file-clear {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0 !important;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  border: 0 !important;
}

.m3-file-drop {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 22px 18px;
  border: 1.5px dashed var(--md-sys-color-outline);
  border-radius: var(--md-shape-corner-m);
  background-color: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
  cursor: pointer;
  text-align: center;
  transition: var(--md-transition-standard);
}

.m3-file-drop:hover,
.m3-file-drop:focus-visible {
  border-color: var(--md-sys-color-primary);
  background-color: var(--md-sys-color-surface-container);
  outline: none;
}

/* O destaque de arrastar fica na CAIXA, não na área: durante o arrasto o
   ponteiro passa sobre os filhos e o `:hover` da área pisca. */
.m3-file.is-dragging .m3-file-drop {
  border-color: var(--md-sys-color-primary);
  border-style: solid;
  background-color: var(--md-sys-color-primary-container);
}

.m3-file-drop-icon {
  font-size: 28px;
  color: var(--md-sys-color-primary);
}

.m3-file-drop-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  font-size: 0.88rem;
  line-height: 1.35;
  color: var(--md-sys-color-outline);
}

.m3-file-drop-text strong {
  color: var(--md-sys-color-on-surface);
  font-weight: 600;
}

.m3-file-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 12px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-shape-corner-m);
  background-color: var(--md-sys-color-surface-container-lowest);
}

/* Ainda não subiu: a borda pontilhada diz isso sem precisar de um aviso. */
.m3-file-card.is-new {
  border-style: dashed;
  border-color: var(--md-sys-color-primary);
}

.m3-file-thumb {
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  object-fit: cover;
  border-radius: var(--md-shape-corner-s);
  background-color: var(--md-sys-color-surface-container-high);
}

.m3-file-icon {
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--md-shape-corner-s);
  background-color: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-primary);
  font-size: 26px;
}

/* `min-width: 0` para o nome longo poder encolher: sem isto o item flex se
   recusa a passar do conteúdo e as ações somem para fora do cartão. */
.m3-file-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.m3-file-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--md-sys-color-on-surface);
  font-size: 0.92rem;
  font-weight: 500;
}

.m3-file-meta {
  color: var(--md-sys-color-outline);
  font-size: 0.78rem;
}

.m3-file-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
}

.m3-file .m3-file-actions button.m3-file-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0 !important;
  border: 0 !important;
  border-radius: var(--md-shape-corner-full) !important;
  background: transparent !important;
  color: var(--md-sys-color-on-surface) !important;
  cursor: pointer;
  transition: var(--md-transition-standard);
}

.m3-file .m3-file-actions button.m3-file-action:hover {
  background-color: var(--md-sys-color-surface-container-high) !important;
}

.m3-file .m3-file-actions button.m3-file-action.is-danger:hover {
  background-color: var(--md-sys-color-error-container) !important;
  color: var(--md-sys-color-on-error-container) !important;
}

.m3-file .m3-file-actions button.m3-file-action.is-done {
  color: var(--md-sys-color-success) !important;
}

.m3-file-action .material-symbols-outlined {
  font-size: 19px;
}

/* ============================================================================
   Inline em tabela — uma linha por item
   ----------------------------------------------------------------------------
   Poucos itens é o caso comum, mas muitos precisa continuar utilizável: daí o
   cabeçalho fixo, a rolagem contida e a linha compacta.
   ========================================================================== */

.m3-inline-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 4px;
}

.m3-inline-title-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.m3-inline-count {
  color: var(--md-sys-color-outline);
  font-size: 0.85rem;
  font-weight: 400;
}

/* A rolagem horizontal fica AQUI, não na página: uma tabela larga não pode
   fazer o formulário inteiro deslizar de lado. */
.m3-inline-scroll {
  overflow-x: auto;
  overflow-y: visible;
  margin-top: 8px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-shape-corner-m);
}

.m3-inline-grid {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}

/* Cabeçalho fixo: com muitos itens, saber de que coluna é o campo que se está
   preenchendo é o que decide se a tabela funciona ou não. */
.m3-inline-grid thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: 10px 12px;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
  background-color: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-align: left;
  text-transform: uppercase;
  white-space: nowrap;
}

.m3-inline-grid thead th.is-required::after {
  content: ' *';
  color: var(--md-sys-color-error);
}

.m3-inline-grid tbody td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
  vertical-align: middle;
}

.m3-inline-grid tbody tr:last-child td {
  border-bottom: 0;
}

.m3-inline-grid tbody tr:hover td {
  background-color: var(--md-sys-color-surface-container-low);
}

/* O formulário-modelo do Django. Fica no DOM porque é dele que a linha nova é
   clonada; some da tela porque não é um item. */
.m3-inline-grid tbody tr.empty-form,
.m3-inline-grid tbody tr.is-removed {
  display: none;
}

/* Marcado para excluir: riscado, não sumido. Nada foi apagado ainda, e
   desmarcar desfaz — esconder a linha mentiria sobre o estado. */
.m3-inline-grid tbody tr.is-deleted td {
  opacity: 0.45;
  text-decoration: line-through;
  background-color: var(--md-sys-color-error-container);
}

.m3-inline-num {
  width: 34px;
  padding-right: 0 !important;
  color: var(--md-sys-color-outline);
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.m3-inline-acoes {
  width: 48px;
  text-align: center;
}

/* O checkbox real do Django. Continua no DOM — é ele que posta — mas quem
   aparece é o botão. */
.m3-inline-acoes input[type="checkbox"][name$="-DELETE"] {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.m3-inline-table button.m3-inline-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0 !important;
  border: 0 !important;
  border-radius: var(--md-shape-corner-full) !important;
  background: transparent !important;
  color: var(--md-sys-color-outline) !important;
  cursor: pointer;
  transition: var(--md-transition-standard);
}

.m3-inline-table button.m3-inline-remove:hover {
  background-color: var(--md-sys-color-error-container) !important;
  color: var(--md-sys-color-on-error-container) !important;
}

.m3-inline-table button.m3-inline-remove .material-symbols-outlined {
  font-size: 18px;
}

.m3-inline-readonly {
  color: var(--md-sys-color-on-surface);
  white-space: nowrap;
}

.m3-inline-grid td.has-error input,
.m3-inline-grid td.has-error select,
.m3-inline-grid td.has-error textarea {
  border-color: var(--md-sys-color-error) !important;
}

/* Sem escopo: o Django emite `<ul class="errorlist">` em qualquer lugar, e
   antes disto ela so era domada dentro da tabela — no modal do item saia com
   marcador e recuo do navegador, parecendo texto solto. */
.errorlist {
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
  color: var(--md-sys-color-error);
  font-size: 0.75rem;
  font-weight: 500;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- linha de leitura + editor ------------------------------------------- */

.m3-inline-grid tbody tr.m3-inline-row {
  cursor: pointer;
}

.m3-inline-resumo {
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--md-sys-color-on-surface);
}

.m3-inline-resumo.is-empty {
  color: var(--md-sys-color-outline);
}

.m3-inline-grid tbody tr.is-editing > td {
  background-color: var(--md-sys-color-surface-container);
  border-bottom-color: transparent;
}

.m3-inline-grid tbody tr.is-editing .m3-inline-editar {
  background-color: var(--md-sys-color-primary-container) !important;
  color: var(--md-sys-color-on-primary-container) !important;
}

.m3-inline-editor-row > td {
  padding: 0 !important;
  background-color: var(--md-sys-color-surface-container-low);
}

/* A linha do editor só existe como endereço de volta: o conteúdo dela é movido
   para o modal ao editar e devolvido para cá ao fechar.
 *
 * Esconder depende da classe que o JS põe no grupo, e não do estado do
 * elemento. Sem JavaScript não há modal para abrir, e aí o editor PRECISA
 * aparecer na tabela — é o que mantém o formulário utilizável. Foi por trocar
 * essa condição por uma sobre o conteúdo (`:has`) que a linha passou a aparecer
 * sempre, duplicando o item na tela. */
.inline-group.m3-js .m3-inline-editor-row {
  display: none;
}

/* Grade que se adapta: com poucos campos vira uma linha, com muitos quebra
   sozinha. Um `grid-template-columns` fixo obrigaria a saber quantos são. */
.m3-inline-editor {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 14px 18px;
  padding: 18px 20px 20px;
  border-bottom: 2px solid var(--md-sys-color-primary);
}

.m3-inline-campo {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}

.m3-inline-campo > label {
  color: var(--md-sys-color-outline);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* Texto longo ocupa a linha inteira da grade: espremê-lo numa coluna de 230px
   seria pior que no formulário empilhado que estamos substituindo. */
.m3-inline-campo:has(textarea) {
  grid-column: 1 / -1;
}

.m3-inline-campo textarea {
  min-height: 76px;
  resize: vertical;
}

.m3-inline-ajuda {
  color: var(--md-sys-color-outline);
  font-size: 0.75rem;
}

.m3-inline-editor-acoes {
  grid-column: 1 / -1;
  display: flex;
  justify-content: flex-end;
}

/* Os atalhos "Hoje | Agora" que o admin injeta ao lado de cada data, e o texto
   solto "Data:" / "Hora:" que os acompanha.
 *
 * Fora em TODO o admin, não só no inline: o campo de data do tema já tem
 * calendário, aceita digitar, e traz "Hoje"/"Agora" dentro do próprio painel.
 * Os atalhos do Django ficavam como um segundo conjunto de controles ao lado do
 * primeiro, com aparência de outra década. */
.datetimeshortcuts,
.datetimeshortcuts + .datetimeshortcuts,
p.datetime .timezonewarning {
  display: none !important;
}

/* O rótulo "Data:"/"Hora:" só faz sentido quando o campo está partido em dois.
   Com um campo só, ele vira um texto solto antes do input. */
.m3-field-group p.datetime,
.m3-inline-campo p.datetime {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 0;
}

.m3-field-group p.datetime input,
.m3-inline-campo p.datetime input {
  font-size: 0.92rem;
}

/* O admin parte data e hora em dois inputs e separa por texto solto ("Data:",
   "Hora:"). Dentro do editor, viram dois campos lado a lado. */
.m3-inline-campo p.datetime {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 0.75rem;
  color: var(--md-sys-color-outline);
}

.m3-inline-campo p.datetime input {
  min-width: 0;
  flex: 1;
}

.m3-inline-acao {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0 !important;
  border: 0 !important;
  border-radius: var(--md-shape-corner-full) !important;
  background: transparent !important;
  color: var(--md-sys-color-outline) !important;
  cursor: pointer;
  transition: var(--md-transition-standard);
}

.m3-inline-acao:hover {
  background-color: var(--md-sys-color-surface-container-high) !important;
  color: var(--md-sys-color-on-surface) !important;
}

.m3-inline-table button.m3-inline-remove:hover {
  background-color: var(--md-sys-color-error-container) !important;
  color: var(--md-sys-color-on-error-container) !important;
}

.m3-inline-acao .material-symbols-outlined {
  font-size: 18px;
}

.m3-inline-acoes {
  white-space: nowrap;
  width: 88px;
}

.m3-inline-editor-row.empty-form,
.m3-inline-editor-row.is-removed {
  display: none;
}

/* ============================================================================
   Campo de data — date picker ancorado (variante *docked* do M3)
   ----------------------------------------------------------------------------
   O calendário abre preso ao campo, não como diálogo sobre a página: escolher
   uma data não é decisão que mereça bloquear a tela. Elevação 3 e canto grande,
   que é o que a especificação reserva para date picker.
   ========================================================================== */

.m3-date {
  position: relative;
  display: block;
  width: 100%;
}

/* Espaço à direita para o botão do calendário não cobrir o texto. */
.m3-date > input {
  width: 100%;
  padding-right: 42px !important;
}

.m3-date-abrir {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0 !important;
  border: 0 !important;
  border-radius: var(--md-shape-corner-full) !important;
  background: transparent !important;
  color: var(--md-sys-color-outline) !important;
  cursor: pointer;
  transition: var(--md-transition-standard);
}

.m3-date-abrir:hover,
.m3-date.is-open .m3-date-abrir {
  background-color: var(--md-sys-color-surface-container-high) !important;
  color: var(--md-sys-color-primary) !important;
}

.m3-date-abrir .material-symbols-outlined {
  font-size: 19px;
}

.m3-date-panel {
  position: fixed;
  z-index: 1300;
  width: 320px;
  padding: 12px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-shape-corner-l);
  background-color: var(--md-sys-color-surface-container-lowest);
  box-shadow: var(--md-elevation-3);
  font-family: var(--md-font-family);
}

.m3-date-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  margin-bottom: 6px;
}

.m3-date-titulo {
  flex: 1;
  padding: 8px 10px !important;
  border: 0 !important;
  border-radius: var(--md-shape-corner-s) !important;
  background: transparent !important;
  color: var(--md-sys-color-on-surface) !important;
  font-family: var(--md-font-family);
  font-size: 0.9rem;
  font-weight: 600;
  text-align: center;
  text-transform: capitalize;
  cursor: pointer;
}

.m3-date-titulo:hover {
  background-color: var(--md-sys-color-surface-container) !important;
}

.m3-date-nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0 !important;
  border: 0 !important;
  border-radius: var(--md-shape-corner-full) !important;
  background: transparent !important;
  color: var(--md-sys-color-on-surface) !important;
  cursor: pointer;
  transition: var(--md-transition-standard);
}

.m3-date-nav:hover {
  background-color: var(--md-sys-color-surface-container-high) !important;
}

.m3-date-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  place-items: center;
}

.m3-date-weekday {
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--md-sys-color-outline);
  font-size: 0.72rem;
  font-weight: 600;
}

.m3-date-vazio {
  height: 38px;
}

/* Alvo de 38px: a especificação pede ~48dp de toque, e o espaçamento da grade
   completa o resto sem obrigar o painel a ficar enorme numa tela de mesa. */
.m3-date-dia {
  width: 38px;
  height: 38px;
  padding: 0 !important;
  border: 1px solid transparent !important;
  border-radius: var(--md-shape-corner-full) !important;
  background: transparent !important;
  color: var(--md-sys-color-on-surface) !important;
  font-family: var(--md-font-family);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: var(--md-transition-standard);
}

.m3-date-dia:hover {
  background-color: var(--md-sys-color-surface-container-high) !important;
}

/* Hoje é contorno; escolhido é preenchido. Os dois ao mesmo tempo continuam
   distinguíveis porque o preenchido vence o contorno. */
.m3-date-dia.is-today {
  border-color: var(--md-sys-color-primary) !important;
  color: var(--md-sys-color-primary) !important;
  font-weight: 600;
}

.m3-date-dia.is-selected {
  background-color: var(--md-sys-color-primary) !important;
  border-color: var(--md-sys-color-primary) !important;
  color: var(--md-sys-color-on-primary) !important;
  font-weight: 600;
}

.m3-date-footer {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--md-sys-color-outline-variant);
}

.m3-date-espaco {
  flex: 1;
}

.m3-date-panel input.m3-date-hora {
  width: 104px;
  min-height: 34px !important;
  padding: 6px 10px !important;
  border: 1px solid var(--md-sys-color-outline) !important;
  border-radius: var(--md-shape-corner-s) !important;
  background-color: var(--md-sys-color-surface-container-lowest) !important;
  color: var(--md-sys-color-on-surface) !important;
  font-family: var(--md-font-family);
  font-size: 0.85rem;
}

.m3-date-acao {
  padding: 7px 14px !important;
  border: 0 !important;
  border-radius: var(--md-shape-corner-s) !important;
  background: transparent !important;
  color: var(--md-sys-color-primary) !important;
  font-family: var(--md-font-family);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition: var(--md-transition-standard);
}

.m3-date-acao:hover {
  background-color: var(--md-sys-color-primary-container) !important;
  color: var(--md-sys-color-on-primary-container) !important;
}

/* --- switch (booleano): estado vindo do :checked ------------------------- */

.m3-switch-field {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}

/* O checkbox fica transparente e de tamanho zero, NÃO `display: none`: assim
   ele continua na ordem de tabulação. Escondido do outro jeito, o campo deixa
   de existir para quem usa teclado. */
.m3-switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  margin: 0;
}

/* Sem isto quem chega pelo Tab não vê onde está — o input em si é invisível,
   então o anel tem de aparecer na trilha. */
.m3-switch input:focus-visible + .m3-switch-slider {
  outline: none;
  box-shadow: 0 0 0 3px var(--md-sys-color-secondary-container);
}

.m3-switch-slider:hover {
  border-color: var(--md-sys-color-on-surface);
}

.m3-switch input:checked + .m3-switch-slider:hover {
  border-color: var(--md-sys-color-primary);
}

.m3-switch input:disabled + .m3-switch-slider {
  opacity: 0.38;
  cursor: not-allowed;
}

/* --- modal do editor de item -------------------------------------------- */

/* `<dialog>` nativo: o scrim, o Esc, o foco preso dentro e a devolução do foco
   ao fechar vêm de graça. Canto extra-grande e elevação 3, que é o que a
   especificação reserva para diálogo. */
.m3-inline-dialog {
  /* Centralizar é a folha padrão do navegador que faz, com `margin: auto` sobre
     `inset: 0`. O `* { margin: 0 }` do `m3-layout.css` atropelava isso e o
     diálogo ficava preso no canto — daí repor os dois aqui, explicitamente, em
     vez de depender de uma regra que já provou perder. */
  inset: 0;
  margin: auto;
  width: min(720px, calc(100vw - 48px));
  max-height: calc(100vh - 80px);
  padding: 0;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-shape-corner-l);
  background-color: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
  box-shadow: var(--md-elevation-3);
  overflow: hidden;
}

.m3-inline-dialog::backdrop {
  /* O scrim do M3. Escurece o suficiente para separar sem apagar o contexto —
     ver a tabela por trás é o que diz qual item está sendo editado. */
  background-color: rgba(0, 0, 0, 0.32);
  backdrop-filter: blur(1px);
}

.m3-inline-dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 20px 12px 24px;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
}

.m3-inline-dialog-title {
  margin: 0;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-font-family);
  font-size: 1.1rem;
  font-weight: 600;
}

.m3-inline-dialog button.m3-inline-dialog-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0 !important;
  border: 0 !important;
  border-radius: var(--md-shape-corner-full) !important;
  background: transparent !important;
  color: var(--md-sys-color-on-surface) !important;
  cursor: pointer;
  transition: var(--md-transition-standard);
}

.m3-inline-dialog button.m3-inline-dialog-close:hover {
  background-color: var(--md-sys-color-surface-container-highest) !important;
}

/* Rola o corpo, não a janela: o título fica visível num item com muitos campos. */
.m3-inline-dialog-body {
  overflow-y: auto;
  max-height: calc(100vh - 200px);
}

/* Dentro do modal o editor não precisa mais da borda que o separava da linha. */
.m3-inline-dialog .m3-inline-editor {
  border-bottom: 0;
  padding: 20px 24px 24px;
}

/* Entrada: sobe um pouco e aparece, na duração "emphasized decelerate" do M3.
   Quem prefere menos movimento não recebe nenhum. */
@media (prefers-reduced-motion: no-preference) {
  .m3-inline-dialog[open] {
    animation: m3-dialog-entra 400ms cubic-bezier(0.05, 0.7, 0.1, 1);
  }
  .m3-inline-dialog[open]::backdrop {
    animation: m3-scrim-entra 400ms cubic-bezier(0.05, 0.7, 0.1, 1);
  }
}

@keyframes m3-dialog-entra {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to { opacity: 1; transform: none; }
}

@keyframes m3-scrim-entra {
  from { background-color: rgba(0, 0, 0, 0); }
  to { background-color: rgba(0, 0, 0, 0.32); }
}

/* Sem `<dialog>` (Safari anterior ao 15.4) não há camada de topo nem `::backdrop`:
   o diálogo é posicionado e escurecido à mão. */
.m3-inline-dialog.is-fallback {
  position: fixed;
  z-index: 1400;
  inset: auto;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* --- realce da linha recém-mexida ---------------------------------------- */

/* Depois de fechar o editor, a linha pisca em âmbar e volta ao normal. Numa
   tabela com muitos itens, achar de novo qual foi o que se acabou de mexer é
   trabalho — e o piscar responde isso antes de a pergunta se formar.
   Duas piscadas: uma só passa por acidente de renderização. */
@keyframes m3-pisca {
  0%, 100% { background-color: transparent; }
  15%, 45% { background-color: var(--md-sys-color-highlight-container); }
  30% { background-color: transparent; }
}

@media (prefers-reduced-motion: no-preference) {
  .m3-inline-grid tbody tr.is-highlight > td {
    animation: m3-pisca 1.4s cubic-bezier(0.2, 0, 0, 1);
  }
}

/* Quem pediu menos movimento recebe o realce parado, e ele some depois — a
   informação (foi esta linha) continua chegando, sem a piscada. */
@media (prefers-reduced-motion: reduce) {
  .m3-inline-grid tbody tr.is-highlight > td {
    background-color: var(--md-sys-color-highlight-container);
    transition: background-color 1.2s ease-out 0.6s;
  }
}

/* ============================================================================
   Campo do formulário — rótulo, estado e texto de apoio
   ----------------------------------------------------------------------------
   Substitui os `style=` inline do `fieldset.html`. Não é arrumação: atributo
   `style` vence qualquer seletor, então enquanto os estilos estavam lá dentro
   o campo não tinha como REAGIR a foco, erro ou somente-leitura.
   ========================================================================== */

.m3-fieldset-description {
  margin-bottom: 16px;
  color: var(--md-sys-color-on-surface-variant);
  font-size: 0.85rem;
}

.m3-fieldset-fields {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.m3-form-row {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}

.m3-field-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  min-width: 240px;
}

.m3-field-label {
  color: var(--md-sys-color-on-surface-variant);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* Ao lado do switch o rótulo é a frase, não a etiqueta de um campo acima. */
.m3-field-label.is-inline {
  color: var(--md-sys-color-on-surface);
  font-size: 0.92rem;
  font-weight: 500;
  cursor: pointer;
  text-transform: none;
}

.m3-field-inline {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 40px;
}

.m3-field-required {
  color: var(--md-sys-color-error);
  margin-left: 2px;
}

/* O rótulo acompanha o foco: com o rótulo acima do campo (e não flutuando na
   borda), é este o retorno que diz onde o cursor está. */
.m3-field-group:focus-within > .m3-field-label {
  color: var(--md-sys-color-primary);
}

/* --- estado de erro ------------------------------------------------------
   Antes disto, um formulário rejeitado mostrava a mensagem em vermelho e o
   campo continuava com a cara de sempre. Num formulário longo, isso é mandar
   procurar. */

.m3-field-group.has-error > .m3-field-label,
.m3-field-group.has-error:focus-within > .m3-field-label {
  color: var(--md-sys-color-error);
}

.m3-field-group.has-error input:not([type="checkbox"]):not([type="radio"]),
.m3-field-group.has-error select,
.m3-field-group.has-error textarea,
.m3-field-group.has-error .m3-rel-field,
.m3-field-group.has-error .m3-file-drop {
  border-color: var(--md-sys-color-error) !important;
}

.m3-field-group.has-error input:focus,
.m3-field-group.has-error select:focus,
.m3-field-group.has-error textarea:focus {
  border-color: var(--md-sys-color-error) !important;
  box-shadow: 0 0 0 3px var(--md-sys-color-error-container) !important;
}

.m3-field-support {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 0.78rem;
  line-height: 1.4;
}

.m3-field-help {
  color: var(--md-sys-color-on-surface-variant);
}

.m3-field-error {
  color: var(--md-sys-color-error);
  font-weight: 500;
}

/* O Django manda os erros numa `<ul>`; sem isto vêm marcadores e recuo. */
.m3-field-error ul,
.m3-field-error .errorlist {
  margin: 0;
  padding: 0;
  list-style: none;
}

.m3-field-readonly {
  padding: 10px 14px;
  border-radius: var(--md-shape-corner-s);
  background-color: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
  min-height: 42px;
}

/* --- contador de caracteres ---------------------------------------------
   Fica na faixa de apoio, à direita, como no M3. Só aparece em campo com
   limite — inventá-lo onde não há limite seria inventar uma regra. */

.m3-field-counter {
  align-self: flex-end;
  color: var(--md-sys-color-on-surface-variant);
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
}

.m3-field-counter.is-near {
  color: var(--md-sys-color-error);
  font-weight: 600;
}

/* --- campo de relacionamento: o campo mostra, o diálogo escolhe ---------- */

/* O campo virou um `<button>`: o que ele faz é abrir o diálogo, e botão é o que
   o teclado e o leitor de tela já sabem operar. */
.m3-rel button.m3-rel-field {
  width: 100%;
  text-align: left;
  cursor: pointer;
  font-family: var(--md-font-family);
}

.m3-rel-texto {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--md-sys-color-on-surface);
  font-size: 0.92rem;
}

.m3-rel-field.is-empty .m3-rel-texto {
  color: var(--md-sys-color-outline);
}

/* `display` SO com `[open]`. A folha do navegador esconde `dialog:not([open])`
   com `display: none`, e qualquer regra de autor que defina `display` atropela
   isso — o diálogo ficava na tela o tempo todo, vazio e sem fundo escurecido,
   por cima do formulário. Mesma armadilha do `[hidden]`: nunca definir
   `display` num elemento cuja visibilidade o navegador controla por atributo. */
.m3-rel-dialog[open] {
  display: flex;
  flex-direction: column;
}

/* Mesma linguagem do cartão do formulário: mesmo fundo, mesmo canto, mesma
   borda. A elevação sobe para 3 — que é o que a especificação reserva para
   diálogo — mas isso é sombra, não cor: o painel continua parecendo parte do
   mesmo sistema, e não uma janela de outro programa. */
.m3-rel-dialog {
  inset: 0;
  margin: auto;
  width: min(520px, calc(100vw - 48px));
  max-height: min(560px, calc(100vh - 96px));
  padding: 0;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-shape-corner-l);
  background-color: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
  box-shadow: var(--md-elevation-3);
  overflow: hidden;
}

.m3-rel-dialog::backdrop {
  background-color: rgba(0, 0, 0, 0.32);
}

/* Sem `<dialog>` não há camada de topo nem `::backdrop`. */
.m3-rel-dialog.is-fallback {
  position: fixed;
  z-index: 1500;
  inset: auto;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.m3-rel-dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 16px 12px 24px;
}

.m3-rel-dialog-title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
}

.m3-rel-dialog button.m3-rel-dialog-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0 !important;
  border: 0 !important;
  border-radius: var(--md-shape-corner-full) !important;
  background: transparent !important;
  color: var(--md-sys-color-on-surface) !important;
  cursor: pointer;
}

.m3-rel-dialog button.m3-rel-dialog-close:hover {
  background-color: var(--md-sys-color-surface-container-highest) !important;
}

.m3-rel-search-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 20px 8px;
  padding: 0 14px;
  border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-shape-corner-m);
  background-color: var(--md-sys-color-surface-container-lowest);
}

.m3-rel-search-row:focus-within {
  border-color: var(--md-sys-color-primary);
  border-width: 2px;
  padding: 0 13px;
}

.m3-rel-search-icon {
  font-size: 20px;
  color: var(--md-sys-color-on-surface-variant);
}

/* Especificidade alta pelo mesmo motivo de sempre: o tema veste todo
   `input[type="text"]` de `.form-row` com borda, fundo e raio próprios, e um
   `.m3-rel-search` simples perde mesmo com `!important`. */
.m3-rel-dialog .m3-rel-search-row > input.m3-rel-search[type="text"] {
  flex: 1;
  width: auto !important;
  min-height: 0 !important;
  padding: 12px 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  outline: none !important;
  font-size: 0.92rem;
}

.m3-rel-dialog-footer {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 20px 18px;
  border-top: 1px solid var(--md-sys-color-outline-variant);
}

.m3-rel-espaco {
  flex: 1;
}

/* ============================================================================
   `hidden` tem que esconder
   ----------------------------------------------------------------------------
   A folha padrão do navegador dá `display: none` a `[hidden]`, mas qualquer
   regra de autor que defina `display` vence — e várias aqui definem, para
   montar o layout do componente. O efeito era silencioso e confuso: a caixa de
   busca aparecia num campo de três opções, e a área de soltar arquivo
   continuava na tela ao lado do anexo já escolhido.
   ========================================================================== */
[hidden] {
  display: none !important;
}

/* --- erro dentro do editor de item -------------------------------------- */

/* O template já marcava o campo com `has-error`, mas nada reagia: o erro saía
   como texto solto e o campo continuava com a cara de sempre. Num item de sete
   campos, isso é mandar procurar. */
.m3-inline-campo.has-error > label {
  color: var(--md-sys-color-error);
}

.m3-inline-campo.has-error input:not([type="checkbox"]):not([type="radio"]),
.m3-inline-campo.has-error select,
.m3-inline-campo.has-error textarea,
.m3-inline-campo.has-error .m3-rel-field,
.m3-inline-campo.has-error .m3-date > input {
  border-color: var(--md-sys-color-error) !important;
  box-shadow: inset 0 0 0 1px var(--md-sys-color-error);
}

/* E a LINHA da tabela avisa qual item tem erro, antes de abrir o modal. Com
   muitos itens, "corrija os erros abaixo" sem dizer onde é uma charada. */
.m3-inline-grid tbody tr.m3-inline-row.has-error > td {
  background-color: var(--md-sys-color-error-container);
}

.m3-inline-row.has-error .m3-inline-num::after {
  content: 'priority_high';
  font-family: 'Material Symbols Outlined';
  font-size: 15px;
  vertical-align: -3px;
  color: var(--md-sys-color-error);
}

/* --- aviso de erro que DIZ o que corrigir -------------------------------- */

.m3-errornote {
  border-left: 4px solid var(--md-sys-color-error);
  background-color: var(--md-sys-color-error-container);
}

.m3-errornote-titulo {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--md-sys-color-error);
  font-weight: 600;
}

.m3-errornote-lista {
  margin: 10px 0 0;
  padding-left: 22px;
  color: var(--md-sys-color-on-error-container);
  font-size: 0.85rem;
  line-height: 1.6;
}

.m3-errornote-lista a {
  color: inherit;
  font-weight: 600;
}

/* --- campo com ícone à esquerda ------------------------------------------
   O espaço para o ícone é do CAMPO, e por isso mora no CSS com `!important`,
   não num `style=` da página. Como `style` inline perde para qualquer regra
   `!important` da folha, o padding escrito ali era refém: bastou a regra de
   foco definir `padding` para o texto ir parar debaixo do ícone ao clicar. */
.m3-campo-icone {
  position: relative;
  display: flex;
  align-items: center;
}

.m3-campo-icone > .material-symbols-outlined {
  position: absolute;
  left: 14px;
  font-size: 20px;
  color: var(--md-sys-color-outline);
  pointer-events: none;
}

.m3-campo-icone > input {
  width: 100%;
  padding-left: 44px !important;
}

.m3-campo-icone:focus-within > .material-symbols-outlined {
  color: var(--md-sys-color-primary);
}

/* Botão de texto: a ação secundária de um diálogo — "Limpar" ao lado de
   "Pronto". Sem fundo, para não competir com a que confirma. */
.m3-btn-texto,
button.m3-btn-texto {
  background: transparent !important;
  color: var(--md-sys-color-primary) !important;
  border: 0 !important;
  box-shadow: none !important;
}

.m3-btn-texto:hover,
button.m3-btn-texto:hover {
  background-color: var(--md-sys-color-surface-container-high) !important;
  box-shadow: none !important;
}

/* Cabeçalho e rodapé do diálogo separam-se do corpo pela mesma linha que o
   resto do admin usa, e não por mudança de fundo. */
.m3-rel-dialog-header,
.m3-rel-dialog-footer,
.m3-inline-dialog-header {
  background-color: transparent;
}

.m3-rel-dialog-header {
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
  margin-bottom: 12px;
}

/* Data, hora e número na tabela do inline: alinhados à direita e com dígitos
   de largura fixa. É o que torna a coluna comparável de relance — as casas
   ficam uma sobre a outra, e "16:00" e "8:05" param de dançar. */
.m3-inline-resumo.is-numero {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* O cabeçalho acompanha a coluna que ele nomeia. */
.m3-inline-grid thead th.is-numero {
  text-align: right;
}

/* --- carga horária: total do capítulo vs. carga de cada conteúdo ---------
   São grandezas de natureza diferente e não podem parecer a mesma: o total é
   DERIVADO (soma dos filhos), a carga de um conteúdo é DIGITADA.

   Mas a diferença se faz com PESO e ícone, não com cor forte. Este tema é todo
   em cinza-ardósia; uma pílula preenchida no meio de uma lista de trinta linhas
   grita, e o que se quer é conseguir percorrer a lista de relance. Nenhum
   preenchimento, nenhuma cor de acento — só o traço, o peso e o símbolo. */

.m3-carga {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-left: 8px;
  padding: 0;
  background: none;
  border: 0;
  color: var(--md-sys-color-outline);
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
  font-weight: 400;
  white-space: nowrap;
  vertical-align: middle;
}

/* O total ganha contorno e peso — o suficiente para ler como "isto resume o que
   vem abaixo", sem virar um bloco de cor. */
.m3-carga-total {
  padding: 1px 8px 1px 6px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-shape-corner-full);
  color: var(--md-sys-color-on-surface-variant);
  font-weight: 600;
}

/* Falta de carga não é um valor. Fica ainda mais apagada que os números, mas
   legível para quem está justamente procurando o que falta preencher. */
.m3-carga-vazia {
  color: var(--md-sys-color-outline);
  font-style: italic;
  opacity: 0.75;
}

.m3-carga .material-symbols-outlined {
  font-size: 14px;
  opacity: 0.8;
}

/* Avaliação que a turma desligou: riscada, não escondida. A linha continua
   existindo — é assim que se religa — e o risco diz que ela não vale, sem
   tirá-la do alcance de quem procura. */
.m3-desligada {
  text-decoration: line-through;
  /* `opacity` no lugar de outra cor: o tema é neutro, e um cinza mais claro
     brigaria com o `outline` que o resto da tabela já usa. */
  opacity: 0.55;
}

/* ============================================================================
   Painel de quem está dando aula
   ----------------------------------------------------------------------------
   Três perguntas, nesta ordem: o que vem agora, o que vence, onde eu estou.
   ========================================================================== */

/* Grade, não coluna estreita: limitar a largura só deixaria cinza vazio
   sobrando numa tela grande, sem ganhar nada em troca — data e título de uma
   linha de lista não sofrem com linha larga do jeito que um parágrafo sofre.
   Aulas e atividades lado a lado usam o espaço; andamento ocupa a largura
   toda embaixo, por ser a seção mais discreta das três. */
.m3-painel {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
  gap: 20px;
  align-items: start;
}

.m3-painel-andamento {
  grid-column: 1 / -1;
}

/* Cada pergunta é um cartão que flutua sobre o fundo — não um bloco corrido.
   É a mesma ideia de um painel de automação residencial: módulos discretos,
   cada um resolvendo uma coisa, em vez de uma folha só de conteúdo. */
.m3-painel-secao {
  padding: 20px 22px;
  border-radius: var(--md-shape-corner-l);
  background-color: var(--md-sys-color-surface-container-low);
  border: 1px solid var(--md-sys-color-outline-variant);
  overflow: hidden;
}

/* Quando a seção contém uma tabela, elimina o container duplo,
   retirando o padding e contorno redundantes para aproveitar o espaço e não poluir */
.m3-painel-secao:has(.m3-table-container),
.m3-painel-secao:has(.m3-table) {
  padding: 0;
  background: transparent;
  border: none;
  box-shadow: none;
  overflow: visible;
}

.m3-painel-secao:has(.m3-table-container) > .m3-painel-titulo,
.m3-painel-secao:has(.m3-table) > .m3-painel-titulo {
  margin-bottom: 8px;
}

.m3-painel-titulo {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 14px;
  color: var(--md-sys-color-on-surface);
  font-size: 1.05rem;
  font-weight: 600;
}

/* Selo redondo por trás do ícone — o mesmo recurso que separa cada módulo à
   primeira vista num painel cheio de módulos parecidos. */
.m3-painel-icone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: var(--md-shape-corner-full);
  background-color: var(--md-sys-color-primary-container);
}

.m3-painel-icone .material-symbols-outlined {
  color: var(--md-sys-color-on-primary-container);
  font-size: 20px;
}

/* A única seção do painel que representa algo que deu errado — não é status
   neutro como andamento, é um dado que não chegou onde precisava. Por isso
   foge do azul do resto do painel. */
.m3-painel-pendencias {
  grid-column: 1 / -1;
  border-color: var(--md-sys-color-error);
  background-color: var(--md-sys-color-error-container);
}

.m3-painel-pendencias .m3-painel-titulo,
.m3-painel-pendencias-texto {
  color: var(--md-sys-color-on-error-container);
}

.m3-painel-icone.is-pendente {
  background-color: var(--md-sys-color-error);
}

.m3-painel-icone.is-pendente .material-symbols-outlined {
  color: var(--md-sys-color-on-error);
}

.m3-painel-pendencias-texto {
  margin: 0 0 14px;
  font-size: 0.85rem;
}

/* `.m3-btn-tonal` sozinho usa sempre `secondary-container` — uma cor neutra
   que não tem relação nenhuma com o vermelho do cartão em que este botão
   vive, e ficava pálido e sem contraste em cima do `error-container`. Dentro
   deste cartão o tom tem que vir do MESMO tema, não do genérico. */
.m3-painel-pendencias .m3-btn-tonal,
.m3-painel-pendencias .m3-btn-tonal * {
  background-color: var(--md-sys-color-error) !important;
  color: var(--md-sys-color-on-error) !important;
}

.m3-painel-pendencias .m3-btn-tonal:hover {
  filter: brightness(0.94);
}

.m3-painel-subtitulo {
  margin: 0 0 12px;
  color: var(--md-sys-color-on-surface-variant);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Lista, não grade de cartões: aula e atividade são uma sequência no TEMPO, e
   ler uma sequência é vertical. Em cartões lado a lado, a ordem se perde.
   Sem fundo nem borda própria: a `.m3-painel-secao` já é o cartão — uma
   segunda borda por dentro dela só duplicaria o contorno. */
.m3-painel-lista {
  display: flex;
  flex-direction: column;
  margin: 0 -22px;
}

.m3-painel-item {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 22px;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
  color: inherit;
  text-decoration: none !important;
  transition: var(--md-transition-standard);
}

.m3-painel-item:last-child {
  border-bottom: 0;
}

.m3-painel-item:hover {
  background-color: var(--md-sys-color-surface-container);
}

/* A data em coluna fixa, alinhada: é o que permite correr o olho pela lista
   sem ler cada linha inteira. */
.m3-painel-quando {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  min-width: 52px;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

.m3-painel-quando strong {
  color: var(--md-sys-color-on-surface);
  font-size: 0.95rem;
  font-weight: 600;
}

.m3-painel-quando small {
  color: var(--md-sys-color-outline);
  font-size: 0.75rem;
}

.m3-painel-corpo {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.m3-painel-linha1 {
  color: var(--md-sys-color-on-surface);
  font-size: 0.92rem;
  font-weight: 500;
}

.m3-painel-linha2 {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--md-sys-color-on-surface-variant);
  font-size: 0.8rem;
}

.m3-painel-marcas {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

.m3-painel-marca {
  padding: 1px 8px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-shape-corner-full);
  color: var(--md-sys-color-on-surface-variant);
  font-size: 0.72rem;
  white-space: nowrap;
}

/* Hoje é a única coisa que ganha cor no painel — porque é a única que muda o
   que a pessoa faz nos próximos minutos. */
.m3-painel-item.e-hoje {
  background-color: var(--md-sys-color-surface-container);
  box-shadow: inset 3px 0 0 var(--md-sys-color-primary);
}

.m3-painel-item.is-atrasado {
  background-color: var(--md-sys-color-surface-container);
  box-shadow: inset 3px 0 0 var(--md-sys-color-error);
}

.m3-painel-marca.is-hoje {
  border-color: var(--md-sys-color-primary);
  color: var(--md-sys-color-primary);
  font-weight: 600;
}

.m3-painel-marca.is-avaliacao {
  border-style: dashed;
  font-weight: 600;
}

/* Correção atrasada é a única marca "para corrigir" que ganha cor — pelo
   mesmo motivo que "hoje" ganha: é a única que muda o que fazer agora. */
.m3-painel-marca.is-vencido {
  border-color: var(--md-sys-color-error);
  color: var(--md-sys-color-error);
  font-weight: 600;
}

.m3-painel-vazio {
  margin: 0;
  padding: 18px;
  border: 1px dashed var(--md-sys-color-outline-variant);
  border-radius: var(--md-shape-corner-l);
  color: var(--md-sys-color-outline);
  font-size: 0.88rem;
  font-style: italic;
}

/* --- andamento: o mais discreto da tela ---------------------------------
   Percentual em destaque vira cobrança, e quem dá aula não precisa ser cobrado
   pelo próprio sistema — precisa conseguir prever. Traço fino, sem cor de
   alerta, sem "faltam X aulas". */

.m3-painel-andamento {
  opacity: 0.9;
}

.m3-andamento {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 5px 0;
}

.m3-andamento-nome {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--md-sys-color-on-surface-variant);
  font-size: 0.82rem;
}

.m3-andamento-trilho {
  display: block;
  width: 160px;
  height: 4px;
  border-radius: var(--md-shape-corner-full);
  background-color: var(--md-sys-color-surface-container-highest);
  overflow: hidden;
}

.m3-andamento-barra {
  display: block;
  height: 100%;
  border-radius: inherit;
  background-color: var(--md-sys-color-outline);
}

.m3-andamento-numero {
  min-width: 34px;
  color: var(--md-sys-color-outline);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* ============================================================================
   Diálogo genérico
   ----------------------------------------------------------------------------
   Mesma linguagem visual do `.m3-rel-dialog` (fundo, canto e borda do resto do
   formulário) mas sem nada específico de campo relacional. Usado pelo painel
   de automação (sig_manager) e por qualquer outro modal simples: visualizar um
   resultado, preencher um formulário de uma etapa. */
.m3-dialog[open] {
  display: flex;
  flex-direction: column;
}

.m3-dialog {
  inset: 0;
  margin: auto;
  width: min(560px, calc(100vw - 48px));
  max-height: min(80vh, calc(100vh - 96px));
  padding: 0;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-shape-corner-l);
  background-color: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
  box-shadow: var(--md-elevation-3);
  overflow: hidden;
}

/* Variante larga: tabela de comparação (Sincronizar Aulas/Avaliações) não
   cabe nos 560px do diálogo padrão sem espremer as colunas. Opt-in via
   `PanelStepResult(..., wide=True)` — o diálogo padrão continua estreito
   para os outros usos (confirmação, formulário de um passo, captura de tela). */
.m3-dialog-wide {
  width: min(1100px, calc(100vw - 48px));
}

.m3-dialog::backdrop {
  background-color: rgba(0, 0, 0, 0.32);
}

/* Sem `<dialog>` não há camada de topo nem `::backdrop`. */
.m3-dialog.is-fallback {
  position: fixed;
  z-index: 1500;
  inset: auto;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.m3-dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 20px 12px;
}

.m3-dialog-title {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 1.05rem;
  font-weight: 600;
}

.m3-dialog-body {
  padding: 0 20px 16px;
  overflow-y: auto;
}

.m3-dialog-body img {
  max-width: 100%;
  border-radius: var(--md-shape-corner-m);
}

.m3-dialog-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 20px 18px;
  border-top: 1px solid var(--md-sys-color-outline-variant);
}

.m3-dialog button.m3-dialog-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0 !important;
  border: 0 !important;
  border-radius: var(--md-shape-corner-full) !important;
  background: transparent !important;
  color: var(--md-sys-color-on-surface) !important;
  cursor: pointer;
}

.m3-dialog button.m3-dialog-close:hover {
  background-color: var(--md-sys-color-surface-container-highest) !important;
}

/* ============================================================================
   Painel de automação (sig_manager)
   ----------------------------------------------------------------------------
   Cada etapa mostra um ícone de status — vazia, pendente, feita ou com erro —
   e opcionalmente uma nota curta abaixo da descrição. */
.m3-step-status {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.m3-step-status .material-symbols-outlined {
  font-size: 22px;
}

.m3-step-status.empty .material-symbols-outlined {
  color: var(--md-sys-color-outline);
}

.m3-step-status.pending .material-symbols-outlined {
  color: var(--md-sys-color-tertiary);
}

.m3-step-status.ok .material-symbols-outlined {
  color: var(--md-sys-color-primary);
}

.m3-step-status.error .material-symbols-outlined {
  color: var(--md-sys-color-error);
}

.m3-step-note {
  margin-top: 4px;
  font-size: 0.82rem;
  color: var(--md-sys-color-outline);
}

.m3-step-note.error {
  color: var(--md-sys-color-error);
}

.m3-step-note.success {
  color: var(--md-sys-color-primary);
}

/* O resultado de um passo (a linha logo abaixo dele na tabela de automação):
   largura cheia, de propósito — é o que deixa uma tabela de comparação
   (Sincronizar Aulas/Avaliações) respirar sem precisar de um diálogo à parte. */
.m3-step-result-row td {
  background-color: var(--md-sys-color-surface-container-lowest) !important;
  padding: 4px 16px 16px !important;
}

.m3-step-result-row .m3-table-container {
  margin-top: 12px;
}

.m3-step-result-row .m3-card-title {
  font-size: 0.95rem;
  margin-top: 16px;
}

.m3-step-result-row .m3-card-title:first-child {
  margin-top: 0;
}

/* Formulário avulso de uma etapa (`panel_form_modal.html`) — não é o form do
   admin, é um `forms.Form` qualquer que a etapa decide pedir. Sem fieldset,
   sem `.m3-field-group`; só o suficiente para não ficar cru dentro do diálogo. */
.m3-dialog-body form > div {
  margin-bottom: 16px;
}

.m3-dialog-body form label {
  display: block;
  margin-bottom: 6px;
  color: var(--md-sys-color-on-surface-variant);
  font-size: 0.8rem;
  font-weight: 600;
}

.m3-dialog-body form input:not([type="checkbox"]):not([type="radio"]),
.m3-dialog-body form select,
.m3-dialog-body form textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-shape-corner-s);
  background-color: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface);
  font-size: 0.92rem;
}

.m3-dialog-body form input:focus,
.m3-dialog-body form select:focus,
.m3-dialog-body form textarea:focus {
  outline: none;
  box-shadow: inset 0 0 0 1px var(--md-sys-color-primary);
  border-color: var(--md-sys-color-primary);
}

.m3-dialog-body form .helptext {
  margin-top: 4px;
  font-size: 0.78rem;
  color: var(--md-sys-color-outline);
}

.m3-dialog-body form .errorlist {
  margin: 0 0 6px;
  padding: 0;
  list-style: none;
  color: var(--md-sys-color-error);
  font-size: 0.82rem;
}

/* Indicador linear indeterminado — a etapa está rodando em segundo plano. */
.m3-linear-progress {
  position: relative;
  width: 100%;
  height: 4px;
  margin-top: 6px;
  border-radius: 999px;
  background-color: var(--md-sys-color-surface-container-highest);
  overflow: hidden;
}

.m3-linear-progress::after {
  content: '';
  position: absolute;
  inset: 0;
  width: 40%;
  border-radius: 999px;
  background-color: var(--md-sys-color-primary);
  animation: m3-linear-indeterminate 1.2s ease-in-out infinite;
}

@keyframes m3-linear-indeterminate {
  0% { transform: translateX(-120%); }
  100% { transform: translateX(350%); }
}
