/*
 * MH Tools — Application CSS
 *
 * Design system (draft 1, 2026-09-15): clarity first.
 * - Bootstrap 5.3 as the base system; overridden through its CSS custom properties.
 * - Brandbook palette (Cloud, Mist, Mint, Sage, Chocolate) for surfaces only; every
 *   colour that carries text or meaning is a darker relative checked against WCAG AA.
 * - Set for readers with dyslexia: Lexend, 16px body, 1.6 line height, no italics,
 *   no capitals, no underlines for emphasis, every status is an icon plus a word.
 * - Flat: thin borders, no shadows except menus and modals, no gradients.
 * - Respect prefers-reduced-motion for all animations.
 */

/* ── Design tokens ──────────────────────────────────────────────────────── */
:root {
    /* Brand surfaces (brandbook) */
    --mh-cloud:     #F5F0ED;   /* Page background */
    --mh-mist:      #E3ECDF;   /* Sidebar, soft panels, hover rows */
    --mh-mint:      #CCD8C8;   /* Table header rule, dividers */
    --mh-sage:      #ADB7AF;   /* Control borders, disabled fills */
    --mh-surface:   #FFFFFF;   /* Cards, tables, inputs */
    --mh-surface-2: #FAF8F6;   /* Zebra rows, tinted cells */

    /* Working colours (derived for contrast) */
    --mh-ink:       #242420;   /* Text. 13.8:1 on Cloud */
    --mh-ink-2:     #5C5A55;   /* Secondary text. 6.1:1 on Cloud */
    --mh-ink-3:     #8C8984;   /* Placeholders, disabled text */
    --mh-brand:       #2F6A50; /* Deep sage: primary buttons, active nav, focus ring */
    --mh-brand-dark:  #26563F; /* Hover / active state */
    --mh-brand-light: #DCEFE0; /* Light tint for banners and editing rows */
    --mh-link:        #256045; /* 7.4:1 on white */
    --mh-accent-text: #6B5344; /* Chocolate, darkened for text (kickers) */
    --mh-danger:      #B3261E; /* Solid danger buttons, error borders */

    /* Layout */
    --mh-sidebar-bg:    var(--mh-mist);
    --mh-sidebar-text:  var(--mh-ink);
    --mh-sidebar-hover: var(--mh-surface);
    --mh-sidebar-width: 264px;
    --mh-header-height: 64px;

    /* Brand tints used by the offer detail tables. */
    --mh-brand-surface:      var(--mh-mist);   /* Alternative-group header row */
    --mh-brand-surface-text: var(--mh-ink-2);  /* Text on --mh-brand-surface */
    --mh-brand-line:         var(--mh-mint);   /* Thin brand-tinted border (alt-group rail, state banner) */

    /* Spacing scale — use instead of ad-hoc rem values. */
    --mh-space-1: 0.25rem;
    --mh-space-2: 0.5rem;
    --mh-space-3: 0.75rem;
    --mh-space-4: 1rem;
    --mh-space-5: 1.5rem;
    --mh-space-6: 2rem;

    /* Radius scale: controls 6px, cards 10px, badges pill */
    --mh-radius-sm: 6px;
    --mh-radius-md: 8px;
    --mh-radius-lg: 10px;

    /* Elevation: flat by default; menus and modals keep Bootstrap's own shadow. */
    --mh-shadow-sm: none;
    --mh-shadow-md: none;

    /* Minimum interactive target for icon-only buttons. */
    --mh-hit-target: 40px;

    /*
     * Semantic status colours. Every badge in the admin resolves through these
     * so offer status, calculation status and sourcing coverage stay coherent.
     * Five tints, one meaning each: neutral, info, ok, warning, danger.
     */
    --mh-status-neutral-bg:  #E6E9E5;
    --mh-status-neutral-fg:  #4B4F4C;
    --mh-status-info-bg:     #D9E7F5;
    --mh-status-info-fg:     #1F4E7A;
    --mh-status-progress-bg: var(--mh-status-info-bg);
    --mh-status-progress-fg: var(--mh-status-info-fg);
    --mh-status-ok-bg:       #DCEFE0;
    --mh-status-ok-fg:       #1F5E3C;
    --mh-status-warn-bg:     #FBEBC2;
    --mh-status-warn-fg:     #6B4A00;
    --mh-status-danger-bg:   #F9DCD8;
    --mh-status-danger-fg:   #8A2B22;

    /* ── Bootstrap token overrides ─────────────────────────────────────── */
    --bs-font-sans-serif: "Lexend", Verdana, "Segoe UI", sans-serif;
    --bs-body-font-size: 1rem;
    --bs-body-line-height: 1.6;
    --bs-body-color: var(--mh-ink);
    --bs-body-color-rgb: 36, 36, 32;
    --bs-secondary-color: var(--mh-ink-2);
    --bs-secondary-color-rgb: 92, 90, 85;
    --bs-tertiary-color: var(--mh-ink-3);
    --bs-tertiary-bg: var(--mh-surface-2);
    --bs-secondary-bg: var(--mh-status-neutral-bg);
    --bs-border-color: #D9DED6;
    --bs-border-radius: 0.375rem;
    --bs-border-radius-sm: 0.25rem;
    --bs-border-radius-lg: 0.625rem;
    --bs-box-shadow-sm: none;
    --bs-heading-color: var(--mh-ink);

    --bs-primary:       var(--mh-brand);
    --bs-primary-rgb:   47, 106, 80;
    --bs-secondary:     var(--mh-ink-2);
    --bs-secondary-rgb: 92, 90, 85;
    --bs-success:       var(--mh-brand);
    --bs-success-rgb:   47, 106, 80;
    --bs-danger:        var(--mh-danger);
    --bs-danger-rgb:    179, 38, 30;
    --bs-light:         var(--mh-cloud);
    --bs-light-rgb:     245, 240, 237;
    --bs-dark:          var(--mh-ink);
    --bs-dark-rgb:      36, 36, 32;

    --bs-link-color:            var(--mh-link);
    --bs-link-color-rgb:        37, 96, 69;
    --bs-link-hover-color:      var(--mh-brand-dark);
    --bs-link-hover-color-rgb:  38, 86, 63;
    --bs-link-decoration:       none;
    --bs-link-hover-decoration: underline;

    --bs-focus-ring-width: 3px;
    --bs-focus-ring-color: rgba(47, 106, 80, 0.55);

    --bs-success-bg-subtle:       var(--mh-status-ok-bg);
    --bs-success-text-emphasis:   var(--mh-status-ok-fg);
    --bs-success-border-subtle:   var(--mh-mint);
    --bs-warning-bg-subtle:       var(--mh-status-warn-bg);
    --bs-warning-text-emphasis:   var(--mh-status-warn-fg);
    --bs-warning-border-subtle:   #F1DA9C;
    --bs-danger-bg-subtle:        var(--mh-status-danger-bg);
    --bs-danger-text-emphasis:    var(--mh-status-danger-fg);
    --bs-danger-border-subtle:    #F0BDB6;
    --bs-info-bg-subtle:          var(--mh-status-info-bg);
    --bs-info-text-emphasis:      var(--mh-status-info-fg);
    --bs-info-border-subtle:      #B7CFE8;
    --bs-primary-bg-subtle:       var(--mh-brand-light);
    --bs-primary-text-emphasis:   var(--mh-status-ok-fg);
    --bs-primary-border-subtle:   var(--mh-mint);
    --bs-secondary-bg-subtle:     var(--mh-status-neutral-bg);
    --bs-secondary-text-emphasis: var(--mh-status-neutral-fg);
    --bs-secondary-border-subtle: var(--bs-border-color);
}

/* ── Reading rules ──────────────────────────────────────────────────────── */
body {
    letter-spacing: 0.005em;
    -webkit-font-smoothing: antialiased;
}
/* Emphasis is weight, never slant. */
em, .fst-italic, dfn, cite, address {
    font-style: normal;
    font-weight: 600;
}
::placeholder {
    color: var(--mh-ink-3);
    font-style: normal;
    opacity: 1;
}
a {
    font-weight: 500;
    text-underline-offset: 3px;
}
/* Prose stops at 70 characters; tables and layout may be wider. */
.mh-prose { max-width: 70ch; }
/* Numbers line up column by column. */
.num,
.table > tbody > tr > td.text-end,
.table > thead > tr > th.text-end,
.mh-money-row, .mh-tile dd, .mh-facts dd { font-variant-numeric: tabular-nums; }

h1, .h1 { font-size: 1.875rem; font-weight: 600; line-height: 1.25; }
h2, .h2 { font-size: 1.5rem;   font-weight: 600; line-height: 1.25; }
h3, .h3 { font-size: 1.25rem;  font-weight: 600; line-height: 1.3; }
h4, .h4, h5, .h5, h6, .h6 { font-weight: 600; line-height: 1.3; }
h5, .h5 { font-size: 1.125rem; }
h6, .h6 { font-size: 1rem; }

/* Keyboard focus: same 3 px ring everywhere, with a white gap. */
.btn:focus-visible,
.btn-icon:focus-visible,
.nav-link:focus-visible,
.page-link:focus-visible,
.form-control:focus,
.form-select:focus,
.form-check-input:focus,
.ts-wrapper.focus .ts-control,
.ts-wrapper .ts-control:focus-within {
    outline: none;
    box-shadow: 0 0 0 2px var(--mh-surface), 0 0 0 5px var(--mh-brand);
}
a:focus-visible,
summary:focus-visible,
.btn-close:focus {
    outline: 3px solid var(--mh-brand);
    outline-offset: 2px;
    box-shadow: none;
}

/* ── Buttons ────────────────────────────────────────────────────────────── */
/* 44 px controls; small (36 px) only inside tables and filter rows. */
.btn {
    --bs-btn-padding-y: 0.5625rem;
    --bs-btn-padding-x: 1.125rem;
    --bs-btn-font-weight: 500;
    --bs-btn-border-radius: var(--mh-radius-sm);
    --bs-btn-focus-box-shadow: 0 0 0 2px var(--mh-surface), 0 0 0 5px var(--mh-brand);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 2.75rem;
    white-space: nowrap;
}
.btn-sm {
    --bs-btn-padding-y: 0.3125rem;
    --bs-btn-padding-x: 0.75rem;
    --bs-btn-font-size: 0.875rem;
    min-height: 2.25rem;
}
.btn-lg { min-height: 3rem; }
.d-grid > .btn { display: flex; }
.btn-primary {
    --bs-btn-bg: var(--mh-brand);
    --bs-btn-border-color: var(--mh-brand);
    --bs-btn-hover-bg: var(--mh-brand-dark);
    --bs-btn-hover-border-color: var(--mh-brand-dark);
    --bs-btn-active-bg: var(--mh-brand-dark);
    --bs-btn-active-border-color: var(--mh-brand-dark);
    --bs-btn-disabled-bg: var(--mh-sage);
    --bs-btn-disabled-border-color: var(--mh-sage);
    --bs-btn-disabled-color: #fff;
    --bs-btn-disabled-opacity: 1;
}
.btn-outline-secondary,
.btn-outline-primary,
.btn-secondary,
.btn-light {
    --bs-btn-color: var(--mh-ink);
    --bs-btn-bg: var(--mh-surface);
    --bs-btn-border-color: var(--mh-sage);
    --bs-btn-hover-color: var(--mh-ink);
    --bs-btn-hover-bg: var(--mh-mist);
    --bs-btn-hover-border-color: var(--mh-sage);
    --bs-btn-active-color: var(--mh-ink);
    --bs-btn-active-bg: var(--mh-mist);
    --bs-btn-active-border-color: var(--mh-sage);
    --bs-btn-disabled-color: var(--mh-ink-3);
    --bs-btn-disabled-bg: var(--mh-surface);
    --bs-btn-disabled-border-color: var(--bs-border-color);
    --bs-btn-disabled-opacity: 1;
}
.btn-outline-primary { --bs-btn-color: var(--mh-link); --bs-btn-border-color: var(--mh-brand); }
.btn-danger {
    --bs-btn-bg: var(--mh-danger);
    --bs-btn-border-color: var(--mh-danger);
    --bs-btn-hover-bg: #8A2B22;
    --bs-btn-hover-border-color: #8A2B22;
    --bs-btn-active-bg: #8A2B22;
    --bs-btn-active-border-color: #8A2B22;
}
/* Danger stays outlined until the confirmation dialog, where it is solid. */
.btn-outline-danger {
    --bs-btn-color: var(--mh-status-danger-fg);
    --bs-btn-bg: var(--mh-surface);
    --bs-btn-border-color: var(--mh-danger);
    --bs-btn-hover-color: var(--mh-status-danger-fg);
    --bs-btn-hover-bg: var(--mh-status-danger-bg);
    --bs-btn-hover-border-color: var(--mh-danger);
    --bs-btn-active-color: var(--mh-status-danger-fg);
    --bs-btn-active-bg: var(--mh-status-danger-bg);
    --bs-btn-active-border-color: var(--mh-danger);
}
.btn-link { --bs-btn-color: var(--mh-link); --bs-btn-hover-color: var(--mh-brand-dark); }

/* ── Form controls ──────────────────────────────────────────────────────── */
.form-control,
.form-select {
    min-height: 2.75rem;
    padding: 0.5rem 0.75rem;
    border-color: var(--mh-sage);
    border-radius: var(--mh-radius-sm);
    background-color: var(--mh-surface);
    color: var(--mh-ink);
}
.form-control-sm,
.form-select-sm,
.input-group-sm > .form-control,
.input-group-sm > .form-select {
    min-height: 2.25rem;
    padding: 0.25rem 0.5rem;
}
/* The arrow gutter Bootstrap draws on selects; the shorthand above would drop it. */
.form-select,
.form-select-sm,
.input-group-sm > .form-select {
    padding-right: 2.25rem;
}
textarea.form-control { min-height: 5.5rem; }
.form-control:focus,
.form-select:focus { border-color: var(--mh-brand); }
.form-control:disabled,
.form-select:disabled { background-color: var(--mh-surface-2); color: var(--mh-ink-2); }
/* An error is a thicker red border plus an icon and a sentence, never a red outline alone. */
.form-control.is-invalid,
.form-select.is-invalid,
.was-validated .form-control:invalid,
.was-validated .form-select:invalid {
    border-color: var(--mh-danger);
    box-shadow: inset 0 0 0 1px var(--mh-danger);
}
.form-control.is-invalid:focus,
.form-select.is-invalid:focus {
    box-shadow: inset 0 0 0 1px var(--mh-danger), 0 0 0 2px var(--mh-surface), 0 0 0 5px var(--mh-danger);
}
.invalid-feedback {
    color: var(--mh-status-danger-fg);
    font-size: 0.875rem;
    font-weight: 500;
}
.form-label { font-weight: 600; margin-bottom: 0.375rem; }
.form-text { color: var(--mh-ink-2); font-size: 0.875rem; }
.input-group-text {
    background-color: var(--mh-surface-2);
    border-color: var(--mh-sage);
    color: var(--mh-ink-2);
}
.form-check-input {
    width: 1.25em;
    height: 1.25em;
    margin-top: 0.2em;
    border-color: var(--mh-sage);
    background-color: var(--mh-surface);
}
.form-check-input:checked { background-color: var(--mh-brand); border-color: var(--mh-brand); }
.form-switch .form-check-input { width: 2.5em; }

/* ── Cards, modals, menus ───────────────────────────────────────────────── */
.card {
    --bs-card-bg: var(--mh-surface);
    --bs-card-border-color: var(--bs-border-color);
    --bs-card-border-radius: var(--mh-radius-lg);
    --bs-card-inner-border-radius: calc(var(--mh-radius-lg) - 1px);
    --bs-card-cap-bg: var(--mh-surface);
    --bs-card-cap-padding-y: 0.875rem;
    --bs-card-cap-padding-x: 1.25rem;
    --bs-card-spacer-y: 1.25rem;
    --bs-card-spacer-x: 1.25rem;
}
.card-header { font-weight: 600; font-size: 1.125rem; }
.modal {
    --bs-modal-bg: var(--mh-surface);
    --bs-modal-border-color: var(--bs-border-color);
    --bs-modal-border-radius: var(--mh-radius-lg);
}
.dropdown-menu {
    --bs-dropdown-bg: var(--mh-surface);
    --bs-dropdown-border-color: var(--bs-border-color);
    --bs-dropdown-border-radius: var(--mh-radius-md);
    --bs-dropdown-link-color: var(--mh-ink);
    --bs-dropdown-link-hover-bg: var(--mh-mist);
    --bs-dropdown-link-active-bg: var(--mh-brand);
    --bs-dropdown-item-padding-y: 0.5rem;
    --bs-dropdown-item-padding-x: 1rem;
    box-shadow: 0 8px 24px rgba(36, 36, 32, 0.12);
}
.dropdown-item { display: flex; align-items: center; gap: 0.5rem; }

/* ── Alerts and flash messages ──────────────────────────────────────────── */
.alert {
    --bs-alert-border-radius: var(--mh-radius-lg);
    --bs-alert-padding-y: 0.75rem;
    --bs-alert-padding-x: 1rem;
}
.flash-messages { max-width: 420px; pointer-events: none; }
/* The fixed container spans its padding; only the messages themselves should
   catch clicks, so nothing underneath the gap is blocked. */
.flash-messages .alert { pointer-events: auto; }

/* ── Breadcrumb ─────────────────────────────────────────────────────────── */
.breadcrumb {
    --bs-breadcrumb-divider: '›';
    --bs-breadcrumb-divider-color: var(--mh-ink-3);
    --bs-breadcrumb-item-active-color: var(--mh-ink);
    --bs-breadcrumb-item-padding-x: 0.625rem;
}
.breadcrumb-item.active { font-weight: 500; }
.breadcrumb-item a { font-weight: 400; }

/* ── Pagination ─────────────────────────────────────────────────────────── */
.pagination {
    --bs-pagination-color: var(--mh-link);
    --bs-pagination-bg: var(--mh-surface);
    --bs-pagination-border-color: var(--bs-border-color);
    --bs-pagination-hover-bg: var(--mh-mist);
    --bs-pagination-hover-color: var(--mh-ink);
    --bs-pagination-active-bg: var(--mh-brand);
    --bs-pagination-active-border-color: var(--mh-brand);
    --bs-pagination-disabled-color: var(--mh-ink-3);
    --bs-pagination-disabled-bg: var(--mh-surface);
    --bs-pagination-padding-y: 0.5rem;
    --bs-pagination-padding-x: 0.875rem;
    --bs-pagination-focus-box-shadow: 0 0 0 2px var(--mh-surface), 0 0 0 5px var(--mh-brand);
}

/* ── Sidebar layout ─────────────────────────────────────────────────────── */
/* Mist, not dark: a dark rail next to a light page is the highest-contrast
   edge on the screen and pulls the eye away from the work. The single solid
   green item makes the current place unmistakable. */
.admin-sidebar {
    background-color: var(--mh-sidebar-bg);
    color: var(--mh-sidebar-text);
    border-right: 1px solid var(--bs-border-color);
    width: var(--mh-sidebar-width);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    transition: width 0.2s ease;
    overflow-x: hidden;
    position: relative;
}

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

.admin-sidebar .nav-link {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-height: 2.75rem;
    color: var(--mh-sidebar-text);
    border-radius: var(--mh-radius-sm);
    padding: 0.5rem 0.875rem;
    margin: 1px 0;
    font-weight: 500;
    white-space: nowrap;
}

.admin-sidebar .nav-link:hover,
.admin-sidebar .nav-link:focus {
    background-color: var(--mh-sidebar-hover);
    color: var(--mh-ink);
}

.admin-sidebar .nav-link.active {
    background-color: var(--mh-brand);
    color: #fff;
    font-weight: 600;
}

/* Sentence case, not tracked capitals. */
.admin-sidebar .nav-section-label {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--mh-ink-2);
    padding: 1.125rem 0.875rem 0.25rem;
    margin: 0;
    pointer-events: none;
}

.sidebar-close-btn {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    z-index: 1;
}

/* ── Brand / logo area ──────────────────────────────────────────────────── */
.admin-brand {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1.375rem 1.25rem 0.875rem;
    border-bottom: 1px solid var(--mh-mint);
    color: var(--mh-ink);
}
.admin-brand__logo {
    width: 200px;
    max-width: 100%;
    height: auto;
    display: block;
}
.admin-brand__app {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--mh-accent-text);
}

/* ── User / logout ──────────────────────────────────────────────────────── */
.admin-user {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.875rem 1rem;
    border-top: 1px solid var(--mh-mint);
}
.admin-user__avatar {
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--mh-brand);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.875rem;
    font-weight: 600;
}
.admin-user__name {
    font-size: 0.875rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.admin-user__logout {
    font-size: 0.875rem;
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
}

/* ── Main content area ──────────────────────────────────────────────────── */
.admin-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    background-color: var(--mh-cloud);
}

.admin-topbar {
    height: var(--mh-header-height);
    background: var(--mh-surface);
    border-bottom: 1px solid var(--bs-border-color);
    display: flex;
    align-items: center;
    padding: 0 1.5rem;
    gap: 0.75rem;
    position: sticky;
    top: 0;
    z-index: 100;
}

/* The top bar has a fixed height, so a long record name in the last crumb has
   to truncate rather than wrap. min-width:0 is what lets a flex item shrink
   below its content width and actually ellipsize. */
.breadcrumb .mh-crumb-record {
    min-width: 0;
    max-width: 34rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mh-crumb-id { color: var(--bs-secondary-color); font-weight: 400; }

.admin-content {
    padding: 2rem 2.5rem;
    flex: 1;
}
@media (max-width: 991.98px) {
    .admin-content { padding: 1.25rem 1rem; }
}

/* ── Admin form fields ──────────────────────────────────────────────────── */
/* Three width tokens replace the ad-hoc style="width:22rem" / col-sm-6 /
   width:150px mix that every form had invented for itself. Applied through
   row_attr on form_row, so the width lives with the field, not in markup. */
.mh-form-grid { display: flex; flex-wrap: wrap; gap: 0 1.25rem; }
.mh-field { margin-bottom: 1rem; }
.mh-field--short  { flex: 0 1 13rem; min-width: 11rem; }
.mh-field--medium { flex: 0 1 18rem; min-width: 12rem; }
.mh-field--wide   { flex: 0 1 26rem; min-width: 15rem; }
.mh-field--full   { flex: 1 1 100%; }

/* The "?" that carries a field's help text. Focusable, so the tooltip is
   reachable by keyboard and not only on hover. */
.mh-field-hint {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
    margin-left: 0.375rem;
    border-radius: 50%;
    border: 1px solid var(--mh-sage);
    color: var(--bs-secondary-color);
    background: var(--mh-surface);
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1;
    cursor: help;
    vertical-align: middle;
}
.mh-field-hint:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px var(--mh-surface), 0 0 0 4px var(--mh-brand);
}

/* ── Ingredient page: "add item and price" in one row ──────────────────── */
.mh-addrow { display: flex; flex-wrap: wrap; gap: 0.75rem 1rem; align-items: flex-end; }
.mh-addrow > * { min-width: 0; }
.mh-addrow__name     { flex: 2 1 12rem; }
.mh-addrow__unit     { flex: 1 1 8.5rem; }
.mh-addrow__conv     { flex: 0 1 10.5rem; }
.mh-addrow__supplier { flex: 1 1 10rem; }
.mh-addrow__pack     { flex: 0 1 6.5rem; }
.mh-addrow__price    { flex: 0 1 7rem; }
.mh-addrow .form-label { font-size: 0.875rem; white-space: nowrap; }
.mh-addrow__active   { flex: 0 0 auto; text-align: center; }
.mh-addrow__active .form-check-input { margin: 0; width: 1.5rem; height: 1.5rem; }
.mh-addrow__active .mh-addrow__box { height: 2.75rem; display: flex; align-items: center; justify-content: center; }

/* ── Dashboard cards ────────────────────────────────────────────────────── */
.stat-card {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    height: 100%;
    border: 1px solid var(--bs-border-color);
    border-radius: var(--mh-radius-lg);
    padding: 1.5rem;
    background: var(--mh-surface);
    color: inherit;
    transition: border-color .15s;
}

a .stat-card:hover {
    border-color: var(--mh-brand);
}

.stat-card--alert { border-color: #E0B94D; }

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

.stat-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}

.stat-card__icon {
    width: 1.5rem;
    height: 1.5rem;
    color: var(--mh-brand);
    flex-shrink: 0;
}

.stat-card__value {
    font-size: 2.25rem;
    font-weight: 600;
    line-height: 1.1;
    color: var(--mh-ink);
    font-variant-numeric: tabular-nums;
}

.stat-card__label {
    font-size: 1rem;
    font-weight: 500;
    color: var(--mh-ink-2);
}

.stat-card__hint {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.875rem;
    color: var(--mh-status-warn-fg);
    margin: 0;
}

/* ── Page header (title + actions) ─────────────────────────────────────── */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    margin-bottom: 1.5rem;
}

.page-header__title {
    font-size: 1.875rem;
    font-weight: 600;
    line-height: 1.25;
    margin: 0;
    color: var(--mh-ink);
}

/* ── Tables ─────────────────────────────────────────────────────────────── */
/*
 * One rhythm for every table. Bootstrap's own cell padding is 0.5rem (0.25rem
 * for .table-sm); each page used to compensate in its own way — a padded
 * .table-responsive here, a ps-4 there. Cell padding is set once here, and a
 * table that sits flush inside a card (.card-body.p-0, .table-card, the offer
 * show's window and breakdown tables) pads its first and last column to the
 * card's own 1.25rem so the columns line up with the card header.
 */
.table {
    --bs-table-color: var(--mh-ink);
    --bs-table-border-color: #ECEEEA;
    --bs-table-striped-bg: var(--mh-surface-2);
    --bs-table-hover-bg: var(--mh-mist);
    --bs-table-hover-color: var(--mh-ink);
}
.table > :not(caption) > * > * {
    padding: 0.75rem 0.875rem;
}
.table-sm > :not(caption) > * > * {
    padding: 0.5rem 0.75rem;
}
.card-body.p-0 .table > :not(caption) > * > :first-child,
.card > .table-responsive > .table > :not(caption) > * > :first-child,
.table-card .table > :not(caption) > * > :first-child,
.mh-win .table > :not(caption) > * > :first-child,
details.mh-internal .table > :not(caption) > * > :first-child {
    padding-left: 1.25rem;
}
.card-body.p-0 .table > :not(caption) > * > :last-child,
.card > .table-responsive > .table > :not(caption) > * > :last-child,
.table-card .table > :not(caption) > * > :last-child,
.mh-win .table > :not(caption) > * > :last-child,
details.mh-internal .table > :not(caption) > * > :last-child {
    padding-right: 1.25rem;
}
.table > thead > tr > th {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--bs-secondary-color);
    border-bottom: 2px solid var(--mh-mint);
    vertical-align: bottom;
}

.table-card {
    background: var(--mh-surface);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--mh-radius-lg);
    overflow: hidden;
}

.table-card .table {
    margin-bottom: 0;
}

.table-card .table thead th {
    background-color: var(--mh-surface);
}

/* Every second row is faintly tinted so the eye can track across. */
.table-card .table > tbody > tr:nth-child(even) > * {
    --bs-table-accent-bg: var(--mh-surface-2);
}

/* ── Search bar ─────────────────────────────────────────────────────────── */
.search-bar {
    max-width: 320px;
}

/* ── Sidebar collapsed state (mobile / toggled) ─────────────────────────── */
.admin-sidebar.is-collapsed {
    width: 0;
    border-right: 0;
}

/* ── Responsive: mobile sidebar overlay ─────────────────────────────────── */
@media (max-width: 767.98px) {
    .admin-wrapper {
        position: relative;
    }

    .admin-sidebar {
        position: fixed;
        top: 0;
        left: 0;
        height: 100%;
        z-index: 200;
        width: 0;
        overflow: hidden;
    }

    .admin-sidebar.is-open {
        width: var(--mh-sidebar-width);
    }

    .sidebar-backdrop {
        display: none;
        position: fixed;
        inset: 0;
        background: rgba(36, 36, 32, 0.4);
        z-index: 199;
    }

    .sidebar-backdrop.is-visible {
        display: block;
    }
}

/* ── Ghost button (icon-only action buttons in tables) ──────────────── */
.btn-ghost {
    background: transparent;
    border: none;
}
.btn-ghost:hover,
.btn-ghost:focus-visible {
    background: var(--mh-mist);
    border-radius: var(--mh-radius-sm);
}

/*
 * Row action button: a small glyph inside a real 40 px target. Hover fills Mist.
 */
.btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--mh-hit-target);
    height: var(--mh-hit-target);
    padding: 0;
    background: transparent;
    border: none;
    border-radius: var(--mh-radius-sm);
    color: var(--bs-secondary-color);
    line-height: 1;
}
.btn-icon:hover,
.btn-icon:focus-visible {
    background: var(--mh-mist);
    color: var(--bs-body-color);
}
.btn-icon--danger { color: var(--mh-status-danger-fg); }
.btn-icon--danger:hover,
.btn-icon--danger:focus-visible {
    background: var(--mh-status-danger-bg);
    color: var(--mh-status-danger-fg);
}
.btn-icon--info { color: var(--mh-status-info-fg); }

/*
 * Standard icon size, used everywhere a lucide glyph appears outside a
 * dedicated size class (.nav-icon, .page-icon, .mh-status-icon, .stat-card__icon).
 */
.mh-icon {
    width: 18px;
    height: 18px;
    stroke: currentColor;
    flex-shrink: 0;
    vertical-align: -0.2em;
}

/* ── Tooltip icon ────────────────────────────────────────────────────
 * Pure CSS, no JS init required (Bootstrap's own tooltip component needs a
 * per-element `new bootstrap.Tooltip()` call this app never wires up).
 * Hover or keyboard-focus the icon to reveal `data-tooltip`.
 */
.mh-tooltip-icon {
    position: relative;
    display: inline-flex;
    cursor: help;
}
.mh-tooltip-icon::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    background: var(--mh-ink);
    color: #fff;
    padding: var(--mh-space-2) var(--mh-space-3);
    border-radius: var(--mh-radius-sm);
    font-size: 0.875rem;
    font-weight: 400;
    line-height: 1.4;
    white-space: normal;
    width: max-content;
    max-width: 260px;
    z-index: 20;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .12s ease;
}
.mh-tooltip-icon:hover::after,
.mh-tooltip-icon:focus-visible::after {
    opacity: 1;
    visibility: visible;
}
.tooltip {
    --bs-tooltip-bg: var(--mh-ink);
    --bs-tooltip-color: #fff;
    --bs-tooltip-font-size: 0.875rem;
    --bs-tooltip-max-width: 280px;
    --bs-tooltip-padding-x: 0.75rem;
    --bs-tooltip-padding-y: 0.5rem;
    --bs-tooltip-border-radius: var(--mh-radius-sm);
    --bs-tooltip-opacity: 1;
    text-align: left;
    line-height: 1.5;
}

/* ── Inline row editing ─────────────────────────────────────────────── */
/*
 * An open editor replaces its row with one full-width cell (a <form> cannot
 * span sibling <td>s). The tint marks which row is being edited, which matters
 * because only one may be open at a time.
 */
.inline-row-edit__editing > td {
    background: var(--mh-brand-light);
    box-shadow: inset 3px 0 0 var(--mh-brand);
}
.inline-row-edit__field {
    min-width: 12rem;
}
/* Keep the buttons on the field baseline rather than the label baseline. */
.inline-row-edit__actions {
    padding-top: 1.9rem;
}
@media (max-width: 575.98px) {
    .inline-row-edit__field,
    .inline-row-edit__field--grow {
        flex: 1 1 100%;
        min-width: 0;
    }
    .inline-row-edit__actions {
        padding-top: var(--mh-space-2);
    }
}

/* ── Recipe component / labor row tables ────────────────────────────── */
/*
 * Some headers carry a hint line beneath the label, so align every header to
 * the top rather than letting single-line headers sink to the baseline.
 */
.recipe-rows > thead th {
    vertical-align: top;
    white-space: nowrap;
}
/* Percentage column widths only hold with a fixed table layout — auto layout
   resizes columns to fit content, which is what pushed "Maun mukaan" wider
   than intended. Scoped to the components table only: the labor table below
   it sizes its columns in pixels and doesn't need this. */
.recipe-rows--components {
    table-layout: fixed;
}
.recipe-rows > tbody > tr > td {
    vertical-align: top;
}
/* Row inputs sit tight; give the select room to breathe on narrow screens. */
.recipe-rows .ts-wrapper {
    min-width: 12rem;
}

/* ── Status badges ──────────────────────────────────────────────────── */
/* Always an icon plus a word. Five tints, one meaning each. */
.mh-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 0.625rem 0.25rem 0.5rem;
    font-size: 0.875rem;
    font-weight: 500;
    line-height: 1.25;
    border-radius: 999px;
    white-space: nowrap;
    vertical-align: middle;
}
.mh-badge__icon {
    width: 16px;
    height: 16px;
    stroke: currentColor;
    flex-shrink: 0;
}
.mh-badge--neutral  { background: var(--mh-status-neutral-bg);  color: var(--mh-status-neutral-fg); }
.mh-badge--info     { background: var(--mh-status-info-bg);     color: var(--mh-status-info-fg); }
.mh-badge--progress { background: var(--mh-status-progress-bg); color: var(--mh-status-progress-fg); }
.mh-badge--ok       { background: var(--mh-status-ok-bg);       color: var(--mh-status-ok-fg); }
.mh-badge--warn     { background: var(--mh-status-warn-bg);     color: var(--mh-status-warn-fg); }
.mh-badge--danger   { background: var(--mh-status-danger-bg);   color: var(--mh-status-danger-fg); }

/* Compact covered/uncovered indicator — a small icon rather than a full
   badge, for use inline next to an ingredient/sub-recipe name. */
.mh-status-icon {
    width: 16px;
    height: 16px;
    stroke-width: 2.5;
    vertical-align: -3px;
    flex-shrink: 0;
}

/* Inline variant for badges that hold their own controls (e.g. the offer line's
   split-% display plus its edit affordance). Hiding is done with the [hidden]
   attribute, which Bootstrap's reboot makes win over any display below. */
.mh-badge--inline { display: inline-flex; align-items: center; gap: 0.25rem; }

/* Bootstrap's own .badge (used for sellable / internal on the recipe list). */
.badge {
    --bs-badge-font-size: 0.875rem;
    --bs-badge-font-weight: 500;
    --bs-badge-padding-y: 0.25em;
    --bs-badge-padding-x: 0.75em;
    --bs-badge-border-radius: 999px;
    line-height: 1.25;
}
.badge.bg-success  { background-color: var(--mh-status-ok-bg) !important; color: var(--mh-status-ok-fg); }
.badge.bg-secondary { background-color: var(--mh-status-neutral-bg) !important; color: var(--mh-status-neutral-fg); }

/* Warning line under a badge (e.g. "no labor" on the recipe list). */
.mh-warn-line {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.875rem;
    color: var(--mh-status-warn-fg);
}

/* ── Empty state ────────────────────────────────────────────────────── */
.mh-empty { text-align: center; padding: 3rem 1rem; }
.mh-empty__icon { width: 2.5rem; height: 2.5rem; color: var(--mh-sage); }
.mh-empty__title { font-size: 1.25rem; font-weight: 600; margin: 0.75rem 0 0.25rem; }
.mh-empty__text { color: var(--bs-secondary-color); max-width: 36ch; margin: 0 auto 1.25rem; }

/* ── Lucide icon sizing ─────────────────────────────────────────────── */
.nav-icon {
    width: 20px;
    height: 20px;
    stroke: currentColor;
    vertical-align: -0.25em;
    flex-shrink: 0;
}
/* Outside the sidebar (dashboard shortcuts) the icon sits in a flex button. */
.btn .nav-icon { margin-right: 0; }

.page-icon {
    width: 1.75rem;
    height: 1.75rem;
    stroke: currentColor;
    color: var(--mh-brand);
    vertical-align: -0.3em;
    margin-right: 0.5rem;
}

/* ── Sortable table headers ─────────────────────────────────────────── */
.sort-link {
    color: inherit;
    white-space: nowrap;
    font-weight: 600;
}
.sort-link:hover {
    color: var(--mh-ink);
    text-decoration: none;
}
.sort-link--active {
    color: var(--mh-ink);
    font-weight: 600;
}
@media (prefers-reduced-motion: reduce) {
    .sort-link i { display: none; }
}

/* Tom Select admin overrides. */
.ts-wrapper {
    min-width: 0; /* allow shrink inside Bootstrap grid */
}
.ts-wrapper .ts-control {
    border-color: var(--mh-sage);
    border-radius: var(--mh-radius-sm);
    box-shadow: none;
    font-size: inherit;
    padding: 0.5rem 0.75rem;
    background-color: var(--mh-surface);
    color: var(--bs-body-color);
}
.ts-wrapper.focus .ts-control,
.ts-wrapper .ts-control:focus-within {
    border-color: var(--mh-brand);
    outline: none;
}
.ts-dropdown {
    background: var(--mh-surface);
    border-color: var(--bs-border-color);
    border-radius: var(--mh-radius-sm);
    font-size: inherit;
    box-shadow: 0 8px 24px rgba(36, 36, 32, 0.12);
    z-index: 1056; /* above Bootstrap modals */
}
.ts-dropdown .ts-dropdown-content {
    max-height: 220px;
}
.ts-dropdown .option.selected,
.ts-dropdown .option:hover,
.ts-dropdown .option.active {
    background-color: var(--mh-mist);
    color: var(--mh-ink);
}
.ts-dropdown .optgroup-header {
    color: var(--bs-secondary-color);
    font-size: 0.875rem;
    font-weight: 600;
    padding: 0.375rem 0.75rem;
    background: var(--mh-surface-2);
}
.ts-wrapper--admin .ts-control { min-height: 2.75rem; }
@media (prefers-reduced-motion: reduce) {
    .ts-dropdown { transition: none; }
}
