/* Odin visual system: Odoo-like ergonomics with GANAL palette. */
/* 1. Tokens: reusable GANAL theme over Bootstrap. */
:root {
    /* GANAL Bootstrap standard tokens. */
    --ganal-color-primary: #18869c;
    --ganal-color-primary-hover: #126c7e;
    --ganal-color-accent: #82c4c0;
    --ganal-color-accent-soft: #d7efed;

    --ganal-color-bg: #f9fafb;
    --ganal-color-surface: #ffffff;
    --ganal-color-surface-muted: #f3f7f8;
    --ganal-color-surface-hover: #f4fbfa;
    --ganal-color-surface-selected: #e6f2f3;

    --ganal-color-border: #d8dadd;
    --ganal-color-border-soft: #e7e9ed;
    /* Borde neutro de botón, igualado al `--sp-border-color` de Spartan
       (`Code/01-personal/apps/spartan/src/core/static/core/base.css`) a
       petición del usuario — más oscuro que `--ganal-color-border`
       (#d8dadd), que sigue siendo el borde neutro general de tablas/
       tarjetas/inputs, sin tocar. Solo para botones. */
    --ganal-color-button-border: #b7b7b7;

    --ganal-color-text: #1c1c1c;
    --ganal-color-text-muted: #6b6560;
    --ganal-color-text-subtle: #948e86;
    --ganal-color-text-inverse: #ffffff;

    --ganal-color-control-bg: #ffffff;
    --ganal-color-control-border: #e7e9ed;
    --ganal-color-control-hover-border: #d8dadd;
    --ganal-color-control-focus-border: #82c4c0;
    --ganal-color-control-disabled-bg: #f1f3f4;
    --ganal-color-control-disabled-border: #dfe3e6;
    --ganal-color-control-disabled-text: #8d969b;

    --ganal-color-secondary-bg: #e7e9ed;
    --ganal-color-secondary-border: #e7e9ed;
    --ganal-color-secondary-hover-bg: #d8dadd;
    --ganal-color-secondary-active-bg: #e6f2f3;

    --ganal-color-success-bg: #e8f5ee;
    --ganal-color-success-border: #b9dfca;
    --ganal-color-success-text: #17633a;
    --ganal-color-warning-bg: #fff4d6;
    --ganal-color-warning-border: #f2d27c;
    --ganal-color-warning-text: #7a5200;
    --ganal-color-danger-bg: #fde8e8;
    --ganal-color-danger-border: #f1b8b8;
    --ganal-color-danger-text: #8a1f1f;
    --ganal-color-info-bg: #e8f1fb;
    --ganal-color-info-border: #bfd6ee;
    --ganal-color-info-text: #184e77;
    --ganal-color-special-bg: #f1eaf4;
    --ganal-color-special-border: #d9c4df;
    --ganal-color-special-text: #69416f;

    --ganal-font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Ubuntu, "Noto Sans", Arial, sans-serif;
    --ganal-font-heading: "SF Pro Display", var(--ganal-font-sans);
    --ganal-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;

    --ganal-radius-control: 4px;
    --ganal-radius-surface: 4px;
    --ganal-radius-pill: 999px;

    --ganal-shadow-none: none;
    --ganal-shadow-dropdown: 0 8px 24px rgba(28, 28, 28, .12);

    --ganal-focus-ring: 0 0 0 .125rem rgba(24, 134, 156, .35);
    --ganal-focus-ring-outer: 0 0 0 .25rem rgba(24, 134, 156, .16);

    --ganal-toolbar-height: 48px;
    /* 40px, igual que `--ganal-touch-target` (zona táctil mínima en
       móvil ya decidida en una ronda de QA anterior) — decisión final del
       usuario tras detectar que igualar a los 34px de `.sp-btn` de Spartan
       dejaba el hamburguesa/engranaje/lupa de móvil (que sí respetan el
       táctil mínimo) más altos que el resto de botones. Un único valor sin
       excepciones, en todas las vistas, prevalece sobre el calco exacto de
       Spartan. Antes 36px, luego 34px en el intento anterior. */
    --ganal-control-height: 40px;
    --ganal-control-height-sm: 29px;
    --ganal-control-height-xs: 25px;
    --ganal-icon-button-size: 36px;
    --ganal-touch-target: 40px;
    --ganal-badge-height: 22px;
    --ganal-row-height: 38px;

    --bs-body-font-family: var(--ganal-font-sans);
    --bs-body-font-size: 14px;
    --bs-body-line-height: 1.5;
    --bs-body-color: var(--ganal-color-text);
    --bs-body-bg: var(--ganal-color-bg);
    --bs-border-color: var(--ganal-color-border);
    --bs-border-radius: var(--ganal-radius-control);
    --bs-border-radius-sm: var(--ganal-radius-control);
    --bs-border-radius-lg: var(--ganal-radius-surface);
    --bs-primary: var(--ganal-color-primary);
    --bs-primary-rgb: 24, 134, 156;
    --bs-secondary: var(--ganal-color-secondary-bg);
    --bs-secondary-rgb: 231, 233, 237;
    --bs-success: var(--ganal-color-success-text);
    --bs-warning: var(--ganal-color-warning-text);
    --bs-danger: var(--ganal-color-danger-text);
    --bs-info: var(--ganal-color-info-text);
    --bs-link-color: var(--ganal-color-primary);
    --bs-link-hover-color: var(--ganal-color-primary-hover);
    --bs-focus-ring-color: rgba(24, 134, 156, .25);
}
/* 2. Base document and typography. */
html {
    overflow-x: clip;
    background: var(--ganal-color-surface);
}

body {
    overflow-x: clip;
    background: var(--ganal-color-surface);
    color: var(--ganal-color-text);
    font-family: var(--ganal-font-sans);
    font-size: 14px;
    line-height: 1.5;
    letter-spacing: 0;
}

h1,
h2,
h3,
h4,
h5,
h6,
.navbar-brand {
    font-family: var(--ganal-font-heading);
}

code,
kbd,
pre,
samp {
    font-family: var(--ganal-font-monospace);
}

a {
    color: var(--ganal-color-primary);
}

a:hover {
    color: var(--ganal-color-primary-hover);
}

/* 3. App shell and navigation. */
.odin-appbar {
    min-height: 48px;
    padding-block: .25rem;
    background: var(--ganal-color-surface);
    border-bottom: 1px solid var(--ganal-color-border);
    box-shadow: var(--ganal-shadow-none);
}

#navMain .offcanvas-header {
    border-bottom: 1px solid var(--ganal-color-border-soft);
}

@media (max-width: 991.98px) {
    #navMain.offcanvas {
        width: fit-content;
        max-width: 85vw;
    }
}

@media (min-width: 992px) {
    #navMain .offcanvas-header {
        display: none;
    }
}

.odin-appbar .navbar-brand,
.odin-brand {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    color: var(--ganal-color-text);
    font-weight: 700;
    letter-spacing: 0;
    text-decoration: none;
}

.odin-brand:hover,
.odin-appbar .navbar-brand:hover {
    color: var(--ganal-color-primary-hover);
}

.odin-brand-mark {
    display: inline-grid;
    width: 28px;
    height: 28px;
    place-items: center;
    border-radius: var(--ganal-radius-control);
    background: var(--ganal-color-primary);
    color: var(--ganal-color-text-inverse);
    font-size: .86rem;
    font-weight: 800;
}

.odin-brand-sub {
    margin-left: .15rem;
    color: var(--ganal-color-text-subtle);
    font-size: .7rem;
    font-weight: 700;
    text-transform: uppercase;
}

.odin-record-avatar {
    display: inline-grid;
    flex-shrink: 0;
    width: 36px;
    height: var(--ganal-control-height);
    place-items: center;
    border-radius: var(--ganal-radius-pill);
    background: var(--ganal-color-accent-soft);
    color: var(--ganal-color-primary-hover);
    font-size: 1rem;
    font-weight: 800;
}

.odin-appbar .nav-link {
    min-height: 38px;
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    border-radius: var(--ganal-radius-control);
    color: var(--ganal-color-text-muted);
    font-weight: 500;
    padding-inline: .7rem;
}

.odin-appbar .nav-link:hover,
.odin-appbar .nav-link:focus {
    color: var(--ganal-color-primary-hover);
    background: var(--ganal-color-accent-soft);
}

.odin-appbar .nav-link.active,
.odin-appbar .show > .nav-link {
    color: var(--ganal-color-primary-hover);
    background: var(--ganal-color-accent-soft);
}

.odin-appbar .dropdown-menu {
    border-color: var(--ganal-color-border);
    border-radius: var(--ganal-radius-surface);
    box-shadow: var(--ganal-shadow-dropdown);
}

.odin-appbar .dropdown-item {
    min-height: var(--ganal-control-height-sm);
    display: flex;
    align-items: center;
    gap: .35rem;
    color: var(--ganal-color-text-muted);
}

.odin-appbar .dropdown-item:hover,
.odin-appbar .dropdown-item:focus {
    color: var(--ganal-color-primary-hover);
    background: var(--ganal-color-accent-soft);
}

/* 4. Page layout and form header primitives. */
.odin-main {
    padding: .6rem .75rem 2rem;
}

main > .d-flex.align-items-center,
main > .d-flex.justify-content-between,
main > .d-flex.align-items-center.justify-content-between {
    min-height: 48px;
    margin-bottom: .8rem !important;
    padding-bottom: .6rem;
    border-bottom: 1px solid var(--ganal-color-border-soft);
}

main h1.h4 {
    margin-bottom: 0;
    color: var(--ganal-color-text);
    font-size: 1.15rem;
    font-weight: 700;
}

.odin-form-header h1.h4,
.odin-form-title {
    font-size: 1.75rem;
}

.odin-form-header .odin-statusbar {
    margin-bottom: 0;
}

.odin-field-grid {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.odin-field-box {
    position: relative;
    background: var(--ganal-color-surface-muted);
    border: 1px solid var(--ganal-color-border);
    border-radius: var(--ganal-radius-control);
    padding: 1.15rem .9rem .7rem;
}

.odin-field-box-label {
    position: absolute;
    top: -.6em;
    left: .7rem;
    padding-inline: .35rem;
    background: var(--ganal-color-surface-muted);
    color: var(--ganal-color-text-muted);
    font-size: .76rem;
}

.odin-field-box-value {
    display: block;
    color: var(--ganal-color-text);
    font-size: .9rem;
    word-break: break-word;
}

.odin-field-box-value + .odin-field-box-value {
    margin-top: .2rem;
}

.odin-eyebrow {
    display: block;
    margin-bottom: .2rem;
    color: var(--ganal-color-text-subtle);
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    text-decoration: none;
}

a.odin-eyebrow:hover {
    color: var(--ganal-color-primary-hover);
}

.odin-muted {
    color: var(--ganal-color-text-muted);
}

.odin-error-code {
    font-family: var(--ganal-font-heading);
    font-size: 4.5rem;
    font-weight: 800;
    color: var(--ganal-color-primary);
    line-height: 1;
    margin-bottom: .5rem;
}

/* 5. Bootstrap normalization and shared controls. */
.odin-filterbar {
    align-items: end;
    margin-bottom: .75rem !important;
    padding: .65rem;
    background: var(--ganal-color-surface);
    border: 1px solid var(--ganal-color-border);
    border-radius: var(--ganal-radius-surface);
    box-shadow: var(--ganal-shadow-none);
}

.odin-filterbar .form-label {
    margin-bottom: .25rem;
    color: var(--ganal-color-text-muted);
    font-size: .75rem;
    font-weight: 700;
}

.form-control,
.form-select {
    min-height: var(--ganal-control-height);
    padding: 5px 10px;
    border-color: var(--ganal-color-control-border);
    border-radius: var(--ganal-radius-control);
    background-color: var(--ganal-color-control-bg);
    color: var(--ganal-color-text);
    font-size: 14px;
    line-height: 1.5;
}

.form-select {
    padding-right: 2rem;
}

.form-control:hover,
.form-select:hover {
    border-color: var(--ganal-color-control-hover-border);
}

.form-control:focus,
.form-select:focus {
    border-color: var(--ganal-color-control-focus-border);
    box-shadow: var(--ganal-focus-ring-outer);
}

.form-control:disabled,
.form-select:disabled,
.form-control[readonly] {
    border-color: var(--ganal-color-control-disabled-border);
    background-color: var(--ganal-color-control-disabled-bg);
    color: var(--ganal-color-control-disabled-text);
}

/* Botones planos estilo Spartan (`sp-btn`, `Code/01-personal/apps/spartan`):
   sin rellenos sólidos en ninguna variante, solo borde + texto de color y
   un tinte gris sutil al pasar el ratón — el color diferencia el borde y
   el texto, nunca el fondo. Adoptado 2026-08-22 a petición explícita del
   usuario ("adapta todos los botones al estilo de Spartan"), sustituye el
   `.btn-primary` con relleno sólido que había antes. Un único tamaño (sin
   `.btn-sm` reducido, como en Spartan) salvo donde ya hay una clase propia
   (`.odin-list-action-button` etc.) que fija su propia altura. */
.btn {
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: var(--ganal-control-height);
    padding: 5px 12px;
    border-width: 1px;
    border-radius: var(--ganal-radius-control);
    background: var(--ganal-color-surface);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.5;
    box-shadow: none;
    transition: none;
}

.btn:focus-visible {
    outline: 0;
    box-shadow: var(--ganal-focus-ring);
}

.btn:active {
    transform: scale(.98);
}

.btn-sm {
    min-height: var(--ganal-control-height-sm);
    padding: 0 5px;
    font-size: calc(var(--bs-body-font-size) - .0625rem);
    line-height: 1.5;
}

.btn-primary,
.btn-outline-primary {
    --bs-btn-color: var(--ganal-color-primary);
    --bs-btn-bg: var(--ganal-color-surface);
    --bs-btn-border-color: var(--ganal-color-primary);
    --bs-btn-hover-color: var(--ganal-color-primary);
    --bs-btn-hover-bg: var(--ganal-color-secondary-hover-bg);
    --bs-btn-hover-border-color: var(--ganal-color-primary);
    --bs-btn-active-color: var(--ganal-color-primary);
    --bs-btn-active-bg: var(--ganal-color-secondary-active-bg);
    --bs-btn-active-border-color: var(--ganal-color-primary);
    --bs-btn-disabled-color: var(--ganal-color-primary);
    --bs-btn-disabled-bg: var(--ganal-color-surface);
    --bs-btn-disabled-border-color: var(--ganal-color-primary);
    color: var(--ganal-color-primary);
    background: var(--ganal-color-surface);
    border-color: var(--ganal-color-primary);
}

.btn-primary:hover,
.btn-outline-primary:hover {
    color: var(--ganal-color-primary);
    background: var(--ganal-color-secondary-hover-bg);
    border-color: var(--ganal-color-primary);
}

.btn-secondary,
.btn-outline-secondary {
    --bs-btn-color: var(--ganal-color-text);
    --bs-btn-bg: var(--ganal-color-surface);
    --bs-btn-border-color: var(--ganal-color-button-border);
    --bs-btn-hover-color: var(--ganal-color-text);
    --bs-btn-hover-bg: var(--ganal-color-secondary-hover-bg);
    --bs-btn-hover-border-color: var(--ganal-color-button-border);
    --bs-btn-active-color: var(--ganal-color-text);
    --bs-btn-active-bg: var(--ganal-color-secondary-active-bg);
    --bs-btn-active-border-color: var(--ganal-color-button-border);
    --bs-btn-disabled-color: var(--ganal-color-control-disabled-text);
    --bs-btn-disabled-bg: var(--ganal-color-surface);
    --bs-btn-disabled-border-color: var(--ganal-color-control-disabled-border);
    color: var(--ganal-color-text);
    background: var(--ganal-color-surface);
    border-color: var(--ganal-color-button-border);
}

.btn-secondary:hover,
.btn-outline-secondary:hover {
    color: var(--ganal-color-text);
    background: var(--ganal-color-secondary-active-bg);
    border-color: var(--ganal-color-primary);
}

.btn-danger,
.btn-outline-danger {
    --bs-btn-color: var(--ganal-color-danger-text);
    --bs-btn-bg: var(--ganal-color-surface);
    --bs-btn-border-color: var(--ganal-color-danger-border);
    --bs-btn-hover-color: var(--ganal-color-danger-text);
    --bs-btn-hover-bg: var(--ganal-color-danger-bg);
    --bs-btn-hover-border-color: var(--ganal-color-danger-border);
    --bs-btn-active-color: var(--ganal-color-danger-text);
    --bs-btn-active-bg: var(--ganal-color-danger-bg);
    --bs-btn-active-border-color: var(--ganal-color-danger-border);
    color: var(--ganal-color-danger-text);
    background: var(--ganal-color-surface);
    border-color: var(--ganal-color-danger-border);
}

.btn-danger:hover,
.btn-outline-danger:hover {
    color: var(--ganal-color-danger-text);
    background: var(--ganal-color-danger-bg);
    border-color: var(--ganal-color-danger-border);
}

.btn:disabled,
.btn.disabled {
    opacity: .4;
    pointer-events: none;
}

.text-primary {
    color: var(--ganal-color-primary) !important;
}

.bg-primary,
.badge.bg-primary {
    background-color: var(--ganal-color-primary) !important;
}

.badge {
    border-radius: var(--ganal-radius-pill);
    font-weight: 700;
    letter-spacing: 0;
}

.card {
    border-color: var(--ganal-color-border);
    border-radius: var(--ganal-radius-surface);
    box-shadow: var(--ganal-shadow-none) !important;
}

.card-header {
    min-height: 40px;
    display: flex;
    align-items: center;
    background: var(--ganal-color-surface-muted);
    border-bottom-color: var(--ganal-color-border);
    color: var(--ganal-color-text);
    font-weight: 700;
}

.card-body {
    color: var(--ganal-color-text);
}

.breadcrumb {
    margin-bottom: .7rem;
    color: var(--ganal-color-text-subtle);
    font-size: .82rem;
}

.breadcrumb a {
    color: var(--ganal-color-text-muted);
    text-decoration: none;
}

.breadcrumb a:hover {
    color: var(--ganal-color-primary-hover);
}

.breadcrumb-item {
    min-width: 0;
    overflow-wrap: anywhere;
}

/* 6. Lists, tables, pagination, and bulk actions. */
.odin-table-card {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
}

.odin-list-table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--ganal-color-text);
    margin-bottom: 0;
    color: var(--ganal-color-text);
    border-top: 1px solid var(--bs-border-color);
}

.odin-list-table thead th:last-child,
.odin-list-table tbody td:last-child {
    padding-right: .8rem;
}

.odin-list-table thead th {
    height: 36px;
    padding: 8px 10px;
    vertical-align: middle;
    background: var(--ganal-color-surface-muted);
    border-bottom: 1px solid var(--ganal-color-border);
    color: var(--ganal-color-text-muted);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.3333;
    letter-spacing: .01em;
    white-space: nowrap;
}

.odin-list-table tbody td {
    height: var(--ganal-row-height);
    padding: 8px 10px;
    vertical-align: middle;
    border-color: var(--ganal-color-border-soft);
    font-size: calc(var(--bs-body-font-size) - .0625rem);
    line-height: var(--bs-body-line-height);
}

.odin-list-table tbody tr {
    background: var(--ganal-color-surface);
}

@media (hover: hover) and (pointer: fine) {
    .odin-list-table tbody tr[data-row-href]:hover {
        background: var(--ganal-color-surface-hover);
    }
}

.odin-list-table tbody tr[data-row-href] {
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    -webkit-user-select: none;
    user-select: none;
}

.odin-list-table tbody tr[data-row-href]:active {
    background: var(--ganal-color-secondary-bg);
}

.odin-list-table .text-end,
.odin-list-table td:last-child,
.odin-list-table th:last-child {
    white-space: nowrap;
}
.odin-list-table td.odin-contact-cell {
    min-width: 0;
    max-width: 260px;
    white-space: normal;
}

.odin-contact-line {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: .35rem;
    min-width: 0;
    max-width: 100%;
    color: var(--ganal-color-text-muted);
}

.odin-contact-line + .odin-contact-line {
    margin-top: .15rem;
}

.odin-contact-line > .bi {
    color: var(--ganal-color-text-subtle);
    font-size: .9rem;
}

.odin-contact-value {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.odin-contact-line .odin-copy-inline {
    flex: 0 0 auto;
}

.odin-list-meta,
.odin-contact-item {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    min-width: 0;
    max-width: 100%;
}

.odin-list-meta > .bi,
.odin-contact-line > .bi {
    flex: 0 0 auto;
}

.odin-list-meta > .bi {
    color: var(--ganal-color-text-subtle);
    font-size: .9rem;
}

.odin-contact-value-items {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem .4rem;
    min-width: 0;
    max-width: 100%;
}

.odin-contact-text,
.odin-contact-link {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.odin-contact-link {
    color: inherit;
    text-decoration: none;
}

.odin-contact-link:hover,
.odin-contact-link:focus {
    color: var(--ganal-color-primary);
    text-decoration: underline;
}

.odin-contact-item .odin-copy-inline {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--ganal-color-primary);
}

.odin-contact-item .odin-copy-inline:hover,
.odin-contact-item .odin-copy-inline:focus {
    background: var(--ganal-color-surface-muted);
    color: var(--ganal-color-primary-hover);
}

.odin-smart-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.odin-smart-button {
    display: inline-flex;
    align-items: baseline;
    gap: .35rem;
    padding: .3rem .7rem;
    border: 1px solid var(--ganal-color-border);
    border-radius: var(--ganal-radius-surface);
    background: var(--ganal-color-surface);
    color: var(--ganal-color-text);
    font-size: .8rem;
    text-decoration: none;
}

a.odin-smart-button:hover,
a.odin-smart-button:focus {
    border-color: var(--ganal-color-primary);
    color: var(--ganal-color-primary-hover);
}

a.odin-smart-button:active {
    background: var(--ganal-color-surface-hover);
}

a.odin-smart-button:focus-visible {
    box-shadow: var(--ganal-focus-ring);
    outline: 0;
}

.odin-smart-button-count {
    font-weight: 800;
    color: var(--ganal-color-primary);
}

.odin-smart-button-static {
    opacity: .7;
    cursor: default;
}

.odin-lines-table {
    --bs-table-bg: var(--ganal-color-surface);
    --bs-table-color: var(--ganal-color-text);
    margin-bottom: 0;
    background: var(--ganal-color-surface);
    color: var(--ganal-color-text);
}

.odin-lines-table thead th {
    height: var(--ganal-control-height);
    vertical-align: middle;
    background: var(--ganal-color-surface-muted);
    border-bottom: 1px solid var(--ganal-color-border);
    color: var(--ganal-color-text-muted);
    font-size: .74rem;
    font-weight: 800;
    text-transform: uppercase;
    white-space: nowrap;
}

.odin-lines-table tbody td {
    vertical-align: middle;
    background: var(--ganal-color-surface);
    border-color: var(--ganal-color-border-soft);
}

.odin-lines-table tbody tr:hover > * {
    background: var(--ganal-color-surface-hover);
}

.odin-sort-link {
    color: inherit;
    text-decoration: none;
    white-space: nowrap;
}

.odin-sort-link:hover {
    color: var(--ganal-color-primary-hover);
}

.odin-sort-link.odin-sort-active {
    color: var(--ganal-color-primary);
}

.odin-group-header td {
    background: var(--ganal-color-surface-muted);
    color: var(--ganal-color-text-muted);
    font-size: .74rem;
    font-weight: 800;
    text-transform: uppercase;
    border-top: 1px solid var(--ganal-color-border);
    border-bottom: 1px solid var(--ganal-color-border);
}

.odin-empty-state {
    min-height: 96px;
    color: var(--ganal-color-text-subtle) !important;
    background: var(--ganal-color-surface);
}

.odin-select-col {
    width: 2.5rem;
    text-align: center;
}

.odin-row-selected {
    background: var(--ganal-color-surface-selected) !important;
    box-shadow: inset 3px 0 0 var(--ganal-color-primary);
}

.odin-row-selected > * {
    background: transparent !important;
}

/* Selección masiva — integrada en la cabecera de lista, en flujo normal
   (patrón Spartan `rule_list.html`/`invoice_list.html`, adoptado 2026-08-22
   a petición del usuario: la barra flotante fija abajo que había antes no
   se consideraba cómoda). Contador con borde de color acento + botón "x"
   para deseleccionar, siempre junto al botón "Acciones". */
.odin-selection-bar {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
}

.odin-counter {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: var(--ganal-control-height);
    padding: 0 6px 0 12px;
    border: 1px solid var(--ganal-color-primary);
    border-radius: var(--ganal-radius-control);
    color: var(--ganal-color-primary);
    font-size: .86rem;
    font-weight: 700;
    white-space: nowrap;
}

.odin-counter-clear {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: none;
    padding: 6px;
    color: inherit;
    cursor: pointer;
}

.odin-counter-clear:hover {
    opacity: .7;
}

/* "Todos" — alternativa al checkbox de cabecera de tabla para cuando este
   no está a la vista: oculto en desktop/tablet (ahí ya está el checkbox),
   visible solo en móvil (ver media query más abajo, mismo criterio que
   ocultar la columna de selección en tarjetas). Reutiliza el mismo patrón
   de `.odin-list-action-button` (gear/lupa de esta misma cabecera, altura
   ya correcta y probada) en vez de reinventar el modelo de caja a mano —
   solo se pisa `width` (ahí es fijo 40px de icono, aquí hace falta ancho
   automático por el texto). */
.odin-select-all-btn {
    display: none;
    width: auto;
    height: var(--ganal-control-height);
    align-items: center;
    justify-content: center;
    padding-inline: 12px;
    border-color: var(--ganal-color-primary);
}

.odin-select-all-btn:hover {
    border-color: var(--ganal-color-primary);
}

.odin-pagination,
.odin-record-pager {
    display: flex;
    justify-content: flex-end;
}

.odin-pager {
    display: inline-flex;
    align-items: baseline;
    min-width: 0;
    gap: 4px;
    color: var(--ganal-color-text);
    font-size: calc(var(--bs-body-font-size) - .0625rem);
    line-height: 1.5;
    white-space: nowrap;
}

.odin-pager-range {
    margin-right: 4px;
    font-variant-numeric: tabular-nums;
}

.odin-pager-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--ganal-control-height);
    height: var(--ganal-control-height);
    border: 1px solid var(--ganal-color-button-border);
    background: var(--ganal-color-surface);
    color: var(--ganal-color-text-muted);
    text-decoration: none;
}

.odin-pager-button:first-of-type {
    border-radius: var(--ganal-radius-control) 0 0 var(--ganal-radius-control);
}

.odin-pager-button:last-of-type {
    margin-left: -1px;
    border-radius: 0 var(--ganal-radius-control) var(--ganal-radius-control) 0;
}

/* Hover/active/focus compartidos con `.odin-list-action-button` (gear/lupa
   de cabecera) — mismo botón-icono plano, dos usos distintos (paginador vs
   menú de acciones), sin duplicar el bloque en cada sitio. */
.odin-pager-button:hover,
.odin-list-action-button:hover {
    background: var(--ganal-color-secondary-active-bg);
    border-color: var(--ganal-color-primary);
    color: var(--ganal-color-text);
}

.odin-pager-button:active,
.odin-list-action-button:active,
.odin-list-action-button[aria-expanded="true"] {
    background: var(--ganal-color-secondary-active-bg);
    border-color: var(--ganal-color-primary);
    color: var(--ganal-color-text);
}

.odin-pager-button:focus-visible,
.odin-list-action-button:focus-visible {
    box-shadow: var(--ganal-focus-ring);
    outline: 0;
}

.odin-pager-button.disabled,
.odin-pager-button[aria-disabled="true"] {
    pointer-events: none;
    opacity: .45;
}

/* 7. Dashboard modules and generic Bootstrap containers. */
.odin-module-grid {
    max-width: 920px;
    padding-inline: .5rem;
}

.odin-module-tile {
    display: flex;
    min-height: 118px;
    padding: 1rem;
    gap: .8rem;
    align-items: flex-start;
    background: var(--ganal-color-surface);
    border: 1px solid var(--ganal-color-border);
    border-radius: var(--ganal-radius-surface);
    color: var(--ganal-color-text);
    box-shadow: var(--ganal-shadow-none);
    transition: border-color .12s ease, box-shadow .12s ease;
}

.odin-module-tile:hover,
.odin-module-tile:focus {
    color: var(--ganal-color-text);
    border-color: var(--ganal-color-accent);
    box-shadow: var(--ganal-shadow-none);
}

.odin-module-icon {
    display: inline-grid;
    width: 42px;
    height: 42px;
    flex: 0 0 42px;
    place-items: center;
    border-radius: var(--ganal-radius-surface);
    color: var(--ganal-color-primary-hover);
    background: var(--ganal-color-accent-soft);
    font-size: 1.35rem;
}

.odin-module-title {
    margin: 0 0 .15rem;
    font-size: .98rem;
    font-weight: 800;
}

.odin-module-copy {
    margin: 0;
    color: var(--ganal-color-text-muted);
    font-size: .84rem;
}

dl.row dt {
    color: var(--ganal-color-text-muted);
    font-size: .78rem;
    font-weight: 800;
}

dl.row dd {
    color: var(--ganal-color-text);
    overflow-wrap: anywhere;
}

.list-group-item {
    border-color: var(--ganal-color-border-soft);
    overflow-wrap: anywhere;
}

.alert {
    border-radius: var(--ganal-radius-surface);
    border-color: var(--ganal-color-border);
    box-shadow: var(--ganal-shadow-none);
}

main.container.py-5 {
    max-width: 480px;
}

.odin-money-inline-label,
.odin-cell-inline-label {
    display: none;
}

@media (max-width: 767.98px) {
    body {
        font-size: .9rem;
    }


    .odin-filterbar {
        padding: .6rem;
    }

    .odin-appbar .navbar-nav {
        padding-top: .4rem;
    }

    .odin-appbar .nav-link {
        width: 100%;
    }

    .odin-list-table {
        min-width: 760px;
    }

    .odin-master-list-cardable {
        /* Las dos, no solo `overflow-x`: por spec CSS, si un eje es
           `visible` y el otro no, el `visible` se recalcula a `auto` —
           `.odin-table-card` fija `overflow-y: hidden` sin condición de
           media query, así que sin este `overflow-y: visible` aquí el
           `overflow-x: visible` de abajo nunca llegaba a aplicarse de
           verdad (quedaba en `auto`, seguía recortando la fila a sangre
           completa de las filas). Confirmado con
           `getComputedStyle()`/`CSSRule` en vivo, no solo por lectura del
           CSS. */
        overflow-x: visible;
        overflow-y: visible;
    }

    .odin-master-list-cardable .odin-list-table {
        min-width: 0;
        /* `width: 100%` (fijo, no `auto`) no crece solo al añadir margen
           negativo como sí hacen los `tr` (cuyo `width:auto` se expande
           automáticamente) — hay que sumar el ancho de la compensación a
           mano para que el `border-top` (línea divisoria superior, entre
           la cabecera y la primera fila) también llegue a sangre completa,
           igual que ya llega el `border-bottom` de cada fila. */
        width: calc(100% + 1.5rem);
        margin-inline: -.75rem;
        border-top: 1px solid var(--ganal-color-border-soft);
    }

    .odin-master-list-cardable .odin-list-table,
    .odin-master-list-cardable .odin-list-table tbody,
    .odin-master-list-cardable .odin-list-table tr,
    .odin-master-list-cardable .odin-list-table td {
        display: block;
    }

    .odin-master-list-cardable .odin-list-table thead {
        display: none;
    }

    .odin-master-list-cardable .odin-list-table tbody tr {
        position: relative;
        /* La tabla (regla de arriba) ya sangra a los dos bordes reales de
           pantalla — la fila, como bloque normal sin ancho propio, hereda
           ese ancho completo sin necesitar su propio margen negativo (así
           su `border-bottom`, la línea divisoria entre filas, llega tan a
           sangre como el `border-top` de la tabla). El padding de `.75rem`
           deja el contenido exactamente en el mismo margen que el botón
           hamburguesa (izquierda) y el paginador (derecha). El checkbox
           (`.odin-select-col`, primera celda) esta siempre oculto en este
           ancho (ver regla mas abajo, mismo breakpoint) — no se reserva
           hueco para el, a diferencia de escritorio/tablet. */
        padding: .4rem .75rem .5rem .75rem;
        border-bottom: 1px solid var(--ganal-color-border-soft);
    }

    .odin-master-list-cardable .odin-list-table tbody td {
        height: auto;
        padding: 0;
        border: 0;
        background: transparent;
        white-space: normal;
    }

    .odin-master-list-cardable .odin-list-table tbody td + td {
        margin-top: .25rem;
    }

    .odin-master-list-cardable .odin-list-table tbody td.odin-select-col,
    .odin-master-list-cardable .odin-list-table tbody td:first-child {
        position: absolute;
        /* .65rem = offset real del texto de la Referencia (2ª celda)
           respecto al `tr`, medido con getBoundingClientRect — antes
           .85rem, quedaba 3px más abajo que el texto. */
        top: .65rem;
        /* .75rem = compensa el margen negativo de la fila (arriba) para
           que el checkbox/referencia no se muevan de sitio. */
        left: .75rem;
        width: var(--ganal-icon-button-size);
        margin-top: 0;
        text-align: left;
    }

    .odin-master-list-cardable .odin-list-table tbody td:nth-child(2) {
        color: var(--ganal-color-text);
        font-size: var(--bs-body-font-size);
        font-weight: 600;
        line-height: var(--bs-body-line-height);
    }

    .odin-master-list-cardable .odin-list-table tbody td:nth-child(n+3) {
        color: var(--ganal-color-text-muted);
        font-size: calc(var(--bs-body-font-size) - .0625rem);
        line-height: var(--bs-body-line-height);
    }

    .odin-master-list-cardable .odin-list-table tbody td.odin-contact-cell {
        display: block;
        max-width: 100%;
    }

    .odin-master-list-cardable .odin-contact-line {
        max-width: 100%;
    }

    .odin-master-list-cardable--no-select .odin-list-table tbody tr {
        padding-left: .75rem;
    }

    .odin-master-list-cardable--no-select .odin-list-table tbody td:first-child {
        position: static;
        top: auto;
        left: auto;
        width: auto;
        text-align: left;
        color: var(--ganal-color-text);
        font-size: var(--bs-body-font-size);
        font-weight: 600;
        line-height: var(--bs-body-line-height);
    }

    .odin-master-list-cardable--no-select .odin-list-table tbody td:nth-child(n+2) {
        color: var(--ganal-color-text-muted);
        font-size: calc(var(--bs-body-font-size) - .0625rem);
        line-height: var(--bs-body-line-height);
    }

    .odin-master-list-cardable .odin-list-table tfoot {
        display: flex !important;
        flex-direction: column;
        background: var(--ganal-color-surface-muted);
        border-top: 2px solid var(--ganal-color-border);
    }

    .odin-master-list-cardable .odin-list-table tfoot tr {
        display: flex !important;
        flex-wrap: wrap;
        align-items: baseline;
        gap: .2rem .75rem;
        padding: .5rem .75rem;
        border-bottom: 1px solid var(--ganal-color-border-soft);
    }

    .odin-master-list-cardable .odin-list-table tfoot tr:last-child {
        border-bottom: 0;
    }

    .odin-master-list-cardable .odin-list-table tfoot td {
        display: block;
        flex: 0 0 auto;
        height: auto;
        padding: 0;
        border: 0;
        background: transparent;
        white-space: normal;
    }

    .odin-master-list-cardable .odin-list-table tfoot td[colspan] {
        text-align: left !important;
        margin-right: auto;
    }

    .odin-master-list-cardable .odin-list-cell-badge {
        position: absolute;
        /* Igual que la Referencia (2ª celda) — ver nota en `:first-child`
           un poco más arriba. */
        top: .65rem;
        /* .75rem = compensa el margen negativo de la fila (mismo mecanismo
           que `left` en `:first-child` de la Referencia) para que quede
           alineado con el paginador, no a sangre. */
        right: .75rem;
        max-width: 55%;
        margin: 0 !important;
        text-align: right;
    }

    .odin-master-list-cardable .odin-list-table tbody td.odin-cell-hide-if-empty {
        display: none !important;
    }

    .odin-master-list-cardable .odin-money-inline {
        display: inline-block !important;
        margin-top: 0 !important;
    }

    .odin-master-list-cardable .odin-money-inline + .odin-money-inline {
        margin-left: 1rem;
    }

    .odin-master-list-cardable .odin-money-inline-label,
    .odin-master-list-cardable .odin-cell-inline-label {
        display: inline;
        color: var(--ganal-color-text-muted);
        font-weight: 400;
    }

    .odin-master-list-cardable--money-right .odin-list-table tbody tr {
        display: flex !important;
        flex-wrap: wrap;
    }

    .odin-master-list-cardable--money-right .odin-list-table tbody td {
        flex: 1 0 100%;
        /* Sin esto, un `.odin-truncate` con `max-width: 100%` (celda que
           ocupa toda la fila) no trunca: `max-width` en porcentaje no
           cuenta en el cálculo del tamaño mínimo de un elemento
           `inline-block` con `white-space: nowrap`, así que el texto largo
           empuja la celda (y la fila) fuera del viewport en vez de
           recortarse con "…". `min-width: 0` permite que la celda se
           encoja por debajo del contenido, dejando que `.odin-truncate`
           trunque de verdad. */
        min-width: 0;
    }

    .odin-master-list-cardable--money-right .odin-list-table tbody td:nth-child(2) {
        flex: 0 0 auto;
        /* Referencia: ya alineada con checkbox/badges de fábrica (margen
           natural de `td + td`) — no tocar. */
    }

    .odin-master-list-cardable--money-right .odin-list-table tbody td:nth-child(3) {
        flex: 0 0 auto;
        /* Mismo margen que la referencia (nth-child(2), heredado también de
           `td + td`) para quedar a la misma altura en vez del `0` que
           tenía antes — ese `0` la subía por encima de la referencia. */
        margin-left: .5rem;
    }

    .odin-master-list-cardable--money-right .odin-list-table tbody td.odin-money-inline {
        flex: 0 0 auto;
        margin-top: .25rem !important;
    }

    .odin-master-list-cardable--money-right .odin-list-table tbody td.odin-money-inline:not(.odin-money-inline ~ .odin-money-inline) {
        margin-left: auto;
    }

    .odin-master-list-cardable .odin-list-table td .odin-truncate {
        /* Más específico que `.odin-truncate` (32ch) y
           `.odin-truncate.odin-truncate-cliente` (16ch) — pensados para
           columnas estrechas de la tabla de escritorio — para ganar el
           empate de especificidad sin depender del orden en el fichero.
           En la tarjeta móvil cada celda ya ocupa su propia línea entera,
           así que Cliente y Descripción pueden usar todo el ancho. */
        max-width: 100%;
    }

    main > .d-flex.align-items-center,
    main > .d-flex.justify-content-between,
    main > .d-flex.align-items-center.justify-content-between {
        align-items: flex-start !important;
        flex-wrap: wrap;
        gap: .6rem;
    }

    main > .d-flex.align-items-center > h1,
    main > .d-flex.justify-content-between > h1 {
        min-width: 0;
        overflow-wrap: anywhere;
    }

    main > .d-flex.align-items-center > .ms-auto,
    main > .d-flex.justify-content-between > .ms-auto {
        width: 100%;
        margin-left: 0 !important;
        flex-wrap: wrap;
    }

    main > .d-flex.align-items-center > .ms-auto .btn,
    main > .d-flex.justify-content-between > .ms-auto .btn {
        flex: 1 1 160px;
    }
}

/* 8. List control panel, search, filters, and active facets. */
.odin-filter-select {
    width: auto;
    min-width: 176px;
}

.odin-record-link {
    color: var(--ganal-color-primary);
    font-weight: 700;
    text-decoration: none;
}

.odin-record-main {
    color: var(--ganal-color-text);
    font-weight: 700;
    text-decoration: none;
}

.odin-record-link:hover,
.odin-record-main:hover {
    color: var(--ganal-color-primary-hover);
    text-decoration: underline;
}

.odin-pagination-compact .odin-pager-button {
    width: var(--ganal-control-height);
    height: var(--ganal-control-height);
}

.odin-form-header {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
}

.odin-form-header-v2 .btn-outline-secondary {
    background: var(--ganal-color-border-soft);
}

.odin-form-header-v2 .dropdown-toggle::after {
    display: none;
}

.odin-form-toolbar-status {
    min-width: 0;
    max-width: 100%;
    overflow-x: auto;
}

.odin-form-header .btn,
.odin-row-copy {
    min-width: var(--ganal-icon-button-size);
}

.odin-header-actions {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    flex-wrap: wrap;
}

.odin-copy-done {
    color: var(--ganal-color-success-text) !important;
    border-color: var(--ganal-color-success-border) !important;
    background: var(--ganal-color-success-bg) !important;
}

.odin-action-history .table {
    font-size: .84rem;
}

.odin-suggestions-dropdown {
    display: none;
    position: absolute;
    top: calc(100% + .25rem);
    left: 0;
    right: 0;
    z-index: 20;
    max-height: 320px;
    overflow-y: auto;
    background: var(--ganal-color-surface);
    border: 1px solid var(--ganal-color-border);
    border-radius: var(--ganal-radius-surface);
    box-shadow: var(--ganal-shadow-none);
}

.odin-suggestions-dropdown.odin-suggestions-open {
    display: block;
}

.odin-suggestion-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .5rem .75rem;
    color: var(--ganal-color-text);
    text-decoration: none;
}

.odin-suggestion-item:hover,
.odin-suggestion-item:focus {
    background: var(--ganal-color-surface-muted);
}

.odin-suggestion-item + .odin-suggestion-item {
    border-top: 1px solid var(--ganal-color-border-soft);
}

.odin-suggestion-meta {
    color: var(--ganal-color-text-muted);
    white-space: nowrap;
}

.odin-suggestion-empty {
    padding: .5rem .75rem;
    color: var(--ganal-color-text-muted);
}

.odin-filter-field {
    flex: 0 1 180px;
    min-width: 150px;
}

.odin-filter-field .form-select,
.odin-filter-field .form-control {
    width: 100%;
}

/* Alias de nomenclatura (odoo-ux-implementation-guide.md §3): el select
   "Agrupar" ya se comporta como .odin-filter-field, esta clase solo le da
   el nombre de componente que pide la guía, sin cambiar el layout. */
.odin-group-menu {
    flex: 0 1 180px;
}

.odin-filter-year {
    flex-basis: 108px;
    min-width: 96px;
    max-width: 120px;
}

.odin-filter-multiselect {
    width: 100%;
}

.odin-filter-multiselect .dropdown-menu {
    max-height: 260px;
    overflow-y: auto;
    min-width: 100%;
}

.odin-filter-multiselect .dropdown-item.form-check {
    display: flex;
    align-items: center;
    cursor: pointer;
    padding-left: 1rem;
    gap: .5rem;
}

.odin-filter-multiselect .dropdown-item.form-check .form-check-input {
    appearance: auto;
    width: auto;
    height: auto;
    margin: 0;
    border: 0;
    background: none;
    flex-shrink: 0;
}

.odin-filter-panel {
    flex-basis: 100%;
}

.odin-filter-panel-body {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
    margin-top: .75rem;
    padding-top: .75rem;
    border-top: 1px solid var(--ganal-color-border-soft);
}

@media (max-width: 767.98px) {
    .odin-filter-field,
    .odin-filter-year {
        flex: 1 1 100%;
        max-width: none;
    }
}
.odin-action-history thead th {
    color: var(--ganal-color-text-muted);
    font-size: .72rem;
    font-weight: 800;
    text-transform: uppercase;
    background: var(--ganal-color-surface-muted);
}
.odin-copy-inline {
    --bs-btn-padding-y: .12rem;
    --bs-btn-padding-x: .32rem;
    --bs-btn-font-size: .78rem;
    margin-left: 0;
    vertical-align: baseline;
    min-height: var(--ganal-control-height);
    padding: 3px 7px;
}

.odin-copy-inline .bi {
    pointer-events: none;
}

/* 9. Canonical component aliases and Odoo-like refinements. */
.odin-control-panel-main {
    min-height: var(--ganal-control-height);
}

.odin-control-panel-title {
    min-width: 0;
}

.odin-control-panel-actions,
.odin-copy-actions {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    flex-wrap: wrap;
}

.odin-search-panel {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 1fr) auto;
    gap: 0;
    margin-top: .75rem;
    padding: .75rem;
    background: var(--ganal-color-surface);
    border: 1px solid var(--ganal-color-border);
    border-radius: var(--ganal-radius-surface);
    box-shadow: var(--ganal-shadow-none);
}

.odin-search-panel--filters-only {
    grid-template-columns: minmax(0, 1fr) auto;
}

.odin-search-panel-section {
    min-width: 0;
    padding-inline: .9rem;
    border-left: 1px solid var(--ganal-color-border-soft);
}

.odin-search-panel-title {
    display: flex;
    align-items: center;
    gap: .35rem;
    margin-bottom: .55rem;
    color: var(--ganal-color-text);
    font-weight: 800;
}

.odin-search-panel-section-body {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
}

.odin-selection-bar .btn {
    min-height: var(--ganal-control-height-xs);
}

/* 10. Badges, monetary values, tabs, status bars, and banners. */
.odin-badge,
.badge.odin-badge {
    display: inline-flex;
    align-items: center;
    min-height: var(--ganal-badge-height);
    padding: 3px 8px;
    border: 1px solid transparent;
    border-radius: var(--ganal-radius-pill);
    font-size: 12px;
    font-weight: 500;
    line-height: 1.3333;
    letter-spacing: 0;
    white-space: nowrap;
}

.odin-badge-neutral,
.badge.bg-secondary,
.badge.bg-secondary-subtle {
    color: var(--ganal-color-text-muted) !important;
    background-color: var(--ganal-color-surface-muted) !important;
    border-color: var(--ganal-color-border) !important;
}

.odin-badge-info,
.badge.bg-info-subtle {
    color: var(--ganal-color-info-text) !important;
    background-color: var(--ganal-color-info-bg) !important;
    border-color: var(--ganal-color-info-border) !important;
}

.odin-badge-success,
.badge.bg-success-subtle {
    color: var(--ganal-color-success-text) !important;
    background-color: var(--ganal-color-success-bg) !important;
    border-color: var(--ganal-color-success-border) !important;
}

.odin-badge-warning,
.badge.bg-warning-subtle {
    color: var(--ganal-color-warning-text) !important;
    background-color: var(--ganal-color-warning-bg) !important;
    border-color: var(--ganal-color-warning-border) !important;
}

.odin-badge-danger,
.badge.bg-danger-subtle {
    color: var(--ganal-color-danger-text) !important;
    background-color: var(--ganal-color-danger-bg) !important;
    border-color: var(--ganal-color-danger-border) !important;
}

.odin-badge-special {
    color: var(--ganal-color-special-text) !important;
    background-color: var(--ganal-color-special-bg) !important;
    border-color: var(--ganal-color-special-border) !important;
}

.odin-num,
.odin-list-table .text-end,
.odin-lines-table .text-end {
    font-variant-numeric: tabular-nums;
}

.odin-money {
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.odin-monetary-footer {
    text-align: right;
}

.odin-monetary-footer td {
    padding: .6rem .8rem;
    background: var(--ganal-color-surface-muted);
    border-top: 1px solid var(--ganal-color-border);
    color: var(--ganal-color-text);
    font-variant-numeric: tabular-nums;
}

.odin-truncate {
    display: inline-block;
    max-width: 32ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

.odin-truncate.odin-truncate-cliente {
    max-width: 16ch;
}

.odin-tabs .nav-tabs,
.nav-tabs.odin-tabs {
    gap: .15rem;
    border-bottom-color: var(--ganal-color-border);
    overflow-x: auto;
    overflow-y: hidden;
    flex-wrap: nowrap;
}

.odin-tabs .nav-link,
.nav-tabs.odin-tabs .nav-link {
    min-height: var(--ganal-row-height);
    border-color: transparent;
    border-radius: var(--ganal-radius-control) var(--ganal-radius-control) 0 0;
    color: var(--ganal-color-text-muted);
    font-weight: 700;
    white-space: nowrap;
}

.odin-tabs .nav-link:hover,
.nav-tabs.odin-tabs .nav-link:hover {
    border-color: var(--ganal-color-border-soft);
    color: var(--ganal-color-primary-hover);
}

.odin-tabs .nav-link.active,
.nav-tabs.odin-tabs .nav-link.active {
    border-color: var(--ganal-color-border) var(--ganal-color-border) var(--ganal-color-surface);
    color: var(--ganal-color-primary-hover);
    box-shadow: inset 0 2px 0 var(--ganal-color-primary);
}

.odin-statusbar {
    display: inline-flex;
    align-items: center;
    gap: 0;
    min-height: var(--ganal-control-height-sm);
    max-width: 100%;
    color: var(--ganal-color-text-muted);
    font-size: .82rem;
    font-weight: 700;
}

.odin-statusbar-step {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    min-height: var(--ganal-icon-button-size);
    padding: .3rem 1rem .3rem 1.4rem;
    margin-left: -13px;
    background: var(--ganal-color-secondary-bg);
    color: var(--ganal-color-text-muted);
    white-space: nowrap;
    clip-path: polygon(0 0, calc(100% - 13px) 0, 100% 50%, calc(100% - 13px) 100%, 0 100%, 13px 50%);
}

.odin-statusbar-step:first-child {
    margin-left: 0;
    padding-left: .85rem;
    clip-path: polygon(0 0, calc(100% - 13px) 0, 100% 50%, calc(100% - 13px) 100%, 0 100%);
}

.odin-statusbar-step-active {
    z-index: 1;
    background: var(--ganal-color-accent);
    color: var(--ganal-color-text-inverse);
}

.odin-alert-banner {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    padding: .65rem .85rem;
    border: 1px solid var(--ganal-color-border);
    border-radius: var(--ganal-radius-surface);
    background: var(--ganal-color-surface-muted);
    color: var(--ganal-color-text);
    box-shadow: var(--ganal-shadow-none);
}

.odin-alert-banner-info {
    background: var(--ganal-color-info-bg);
    color: var(--ganal-color-info-text);
    border-color: var(--ganal-color-info-border);
}

.odin-alert-banner-success {
    background: var(--ganal-color-success-bg);
    color: var(--ganal-color-success-text);
    border-color: var(--ganal-color-success-border);
}

.odin-alert-banner-warning {
    background: var(--ganal-color-warning-bg);
    color: var(--ganal-color-warning-text);
    border-color: var(--ganal-color-warning-border);
}

.odin-alert-banner-danger {
    background: var(--ganal-color-danger-bg);
    color: var(--ganal-color-danger-text);
    border-color: var(--ganal-color-danger-border);
}

.odin-alert-banner-special {
    background: var(--ganal-color-special-bg);
    color: var(--ganal-color-special-text);
    border-color: var(--ganal-color-special-border);
}

/* 11. Chatter, action history, mobile refinements, and document totals. */
.odin-chatter-history,
.odin-action-history {
    margin-top: 1rem;
    border-top: 1px solid var(--ganal-color-border);
    padding-top: .75rem;
}

.odin-chatter-history-event,
.odin-action-history .list-group-item {
    display: grid;
    gap: .25rem;
    padding-block: .65rem;
    background: var(--ganal-color-surface);
}

.odin-chatter-history-meta {
    color: var(--ganal-color-text-subtle);
    font-size: .78rem;
    font-weight: 700;
}

.odin-chatter-history-title {
    color: var(--ganal-color-text);
    font-size: .92rem;
    font-weight: 700;
}

.odin-chatter-history-body {
    color: var(--ganal-color-text-muted);
    font-size: .86rem;
}

.odin-chatter-history-error {
    color: var(--ganal-color-danger-text);
    font-size: .84rem;
    font-weight: 700;
}

.odin-view-switcher {
    display: inline-flex;
    align-items: center;
    gap: .2rem;
}

.odin-view-switcher .btn,
.odin-view-switcher-button {
    min-width: var(--ganal-control-height-sm);
    min-height: var(--ganal-control-height-sm);
    padding-inline: .45rem;
}

@media (max-width: 767.98px) {
    .odin-search-panel {
        grid-template-columns: 1fr;
    }

    .odin-search-panel--filters-only {
        grid-template-columns: minmax(0, 1fr) auto;
    }

    .odin-search-panel-section {
        padding: .65rem 0;
        border-left: 0;
        border-top: 1px solid var(--ganal-color-border-soft);
    }

    /* Móvil: sin checkboxes visibles en las tarjetas (patrón Odoo/Spartan,
       selección por pulsación larga, ver base.html) — "Todos" es la
       alternativa explícita al checkbox de cabecera, que aquí no se ve. */
    .odin-select-all-btn {
        display: inline-flex;
    }

    .odin-master-list-cardable .odin-list-table thead .odin-select-col,
    .odin-master-list-cardable .odin-list-table tbody .odin-select-col {
        display: none;
    }
}

.odin-document-totals {
    width: min(100%, 340px);
    margin-top: .75rem;
    padding-top: .75rem;
    border-top: 1px solid var(--ganal-color-border);
    color: var(--ganal-color-text);
}

.odin-document-totals-row {
    display: flex;
    justify-content: space-between;
    gap: 1.5rem;
    padding-block: .18rem;
    font-size: .9rem;
}

.odin-document-totals-row span {
    color: var(--ganal-color-text-muted);
}

.odin-document-totals-row-total {
    margin-top: .25rem;
    padding-top: .4rem;
    border-top: 1px solid var(--ganal-color-border-soft);
    font-size: 1rem;
    font-weight: 800;
}
/* 12. Record sheets, form blocks, and rich text surfaces. */
.odin-form-sheet {
    /* Padding horizontal igualado a `.odin-control-panel` (misma variable
       de diseño en los dos breakpoints, ver media queries abajo) para que
       el título, los separadores y el resto del contenido queden alineados
       a la izquierda con el botón sándwich de la cabecera. Sin `border`:
       el marco visible generaba una indentación extra que rompía esa
       alineación sin aportar nada (el fondo ya distingue la superficie). */
    margin-top: .5rem;
    padding: 16px 12px;
    border-radius: var(--ganal-radius-surface);
    background: var(--ganal-color-surface);
}

.odin-form-sheet .odin-statusbar,
.odin-form-sheet .odin-smart-buttons {
    margin-bottom: .85rem !important;
}

.odin-form-sheet .odin-alert-banner {
    box-shadow: none;
}

.odin-form-block {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none !important;
}

.odin-form-block + .odin-form-block,
.odin-document-sections section + section {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--ganal-color-border-soft);
}

.odin-form-block-title {
    margin-bottom: .65rem;
    color: var(--ganal-color-text-muted);
    font-size: .76rem;
    font-weight: 800;
    letter-spacing: .02em;
    text-transform: uppercase;
}

.odin-form-block-body {
    color: var(--ganal-color-text);
}

.odin-form-sheet-danger {
    border-color: var(--ganal-color-danger-border);
}

.odin-text-danger {
    color: var(--ganal-color-danger-text) !important;
}

.odin-pre-line {
    white-space: pre-line;
}

.odin-pre-wrap {
    white-space: pre-wrap;
}

.odin-form-sheet .table-responsive {
    border: 1px solid var(--ganal-color-border);
    border-radius: var(--ganal-radius-control);
    background: var(--ganal-color-surface);
}

.odin-form-sheet section > h2.h5 {
    margin-bottom: .65rem !important;
    color: var(--ganal-color-text-muted);
    font-size: .76rem;
    font-weight: 800;
    letter-spacing: .02em;
    text-transform: uppercase;
}

@media (min-width: 768px) {
    .odin-form-sheet {
        padding: 20px 12px;
    }
}

@media (max-width: 575.98px) {
    .odin-form-sheet {
        padding: 12px 0;
    }
}

.odin-master-sheet .odin-tabs {
    margin-top: -.25rem;
}

.odin-master-sheet .tab-content {
    padding-top: .25rem;
}

/* Árbol de apartados/subapartados de Oferta Diseño (tech-spec.md §2.3.1)
   — <details>/<summary> nativo, sin JS. */
.odin-capitulo {
    border: 1px solid var(--ganal-color-border);
    border-radius: var(--ganal-radius-control);
    background: var(--ganal-color-surface);
    margin-bottom: .5rem;
}

.odin-capitulo .odin-capitulo {
    margin-top: .5rem;
    margin-left: 1rem;
}

.odin-capitulo:last-child {
    margin-bottom: 0;
}

.odin-capitulo-summary {
    display: flex;
    align-items: baseline;
    /* Sin justify-content: space-between — el ::before (marcador) cuenta
       como un elemento flex más dentro de un contenedor flex, así que con
       3 elementos (marcador/título/subtotal) el hueco se repartía en dos
       mitades iguales alrededor del título, dejándolo con pinta de
       centrado cuando el texto era corto. El subtotal se empuja a la
       derecha con margin-left: auto en su lugar. */
    gap: .75rem;
    padding: .6rem .85rem;
    cursor: pointer;
    list-style: none;
}

.odin-capitulo-summary::-webkit-details-marker {
    display: none;
}

.odin-capitulo-summary::before {
    content: "\25B8";
    margin-right: .5rem;
    display: inline-block;
    color: var(--ganal-color-text-muted);
    transition: transform .15s ease;
}

.odin-capitulo[open] > .odin-capitulo-summary::before {
    transform: rotate(90deg);
}

.odin-capitulo-titulo {
    min-width: 0;
    font-weight: 700;
    color: var(--ganal-color-text);
}

.odin-capitulo-subtotal {
    flex: 0 0 auto;
    margin-left: auto;
    font-weight: 700;
    white-space: nowrap;
    color: var(--ganal-color-text);
}

.odin-capitulo-body {
    padding: 0 .85rem .75rem;
    border-top: 1px solid var(--ganal-color-border-soft);
}

.odin-capitulo-body .odin-lines-table {
    margin-top: .5rem;
}

.odin-form-list {
    border: 1px solid var(--ganal-color-border);
    border-radius: var(--ganal-radius-control);
    overflow: hidden;
}

.odin-form-list .list-group-item {
    border-color: var(--ganal-color-border-soft);
}

.odin-html-toolbar .btn {
    min-width: var(--ganal-control-height-sm);
}

.odin-html-editor-surface {
    min-height: 220px;
    overflow: auto;
    background: var(--ganal-color-text-inverse);
}

.odin-html-editor-surface:focus {
    border-color: var(--ganal-color-control-focus-border);
    box-shadow: var(--ganal-focus-ring);
    outline: 0;
}

.odin-html-editor-source {
    min-height: 220px;
    font-size: .8rem;
}

.odin-record-form .odin-html-editor-source {
    min-height: 260px;
}

/* En modo código solo tiene sentido el botón de alternar vista — el resto
   de comandos (negrita, listas...) actúan sobre la superficie contenteditable,
   no sobre el textarea de texto plano. */
.odin-html-editor--source .odin-html-toolbar .btn-group:not(:last-child) {
    display: none;
}
/* 13. Odoo-like compact list header and filter facets. */
.odin-control-panel {
    min-height: var(--ganal-toolbar-height);
    margin-bottom: .75rem;
    padding: 0 12px 12px 12px;
    background: var(--ganal-color-surface);
}

.odin-list-header-row {
    min-height: var(--ganal-toolbar-height);
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    width: 100%;
}

.odin-list-header-title {
    flex: 0 0 auto;
    margin-top: -5px;
}

.odin-list-header-title h1 {
    color: var(--ganal-color-text);
    font-size: calc(var(--bs-body-font-size) + .25rem);
    font-weight: 600;
    line-height: 1;
}
.odin-list-action-menu {
    flex: 0 0 auto;
    margin-top: calc(var(--bs-spacer) * .625);
    margin-right: .2rem;
    margin-left: calc(var(--bs-spacer) * .625);
}

.odin-list-action-menu .dropdown-menu {
    --bs-dropdown-min-width: 10rem;
    --bs-dropdown-padding-y: .25rem;
    --bs-dropdown-bg: var(--ganal-color-surface);
    --bs-dropdown-border-color: var(--ganal-color-border);
    --bs-dropdown-border-radius: var(--ganal-radius-surface);
    --bs-dropdown-box-shadow: var(--ganal-shadow-dropdown);
    --bs-dropdown-link-color: var(--ganal-color-text);
    --bs-dropdown-link-hover-color: var(--ganal-color-text);
    --bs-dropdown-link-hover-bg: var(--ganal-color-secondary-bg);
    --bs-dropdown-link-active-color: var(--ganal-color-text);
    --bs-dropdown-link-active-bg: var(--ganal-color-surface-selected);
    min-width: var(--bs-dropdown-min-width);
    padding: var(--bs-dropdown-padding-y) 0;
    border-color: var(--bs-dropdown-border-color);
    border-radius: var(--bs-dropdown-border-radius);
    background: var(--bs-dropdown-bg);
    box-shadow: var(--bs-dropdown-box-shadow);
}

.odin-list-action-menu .dropdown-item {
    min-height: var(--ganal-control-height-sm);
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: 0 var(--bs-dropdown-item-padding-x);
    color: var(--bs-dropdown-link-color);
    font-size: var(--bs-body-font-size);
    line-height: var(--bs-body-line-height);
}

.odin-list-action-menu .dropdown-item i {
    width: 1rem;
    color: currentColor;
    text-align: center;
}

.odin-list-action-button {
    width: 40px;
    height: var(--ganal-control-height);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--ganal-color-surface);
    border-color: var(--ganal-color-button-border);
    color: var(--bs-btn-color);
    font-size: var(--bs-btn-font-size);
}

.odin-mobile-search-button {
    display: none;
}
.odin-mobile-nav-toggle {
    display: none;
}
.odin-list-action-button::after {
    display: none;
}

@media (min-width: 576px) {
    .odin-mobile-search-overlay.collapse:not(.show) {
        display: block;
    }
}
.odin-list-search-form {
    min-width: 250px;
    width: 100%;
}

.odin-list-search-control {
    position: relative;
    display: flex;
    align-items: center;
    gap: .25rem;
    width: 100%;
    box-sizing: border-box;
    min-height: var(--ganal-control-height);
    padding-left: calc(var(--ganal-icon-button-size) + .1875rem);
    border: 1px solid var(--ganal-color-border);
    border-radius: var(--ganal-radius-control);
    background: var(--ganal-color-bg);
}

.odin-list-search-control:focus-within {
    border-color: var(--ganal-color-control-focus-border);
    box-shadow: var(--ganal-focus-ring);
}

.odin-list-search-control > .bi {
    position: absolute;
    top: 50%;
    left: calc(var(--ganal-icon-button-size)/3);
    transform: translateY(-50%);
    color: var(--ganal-color-text);
    font-size: 1rem;
    pointer-events: none;
    z-index: 1;
}

.odin-list-search-control .form-control {
    flex: 1 1 160px;
    min-width: 120px;
    height: auto;
    min-height: calc(var(--ganal-control-height) - 2px);
    padding-left: .25rem;
    padding-block: 0;
    border: 0;
    background: transparent;
    color: var(--ganal-color-text);
    font-size: var(--bs-body-font-size);
    box-shadow: none;
}

.odin-list-filter-toggle {
    align-self: stretch;
    flex: 0 0 var(--ganal-control-height);
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-left: 1px solid var(--ganal-color-border);
    background: var(--ganal-color-bg);
    color: var(--ganal-color-text);
}

.odin-list-filter-toggle:hover {
    background: var(--ganal-color-secondary-hover-bg);
    color: var(--ganal-color-text);
}

.odin-list-filter-toggle:active {
    background: var(--ganal-color-secondary-active-bg);
    color: var(--ganal-color-text);
}

.odin-list-filter-toggle:focus-visible {
    box-shadow: var(--ganal-focus-ring);
    outline: 0;
}

.odin-list-search-form .odin-filter-panel {
    width: 100%;
    margin-top: .35rem;
}

.odin-list-header-pagination {
    flex: 0 0 auto;
    margin-top: 0;
    margin-left: auto;
}

@media (max-width: 991.98px) {
    .odin-appbar .navbar-brand {
        display: none;
    }

    .odin-appbar {
        min-height: 0;
        padding-block: 0;
        border-bottom: 0;
    }

    .odin-main {
        padding-top: 1rem;
    }

    .odin-mobile-nav-toggle {
        order: -1;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 var(--ganal-touch-target);
        width: var(--ganal-touch-target);
        min-width: var(--ganal-touch-target);
        height: var(--ganal-touch-target);
        min-height: var(--ganal-touch-target);
        padding: 0;
        border: 1px solid var(--ganal-color-text);
        border-radius: var(--ganal-radius-surface);
        background: var(--ganal-color-surface);
        color: var(--ganal-color-text);
        font-size: 2rem;
        line-height: 1;
        -webkit-text-stroke: .5px currentColor;
        position: relative;
        z-index: 25;
    }

    .odin-mobile-nav-toggle:focus-visible {
        box-shadow: var(--ganal-focus-ring);
        outline: 0;
    }
}

@media (max-width: 575.98px) {
    .odin-control-panel {
        position: relative;
        margin-bottom: .5rem;
        padding: 0 0 .75rem;
    }

    .odin-list-header-row {
        align-items: flex-start;
        gap: .5rem;
        flex-wrap: nowrap;
        min-height: var(--ganal-toolbar-height);
    }

    .odin-list-header-title {
        order: 0;
        flex: 0 1 auto;
        min-width: 0;
        margin-top: 0;
        position: relative;
        z-index: 25;
    }

    /* La barra de selección ocupa el mismo hueco que el título en vez de
       compartir línea con él (aplastaba el título a 0 de ancho, bug real
       visto en dispositivo: "CLIENTES"/título superpuestos con la barra) o
       de añadir una línea nueva (descartado explícitamente por el usuario:
       "que tape el título, no que pase a la línea de abajo"). El título se
       oculta mientras hay selección activa (:has() más abajo) y la barra
       ocupa su lugar en el flujo flex — sin position:absolute ni z-index,
       solo intercambio de qué elemento ocupa el hueco. */
    .odin-selection-bar {
        order: 0;
        flex: 0 1 auto;
        min-width: 0;
        overflow: hidden;
    }

    .odin-list-header-row:has(.odin-selection-bar:not([hidden]))
        .odin-list-header-title {
        display: none;
    }

    /* Libera sitio para el contador mientras se selecciona (paginar no es
       una necesidad inmediata en mitad de una selección activa). */
    .odin-list-header-row:has(.odin-selection-bar:not([hidden]))
        .odin-list-header-pagination {
        display: none;
    }

    .odin-counter {
        min-width: 0;
        overflow: hidden;
    }

    .odin-counter span[data-bulk-count-text] {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .odin-list-header-title h1 {
        font-size: calc(var(--bs-body-font-size) + .4375rem);
        line-height: 1.15;
    }

    .odin-list-header-title h1 i {
        display: none;
    }

    .odin-list-action-menu {
        order: 1;
        margin: 0;
        position: relative;
        z-index: 25;
    }

    .odin-mobile-search-button {
        order: 2;
        display: inline-flex;
        flex: 0 0 var(--ganal-touch-target);
        width: var(--ganal-touch-target);
        min-width: var(--ganal-touch-target);
        height: var(--ganal-touch-target);
        min-height: var(--ganal-touch-target);
        border: 1px solid var(--ganal-color-button-border);
        border-radius: var(--ganal-radius-surface);
        background: var(--ganal-color-surface);
        color: var(--bs-btn-color);
        font-size: calc(var(--bs-body-font-size) + .125rem);
        position: relative;
        z-index: 25;
    }

    .odin-mobile-search-button[aria-expanded="true"] {
        border-color: var(--ganal-color-primary);
        background: var(--ganal-color-secondary-active-bg);
        box-shadow: none;
        color: var(--ganal-color-text);
    }

    .odin-list-header-pagination {
        order: 3;
        flex: 0 0 auto;
        align-self: flex-start;
        margin-left: auto;
        position: relative;
        z-index: 25;
    }

    .odin-list-header-pagination .odin-pager-range {
        display: none;
    }

    .odin-list-header-pagination .odin-pager-button {
        width: var(--ganal-touch-target);
        height: var(--ganal-touch-target);
    }

    .odin-list-search-form {
        position: absolute;
        top: calc(100% - .75rem);
        right: -.75rem;
        left: -.75rem;
        z-index: 15;
        min-width: 0;
        width: auto;
        margin: 0;
        padding: .75rem;
        border: 1px solid var(--ganal-color-border-soft);
        border-top: 0;
        border-radius: 0 0 var(--ganal-radius-surface) var(--ganal-radius-surface);
        background: var(--ganal-color-surface);
        box-shadow: var(--ganal-shadow-dropdown);
    }

    .odin-mobile-search-overlay.collapse:not(.show) {
        display: none !important;
    }

    .odin-list-search-form.collapsing {
        overflow: hidden;
    }

    .odin-list-search-control {
        display: grid;
        grid-template-columns: 1.5rem minmax(0, 1fr) var(--ganal-touch-target);
        grid-template-rows: auto auto;
        align-items: center;
        gap: 0 .5rem;
        width: 100%;
        min-width: 0;
        min-height: calc((var(--ganal-touch-target) * 2) + .5rem);
        padding: .5rem 0 .5rem .625rem;
        border: 1px solid var(--ganal-color-control-border);
        border-radius: var(--ganal-radius-surface);
        background: var(--ganal-color-control-bg);
    }

    .odin-list-search-control:focus-within {
        border-color: var(--ganal-color-control-focus-border);
        box-shadow: var(--ganal-focus-ring);
    }

    .odin-list-search-control > .bi {
        position: static;
        grid-column: 1;
        grid-row: 1 / span 2;
        display: block;
        justify-self: center;
        transform: none;
        color: var(--ganal-color-text-subtle);
        font-size: calc(var(--bs-body-font-size) + .125rem);
        pointer-events: none;
    }

    .odin-list-search-control .odin-search-facets {
        grid-column: 2;
        grid-row: 1;
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        align-self: start;
        gap: .3rem;
        min-width: 0;
        width: 100%;
    }

    .odin-list-search-control .odin-search-facet {
        flex-shrink: 0;
        max-width: 100%;
        min-height: 22px;
        gap: .35rem;
        padding: 0 .5rem 0 0;
        border-radius: var(--ganal-radius-control);
        background: var(--ganal-color-secondary-bg);
        color: var(--ganal-color-text-muted);
        font-size: calc(var(--bs-body-font-size) - .0625rem);
        font-weight: 400;
        overflow: hidden;
    }

    .odin-list-search-control .odin-search-facet:not(.odin-search-facet-clear)::before {
        content: "\F3E0";
        flex: 0 0 auto;
        align-self: stretch;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 20px;
        background: var(--ganal-color-primary);
        color: #fff;
        font-family: "bootstrap-icons";
        font-size: .68rem;
    }

    .odin-list-search-control .odin-search-facet-clear {
        display: none;
    }

    .odin-list-search-control .form-control {
        grid-column: 2;
        grid-row: 2;
        display: block;
        min-width: 0;
        min-height: var(--ganal-control-height-sm);
        padding: 0;
        border: 0;
        background: transparent;
        color: var(--ganal-color-text);
        font-size: calc(var(--bs-body-font-size) + .0625rem);
    }

    .odin-list-search-control .form-control::placeholder {
        color: var(--ganal-color-text-subtle);
    }

    .odin-list-search-control:not(:has(.odin-search-facets)) {
        grid-template-rows: var(--ganal-touch-target);
        min-height: var(--ganal-touch-target);
        padding-block: 0;
    }

    .odin-list-search-control:not(:has(.odin-search-facets)) > .bi,
    .odin-list-search-control:not(:has(.odin-search-facets)) .form-control,
    .odin-list-search-control:not(:has(.odin-search-facets)) .odin-list-filter-toggle {
        grid-row: 1;
    }

    .odin-list-search-control:not(:has(.odin-search-facets)) .form-control {
        min-height: calc(var(--ganal-control-height) - 2px);
    }

    .odin-list-search-control:not(:has(.odin-list-filter-toggle)) {
        grid-template-columns: var(--ganal-touch-target) minmax(0, 1fr);
    }

    .odin-list-filter-toggle {
        grid-column: 3;
        grid-row: 1 / span 2;
        align-self: center;
        display: inline-flex;
        flex: 0 0 var(--ganal-touch-target);
        width: var(--ganal-touch-target);
        min-width: var(--ganal-touch-target);
        height: var(--ganal-touch-target);
        min-height: var(--ganal-touch-target);
        margin-left: 0;
        border: 1px solid var(--ganal-color-secondary-border);
        border-radius: var(--ganal-radius-control);
        background: var(--ganal-color-secondary-bg);
        color: var(--ganal-color-text);
    }

    .odin-list-search-form:has(.odin-filter-panel.show) .odin-list-filter-toggle {
        border-color: var(--ganal-color-primary);
        background: var(--ganal-color-secondary-active-bg);
        color: var(--ganal-color-text);
    }

    .odin-list-search-form:has(.odin-filter-panel.show) .odin-list-filter-toggle .bi {
        transform: rotate(180deg);
    }

    .odin-list-search-form .odin-filter-panel {
        width: 100%;
        margin-top: .75rem;
    }

    .odin-list-search-form .odin-search-panel,
    .odin-list-search-form .odin-search-panel--filters-only {
        grid-template-columns: 1fr;
        margin-top: 0;
        padding: 0;
        border: 1px solid var(--ganal-color-control-border);
        border-radius: var(--ganal-radius-surface);
        background: var(--ganal-color-surface);
        overflow: visible;
    }

    .odin-list-search-form .odin-filter-multiselect .dropdown-menu {
        z-index: 30;
    }

    .odin-list-search-form .odin-search-panel-section {
        padding: 1rem .75rem .75rem;
        border-left: 0;
        border-top: 1px solid var(--ganal-color-border-soft);
    }

    .odin-list-search-form .odin-search-panel-section:first-child {
        border-top: 0;
    }

    .odin-list-search-form .odin-search-panel-title {
        gap: .5rem;
        margin-bottom: .75rem;
        color: var(--ganal-color-text);
        font-size: calc(var(--bs-body-font-size) + .25rem);
        font-weight: 700;
    }

    .odin-list-search-form .odin-search-panel-title i {
        color: var(--ganal-color-primary);
        font-size: var(--bs-body-font-size);
    }

    .odin-list-search-form .odin-search-panel-section-body {
        display: block;
    }
}
.odin-search-facets {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
}

.odin-search-facet {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    max-width: 260px;
    min-height: 26px;
    padding: .12rem .65rem;
    border-radius: var(--ganal-radius-pill);
    background: var(--bs-gray-300);
    color: var(--ganal-color-text);
    font-size: .82rem;
    font-weight: 600;
    line-height: 1.3333;
    text-decoration: none;
    white-space: nowrap;
}

.odin-search-facet:hover,
.odin-search-facet:focus {
    background: var(--ganal-color-surface);
}

.odin-search-facet-label {
    color: var(--ganal-color-text-muted);
    font-size: .72rem;
    font-weight: 800;
    text-transform: uppercase;
}

.odin-search-facet span:not(.odin-search-facet-label) {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}
.odin-search-facet-clear {
    width: 26px;
    flex: 0 0 26px;
    justify-content: center;
    padding-inline: 0;
    font-weight: 700;
}
.odin-icon-button {
    width: var(--ganal-icon-button-size);
    min-width: var(--ganal-icon-button-size);
    height: var(--ganal-icon-button-size);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border-color: var(--ganal-color-border);
    background: var(--ganal-color-secondary-bg);
    color: var(--ganal-color-text-muted);
}

.odin-icon-button:hover,
.odin-icon-button:focus {
    background: var(--ganal-color-surface-hover);
    color: var(--ganal-color-primary);
}

.odin-icon-button:focus-visible {
    box-shadow: var(--ganal-focus-ring);
    outline: 0;
}

@media (max-width: 767.98px) {
    .btn,
    .btn-sm {
        min-height: var(--ganal-touch-target);
        padding: 3px 7px;
    }

    .btn-lg {
        min-height: 44px;
        padding: 8px 16px;
    }

    .odin-icon-button,
    .odin-pager-button {
        width: 40px;
        min-width: 40px;
        height: 40px;
    }

    .form-control,
    .form-select {
        min-height: 40px;
    }

    .odin-search-facet {
        min-height: 30px;
	}

	.odin-copy-inline {
		min-height: calc(var(--ganal-control-height)-5px);
		margin-left:0;
		padding: 0 5px;
    }
}
.odin-record-form {
    max-width: 980px;
    border-color: var(--ganal-color-border-soft);
    box-shadow: none;
}

.odin-record-body {
    display: grid;
    grid-template-columns: 130px minmax(0, 1fr);
    gap: 16px;
    align-items: start;
}

.odin-record-icon-panel {
    display: grid;
    width: 130px;
    aspect-ratio: 1;
    place-items: center;
    align-content: center;
    gap: .45rem;
    border: 1px solid var(--ganal-color-border);
    border-radius: var(--ganal-radius-control);
    color: var(--ganal-color-text-muted);
    background: var(--ganal-color-surface-muted);
}

.odin-record-icon-panel .bi {
    color: var(--ganal-color-primary);
    font-size: 2.8rem;
    line-height: 1;
}

.odin-record-icon-panel span {
    color: var(--ganal-color-text-muted);
    font-size: .72rem;
    font-weight: 800;
    letter-spacing: .08em;
}

.odin-record-identity {
    min-width: 0;
}

.odin-record-title-input {
    display: block;
    width: 100%;
    min-height: 48px;
    padding: 0 0 4px;
    border: 0;
    border-bottom: 1px solid transparent;
    border-radius: 0;
    color: var(--ganal-color-text);
    background: transparent;
    font-size: 2rem;
    font-weight: 500;
    line-height: 1.2;
}

.odin-record-title-input:hover,
.odin-record-title-input:focus {
    border-bottom-color: var(--ganal-color-control-focus-border);
    outline: 0;
}

.odin-record-title-input::placeholder {
    color: var(--ganal-color-text-subtle);
}

.odin-record-meta-lines {
    display: grid;
    gap: .2rem;
    margin-top: .35rem;
    max-width: 760px;
}

.odin-record-meta-line {
    display: grid;
    grid-template-columns: 18px 110px minmax(0, 1fr);
    gap: .55rem;
    align-items: center;
    min-height: 31px;
}

.odin-record-meta-line > .bi {
    color: var(--ganal-color-text-muted);
    font-size: .92rem;
    text-align: center;
}

.odin-record-meta-line label,
.odin-record-field-label {
    margin: 0;
    color: var(--ganal-color-text);
    font-size: .88rem;
    font-weight: 700;
}

.odin-record-inline-control.form-control,
.odin-record-inline-control.form-select {
    min-height: 31px;
    padding: 2px 0;
    border: 0;
    border-bottom: 1px solid transparent;
    border-radius: 0;
    color: var(--ganal-color-text);
    background-color: transparent;
    box-shadow: none;
}

.odin-record-inline-control.form-select {
    padding-right: 1.5rem;
    background-position: right .15rem center;
}

.odin-record-inline-control.form-control:hover,
.odin-record-inline-control.form-control:focus {
    border-bottom-color: var(--ganal-color-control-focus-border);
    box-shadow: none;
}

.odin-record-inline-control.form-select:hover,
.odin-record-inline-control.form-select:focus {
    border-bottom-color: transparent;
    box-shadow: none;
}

.odin-record-check {
    display: inline-flex;
    align-items: center;
    min-height: 31px;
    gap: .45rem;
    margin: 0;
    padding-left: 0;
}

.odin-record-check .form-check-input {
    float: none;
    margin: 0;
}

.odin-record-check .form-check-label {
    color: var(--ganal-color-text-muted);
    font-size: .88rem;
}

.odin-record-html-section {
    margin-top: 1.35rem;
    padding-top: 1rem;
    border-top: 1px solid var(--ganal-color-border-soft);
}

.odin-record-section-title {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    margin-bottom: .5rem;
    color: var(--ganal-color-text);
    font-size: .9rem;
    font-weight: 800;
}

.odin-record-section-title label {
    margin: 0;
}

.odin-record-form .odin-html-editor-surface {
    min-height: 260px;
}

@media (max-width: 767.98px) {
    .odin-record-body {
        grid-template-columns: 1fr;
        gap: 12px;
    }

    .odin-record-icon-panel {
        width: 88px;
        aspect-ratio: 1;
    }

    .odin-record-icon-panel .bi {
        font-size: 2rem;
    }

    .odin-record-title-input {
        min-height: 42px;
        font-size: 1.55rem;
    }

    .odin-record-meta-line {
        grid-template-columns: 18px minmax(84px, 32%) minmax(0, 1fr);
        gap: .45rem;
    }
}
