/*
 * Huckleberry admin skin.
 *
 * Layered over AdminLTE rather than replacing it: every screen keeps working
 * if this file is removed, which is what makes it safe to change.
 *
 * Three rules held throughout:
 *
 *  1. No web fonts and no external requests. The panel is used from a
 *     warehouse on a patchy connection, and a back office that waits on
 *     someone else's font server is a back office that feels broken.
 *  2. Contrast before decoration. Staff read this all day; a table has to be
 *     scannable at a glance, and grey-on-grey is not.
 *  3. Motion is small and can be switched off. Anything that moves respects
 *     `prefers-reduced-motion`.
 */

:root {
    /*
     * Indigo, with an amber accent held in reserve.
     *
     * Indigo carries every primary action and active state — links, buttons,
     * focus rings, the sidebar's "you are here" marker. Amber is kept for the
     * handful of places something is meant to catch the eye ahead of
     * everything around it: today's takings, cash still with a courier. Used
     * as a general-purpose colour it would stop meaning that.
     */
    --hb-brand: #4f46e5;
    --hb-brand-dark: #4338ca;
    --hb-brand-light: #6366f1;
    --hb-brand-soft: #eef2ff;
    --hb-brand-tint: rgba(79, 70, 229, 0.12);

    --hb-gold: #d97706;
    --hb-gold-dark: #b45309;
    --hb-gold-light: #f59e0b;
    --hb-gold-soft: #fffbeb;
    --hb-gold-tint: rgba(217, 119, 6, 0.14);

    /* Neutral slate, with no colour cast of its own. */
    --hb-ink: #111827;
    --hb-body: #374151;
    --hb-muted: #6b7280;
    --hb-line: #e5e7eb;
    --hb-line-soft: #f3f4f6;
    --hb-surface: #ffffff;
    --hb-canvas: #f7f8fa;

    /* The sidebar is a near-black slate rather than the content's white:
       darker than everything else, so it reads as the fixed anchor it is. */
    --hb-sidebar: #161821;
    --hb-sidebar-deep: #101219;
    --hb-sidebar-hover: #232636;
    --hb-sidebar-text: #c7cbd9;
    --hb-sidebar-muted: #7d8299;

    --hb-success: #16a34a;
    --hb-warning: #d97706;
    --hb-danger: #dc2626;
    --hb-info: #0891b2;

    --hb-radius: 14px;
    --hb-radius-sm: 9px;

    --hb-shadow-sm: 0 1px 2px rgba(17, 24, 39, 0.05);
    --hb-shadow: 0 1px 3px rgba(17, 24, 39, 0.06), 0 6px 16px rgba(17, 24, 39, 0.06);
    --hb-shadow-lg: 0 10px 34px rgba(17, 24, 39, 0.16);

    --hb-ease: cubic-bezier(0.2, 0, 0.2, 1);
}

/*
|------------------------------------------------------------------------------
| Typography
|------------------------------------------------------------------------------
| The system stack, so text renders in whatever the operating system already
| considers readable — and renders instantly, with no font file to fetch and no
| flash of unstyled text. Bangla falls through to the platform's own font.
*/

body,
.wrapper {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
        'Helvetica Neue', 'Noto Sans Bengali', Arial, sans-serif;
    font-size: 14px;
    line-height: 1.55;
    color: var(--hb-body);
    background-color: var(--hb-canvas);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    color: var(--hb-ink);
    font-weight: 650;
    letter-spacing: -0.011em;
}

.content-header h1 {
    font-size: 1.4rem;
    font-weight: 680;
}

.content-header h1 small {
    font-weight: 400;
    font-size: 0.9rem;
    color: var(--hb-muted);
}

/* Numbers in tables line up when they share a width. */
.text-right,
td.text-right,
.info-box-number,
.small-box h3 {
    font-variant-numeric: tabular-nums;
}

code {
    background: var(--hb-line-soft);
    color: var(--hb-brand-dark);
    padding: 0.1rem 0.35rem;
    border-radius: 4px;
    font-size: 86%;
}

/*
|------------------------------------------------------------------------------
| Sidebar
|------------------------------------------------------------------------------
*/

.main-sidebar {
    background: linear-gradient(180deg, var(--hb-sidebar) 0%, var(--hb-sidebar-deep) 100%);
    box-shadow: inset -1px 0 0 rgba(255, 255, 255, 0.06);
}

.main-sidebar .brand-link {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.65rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    color: #fff;
    padding: 0.9rem 1rem;
}

/*
 * AdminLTE's own `.brand-image` rules assume a specific stock logo's
 * proportions — negative margins, a float, a fixed max-height tuned to a
 * 33px image — which fought this SVG's own sizing and were the actual cause
 * of the broken-looking mark next to the wordmark. Reset to plain box sizing
 * inside the flex row above instead of layering another patch on top.
 */
.main-sidebar .brand-link .brand-image {
    float: none;
    margin: 0;
    width: 30px;
    height: 30px;
    max-height: none;
    flex: 0 0 auto;
}

.main-sidebar .brand-link .brand-text {
    line-height: 1.2;
}

/*
 * The shop's own uploaded logo, shown instead of `.brand-image` + wordmark
 * once one exists (see the brand-logo-xs override). Sized to the sidebar's
 * width rather than the 30px icon slot above — a real logo is wide, not
 * square, and needs room to stay legible.
 */
.main-sidebar .brand-link .brand-image-full {
    max-width: 100%;
    max-height: 40px;
    width: auto;
    height: auto;
    object-fit: contain;
}

.brand-wordmark {
    color: #fff;
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: 0.01em;
}

.sidebar .nav-sidebar > .nav-item {
    margin-bottom: 1px;
}

.sidebar .nav-sidebar .nav-link {
    color: var(--hb-sidebar-text);
    border-radius: var(--hb-radius-sm);
    padding: 0.5rem 0.75rem;
    font-size: 0.875rem;
    transition: background-color 140ms var(--hb-ease), color 140ms var(--hb-ease);
}

.sidebar .nav-sidebar .nav-link p {
    font-weight: 500;
}

.sidebar .nav-sidebar .nav-link .nav-icon {
    color: var(--hb-sidebar-muted);
    transition: color 140ms var(--hb-ease);
}

.sidebar .nav-sidebar .nav-link:hover {
    background-color: var(--hb-sidebar-hover);
    color: #fff;
}

.sidebar .nav-sidebar .nav-link:hover .nav-icon {
    color: var(--hb-sidebar-text);
}

/*
 * The active item is marked by a bar down its edge rather than a filled block.
 * With a dozen sections open at once, filled highlights turn the sidebar into
 * a patchwork and stop meaning "you are here".
 */
.sidebar .nav-sidebar .nav-link.active,
.sidebar .nav-sidebar .nav-link.active:hover {
    background-color: rgba(255, 255, 255, 0.07);
    color: #fff;
    box-shadow: inset 3px 0 0 var(--hb-brand-light);
    font-weight: 600;
}

.sidebar .nav-sidebar .nav-link.active .nav-icon {
    color: var(--hb-brand-light);
}

.sidebar .nav-treeview > .nav-item > .nav-link {
    padding-left: 2.2rem;
    font-size: 0.84rem;
    color: var(--hb-sidebar-muted);
}

.sidebar .nav-treeview > .nav-item > .nav-link:hover,
.sidebar .nav-treeview > .nav-item > .nav-link.active {
    color: #fff;
    background-color: transparent;
    box-shadow: none;
}

.sidebar .nav-treeview > .nav-item > .nav-link.active p {
    font-weight: 600;
}

.nav-sidebar .nav-header {
    color: var(--hb-sidebar-muted);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    padding: 1.1rem 1rem 0.35rem;
}

/*
|------------------------------------------------------------------------------
| Top bar
|------------------------------------------------------------------------------
*/

.main-header.navbar {
    background-color: var(--hb-surface);
    border-bottom: 1px solid var(--hb-line);
    box-shadow: var(--hb-shadow-sm);
}

.main-header .nav-link {
    color: var(--hb-body);
}

.main-header .nav-link:hover {
    color: var(--hb-ink);
}

/*
|------------------------------------------------------------------------------
| Cards
|------------------------------------------------------------------------------
*/

.card {
    background: var(--hb-surface);
    border: 1px solid var(--hb-line);
    border-radius: var(--hb-radius);
    box-shadow: var(--hb-shadow-sm);
    margin-bottom: 1.25rem;
}

.card-header {
    background: transparent;
    border-bottom: 1px solid var(--hb-line-soft);
    padding: 0.9rem 1.15rem;
}

.card-title {
    display: flex;
    align-items: center;
    font-size: 0.95rem;
    font-weight: 650;
    color: var(--hb-ink);
    margin: 0;
}

.card-body {
    padding: 1.15rem;
}

.card-footer {
    background: var(--hb-canvas);
    border-top: 1px solid var(--hb-line-soft);
    padding: 0.85rem 1.15rem;
}

/* AdminLTE's coloured outline cards, softened to a single top edge. */
.card.card-outline {
    border-top-width: 3px;
}

.card.card-primary.card-outline { border-top-color: var(--hb-brand); }
.card.card-success.card-outline { border-top-color: var(--hb-success); }
.card.card-warning.card-outline { border-top-color: var(--hb-warning); }
.card.card-danger.card-outline  { border-top-color: var(--hb-danger); }
.card.card-info.card-outline    { border-top-color: var(--hb-info); }

/*
|------------------------------------------------------------------------------
| Statistic boxes
|------------------------------------------------------------------------------
*/

.small-box,
.info-box {
    border-radius: var(--hb-radius);
    box-shadow: var(--hb-shadow-sm);
    border: 1px solid var(--hb-line);
}

.info-box {
    background: var(--hb-surface);
    min-height: 84px;
    padding: 0.9rem 1.1rem;
}

.info-box .info-box-text {
    color: var(--hb-muted);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.info-box .info-box-number {
    color: var(--hb-ink);
    font-size: 1.45rem;
    font-weight: 680;
    line-height: 1.3;
}

.info-box .info-box-icon {
    border-radius: var(--hb-radius-sm);
    width: 54px;
    height: 54px;
    line-height: 54px;
    font-size: 1.25rem;
    margin-right: 0.9rem;
}

.small-box {
    border: 0;
}

.small-box h3 {
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -0.02em;
}

.small-box p {
    font-size: 0.85rem;
    opacity: 0.92;
}

.small-box .icon > i {
    opacity: 0.22;
    font-size: 4.5rem;
    top: 12px;
    right: 14px;
}

.small-box:hover .icon > i {
    opacity: 0.3;
}

/*
|------------------------------------------------------------------------------
| Buttons
|------------------------------------------------------------------------------
| Flat, with a clear hover and a visible focus ring. The ring matters more
| than it looks: staff move through these forms by keyboard, and a control you
| cannot see the focus on is a control you cannot use without a mouse.
*/

.btn {
    border-radius: var(--hb-radius-sm);
    font-weight: 550;
    font-size: 0.875rem;
    padding: 0.42rem 0.95rem;
    border-width: 1px;
    transition: background-color 130ms var(--hb-ease), border-color 130ms var(--hb-ease),
        box-shadow 130ms var(--hb-ease), transform 90ms var(--hb-ease);
}

.btn:active {
    transform: translateY(1px);
}

.btn:focus,
.btn.focus,
.btn:focus-visible {
    box-shadow: 0 0 0 3px var(--hb-brand-tint);
    outline: none;
}

.btn-primary {
    background-color: var(--hb-brand);
    border-color: var(--hb-brand);
}

.btn-primary:hover,
.btn-primary:focus {
    background-color: var(--hb-brand-dark);
    border-color: var(--hb-brand-dark);
}

.btn-default {
    background-color: var(--hb-surface);
    border-color: var(--hb-line);
    color: var(--hb-body);
}

.btn-default:hover {
    background-color: var(--hb-canvas);
    border-color: #d1d5db;
    color: var(--hb-ink);
}

.btn-success { background-color: var(--hb-success); border-color: var(--hb-success); }
.btn-danger  { background-color: var(--hb-danger);  border-color: var(--hb-danger); }
.btn-warning { background-color: var(--hb-warning); border-color: var(--hb-warning); color: #fff; }
.btn-info    { background-color: var(--hb-info);    border-color: var(--hb-info); }

.btn-warning:hover { color: #fff; }

.btn-xs {
    padding: 0.18rem 0.5rem;
    font-size: 0.775rem;
    border-radius: 5px;
}

.btn-sm {
    padding: 0.3rem 0.7rem;
    font-size: 0.82rem;
}

.btn-link {
    color: var(--hb-brand);
    font-weight: 550;
}

.btn-link:hover {
    color: var(--hb-brand-dark);
}

/*
|------------------------------------------------------------------------------
| Forms
|------------------------------------------------------------------------------
*/

label {
    font-weight: 600;
    font-size: 0.82rem;
    color: var(--hb-body);
    margin-bottom: 0.3rem;
}

.form-control,
.custom-select {
    border-radius: var(--hb-radius-sm);
    border: 1px solid var(--hb-line);
    color: var(--hb-ink);
    font-size: 0.875rem;
    padding: 0.45rem 0.7rem;
    height: auto;
    transition: border-color 130ms var(--hb-ease), box-shadow 130ms var(--hb-ease);
}

.form-control::placeholder {
    color: #9ca3af;
}

.form-control:focus,
.custom-select:focus {
    border-color: var(--hb-brand-light);
    box-shadow: 0 0 0 3px var(--hb-brand-tint);
}

.form-control.is-invalid,
.is-invalid .form-control {
    border-color: var(--hb-danger);
}

.form-control:disabled,
.form-control[readonly] {
    background-color: var(--hb-line-soft);
    color: var(--hb-muted);
}

.form-text {
    font-size: 0.78rem;
    color: var(--hb-muted);
}

.invalid-feedback {
    font-size: 0.78rem;
    font-weight: 500;
}

.input-group-text {
    background: var(--hb-canvas);
    border-color: var(--hb-line);
    border-radius: var(--hb-radius-sm);
    color: var(--hb-muted);
    font-size: 0.82rem;
}

/*
 * Select2, matched to the native inputs.
 *
 * The theme stylesheet gets most of the way; these close the last gap so a
 * searchable select and a plain one line up on the same row rather than
 * sitting a pixel or two apart, which is what makes a form look unfinished.
 */
.select2-container--bootstrap4 .select2-selection {
    border-radius: var(--hb-radius-sm) !important;
    border-color: var(--hb-line) !important;
    min-height: 36px;
}

.select2-container--bootstrap4.select2-container--focus .select2-selection,
.select2-container--bootstrap4.select2-container--open .select2-selection {
    border-color: var(--hb-brand-light) !important;
    box-shadow: 0 0 0 3px var(--hb-brand-tint);
}

.select2-container--bootstrap4 .select2-selection--single .select2-selection__rendered {
    line-height: 24px;
    color: var(--hb-ink);
}

.select2-container--bootstrap4 .select2-dropdown {
    border-color: var(--hb-line);
    border-radius: var(--hb-radius-sm);
    box-shadow: var(--hb-shadow-lg);
    overflow: hidden;
}

.select2-container--bootstrap4 .select2-results__option--highlighted[aria-selected] {
    background-color: var(--hb-brand);
}

.select2-container--bootstrap4 .select2-selection--multiple .select2-selection__choice {
    background-color: var(--hb-brand-tint);
    border-color: transparent;
    color: var(--hb-brand-dark);
    border-radius: 4px;
    font-size: 0.8rem;
}

/* The native dropdown arrow, so a plain select does not look inert. */
select.form-control:not([multiple]):not([size]) {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%236b7280' d='M4.5 6.5 8 10l3.5-3.5z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.55rem center;
    background-size: 16px;
    padding-right: 1.9rem;
}

.custom-control-input:checked ~ .custom-control-label::before {
    background-color: var(--hb-brand);
    border-color: var(--hb-brand);
}

.custom-control-input:focus ~ .custom-control-label::before {
    box-shadow: 0 0 0 3px var(--hb-brand-tint);
}

/*
|------------------------------------------------------------------------------
| Tables
|------------------------------------------------------------------------------
*/

.table {
    color: var(--hb-body);
    margin-bottom: 0;
}

.table thead th {
    background: var(--hb-canvas);
    border-bottom: 1px solid var(--hb-line);
    border-top: 0;
    color: var(--hb-muted);
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.045em;
    text-transform: uppercase;
    padding: 0.65rem 0.9rem;
    white-space: nowrap;
}

.table td {
    border-top: 1px solid var(--hb-line-soft);
    padding: 0.7rem 0.9rem;
    vertical-align: middle;
}

.table-hover tbody tr {
    transition: background-color 110ms var(--hb-ease);
}

.table-hover tbody tr:hover {
    background-color: var(--hb-brand-tint);
}

.table-hover tbody tr[data-href] {
    cursor: pointer;
}

.table-sm td,
.table-sm th {
    padding: 0.45rem 0.7rem;
}

/* Row states, muted so a warning row is readable rather than shouted. */
.table .table-warning,
.table .table-warning > td { background-color: #fdf6e7; }
.table .table-danger,
.table .table-danger > td { background-color: #fdeeee; }

/*
|------------------------------------------------------------------------------
| Badges, alerts and callouts
|------------------------------------------------------------------------------
*/

.badge {
    font-weight: 600;
    font-size: 0.72rem;
    letter-spacing: 0.02em;
    padding: 0.32em 0.6em;
    border-radius: 5px;
}

.badge-primary   { background-color: var(--hb-brand); }
.badge-success   { background-color: var(--hb-success); }
.badge-warning   { background-color: var(--hb-warning); color: #fff; }
.badge-danger    { background-color: var(--hb-danger); }
.badge-info      { background-color: var(--hb-info); }
.badge-secondary { background-color: #9ca3af; }

.alert,
.callout {
    border-radius: var(--hb-radius-sm);
    border: 1px solid var(--hb-line);
    box-shadow: none;
    font-size: 0.875rem;
    padding: 0.85rem 1.05rem;
}

.callout {
    border-left-width: 3px;
    background: var(--hb-surface);
    margin-bottom: 1.25rem;
}

.callout.callout-info    { border-left-color: var(--hb-info); }
.callout.callout-success { border-left-color: var(--hb-success); }
.callout.callout-warning { border-left-color: var(--hb-warning); }
.callout.callout-danger  { border-left-color: var(--hb-danger); }

/*
|------------------------------------------------------------------------------
| Modals and dropdowns
|------------------------------------------------------------------------------
*/

.modal-content {
    border: 0;
    border-radius: var(--hb-radius);
    box-shadow: var(--hb-shadow-lg);
}

.modal-header {
    border-bottom: 1px solid var(--hb-line-soft);
    padding: 1rem 1.25rem;
}

.modal-title {
    font-size: 1rem;
    font-weight: 650;
    color: var(--hb-ink);
}

.modal-footer {
    border-top: 1px solid var(--hb-line-soft);
    padding: 0.85rem 1.25rem;
}

.dropdown-menu {
    border: 1px solid var(--hb-line);
    border-radius: var(--hb-radius-sm);
    box-shadow: var(--hb-shadow-lg);
    padding: 0.35rem;
    font-size: 0.875rem;
}

.dropdown-item {
    border-radius: 5px;
    padding: 0.45rem 0.65rem;
    color: var(--hb-body);
}

.dropdown-item:hover,
.dropdown-item:focus {
    background-color: var(--hb-brand-tint);
    color: var(--hb-brand-dark);
}

.dropdown-divider {
    border-color: var(--hb-line-soft);
}

/*
|------------------------------------------------------------------------------
| Pagination, tabs, toasts
|------------------------------------------------------------------------------
*/

.pagination {
    margin-bottom: 0;
    flex-wrap: wrap;
    gap: 2px;
}

.page-link {
    border-color: var(--hb-line);
    color: var(--hb-body);
    border-radius: 6px;
    font-size: 0.85rem;
    min-width: 34px;
    text-align: center;
    padding: 0.35rem 0.6rem;
    transition: background-color 120ms var(--hb-ease), border-color 120ms var(--hb-ease);
}

/*
 * The previous and next arrows.
 *
 * Laravel renders them as the entities « and », which are typographically
 * small and sit high in the line. Nudged down and given a little weight so
 * they read as buttons rather than stray punctuation.
 */
.page-item:first-child .page-link,
.page-item:last-child .page-link {
    font-size: 1rem;
    line-height: 1.2;
    font-weight: 600;
    padding: 0.28rem 0.7rem;
}

.page-item.disabled .page-link {
    color: #9ca3af;
    background: var(--hb-canvas);
    border-color: var(--hb-line-soft);
}

.page-item.active .page-link {
    background-color: var(--hb-brand);
    border-color: var(--hb-brand);
}

.page-link:hover {
    background-color: var(--hb-canvas);
    color: var(--hb-ink);
}

.nav-tabs {
    border-bottom: 1px solid var(--hb-line);
}

.nav-tabs .nav-link {
    border: 0;
    border-bottom: 2px solid transparent;
    color: var(--hb-muted);
    font-weight: 600;
    font-size: 0.875rem;
    padding: 0.55rem 0.9rem;
}

.nav-tabs .nav-link:hover {
    border-bottom-color: var(--hb-line);
    color: var(--hb-ink);
}

.nav-tabs .nav-link.active {
    color: var(--hb-brand);
    border-bottom-color: var(--hb-brand);
    background: transparent;
}

/*
 * Toasts, top right.
 *
 * Sized to be read at a glance and dismissed by ignoring: a save
 * confirmation should never be something you have to click away before
 * carrying on.
 */
.swal2-container.swal2-top-end {
    padding: 0.85rem;
}

.hb-toast.swal2-popup {
    border: 1px solid var(--hb-line);
    border-radius: var(--hb-radius-sm);
    box-shadow: var(--hb-shadow-lg);
    padding: 0.7rem 0.9rem;
    font-size: 0.875rem;
    grid-column: auto !important;
    align-items: center;
}

.hb-toast .swal2-title {
    font-size: 0.875rem;
    font-weight: 550;
    color: var(--hb-ink);
    margin: 0;
    padding: 0;
    line-height: 1.4;
}

.hb-toast .swal2-icon {
    width: 1.6em;
    height: 1.6em;
    margin: 0 0.6rem 0 0;
    border-width: 2px;
}

.hb-toast .swal2-close {
    font-size: 1.4rem;
    color: var(--hb-muted);
    margin-left: 0.4rem;
}

.hb-toast .swal2-close:focus {
    box-shadow: none;
    outline: 2px solid var(--hb-brand-light);
}

/* The house colours rather than SweetAlert's defaults. */
.hb-toast .swal2-icon.swal2-success {
    border-color: var(--hb-success);
    color: var(--hb-success);
}

.hb-toast .swal2-icon.swal2-success [class^='swal2-success-line'] {
    background-color: var(--hb-success);
}

.hb-toast .swal2-icon.swal2-success .swal2-success-ring {
    border-color: rgba(22, 163, 74, 0.3);
}

.hb-toast .swal2-icon.swal2-error {
    border-color: var(--hb-danger);
    color: var(--hb-danger);
}

.hb-toast .swal2-icon.swal2-error [class^='swal2-x-mark-line'] {
    background-color: var(--hb-danger);
}

.hb-toast .swal2-icon.swal2-warning {
    border-color: var(--hb-gold);
    color: var(--hb-gold-dark);
}

.hb-toast .swal2-icon.swal2-info {
    border-color: var(--hb-info);
    color: var(--hb-info);
}

.hb-toast .swal2-timer-progress-bar {
    background: var(--hb-brand-light);
}

/*
|------------------------------------------------------------------------------
| Page transition
|------------------------------------------------------------------------------
| The sidebar and the top bar never move. Only the content area animates, and
| only on the way in — a shell that flashes on every click makes a fast
| application feel slow and makes it hard to keep your place.
|
| Short and slight on purpose: 180ms and 6px. Long enough to soften the swap,
| short enough that nobody waiting on it notices they are waiting.
|
| The fill mode is `backwards`, never `forwards` or `both`, and that is not a
| detail. A filling animation keeps applying its last keyframe, and `transform:
| none` inside a keyframe does not compute to the keyword `none` — it computes
| to `matrix(1, 0, 0, 1, 0, 0)`. Any computed transform makes the element the
| containing block for its `position: fixed` descendants, so with `both` this
| animation quietly turned every modal on the site from viewport-fixed into
| something positioned against `.content` — off-screen on a tall page, leaving
| a dimmed backdrop over a screen with no visible dialog on it.
|
| `backwards` fills only before the delay, which is all this needs: it hides
| the content during the 25ms wait. Once the animation is over it stops
| applying, and the element is left with no transform at all.
*/

.content-wrapper > .content-header,
.content-wrapper > .content {
    animation: hb-page-in 180ms var(--hb-ease) backwards;
}

.content-wrapper > .content {
    animation-delay: 25ms;
}

@keyframes hb-page-in {
    from {
        opacity: 0;
        transform: translateY(6px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Some people get motion sick, and some just find it distracting. */
@media (prefers-reduced-motion: reduce) {
    .content-wrapper > .content-header,
    .content-wrapper > .content {
        animation: none;
    }

    *,
    *::before,
    *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
    }
}

/*
|------------------------------------------------------------------------------
| Odds and ends
|------------------------------------------------------------------------------
*/

.main-footer {
    background: var(--hb-surface);
    border-top: 1px solid var(--hb-line);
    color: var(--hb-muted);
    font-size: 0.82rem;
    padding: 0.85rem 1rem;
}

.text-muted {
    color: var(--hb-muted) !important;
}

/* Bootstrap 4 has no min-width utility; a flex child needs one to truncate
   its text instead of forcing the row wider than the column. */
.min-width-0 {
    min-width: 0;
}

hr {
    border-color: var(--hb-line-soft);
}

/* A focus ring on anything reachable by keyboard, not only buttons. */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--hb-brand-light);
    outline-offset: 2px;
    border-radius: 3px;
}

/* Scrollbars, on the platforms that let us style them. */
* {
    scrollbar-width: thin;
    scrollbar-color: #d1d5db transparent;
}

*::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

*::-webkit-scrollbar-thumb {
    background-color: #d1d5db;
    border-radius: 6px;
    border: 2px solid transparent;
    background-clip: content-box;
}

*::-webkit-scrollbar-thumb:hover {
    background-color: #6b7280;
}

/* Print: the panel prints invoices and picking lists. */
@media print {
    .main-sidebar,
    .main-header,
    .main-footer,
    .btn,
    .no-print {
        display: none !important;
    }

    .content-wrapper {
        margin-left: 0 !important;
        background: #fff;
    }

    .card {
        border: 0;
        box-shadow: none;
    }
}

/*
|------------------------------------------------------------------------------
| Charts
|------------------------------------------------------------------------------
| The holder has a fixed height and the canvas fills it.
|
| This is not decoration. Chart.js with `responsive: true` and
| `maintainAspectRatio: false` sizes the canvas from its parent; if the parent
| has no height of its own it takes its height from the canvas, and the two
| push each other a few pixels taller on every resize until the chart runs off
| the bottom of the page. A parent with a real height breaks the loop.
*/

.hb-chart-holder {
    position: relative;
    width: 100%;
    height: 260px;
}

.hb-chart-holder > canvas {
    display: block;
    width: 100% !important;
    height: 100% !important;
}

/*
|------------------------------------------------------------------------------
| Gold accents
|------------------------------------------------------------------------------
| Sparingly, and only where something is genuinely worth the eye: the figure a
| dashboard exists to show, a highlighted total, the brand mark. Gold used as a
| general-purpose colour stops looking like gold.
*/

.hb-gold {
    color: var(--hb-gold-dark);
}

.hb-accent-bar {
    height: 3px;
    border-radius: 3px;
    background: linear-gradient(90deg, var(--hb-gold) 0%, var(--hb-brand) 100%);
}

.btn-gold {
    background-color: var(--hb-gold);
    border-color: var(--hb-gold);
    color: #fff;
}

.btn-gold:hover,
.btn-gold:focus {
    background-color: var(--hb-gold-dark);
    border-color: var(--hb-gold-dark);
    color: #fff;
}

.badge-gold {
    background-color: var(--hb-gold-tint);
    color: var(--hb-gold-dark);
}

/*
|------------------------------------------------------------------------------
| Dashboard
|------------------------------------------------------------------------------
*/

/* The headline figures: one card, subdivided, rather than four floating tiles. */
.hb-section-title {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--hb-ink);
}

.hb-kpi {
    background: var(--hb-surface);
    border: 1px solid var(--hb-line);
    border-radius: var(--hb-radius);
    box-shadow: var(--hb-shadow-sm);
    overflow: hidden;
}

/*
 * The selector is deliberately specific. Bootstrap's
 * `.no-gutters > [class*="col-"]` zeroes horizontal padding and beats a plain
 * class, which is why these read flush against the card edge otherwise.
 */
.hb-kpi .row.no-gutters > .hb-kpi__item {
    padding: 1.2rem 1.35rem;
    border-right: 1px solid var(--hb-line-soft);
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
}

.hb-kpi .row.no-gutters > .hb-kpi__item:last-child {
    border-right: 0;
}

.hb-kpi__icon {
    flex: 0 0 38px;
    height: 38px;
    border-radius: 10px;
    display: grid;
    place-items: center;
    font-size: 0.95rem;
    background: var(--hb-brand-soft);
    color: var(--hb-brand);
    margin-top: 0.15rem;
}

.hb-kpi__icon--gold {
    background: var(--hb-gold-soft);
    color: var(--hb-gold-dark);
}

.hb-kpi__icon--danger {
    background: rgba(220, 38, 38, 0.1);
    color: var(--hb-danger);
}

.hb-kpi__icon--success {
    background: rgba(22, 163, 74, 0.1);
    color: var(--hb-success);
}

.hb-kpi__value--danger {
    color: var(--hb-danger);
}

.hb-kpi__value--success {
    color: var(--hb-success);
}

.hb-kpi__body {
    min-width: 0;
}

/* A smaller variant of .hb-kpi for grids denser than four items. */
.hb-kpi--compact .row.no-gutters > .hb-kpi__item {
    padding: 0.95rem 1.1rem;
}

.hb-kpi--compact .hb-kpi__icon {
    flex: 0 0 34px;
    height: 34px;
    font-size: 0.85rem;
}

.hb-kpi--compact .hb-kpi__value {
    font-size: 1.25rem;
}

@media (max-width: 991.98px) {
    .hb-kpi .row.no-gutters > .hb-kpi__item {
        border-right: 0;
        border-bottom: 1px solid var(--hb-line-soft);
    }

    .hb-kpi .row.no-gutters > .hb-kpi__item:last-child {
        border-bottom: 0;
    }
}

.hb-kpi__label {
    color: var(--hb-muted);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    margin-bottom: 0.35rem;
}

.hb-kpi__value {
    color: var(--hb-ink);
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.02em;
}

.hb-kpi__value--gold {
    color: var(--hb-gold-dark);
}

.hb-kpi__meta {
    font-size: 0.78rem;
    color: var(--hb-muted);
    margin-top: 0.3rem;
}

.hb-kpi__delta {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    font-weight: 650;
    font-size: 0.78rem;
    padding: 0.1rem 0.4rem;
    border-radius: 5px;
}

.hb-kpi__delta--up {
    color: var(--hb-success);
    background: rgba(22, 163, 74, 0.1);
}

.hb-kpi__delta--down {
    color: var(--hb-danger);
    background: rgba(220, 38, 38, 0.1);
}

/* The work queue: a row of things that need doing, each one a link. */
.hb-queue {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.85rem 1rem;
    border: 1px solid var(--hb-line);
    border-radius: var(--hb-radius-sm);
    background: var(--hb-surface);
    color: inherit;
    transition: border-color 130ms var(--hb-ease), box-shadow 130ms var(--hb-ease),
        transform 130ms var(--hb-ease);
    height: 100%;
}

a.hb-queue:hover {
    border-color: var(--hb-brand-light);
    box-shadow: var(--hb-shadow);
    transform: translateY(-1px);
    color: inherit;
    text-decoration: none;
}

.hb-queue__icon {
    flex: 0 0 40px;
    height: 40px;
    border-radius: 10px;
    display: grid;
    place-items: center;
    font-size: 1rem;
    background: var(--hb-brand-soft);
    color: var(--hb-brand);
}

.hb-queue__icon--gold  { background: var(--hb-gold-soft); color: var(--hb-gold-dark); }
.hb-queue__icon--alert { background: rgba(220, 38, 38, 0.1); color: var(--hb-danger); }

.hb-queue__count {
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--hb-ink);
    line-height: 1.1;
}

.hb-queue__label {
    font-size: 0.78rem;
    color: var(--hb-muted);
}

/* A quiet row list, for "best sellers" and "running out". */
.hb-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.hb-list__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.7rem 1.15rem;
    border-bottom: 1px solid var(--hb-line-soft);
}

.hb-list__row:last-child {
    border-bottom: 0;
}

.hb-list__name {
    font-weight: 550;
    color: var(--hb-ink);
}

.hb-list__meta {
    font-size: 0.78rem;
    color: var(--hb-muted);
}

.hb-empty {
    padding: 2rem 1rem;
    text-align: center;
    color: var(--hb-muted);
    font-size: 0.875rem;
}

/*
|------------------------------------------------------------------------------
| Breadcrumbs
|------------------------------------------------------------------------------
*/

.breadcrumb {
    background: transparent;
    padding: 0;
    margin: 0;
    font-size: 0.8rem;
}

.breadcrumb-item,
.breadcrumb-item a {
    color: var(--hb-muted);
}

.breadcrumb-item a:hover {
    color: var(--hb-brand);
    text-decoration: none;
}

.breadcrumb-item.active {
    color: var(--hb-body);
    font-weight: 550;
}

.breadcrumb-item + .breadcrumb-item::before {
    color: #9ca3af;
    content: '/';
}

/*
|------------------------------------------------------------------------------
| Card icons
|------------------------------------------------------------------------------
| A small coloured chip ahead of a card's title, so a page of several stacked
| cards sorts itself by shape and colour before anyone reads a word — "the
| green one is money, the red one is trouble" — the way a dashboard with a
| dozen panels stays scannable instead of turning into a wall of text.
*/

.hb-card-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: var(--hb-brand-soft);
    color: var(--hb-brand);
    font-size: 0.85rem;
}

.hb-card-icon--gold    { background: var(--hb-gold-soft); color: var(--hb-gold-dark); }
.hb-card-icon--success { background: rgba(22, 163, 74, 0.1); color: var(--hb-success); }
.hb-card-icon--danger  { background: rgba(220, 38, 38, 0.1); color: var(--hb-danger); }
.hb-card-icon--info    { background: rgba(8, 145, 178, 0.1); color: var(--hb-info); }
.hb-card-icon--muted   { background: var(--hb-line-soft); color: var(--hb-muted); }

/*
|------------------------------------------------------------------------------
| Avatars
|------------------------------------------------------------------------------
| A name's initials, on a flat colour circle. Used wherever a person needs to
| be picked out of a list at a glance rather than read — a customer on an
| order row, a chosen customer in the POS. Deliberately not a photo: a table
| of thirty strangers' random avatar photos is noise, and initials never fail
| to load.
*/

.hb-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--hb-brand-soft);
    color: var(--hb-brand-dark);
    font-weight: 700;
    font-size: 0.78rem;
}

.hb-avatar--sm {
    width: 26px;
    height: 26px;
    font-size: 0.68rem;
}

/*
|------------------------------------------------------------------------------
| Filter pills
|------------------------------------------------------------------------------
| A row of one-click presets ahead of the full filter form below it. Most
| visits to a list page are answering one of a handful of recurring
| questions — "what's unpaid?" — and a pill answers that in one click instead
| of a dropdown, a value and a submit.
*/

.hb-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.hb-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.85rem;
    border-radius: 999px;
    border: 1px solid var(--hb-line);
    background: var(--hb-surface);
    color: var(--hb-body);
    font-size: 0.82rem;
    font-weight: 600;
    transition: border-color 130ms var(--hb-ease), background-color 130ms var(--hb-ease),
        color 130ms var(--hb-ease);
}

.hb-pill:hover {
    border-color: var(--hb-brand-light);
    color: var(--hb-ink);
    text-decoration: none;
}

.hb-pill.is-active {
    background: var(--hb-brand);
    border-color: var(--hb-brand);
    color: #fff;
}

.hb-pill__count {
    background: rgba(0, 0, 0, 0.08);
    border-radius: 999px;
    padding: 0.05rem 0.45rem;
    font-size: 0.72rem;
}

.hb-pill.is-active .hb-pill__count {
    background: rgba(255, 255, 255, 0.25);
}

/*
|------------------------------------------------------------------------------
| Sticky table header
|------------------------------------------------------------------------------
| For a list long enough to scroll: the column headings travel with it, so
| the tenth row down is still legible without scrolling back up to check
| which column is which.
*/

.hb-table-sticky thead th {
    position: sticky;
    top: 0;
    z-index: 5;
}

/*
|------------------------------------------------------------------------------
| Timeline
|------------------------------------------------------------------------------
| Replaces AdminLTE's stock `.timeline` widget — a dashed line and stock
| circle icons that read as a demo template rather than part of this system.
| A plain vertical rule and a flat dot in the entry's own colour matches
| everything else on the page instead of standing apart from it.
*/

.hb-timeline {
    position: relative;
    margin: 0;
    padding: 0 0 0 1.6rem;
}

.hb-timeline::before {
    content: '';
    position: absolute;
    top: 4px;
    bottom: 4px;
    left: 5px;
    width: 2px;
    background: var(--hb-line);
}

.hb-timeline__item {
    position: relative;
    padding-bottom: 1.4rem;
}

.hb-timeline__item:last-child {
    padding-bottom: 0;
}

.hb-timeline__dot {
    position: absolute;
    top: 3px;
    left: -1.6rem;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--hb-brand);
    border: 2px solid var(--hb-surface);
    box-shadow: 0 0 0 1px var(--hb-line);
}

.hb-timeline__dot--success { background: var(--hb-success); }
.hb-timeline__dot--info    { background: var(--hb-info); }
.hb-timeline__dot--muted   { background: var(--hb-muted); }

.hb-timeline__time {
    font-size: 0.74rem;
    color: var(--hb-muted);
    display: block;
    margin-bottom: 0.15rem;
}

.hb-timeline__title {
    font-size: 0.875rem;
    color: var(--hb-ink);
    font-weight: 600;
}

.hb-timeline__body {
    font-size: 0.85rem;
    color: var(--hb-body);
    margin-top: 0.25rem;
}
