/* ==========================================================================
   FindHere Admin UI
   --------------------------------------------------------------------------
   Single source of truth for the admin panel look. Loaded LAST in
   resources/views/admin/layout.blade.php so it wins over backend-template.css,
   style.css and rtl.css without needing !important everywhere.

   This file replaces the ~780 line inline <style> block that used to live in
   layout.blade.php. Do not reintroduce page-level <style> blocks — add a
   component here instead.

   Note: rtl.css sets `body { direction: rtl }` for every locale, so layout
   uses logical properties (inset-inline-*, margin-inline-*, padding-inline-*)
   rather than left/right wherever direction matters.

   Sections
     1.  Tokens
     2.  Base surfaces
     3.  Sidebar
     4.  Page header
     5.  Cards
     6.  Forms & controls
     7.  Select2
     8.  Buttons
     9.  Tables
     10. Row action buttons
     11. Badges, avatars, toggles
     12. Filter card
     13. Pagination
     14. Show-page (read-only detail view)
     15. Legacy shims
   ========================================================================== */


/* ==========================================================================
   1. Tokens
   ========================================================================== */

:root {
    /* Brand. The same codebase runs several restaurants off separate .env /
       VENDOR_ID — never hardcode a brand colour outside these three. */
    --ui-primary: #D95525;
    --ui-primary-hover: #BF461C;
    --ui-primary-soft: rgba(217, 85, 37, 0.10);

    /* Neutrals */
    --ui-bg: #F8FAFC;
    --ui-surface: #FFFFFF;
    --ui-border: #E2E8F0;
    --ui-border-strong: #CBD5E1;
    --ui-hairline: #EEF2F7;
    --ui-text: #1A202C;
    --ui-text-muted: #64748B;
    --ui-text-label: #334155;
    --ui-text-faint: #94A3B8;

    /* Semantic */
    --ui-success: #16A34A;
    --ui-success-soft: rgba(22, 163, 74, 0.10);
    --ui-info: #0EA5E9;
    --ui-info-soft: rgba(14, 165, 233, 0.10);
    --ui-danger: #EF4444;
    --ui-danger-soft: rgba(239, 68, 68, 0.10);
    --ui-warning: #F59E0B;
    --ui-warning-soft: rgba(245, 158, 11, 0.12);

    /* Spacing — 4px base */
    --ui-space-1: 4px;
    --ui-space-2: 8px;
    --ui-space-3: 12px;
    --ui-space-4: 16px;
    --ui-space-5: 20px;
    --ui-space-6: 24px;

    /* Controls */
    --ui-radius-sm: 6px;
    --ui-radius: 8px;
    --ui-radius-lg: 12px;
    --ui-control-h: 42px;
    --ui-control-h-sm: 34px;
    --ui-detail-label: 150px;   /* label column on read-only detail lists */
    --ui-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 8px 24px rgba(15, 23, 42, .04);
    --ui-ring: 0 0 0 3px var(--ui-primary-soft);
}


/* ==========================================================================
   2. Base surfaces
   ========================================================================== */

body {
    background: var(--ui-bg);
    color: var(--ui-text);
}

.pcoded-main-container,
.pcoded-content,
.pcoded-inner-content,
.main-body,
.page-wrapper {
    background: var(--ui-bg);
}

.pcoded-content {
    padding: var(--ui-space-6) var(--ui-space-6) var(--ui-space-4);
}

/* Header height is set once, in §30 Top bar, where the rest of the bar's
   geometry lives. */

.active-case span {
    color: #385d7a;
    padding: 0 var(--ui-space-1);
    font-size: 14px;
}

/* Chrome / Safari / Edge number spinners */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

input[type=number] {
    -moz-appearance: textfield;
}


/* ==========================================================================
   3. Sidebar — light RTL theme
   ========================================================================== */

.pcoded-navbar,
.pcoded-navbar.navbar-light,
.pcoded-navbar[class*="navbar-"] {
    right: 0;
    left: auto;
    background: var(--ui-surface);
    border-left: 1px solid var(--ui-border);
    box-shadow: -4px 0 18px 0 rgba(15, 23, 42, 0.04);
    color: #4A5568;
}

.pcoded-navbar .header-logo,
.pcoded-navbar.brand-light .header-logo,
.pcoded-navbar[class*="navbar-"].brand-light .header-logo {
    background: transparent;
    border-bottom: 1px solid #F1F5F9;
    min-height: 76px;
    padding: 14px var(--ui-space-5);
}

.pcoded-navbar .header-logo .b-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
}

.pcoded-navbar .header-logo img {
    max-width: 120px;
    max-height: 54px;
    object-fit: contain;
}

.pcoded-navbar .navbar-content {
    background: var(--ui-surface);
    padding: 10px 0 18px;
}

.pcoded-navbar .pcoded-inner-navbar {
    padding: 0 10px;
}

.pcoded-navbar .pcoded-menu-caption label {
    color: var(--ui-text-faint);
    font-weight: 700;
    letter-spacing: 0;
}

.pcoded-navbar .pcoded-inner-navbar li > a {
    position: relative;
    margin: 2px 0;
    border-radius: var(--ui-radius);
    color: #4A5568;
    background: transparent;
    transition: background-color .2s ease, color .2s ease;
}

.pcoded-navbar .pcoded-inner-navbar li > a .pcoded-micon,
.pcoded-navbar .pcoded-inner-navbar li > a .pcoded-micon i,
.pcoded-navbar .pcoded-inner-navbar li > a .pcoded-mtext {
    color: #4A5568;
}

.pcoded-navbar .pcoded-inner-navbar li:not(.active):not(.pcoded-trigger) > a:hover,
.pcoded-navbar .pcoded-inner-navbar li:not(.active):not(.pcoded-trigger) > a:focus {
    background: #F1F5F9;
    color: var(--ui-text);
}

.pcoded-navbar .pcoded-inner-navbar li:not(.active):not(.pcoded-trigger) > a:hover .pcoded-micon,
.pcoded-navbar .pcoded-inner-navbar li:not(.active):not(.pcoded-trigger) > a:hover .pcoded-micon i,
.pcoded-navbar .pcoded-inner-navbar li:not(.active):not(.pcoded-trigger) > a:hover .pcoded-mtext {
    color: var(--ui-text);
}

.pcoded-navbar .pcoded-inner-navbar li.active > a,
.pcoded-navbar .pcoded-inner-navbar li.pcoded-trigger > a {
    background: var(--ui-primary-soft);
    color: var(--ui-primary);
    font-weight: 700;
}

.pcoded-navbar .pcoded-inner-navbar li.active > a::before,
.pcoded-navbar .pcoded-inner-navbar li.pcoded-trigger > a::before {
    content: "";
    position: absolute;
    top: 10px;
    inset-inline-end: 0;
    width: 4px;
    height: calc(100% - 20px);
    border-radius: 4px 0 0 4px;
    background: var(--ui-primary);
}

.pcoded-navbar .pcoded-inner-navbar li.active > a .pcoded-micon,
.pcoded-navbar .pcoded-inner-navbar li.active > a .pcoded-micon i,
.pcoded-navbar .pcoded-inner-navbar li.active > a .pcoded-mtext,
.pcoded-navbar .pcoded-inner-navbar li.pcoded-trigger > a .pcoded-micon,
.pcoded-navbar .pcoded-inner-navbar li.pcoded-trigger > a .pcoded-micon i,
.pcoded-navbar .pcoded-inner-navbar li.pcoded-trigger > a .pcoded-mtext {
    color: var(--ui-primary);
}

.pcoded-navbar .pcoded-submenu {
    background: transparent;
    padding: var(--ui-space-1) 0;
}

.pcoded-navbar .pcoded-submenu li > a {
    padding-inline-start: 46px;
}


/* ==========================================================================
   4. Page header
   --------------------------------------------------------------------------
   Title + breadcrumb on one side, primary action on the other. Replaces the
   orphan `<div class="row" style="justify-content:space-between">` that used
   to float the add button between .card-header and .card-block.
   ========================================================================== */

.page-header {
    background: transparent;
    box-shadow: none;
    margin-bottom: var(--ui-space-4);
    padding: 0;
}

.ui-page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--ui-space-3);
}

.ui-page-header__titles {
    min-width: 0;
}

.ui-page-header__actions {
    display: flex;
    align-items: center;
    gap: var(--ui-space-2);
    flex-wrap: wrap;
}

.page-header-title h5,
.card .card-header h5 {
    color: var(--ui-text);
    font-weight: 700;
    letter-spacing: 0;
    margin-bottom: 6px;
    font-size: 18px;
}

.page-header-title + .breadcrumb,
.breadcrumb {
    background: transparent;
    padding: 0;
    margin-bottom: 0;
}

.breadcrumb-item,
.breadcrumb-item a,
.breadcrumb-item + .breadcrumb-item::before {
    color: var(--ui-text-muted);
    font-size: 13px;
}

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


/* ==========================================================================
   5. Cards
   ========================================================================== */

.card {
    background: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius-lg);
    box-shadow: var(--ui-shadow);
    margin-bottom: var(--ui-space-5);
    overflow: hidden;
}

.card .card-header {
    background: var(--ui-surface);
    border-bottom: 1px solid var(--ui-border);
    padding: var(--ui-space-4) var(--ui-space-5);
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--ui-space-2);
}

.card .card-header h5 {
    margin-bottom: 0;
    font-size: 15px;
}

.card .card-header h5:after {
    display: none;
}

.card .card-block,
.card .card-body {
    background: var(--ui-surface);
    padding: var(--ui-space-5);
}

/* A card whose body is nothing but a table — the table draws its own edges. */
.card .card-block--flush,
.card .card-body--flush {
    padding: 0;
}

.card-header-right .btn,
.card-option .btn {
    background: var(--ui-bg);
    border: 1px solid var(--ui-border);
    color: #4A5568;
    border-radius: var(--ui-radius);
}

/* Toolbar strip between the card header and the table (bulk actions, counts) */
.ui-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--ui-space-3);
    padding: var(--ui-space-3) var(--ui-space-5);
    border-bottom: 1px solid var(--ui-border);
    background: var(--ui-surface);
}

.ui-toolbar__count {
    color: var(--ui-text-muted);
    font-size: 13px;
    font-weight: 600;
}


/* ==========================================================================
   6. Forms & controls
   --------------------------------------------------------------------------
   One height token for every control type. The old rules forced
   `height: 50px !important` on inputs while select2 containers were 50px with
   a 48px inner element, so text inputs, native selects and select2 never
   lined up on the same row.
   ========================================================================== */

.form-control,
.custom-select,
select.form-control,
.form-group input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not(.select2-search__field),
.form-group textarea,
.form-group select.form-control,
.card-block input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not(.select2-search__field),
.card-block textarea,
.card-block select.form-control,
.modal-body input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not(.select2-search__field),
.modal-body textarea,
.modal-body select.form-control,
.modal-content input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not(.select2-search__field),
.modal-content textarea,
.modal-content select.form-control {
    height: var(--ui-control-h);
    padding: 0 var(--ui-space-3);
    border: 1px solid var(--ui-border-strong);
    border-radius: var(--ui-radius);
    background-color: var(--ui-surface);
    color: var(--ui-text);
    font-size: 14px;
    box-shadow: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.form-control:focus,
.custom-select:focus,
select.form-control:focus,
.form-group input:focus,
.form-group textarea:focus,
.card-block input:focus,
.card-block select:focus {
    border-color: var(--ui-primary);
    box-shadow: var(--ui-ring);
    outline: 0;
}

.form-control::placeholder {
    color: var(--ui-text-faint);
}

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

.form-group textarea,
.card-block textarea,
.modal-content textarea {
    height: auto;
    min-height: 110px;
    padding: 10px var(--ui-space-3);
    line-height: 1.6;
}

select.form-control {
    /* native arrow sits on the correct edge under direction: rtl */
    padding-inline-end: var(--ui-space-3);
}

label,
.form-group label,
.card-block label,
.modal-content label,
.modal-content p {
    color: var(--ui-text-label);
    font-weight: 600;
    font-size: 13px;
    margin-bottom: 6px;
}

.form-group {
    margin-bottom: var(--ui-space-4);
}

/* Required marker. Lives INSIDE the <label> so it does not break the
   .form-control + .invalid-feedback sibling chain Bootstrap depends on. */
.asterisk,
.ui-req {
    color: var(--ui-danger);
    font-weight: 700;
    margin-inline-start: 2px;
}

.invalid-feedback {
    display: block;
    color: var(--ui-danger);
    font-size: 12px;
    font-weight: 600;
    margin-top: 5px;
}

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

.form-control.is-invalid:focus {
    box-shadow: 0 0 0 3px var(--ui-danger-soft);
}

.ui-hint {
    display: block;
    color: var(--ui-text-muted);
    font-size: 12px;
    font-weight: 500;
    margin-top: 5px;
}

/* --- Form sections ------------------------------------------------------ */

.ui-form-section + .ui-form-section {
    margin-top: var(--ui-space-6);
    padding-top: var(--ui-space-5);
    border-top: 1px solid var(--ui-hairline);
}

.ui-form-section__title {
    display: flex;
    align-items: center;
    gap: var(--ui-space-2);
    font-size: 14px;
    font-weight: 700;
    color: var(--ui-text);
    margin-bottom: var(--ui-space-4);
}

.ui-form-section__title i {
    color: var(--ui-primary);
    font-size: 16px;
}

/* --- Input group (country code + phone) --------------------------------- */

/* The shape declarations below carry !important on purpose. The legacy
   compatibility rule above matches `.form-group input:not(…):not(…):not(…):not(…)`,
   which scores 0,0,5,1 — no practical selector for a child of .ui-input-group
   can outrank that, and an input group is by definition an override of the
   base control shape. Sizing and colour are inherited normally. */
.ui-input-group {
    display: flex;
    align-items: stretch;
}

.ui-input-group > select.form-control {
    flex: 0 0 104px;
    width: 104px;
    border-start-end-radius: 0 !important;
    border-end-end-radius: 0 !important;
    border-inline-end: 0 !important;
    background: var(--ui-bg);
    font-weight: 600;
    direction: ltr;
    text-align: center;
}

.ui-input-group > input.form-control {
    flex: 1 1 auto;
    min-width: 0;
    border-start-start-radius: 0 !important;
    border-end-start-radius: 0 !important;
    direction: ltr;
    text-align: start;
}

.ui-input-group > .form-control:focus {
    position: relative;
    z-index: 2;
}

/* If the leading control gets select2 applied to it, select2 hides the <select>
   and inserts a <span class="select2-container"> as the flex child instead. The
   `> select.form-control` rule above then matches nothing, and select2 sizes its
   own container to 100% — the country code stretches across the row and the
   phone field is squeezed beside it. That shipped on get-profile.

   The select itself is the right control for a short code list, so the fix there
   was to stop applying select2. This rule is the backstop for anywhere it gets
   applied again: same track width, same seam. */
.ui-input-group > .select2-container {
    flex: 0 0 104px;
    width: 104px !important;
}

.ui-input-group > .select2-container .select2-selection {
    height: 100%;
    border-start-end-radius: 0;
    border-end-end-radius: 0;
    border-inline-end: 0;
}

/* --- Password field ------------------------------------------------------ */

.ui-password {
    position: relative;
}

.ui-password > input.form-control {
    padding-inline-end: 42px;
}

.ui-password__toggle {
    position: absolute;
    inset-inline-end: 4px;
    top: 0;
    height: var(--ui-control-h);
    width: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    color: var(--ui-text-faint);
    cursor: pointer;
}

.ui-password__toggle:hover {
    color: var(--ui-text-label);
}

/* --- Date inputs --------------------------------------------------------- */

/* Native date inputs keep an LTR value mask (dd/mm/yyyy) regardless of page
   direction. Forcing direction: ltr keeps the mask and the picker icon on the
   same edge instead of splitting them. */
input[type="date"].form-control,
input[type="time"].form-control,
input[type="datetime-local"].form-control {
    direction: ltr;
    text-align: start;
}

/* --- Roles / checkbox picker -------------------------------------------- */

.ui-checkbox-grid {
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius);
    background: var(--ui-bg);
    padding: var(--ui-space-3);
    max-height: 240px;
    overflow-y: auto;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--ui-space-2);
}

.ui-checkbox-card {
    display: flex;
    align-items: center;
    gap: var(--ui-space-2);
    padding: 9px var(--ui-space-3);
    background: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius-sm);
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease;
    margin: 0;
    font-weight: 600;
    font-size: 13px;
    color: var(--ui-text-label);
}

.ui-checkbox-card:hover {
    border-color: var(--ui-border-strong);
}

.ui-checkbox-card input {
    width: 16px;
    height: 16px;
    accent-color: var(--ui-primary);
    margin: 0;
    flex: 0 0 auto;
    cursor: pointer;
}

.ui-checkbox-card:has(input:checked) {
    border-color: var(--ui-primary);
    background: var(--ui-primary-soft);
    color: var(--ui-primary);
}

.ui-checkbox-grid__empty {
    grid-column: 1 / -1;
    color: var(--ui-text-faint);
    font-size: 13px;
    text-align: center;
    padding: var(--ui-space-4) 0;
}

/* --- Form footer --------------------------------------------------------- */

.ui-form-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--ui-space-2);
    margin-top: var(--ui-space-5);
    padding-top: var(--ui-space-4);
    border-top: 1px solid var(--ui-hairline);
}

.ui-form-footer .btn {
    min-width: 120px;
    height: var(--ui-control-h);
}


/* ==========================================================================
   7. Select2
   ========================================================================== */

.form-group span.select2.select2-container,
.modal-content span.select2.select2-container {
    border: 1px solid var(--ui-border-strong);
    border-radius: var(--ui-radius);
    background: var(--ui-surface);
    min-height: var(--ui-control-h);
    height: var(--ui-control-h);
    padding: 0;
    position: relative;
    width: 100% !important;
}

.form-group span.select2-selection--single,
.modal-content span.select2-selection--single {
    border: 0;
    height: calc(var(--ui-control-h) - 2px);
    display: flex;
    align-items: center;
    width: 100%;
    background: transparent;
}

.form-group span.select2-selection--single .select2-selection__rendered,
.modal-content span.select2-selection--single .select2-selection__rendered {
    line-height: normal;
    padding-inline-start: var(--ui-space-3);
    color: var(--ui-text);
    font-size: 14px;
}

.form-group span.select2-selection--single .select2-selection__arrow,
.modal-content span.select2-selection--single .select2-selection__arrow {
    top: 8px;
}

/* Multi-select grows past the fixed height */
.form-group span.select2.select2-container:has(.select2-selection--multiple),
.modal-content span.select2.select2-container:has(.select2-selection--multiple) {
    height: auto;
}

.form-group span.select2-selection--multiple,
.modal-content span.select2-selection--multiple {
    border: 0;
    min-height: calc(var(--ui-control-h) - 2px);
    background: transparent;
    padding: 5px;
}

.form-group span.select2-selection--multiple .select2-selection__rendered,
.modal-content span.select2-selection--multiple .select2-selection__rendered {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    padding: 0;
    margin: 0;
}

.form-group span.select2-selection--multiple .select2-search--inline,
.modal-content span.select2-selection--multiple .select2-search--inline {
    display: flex;
    align-items: center;
}

.form-group span.select2-selection--multiple .select2-search__field,
.modal-content span.select2-selection--multiple .select2-search__field {
    border: 0;
    background: transparent;
    padding: 0;
    height: auto;
    box-shadow: none;
}

.form-group span.select2-selection--multiple .select2-selection__choice,
.modal-content span.select2-selection--multiple .select2-selection__choice {
    background-color: var(--ui-primary-soft);
    border: 1px solid var(--ui-primary);
    color: var(--ui-primary);
    border-radius: var(--ui-radius-sm);
    padding: 2px var(--ui-space-2);
    margin: 0;
    font-size: 13px;
    font-weight: 600;
    display: flex;
    flex-direction: row-reverse;
    gap: 5px;
    align-items: center;
}

.form-group span.select2-selection--multiple .select2-selection__choice__remove,
.modal-content span.select2-selection--multiple .select2-selection__choice__remove {
    color: var(--ui-danger);
    border: 0;
    background: transparent;
    font-weight: 700;
    margin: 0;
    cursor: pointer;
}

.select2-container--open .select2-selection,
.select2-container--focus .select2-selection {
    box-shadow: none;
}

.select2-dropdown {
    border-color: var(--ui-border-strong);
    border-radius: var(--ui-radius);
    box-shadow: var(--ui-shadow);
}

.select2-results__option--highlighted {
    background: var(--ui-primary) !important;
}


/* ==========================================================================
   8. Buttons
   --------------------------------------------------------------------------
   One scale. `btn-sm` / `btn-lg` are normalised so the legacy markup that
   still carries them does not reintroduce three different heights.
   ========================================================================== */

.btn {
    border-radius: var(--ui-radius);
    font-weight: 600;
    font-size: 14px;
    box-shadow: none;
    height: var(--ui-control-h);
    padding: 0 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    white-space: nowrap;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.btn:focus {
    box-shadow: var(--ui-ring);
}

.btn.btn-sm {
    height: var(--ui-control-h-sm);
    padding: 0 14px;
    font-size: 13px;
}

.btn.btn-lg {
    height: var(--ui-control-h);
    padding: 0 18px;
    font-size: 14px;
}

.btn-primary,
.add-button {
    background-color: var(--ui-primary);
    background-image: none;
    border-color: var(--ui-primary);
    color: #FFFFFF;
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:not(:disabled):not(.disabled):active,
.add-button:hover,
.add-button:focus {
    background-color: var(--ui-primary-hover);
    background-image: none;
    border-color: var(--ui-primary-hover);
    color: #FFFFFF;
}

.btn-primary:disabled,
.btn-primary.disabled {
    background-color: var(--ui-primary);
    border-color: var(--ui-primary);
    opacity: .6;
}

/* Neutral / cancel. Cancel is navigation, not destruction — it must not be red. */
.btn-light,
.ui-btn-cancel {
    background-color: var(--ui-surface);
    background-image: none;
    border: 1px solid var(--ui-border-strong);
    color: var(--ui-text-label);
}

.btn-light:hover,
.ui-btn-cancel:hover,
.ui-btn-cancel:focus {
    background: var(--ui-bg);
    border-color: var(--ui-text-faint);
    color: var(--ui-text);
}

.btn-success {
    background-color: var(--ui-success);
    background-image: none;
    border-color: var(--ui-success);
    color: #FFFFFF;
}

.btn-success:hover,
.btn-success:focus {
    background-color: #15803D;
    border-color: #15803D;
    color: #FFFFFF;
}

/* Outline danger for standalone buttons; solid danger is reserved for the
   delete row action (see §10). */
.btn-danger {
    background-color: var(--ui-surface);
    background-image: none;
    border-color: var(--ui-danger);
    color: #DC2626;
}

.btn-danger:hover,
.btn-danger:focus {
    background-color: #FEF2F2;
    border-color: var(--ui-danger);
    color: #B91C1C;
}

/* Submit-once guard sets this while the request is in flight */
.btn[data-submitting] {
    pointer-events: none;
    opacity: .65;
}


/* ==========================================================================
   9. Tables
   ========================================================================== */

.table-responsive {
    border: 0;
    border-radius: 0;
    overflow: auto;
}

/* A table that sits flush in a card body draws no outer border of its own */
.card .card-block--flush .table-responsive,
.card .card-body--flush .table-responsive {
    border: 0;
    border-radius: 0;
}

table.table,
.table,
.ui-table {
    background: var(--ui-surface);
    color: var(--ui-text);
    margin-bottom: 0;
    width: 100%;
}

.table thead th,
.ui-table thead th {
    background: var(--ui-bg);
    border-top: 0;
    border-bottom: 1px solid var(--ui-border);
    color: var(--ui-text-muted);
    font-weight: 700;
    font-size: 12px;
    letter-spacing: .01em;
    white-space: nowrap;
    padding: var(--ui-space-3) var(--ui-space-4);
    vertical-align: middle;
}

.table tbody td,
.ui-table tbody td {
    border-top: 1px solid var(--ui-hairline);
    color: var(--ui-text-label);
    font-size: 13.5px;
    vertical-align: middle;
    padding: 10px var(--ui-space-4);
}

.table tbody tr:first-child td,
.ui-table tbody tr:first-child td {
    border-top: 0;
}

.table-hover tbody tr:hover,
.ui-table tbody tr:hover {
    background: var(--ui-bg);
}

/* style.css:9782 sets `white-space: nowrap` on EVERY .table cell. That pushed
   this table wider than its container, the overflow engaged the sticky actions
   column below, and the pinned column landed on top of the status toggle — the
   view button ended up flush against it with no gap.
   Let ordinary text cells wrap; only the deliberately narrow columns stay on
   one line. Headers keep nowrap so labels never break mid-word. */
.ui-table tbody td {
    white-space: normal;
}

/* Narrow, fixed-content columns */
.ui-table .ui-col-index {
    width: 56px;
    white-space: nowrap;
    color: var(--ui-text-faint);
    font-weight: 600;
}

.ui-table .ui-col-media {
    width: 64px;
    white-space: nowrap;
}

.ui-table .ui-col-toggle {
    width: 96px;
    white-space: nowrap;
    text-align: center;
    padding-inline: var(--ui-space-4);
}

/* Actions column.

   This was `position: sticky; inset-inline-end: 0` so it stayed reachable while
   a wide table scrolled sideways. Dropped deliberately: a sticky cell is
   positioned, so it paints above its unpositioned siblings and — whenever the
   scroll container reported any overflow at all — it rendered on top of the
   status column instead of beside it. The cells always had 16px of padding
   either side, so the collision was the positioning, not the spacing.

   An 8-column table does not need a frozen column; on a narrow screen the
   wrapper scrolls like any other table. A hairline separates it instead. */
/* No `width` here, deliberately.

   This column used to carry `width: 1%`, the usual "shrink to content" idiom.
   It relies on the browser expanding the cell to its min-content width, and
   measured in Chrome that expansion never happened: the cell stayed 34px wide
   against 122px of buttons, so the outermost button — view, under RTL —
   painted straight over the status column. `width: 1px`, `display: flex` on the
   inner wrapper and `white-space: nowrap` were all measured and all still
   failed; only removing the width declaration sizes the column correctly. */
.ui-table .ui-col-actions {
    white-space: nowrap;
    text-align: center;
    padding-inline: var(--ui-space-4);
    border-inline-end: 1px solid var(--ui-hairline);
}

.ui-table thead .ui-col-actions {
    border-inline-end-color: var(--ui-border);
}

/* Secondary text under a primary cell value */
.ui-cell-title {
    font-weight: 600;
    color: var(--ui-text);
}

.ui-cell-sub {
    display: block;
    color: var(--ui-text-faint);
    font-size: 12px;
    font-weight: 500;
    margin-top: 1px;
}

.ui-cell-muted {
    color: var(--ui-text-faint);
}

/* Values that must always read left-to-right (phones, emails, ids) */
.ui-ltr {
    direction: ltr;
    display: inline-block;
    unicode-bidi: isolate;
}


/* ==========================================================================
   10. Row action buttons
   --------------------------------------------------------------------------
   Replaces the old inline
     style="position:relative;background-color:#1b6d85;width:50px"
   with absolutely positioned icons at `left: 7px`, which put the glyph
   off-centre under direction: rtl.
   ========================================================================== */

.ui-actions {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--ui-space-2);
}

/* The row's rhythm comes from `gap` alone. style.css puts margin: 10px on .btn,
   which showed up as an 18px gap next to the one labelled action button while
   its icon-only neighbours sat at 8px. */
.ui-actions > * {
    margin: 0;
}

.btn-icon {
    /* Never shrink: these are fixed-size targets, and letting them flex made
       the surrounding cell's min-content width collapse (see .ui-col-actions). */
    flex: 0 0 auto;
    width: var(--ui-control-h-sm);
    height: var(--ui-control-h-sm);
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--ui-radius-sm);
    border: 1px solid transparent;
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}

.btn-icon i {
    font-size: 13px;
    line-height: 1;
}

.btn-icon--view {
    background: var(--ui-info-soft);
    border-color: transparent;
    color: #0284C7;
}

.btn-icon--view:hover,
.btn-icon--view:focus {
    background: var(--ui-info);
    color: #FFFFFF;
}

.btn-icon--edit {
    background: #F1F5F9;
    border-color: transparent;
    color: #475569;
}

.btn-icon--edit:hover,
.btn-icon--edit:focus {
    background: #475569;
    color: #FFFFFF;
}

.btn-icon--paid {
    background: var(--ui-success-soft);
    border-color: transparent;
    color: #15803D;
}

.btn-icon--paid:hover,
.btn-icon--paid:focus {
    background: var(--ui-success);
    color: #FFFFFF;
}

.btn-icon--delete {
    background: var(--ui-danger-soft);
    border-color: transparent;
    color: #DC2626;
}

/* A one-button form (mark-as-paid) sitting among icon buttons must not break
   the flex row it lives in. */
.ui-inline-form {
    display: inline-flex;
    margin: 0;
}

/* The "advance to next status" action carries a label, not just an icon, so it
   is a real button rather than a .btn-icon square. */
.ui-actions .ui-next-status {
    height: var(--ui-control-h-sm);
    padding: 0 12px;
    font-size: 12px;
    white-space: nowrap;
}

.btn-icon--delete:hover,
.btn-icon--delete:focus {
    background: var(--ui-danger);
    color: #FFFFFF;
}


/* ==========================================================================
   11. Badges, avatars, toggles
   ========================================================================== */

.ui-badges {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ui-space-1);
}

.ui-badge {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 700;
    line-height: 1.6;
    background: var(--ui-primary-soft);
    color: var(--ui-primary);
    white-space: nowrap;
}

.ui-badge--muted {
    background: #F1F5F9;
    color: var(--ui-text-muted);
}

.ui-badge--success {
    background: var(--ui-success-soft);
    color: #15803D;
}

.ui-badge--danger {
    background: var(--ui-danger-soft);
    color: #B91C1C;
}

.ui-badge--info {
    background: var(--ui-info-soft);
    color: #0369A1;
}

.ui-badge--warning {
    background: var(--ui-warning-soft);
    color: #B45309;
}

/* .ui-badge already defaults to the brand colour; the explicit modifier exists
   so orderStatusMap() can name a variant for every status without a special case. */
.ui-badge--primary {
    background: var(--ui-primary-soft);
    color: var(--ui-primary);
}

.ui-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid var(--ui-border);
    background: var(--ui-surface);
    display: block;
}

/* --- Switch -------------------------------------------------------------- */

.ui-switch {
    position: relative;
    display: inline-block;
    width: 42px;
    height: 24px;
    flex: 0 0 auto;
    margin: 0;
    vertical-align: middle;
}

.ui-switch input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.ui-switch .ui-switch__slider {
    position: absolute;
    inset: 0;
    background: #CBD5E1;
    border-radius: 999px;
    cursor: pointer;
    transition: background-color .2s ease;
}

.ui-switch .ui-switch__slider::before {
    content: "";
    position: absolute;
    top: 3px;
    inset-inline-start: 3px;
    width: 18px;
    height: 18px;
    background: #FFFFFF;
    border-radius: 50%;
    box-shadow: 0 1px 3px rgba(15, 23, 42, .2);
    transition: transform .2s ease;
}

.ui-switch input:checked + .ui-switch__slider {
    background: var(--ui-success);
}

.ui-switch input:checked + .ui-switch__slider::before {
    transform: translateX(-18px);
}

.ui-switch input:focus-visible + .ui-switch__slider {
    box-shadow: var(--ui-ring);
}

/* Under LTR the knob travels the other way */
[dir="ltr"] .ui-switch input:checked + .ui-switch__slider::before {
    transform: translateX(18px);
}

/* Switch paired with a text label in a form. Boxed to the same height as a
   text input so it reads as a field on the grid rather than a floating control.
   (The old markup put the caption INSIDE .switch, whose 60x30 box then clipped it.) */
.ui-switch-field {
    display: flex;
    align-items: center;
    gap: var(--ui-space-3);
    height: var(--ui-control-h);
    padding: 0 var(--ui-space-3);
    border: 1px solid var(--ui-border-strong);
    border-radius: var(--ui-radius);
    background: var(--ui-surface);
}

.ui-switch-field > label {
    margin-bottom: 0;
}

.ui-switch-field__caption {
    color: var(--ui-text-muted);
    font-size: 13px;
    font-weight: 600;
}


/* ==========================================================================
   12. Filter card
   ========================================================================== */

.admin-filter-card .card-header {
    cursor: pointer;
    user-select: none;
}

.admin-filter-card .card-header h5 {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

.admin-filter-toggle {
    width: var(--ui-control-h-sm);
    height: var(--ui-control-h-sm);
    border-radius: var(--ui-radius);
    border: 1px solid var(--ui-border);
    background: var(--ui-bg);
    color: #4A5568;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: transform .2s ease, background-color .2s ease, color .2s ease;
}

.admin-filter-card:not(.is-collapsed) .admin-filter-toggle {
    background: var(--ui-primary-soft);
    color: var(--ui-primary);
    transform: rotate(180deg);
}

.admin-filter-card.is-collapsed .card-block,
.admin-filter-card.is-collapsed .card-body,
.admin-filter-card.is-collapsed .ui-filter-body {
    display: none;
}

/* Count of filters currently applied, shown next to the "Search" heading */
.ui-filter-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--ui-primary);
    color: #FFFFFF;
    font-size: 11px;
    font-weight: 700;
}

.ui-filter-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--ui-space-4);
}

@media (max-width: 991.98px) {
    .ui-filter-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 575.98px) {
    .ui-filter-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

.ui-filter-grid .form-group {
    margin-bottom: 0;
    min-width: 0;
}

/* A free-text search box needs more room than a two-option select, and giving
   it two columns also stops the last field orphaning onto a row of its own —
   5 equal fields in a 4-column grid left "to date" stranded next to a gap. */
.ui-filter-grid .ui-col-span-2 {
    grid-column: span 2;
}

@media (max-width: 575.98px) {
    .ui-filter-grid .ui-col-span-2 {
        grid-column: span 1;
    }
}

.ui-filter-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: var(--ui-space-2);
    margin-top: var(--ui-space-5);
    padding-top: var(--ui-space-4);
    border-top: 1px solid var(--ui-hairline);
}

.ui-filter-actions .btn {
    min-width: 110px;
}


/* ==========================================================================
   13. Pagination
   --------------------------------------------------------------------------
   Requires Paginator::useBootstrapFour() in AppServiceProvider — without it
   Laravel 12 emits its Tailwind paginator, which matches nothing here.
   ========================================================================== */

.ui-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--ui-space-3);
    padding: var(--ui-space-3) var(--ui-space-5);
    border-top: 1px solid var(--ui-border);
    background: var(--ui-surface);
}

.ui-pagination__summary {
    color: var(--ui-text-muted);
    font-size: 13px;
    font-weight: 600;
}

.ui-pagination__summary strong {
    color: var(--ui-text-label);
    font-weight: 700;
}

.ui-pagination nav {
    margin-inline-start: auto;
}

.ui-pagination .pagination {
    margin: 0;
    display: flex;
    align-items: center;
    gap: var(--ui-space-1);
    flex-wrap: wrap;
}

.pagination .page-item .page-link,
.ui-pagination .page-link {
    min-width: var(--ui-control-h-sm);
    height: var(--ui-control-h-sm);
    padding: 0 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius-sm);
    background: var(--ui-surface);
    color: var(--ui-text-label);
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.pagination .page-item .page-link:hover {
    background: var(--ui-bg);
    border-color: var(--ui-border-strong);
    color: var(--ui-text);
}

.pagination .page-item.active .page-link,
.ui-pagination .page-item.active .page-link {
    background: var(--ui-primary);
    border-color: var(--ui-primary);
    color: #FFFFFF;
}

.pagination .page-item.disabled .page-link {
    background: var(--ui-bg);
    border-color: var(--ui-border);
    color: var(--ui-text-faint);
    opacity: 1;
}

.pagination .page-item .page-link:focus {
    box-shadow: var(--ui-ring);
}

/* The stock view bakes « / » into the markup, which points the wrong way under
   RTL. resources/views/vendor/pagination/bootstrap-4.blade.php leaves the glyph
   empty and tags prev/next with a class; the chevron is drawn here so it flips
   with the writing direction. */
.pagination .page-link--prev::after,
.pagination .page-link--next::after {
    font-size: 17px;
    line-height: 1;
    font-family: inherit;
}

/* Page direction is RTL by default (rtl.css applies it for every locale):
   "previous" points towards the start of the line, i.e. to the right. */
.pagination .page-link--prev::after {
    content: "\203A"; /* › */
}

.pagination .page-link--next::after {
    content: "\2039"; /* ‹ */
}

[dir="ltr"] .pagination .page-link--prev::after {
    content: "\2039";
}

[dir="ltr"] .pagination .page-link--next::after {
    content: "\203A";
}

.pagination .page-link--dots {
    border-color: transparent;
    background: transparent;
    letter-spacing: 1px;
}


/* ==========================================================================
   14. Show-page (read-only detail view)
   --------------------------------------------------------------------------
   14a is the design system: .ui-tabs + .ui-details, used by migrated pages.
   14b below is the legacy `body.admin-show-page` chain, kept for the ~47 show
   pages still on the old markup. Delete 14b as those pages migrate.
   ========================================================================== */

/* --- 14a. Tabs ----------------------------------------------------------- */

/* Underline tabs rather than Bootstrap's boxed folder tabs. Because the markup
   omits `.nav-tabs`, none of Bootstrap's tab styling applies and nothing has to
   be overridden — see admin.partial.ui.tab-nav. */
.ui-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ui-space-1);
    list-style: none;
    margin: 0;
    padding: 0 var(--ui-space-5);
    border-bottom: 1px solid var(--ui-border);
    background: var(--ui-surface);
}

.ui-tabs .nav-item {
    margin: 0;
}

.ui-tabs .nav-link {
    display: block;
    padding: var(--ui-space-3) var(--ui-space-4);
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    background: transparent;
    color: var(--ui-text-muted);
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
    transition: color .15s ease, border-color .15s ease;
}

.ui-tabs .nav-link:hover {
    color: var(--ui-text);
}

.ui-tabs .nav-link.active {
    color: var(--ui-primary);
    border-bottom-color: var(--ui-primary);
}

/* --- 14a. Detail list ---------------------------------------------------- */

.ui-details {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--ui-space-6);
    margin: 0;
}

/* Fixed label column, not a percentage. With `minmax(110px, 32%)` a
   .ui-detail--wide row measured its 32% against the full card rather than
   against one of the two columns, so its value started ~180px further in than
   every other row's. A fixed width aligns normal and wide rows automatically. */
.ui-detail {
    display: grid;
    grid-template-columns: var(--ui-detail-label) 1fr;
    gap: var(--ui-space-3);
    align-items: start;
    min-height: 46px;
    padding: var(--ui-space-3) 0;
    border-bottom: 1px solid var(--ui-hairline);
}

.ui-detail--wide {
    grid-column: 1 / -1;
}

.ui-detail__label {
    margin: 0;
    color: var(--ui-text-muted);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.6;
}

.ui-detail__value {
    margin: 0;
    color: var(--ui-text);
    font-size: 13px;
    font-weight: 700;
    line-height: 1.6;
    overflow-wrap: anywhere;
}

/* Last row in each column carries no rule, so the list does not end on a line */
.ui-details > .ui-detail:last-child,
.ui-details > .ui-detail:nth-last-child(2):not(.ui-detail--wide) {
    border-bottom: 0;
}

@media (max-width: 767.98px) {
    .ui-details {
        grid-template-columns: minmax(0, 1fr);
    }

    .ui-detail {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--ui-space-1);
        min-height: 0;
    }
}

/* Tab panes carry no chrome of their own — the card around them provides it.
   The old markup nested pcoded-wrapper > pcoded-content > pcoded-inner-content >
   main-body > page-wrapper > row > col > card inside every single pane, six
   levels deep, each contributing padding.

   Both selectors are needed, and only at this one level of nesting. A pane's
   tables must stay flush with the card edge, so the inset lives on the pane's
   text content rather than on the pane itself. A pane that groups its details
   under headings (branches/show, vendors/show) wraps them in .ui-form-section,
   which is then the direct child — measured in Chrome, those grids sat 20px
   further out than the pane's own top-level list, giving one show page three
   different label columns instead of two. */
.tab-content > .tab-pane > .ui-details,
.tab-content > .tab-pane > .ui-form-section {
    padding: var(--ui-space-5);
}

/* …and the nested list must not add the inset a second time. */
.tab-content > .tab-pane > .ui-form-section > .ui-details {
    padding: 0;
}


/* --- 14a. Stacked info blocks ------------------------------------------

   The orders show page lays its fields out as stacked label-above-value blocks
   in a Bootstrap grid, rather than the two-column .ui-details list. Both are
   legitimate; this is the stacked variant. These three classes replace an
   `.info-label` / `.info-value` / `.info-row` set that lived in a page-level
   <style> block on that view. */

.ui-info {
    margin-bottom: var(--ui-space-4);
}

.ui-info__label {
    color: var(--ui-text-muted);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    margin-bottom: 3px;
}

.ui-info__value {
    color: var(--ui-text);
    font-size: 14px;
    font-weight: 700;
    overflow-wrap: anywhere;
}

.ui-info__value a {
    color: var(--ui-primary);
}

/* Inline caption sitting next to an icon button ("Invoice:", "Print:") */
.ui-info__inline-label {
    color: var(--ui-text-muted);
    font-size: 12px;
    font-weight: 600;
}

/* A table with more columns than the viewport comfortably fits; the wrapping
   .table-responsive scrolls it. */
.ui-table--wide {
    min-width: 700px;
}


/* --- 14b. Legacy show pages --------------------------------------------- */

body.admin-show-page .card {
    box-shadow: 0 4px 16px rgba(23, 39, 65, 0.035);
}

body.admin-show-page .card .card-header {
    padding: 14px var(--ui-space-5);
}

body.admin-show-page .card .card-header h5 {
    font-size: 15px;
    font-weight: 700;
}

body.admin-show-page .card .card-body > .row > [class*="col-"] .form-group,
body.admin-show-page .tab-content > .tab-pane > .row > [class*="col-"] .form-group {
    display: grid;
    grid-template-columns: minmax(120px, 34%) 1fr;
    gap: 10px;
    align-items: start;
    min-height: 46px;
    margin-bottom: 0;
    padding: var(--ui-space-3) 0;
    border-bottom: 1px solid #EDF1F6;
}

body.admin-show-page .card .card-body > .row > [class*="col-"]:nth-last-child(-n+2) .form-group {
    border-bottom-color: transparent;
}

body.admin-show-page .card .card-body > .row > [class*="col-"] .form-group label,
body.admin-show-page .tab-content > .tab-pane > .row > [class*="col-"] .form-group label {
    color: #7B8494;
    font-size: 12px;
    font-weight: 600;
    margin: 0;
    line-height: 1.6;
}

body.admin-show-page .card .card-body > .row > [class*="col-"] .form-group span,
body.admin-show-page .tab-content > .tab-pane > .row > [class*="col-"] .form-group span {
    color: #263244;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.6;
    margin-right: 0;
    overflow-wrap: anywhere;
}

body.admin-show-page .card .card-body > .row > [class*="col-"] .form-group img,
body.admin-show-page .tab-content > .tab-pane > .row > [class*="col-"] .form-group img {
    width: 58px;
    height: 58px;
    border-radius: var(--ui-radius);
    object-fit: contain;
    border: 1px solid #E5EDF6;
    background: #fff;
}

body.admin-show-page .nav.nav-pills,
body.admin-show-page .nav.nav-tabs {
    background: #fff;
    border: 1px solid #E7EDF5;
    border-radius: var(--ui-radius);
    padding: var(--ui-space-3) 14px;
    box-shadow: 0 4px 16px rgba(23, 39, 65, 0.035);
    gap: var(--ui-space-2);
}

body.admin-show-page .nav.nav-pills .nav-link,
body.admin-show-page .nav.nav-tabs .nav-link {
    border-radius: var(--ui-radius-sm);
    color: #6B7280;
    font-size: 14px;
    font-weight: 600;
    padding: 9px var(--ui-space-4);
    border: 0;
}

body.admin-show-page .nav.nav-pills .nav-link.active,
body.admin-show-page .nav.nav-tabs .nav-link.active {
    background: #10AEE8;
    color: #fff;
    box-shadow: 0 8px 18px rgba(16, 174, 232, 0.18);
}

body.admin-show-page .tab-content > .tab-pane > .row {
    background: #fff;
    border: 1px solid #E7EDF5;
    border-radius: var(--ui-radius);
    box-shadow: 0 4px 16px rgba(23, 39, 65, 0.035);
    margin: 0 0 var(--ui-space-5);
    padding: var(--ui-space-1) var(--ui-space-5) var(--ui-space-5);
}

body.admin-show-page .form-group:has(textarea),
body.admin-show-page .form-group:has(.ck-editor),
body.admin-show-page .form-group:has(.cke) {
    grid-template-columns: 1fr;
}

body.admin-show-page .form-group textarea {
    width: 100%;
    min-height: 110px;
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius);
    padding: var(--ui-space-3);
    color: #263244;
    font-size: 13px;
    background: var(--ui-bg);
}

@media (max-width: 575.98px) {
    body.admin-show-page .card .card-body > .row > [class*="col-"] .form-group,
    body.admin-show-page .tab-content > .tab-pane > .row > [class*="col-"] .form-group {
        grid-template-columns: 1fr;
        gap: 6px;
    }
}


/* ==========================================================================
   15. Legacy shims
   --------------------------------------------------------------------------
   Kept so the ~48 pages not yet migrated do not regress. Delete each block as
   its pages move to the ui/* partials.
   ========================================================================== */

/* Legacy row-action buttons (66 files still use .views-b). */
.table .views-b,
.table .views-b3,
td .views-b,
td .views-b3 {
    min-width: var(--ui-control-h-sm);
    height: var(--ui-control-h-sm);
    padding: 0 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.table .views-b.btn-danger,
.table .views-b3.btn-danger,
td .views-b.btn-danger,
td .views-b3.btn-danger {
    background: var(--ui-danger);
    border-color: var(--ui-danger);
    color: #FFFFFF;
}

.table .views-b.btn-danger i,
.table .views-b3.btn-danger i,
td .views-b.btn-danger i,
td .views-b3.btn-danger i {
    color: #FFFFFF;
    font-size: 13px;
}

.table .views-b.btn-danger:hover,
.table .views-b3.btn-danger:hover,
td .views-b.btn-danger:hover,
td .views-b3.btn-danger:hover {
    background: #DC2626;
    border-color: #DC2626;
}

/* Legacy .switch toggle used by unmigrated forms and the layout markup. */
.switch {
    position: relative;
    display: inline-block;
    width: 42px;
    height: 24px;
    margin: 0 var(--ui-space-2);
    vertical-align: middle;
}

.switch input {
    opacity: 0;
    width: 0;
    height: 0;
}

.slider {
    position: absolute;
    inset: 0;
    background-color: #CBD5E1;
    cursor: pointer;
    transition: .3s;
}

.slider:before {
    position: absolute;
    content: "";
    width: 18px;
    height: 18px;
    inset-inline-start: 3px;
    bottom: 3px;
    background-color: #fff;
    transition: .3s;
}

input:checked + .slider {
    background-color: var(--ui-success);
}

input:focus + .slider {
    box-shadow: 0 0 1px var(--ui-success);
}

input:checked + .slider:before {
    transform: translateX(-18px);
}

[dir="ltr"] input:checked + .slider:before {
    transform: translateX(18px);
}

.slider.round {
    border-radius: 999px;
}

.slider.round:before {
    border-radius: 50%;
}

/* Legacy filter action rows on the 12 unmigrated filter pages. */
form[method="get"] ._show_save {
    justify-content: flex-start;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 10px;
}

form[method="get"] button,
form[method="get"] .btn,
form[method="get"] .form-btns a,
form[method="get"] .form-btns button {
    height: var(--ui-control-h);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--ui-radius);
    padding: 0 var(--ui-space-5);
    margin-bottom: 0;
    font-weight: 600;
}

form[method="get"] .col-md-3[style*="padding-top"],
form[method="get"] .col-md-2[style*="padding-top"] {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    flex-wrap: wrap;
}

._show_save {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 10px;
}

.form-btns a,
.form-btns button,
.modal-footer .btn {
    border-radius: var(--ui-radius);
    padding: 0 var(--ui-space-5);
}

.card form .row > [class*="col-"] {
    margin-bottom: var(--ui-space-4);
}

/* Migrated forms space their fields with .form-group's own margin. Without this
   they picked up the legacy column margin as well and every row sat 32px apart. */
.card form .ui-form-section .row > [class*="col-"] {
    margin-bottom: 0;
}

/* Unmigrated index pages still put the "add" button in an orphan .row wedged
   between .card-header and .card-block. Migrated pages move it into the page
   header instead (admin.partial.ui.page-header) and never match this. */
.card > .row:has(.add-button) {
    display: flex;
    justify-content: flex-end;
    padding: 10px var(--ui-space-5);
    margin: 0;
}

.status_para {
    color: #fff;
}

/* Today-orders status tiles. .box-a and .c2–.c6 live in style.css; only the
   "new order" colour is ours, because it is brand-derived. */
.c1 {
    background: var(--ui-primary);
}

/* --- Status stat tiles --------------------------------------------------

   Replaces .box-a: a fully saturated 190px-tall block per status, laid out in
   Bootstrap columns that left a hole in the last row (nine tiles at col-xl-3
   gives 4+4+1), with the count at one edge and the label at the other.

   Now: a surface card with one accent colour, ~76px tall, count and label
   stacked beside a coloured icon chip. The accent arrives as --ui-stat-accent
   from orderStatusMap(), so the colour lives with the status definition.

   Nine statuses across three columns divides evenly. */

.ui-status-tiles {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--ui-space-3);
    margin-bottom: var(--ui-space-5);
}

@media (max-width: 991.98px) {
    .ui-status-tiles {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* Nine tiles cannot divide into two columns, so the last one spans the row
       rather than sitting beside a gap. */
    .ui-status-tiles > .ui-stat:last-child {
        grid-column: 1 / -1;
    }
}

@media (max-width: 575.98px) {
    .ui-status-tiles {
        grid-template-columns: minmax(0, 1fr);
    }
}

.ui-stat {
    display: flex;
    align-items: center;
    gap: var(--ui-space-3);
    width: 100%;
    padding: var(--ui-space-3) var(--ui-space-4);
    background: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius-lg);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
    text-align: start;
    cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}

/* The accent reads as a rail on the leading edge rather than flooding the card,
   so nine tiles side by side stay legible. */
.ui-stat::before {
    content: "";
    align-self: stretch;
    flex: 0 0 3px;
    border-radius: 3px;
    background: var(--ui-stat-accent, var(--ui-primary));
}

.ui-stat:hover {
    border-color: var(--ui-stat-accent, var(--ui-primary));
    box-shadow: 0 8px 20px rgba(15, 23, 42, .08);
    transform: translateY(-1px);
}

.ui-stat:focus-visible {
    outline: 2px solid var(--ui-stat-accent, var(--ui-primary));
    outline-offset: 2px;
}

/* Solid accent chip: the lottie animations are white line art and would vanish
   on the card surface. */
.ui-stat__icon {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 7px;
    border-radius: 50%;
    background: var(--ui-stat-accent, var(--ui-primary));
}

.ui-stat__icon svg {
    width: 100%;
    height: 100%;
    display: block;
}

.ui-stat__body {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.ui-stat__value {
    color: var(--ui-text);
    font-size: 20px;
    font-weight: 700;
    line-height: 1.2;
}

.ui-stat__label {
    color: var(--ui-text-muted);
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.35;
    overflow-wrap: anywhere;
}

/* ==========================================================================
   16. Media — uploads, thumbnails, ratings, inline empty states
   --------------------------------------------------------------------------
   Added for the activities / order-types / reviews / branches / vendor pages,
   which between them hand-rolled the same four widgets with inline styles:

     - a file input plus a 50px preview thumbnail wired by an inline
       `onchange="document.getElementById('imgPreviewMain').src = ..."`,
       copy-pasted with a different hardcoded id per page;
     - a strip of client images, each `style="width:50px;height:50px;
       border-radius:50%"` — circles crop the middle out of a photo;
     - a numeric rating rendered as a bare digit;
     - "no rows" handled by rendering an empty <tbody>.
   ========================================================================== */

/* --- Upload field ------------------------------------------------------- */

.ui-upload {
    display: flex;
    align-items: center;
    gap: var(--ui-space-3);
}

/* The native control keeps its own height: a file input renders a button
   inside itself, and forcing --ui-control-h on it clips that button in
   Chrome. Padding centres it instead. */
.ui-upload > input[type="file"].form-control {
    height: auto;
    min-height: var(--ui-control-h);
    padding: 8px 12px;
    line-height: 1.5;
    cursor: pointer;
}

.ui-upload__preview {
    flex: 0 0 auto;
    width: var(--ui-control-h);
    height: var(--ui-control-h);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius);
    background: var(--ui-bg);
    object-fit: cover;
    display: block;
}

/* `display: block` above is an AUTHOR declaration, and author styles beat the
   UA stylesheet's `[hidden] { display: none }` regardless of specificity — the
   attribute does not win by being more specific, it loses by being in a weaker
   origin. So the placeholder <img hidden> that image-field emits when there is
   no current image was still laid out, as a 42px broken-image box, on every
   create form. It has to be re-stated here. */
.ui-upload__preview[hidden] {
    display: none;
}

/* --- Thumbnail strip ---------------------------------------------------- */

.ui-thumbs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ui-space-2);
}

/* Square with a soft radius, not a circle: these are photographs of a place,
   and a circular mask throws away the corners of every one of them. */
.ui-thumb {
    display: block;
    width: 64px;
    height: 64px;
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius);
    overflow: hidden;
    background: var(--ui-bg);
    transition: border-color .15s ease, transform .15s ease;
}

.ui-thumb:hover,
.ui-thumb:focus-visible {
    border-color: var(--ui-primary);
    transform: translateY(-1px);
}

.ui-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* A single larger figure — a static map, a licence scan. */
.ui-figure {
    display: block;
    max-width: 100%;
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius);
    overflow: hidden;
}

.ui-figure img {
    display: block;
    max-width: 100%;
    height: auto;
}

/* --- Rating ------------------------------------------------------------- */

.ui-rating {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}

.ui-rating__stars {
    /* Stars read left-to-right in every locale — a filled-then-empty run
       reversed by the RTL body would show the empty ones first. */
    direction: ltr;
    unicode-bidi: isolate;
    color: var(--ui-warning);
    font-size: 13px;
    letter-spacing: 1px;
}

.ui-rating__stars i.is-empty {
    color: var(--ui-border-strong);
}

.ui-rating__value {
    color: var(--ui-text);
    font-size: 13px;
    font-weight: 700;
}

/* --- Inline empty state ------------------------------------------------- */

/* partial/empty-state.blade.php swaps a whole table for an illustration. That
   is right for a page's main list, but too loud for a secondary table inside
   a tab, so those use a single muted row instead. */
.ui-table td.ui-empty {
    padding: var(--ui-space-6) var(--ui-space-4);
    color: var(--ui-text-muted);
    font-size: 13px;
    text-align: center;
}

/* --- Comment thread ----------------------------------------------------- */

.ui-thread {
    display: flex;
    flex-direction: column;
    gap: var(--ui-space-3);
    margin: 0;
    padding: 0;
    list-style: none;
}

.ui-comment {
    display: flex;
    align-items: flex-start;
    gap: var(--ui-space-3);
    padding: var(--ui-space-4);
    background: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius-lg);
}

.ui-comment__body {
    flex: 1 1 auto;
    min-width: 0;
}

.ui-comment__head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--ui-space-2);
    margin-bottom: var(--ui-space-1);
}

.ui-comment__author {
    color: var(--ui-text);
    font-size: 13.5px;
    font-weight: 700;
}

.ui-comment__time {
    color: var(--ui-text-faint);
    font-size: 12px;
}

.ui-comment__text {
    margin: 0 0 var(--ui-space-3);
    color: var(--ui-text);
    font-size: 13.5px;
    line-height: 1.6;
    overflow-wrap: anywhere;
}

.ui-comment__actions {
    display: flex;
    gap: var(--ui-space-2);
}

/* ==========================================================================
   17. Map picker
   --------------------------------------------------------------------------
   The branch location modal. The container needs an explicit height: a Google
   map fills its parent, and a parent with no height collapses to zero — which
   is half of why the picker used to come up as a grey box (the other half was
   being initialised while the modal was still display:none; see
   branches/_scripts.blade.php).
   ========================================================================== */

.ui-map {
    width: 100%;
    height: 380px;
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius);
    background: var(--ui-bg);
}

@media (max-height: 700px) {
    .ui-map {
        height: 260px;
    }
}

/* A button that belongs to the fields above it rather than to the form footer —
   "pick on the map", "recalculate", and so on. */
.ui-form-inline-action {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ui-space-2);
    margin-top: calc(var(--ui-space-1) * -1);
}


/* ==========================================================================
   18. Wizard (multi-step form)
   --------------------------------------------------------------------------
   Replaces public/wizard-form/wizard-style.css, which vendors/create and
   vendors/edit loaded as a page-level stylesheet. Three reasons it had to go
   rather than be overridden:

     1. It hardcoded #2e6dd3 in five places — the step pill background, the
        finish button, the connector line and two hover states. That blue is
        not in the token set; the panel's accent is --ui-primary. Overriding it
        would have meant re-declaring each of those five rules at a higher
        specificity and leaving the dead source in the tree.

     2. It styled the bare `button` ELEMENT:

            button { background-color: #2e6dd3; border-radius: 4px !important; }

        Element selectors do not stay inside their feature. Every button on the
        page inherited that 4px radius through !important — the page-header
        action, the modal close, the row-action icon buttons, the pagination
        controls — so the two vendor forms were the only pages in the panel
        where button corners did not match. And any button without a .btn-*
        variant to outrank the 0,0,1 background-color also came out blue.

     3. Its connector line was `width: 350%; right: -250px` on a pseudo-element
        with z-index: -1. The 350%/-250px pair is tuned for one particular pill
        count and pill width, `right` is physical rather than logical so it
        pointed the wrong way in LTR, and z-index: -1 put the line behind the
        card background instead of behind the pills. The version below draws
        the connector between adjacent pills with logical properties, so it
        works at any step count and in both directions.

   The companion <link> to wizard-form/jquery.steps.css was a 404 on every
   request — the file does not exist in public/. jQuery Steps is not used here;
   the stepper is hand-rolled in vendors/_scripts.blade.php.
   ========================================================================== */

.ui-wizard {
    display: block;
}

/* --- Step strip ---------------------------------------------------------- */

.ui-wizard__steps {
    display: flex;
    align-items: flex-start;
    gap: var(--ui-space-2);
    margin-bottom: var(--ui-space-6);
    padding-bottom: var(--ui-space-2);
    list-style: none;
}

.ui-wizard__step {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--ui-space-2);
    position: relative;
    padding: 0;
    margin: 0;
    background: none;
    border: 0;
    cursor: pointer;
    text-align: center;
    font: inherit;
    color: var(--ui-text-faint);
}

/* The connector. Drawn from the start edge of each pill back towards the
   previous one, so it needs no knowledge of how many steps there are. Logical
   inset keeps it on the correct side in both RTL and LTR. */
.ui-wizard__step::before {
    content: '';
    position: absolute;
    top: 15px;
    inset-inline-end: 50%;
    inset-inline-start: -50%;
    height: 2px;
    background: var(--ui-border);
    z-index: 0;
}

.ui-wizard__step:first-child::before {
    display: none;
}

.ui-wizard__step--done::before,
.ui-wizard__step--active::before {
    background: var(--ui-primary);
}

/* --- Step marker -------------------------------------------------------- */

.ui-wizard__num {
    position: relative;
    z-index: 1;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 2px solid var(--ui-border);
    background: var(--ui-surface);
    color: var(--ui-text-faint);
    font-size: 13px;
    font-weight: 700;
    line-height: 1;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.ui-wizard__step--done .ui-wizard__num {
    border-color: var(--ui-primary);
    background: var(--ui-primary);
    color: #fff;
}

.ui-wizard__step--active .ui-wizard__num {
    border-color: var(--ui-primary);
    background: var(--ui-primary);
    color: #fff;
    box-shadow: var(--ui-ring);
}

.ui-wizard__step:hover:not(.ui-wizard__step--active) .ui-wizard__num {
    border-color: var(--ui-border-strong);
}

/* A completed step that is not the current one shows a check instead of its
   number, which is how you tell "done" from "here" at a glance. */
.ui-wizard__step--done:not(.ui-wizard__step--active) .ui-wizard__num::after {
    content: '\2713';
    font-size: 15px;
}

.ui-wizard__step--done:not(.ui-wizard__step--active) .ui-wizard__num span {
    display: none;
}

/* --- Step label --------------------------------------------------------- */

.ui-wizard__label {
    font-size: 12px;
    font-weight: 600;
    line-height: 1.35;
    color: inherit;
    /* Long Arabic step names must wrap rather than widen the strip; style.css
       sets white-space: nowrap globally (see section 15). */
    white-space: normal;
    overflow-wrap: anywhere;
}

.ui-wizard__step--active {
    color: var(--ui-primary);
}

.ui-wizard__step--done:not(.ui-wizard__step--active) {
    color: var(--ui-text-label);
}

/* --- Panels ------------------------------------------------------------- */

.ui-wizard__panel {
    display: none;
}

.ui-wizard__panel.is-active {
    display: block;
}

/* --- Step footer -------------------------------------------------------- */

/* Previous sits at the start edge, Next/Save at the end edge. The old markup
   emitted both buttons as bare siblings with no container, so they inherited
   the element-level button rule and sat wherever the text flow left them. */
.ui-wizard__nav {
    display: flex;
    align-items: center;
    gap: var(--ui-space-2);
    margin-top: var(--ui-space-5);
    padding-top: var(--ui-space-4);
    border-top: 1px solid var(--ui-hairline);
}

.ui-wizard__nav .ui-wizard__spacer {
    margin-inline-start: auto;
}

.ui-wizard__nav .btn {
    min-width: 120px;
    height: var(--ui-control-h);
}

@media (max-width: 767.98px) {
    .ui-wizard__steps {
        overflow-x: auto;
        gap: var(--ui-space-1);
    }

    .ui-wizard__step {
        flex: 0 0 96px;
    }

    .ui-wizard__nav .btn {
        min-width: 0;
        flex: 1 1 auto;
    }
}

/* --- Upload rows -------------------------------------------------------- */

/* The image step was a 7-column <table> — number, name, required size,
   dimension, upload, preview, operations — which at 1024px overflowed and got
   a horizontal scrollbar for what is a list of four upload fields. It is a
   grid of cards now; the size and dimension columns became hint text under
   the label, and the "# 1" column carried no information at all. */
.ui-uploads {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--ui-space-4);
}

.ui-upload-card {
    display: flex;
    flex-direction: column;
    gap: var(--ui-space-3);
    padding: var(--ui-space-4);
    background: var(--ui-bg);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius);
}

.ui-upload-card__head {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.ui-upload-card__title {
    font-size: 13px;
    font-weight: 700;
    color: var(--ui-text-label);
    margin: 0;
}

.ui-upload-card__meta {
    font-size: 11px;
    font-weight: 500;
    color: var(--ui-text-muted);
}

.ui-upload-card .form-group {
    margin-bottom: 0;
}

.ui-upload-card__foot {
    display: flex;
    justify-content: flex-end;
}

/* Inside an upload card the preview is the point of the card, not a 42px
   adornment next to the input, so it stacks above at a readable size.
   object-fit is contain rather than cover: a logo cropped to fill a 16:9 box
   is not a useful preview of a logo. */
.ui-upload-card .ui-upload {
    flex-direction: column;
    align-items: stretch;
    gap: var(--ui-space-3);
}

.ui-upload-card .ui-upload__preview {
    order: -1;
    width: 100%;
    height: 128px;
    object-fit: contain;
    padding: var(--ui-space-2);
}

/* `[hidden]` is handled once on the base rule in section 16. */


/* ==========================================================================
   19. `hidden` — origin, not specificity
   --------------------------------------------------------------------------
   The UA stylesheet's `[hidden] { display: none }` loses to ANY author
   `display` declaration, however weak the selector, because author styles are
   a stronger origin than the UA sheet. Specificity never enters into it. So
   every component here that sets `display` — .btn-icon, .ui-actions,
   .ui-upload__preview, .ui-thumbs — silently defeated the attribute, and markup
   that hid an element the standard way stayed visible.

   Re-stating it in the author origin fixes that — but a bare `[hidden]` scores
   0,1,0, exactly the same as a single-class rule like `.picker-row`, so it
   would win or lose purely on which came later in the file. That is a trap for
   whoever appends the next section: adding `.foo { display: flex }` below would
   silently re-break `hidden` on .foo.

   `[hidden][hidden]` repeats the attribute to score 0,2,0. It matches exactly
   the same elements and now outranks any single-class rule wherever it sits, so
   the guard no longer depends on source order. The third selector below is for
   the one place a two-class rule still outranks it.
   ========================================================================== */

[hidden][hidden] {
    display: none;
}

.ui-upload-card .ui-upload__preview[hidden] {
    display: none;
}

/* An empty repeater or sub-list, inline rather than the full illustrated
   empty state that partial/empty-state.blade.php gives listing tables. */
.ui-empty-inline {
    margin: 0;
    padding: var(--ui-space-4);
    text-align: center;
    color: var(--ui-text-faint);
    font-size: 13px;
    font-weight: 500;
    background: var(--ui-bg);
    border: 1px dashed var(--ui-border);
    border-radius: var(--ui-radius);
}


/* ==========================================================================
   20. Bootstrap — what this file must NOT re-implement
   --------------------------------------------------------------------------
   CORRECTION. An earlier version of this file carried ~540 lines here
   re-implementing the Bootstrap grid, box-sizing, .form-control widths, the
   modal and dropdown components and the display/flex/spacing utilities, on the
   conclusion that the panel loaded no Bootstrap at all.

   That conclusion was wrong, and the way it was reached is worth recording so
   the mistake is not repeated. The evidence was:

     - `grep '\.col-'` over the three stylesheets named in layout.blade.php's
       <link> tags → zero matches;
     - the same three fetched from the running server → zero matches;
     - a headless browser reported `.row { display: block }` and
       `.col-md-6` undefined.

   All three were consistent, and all three were wrong for the same reason:
   **Bootstrap is pulled in by an `@import`, not a `<link>`.** style.css line 58:

       @import url("/backend/assets/plugins/bootstrap/css/bootstrap.min.css");

   Grepping the file for `.col-` cannot see through an @import, listing <link>
   tags cannot either — and the browser check failed because the probe loaded the
   page over file://, where the absolute path `/backend/...` resolves against the
   filesystem root instead of the document root, so the import 404'd. Three
   different methods, one blind spot shared by all of them.

   Re-measured over HTTP with the imports resolving, Bootstrap supplies:

       .row              display: flex
       .col-md-6         flex-basis 50%, max-width 50%
       *                 box-sizing: border-box
       .form-control     width: 100%
       .modal            display: none   (0 visible modals on an index page)
       .dropdown-menu    display: none   (0 open header menus)

   So none of it belonged here. What remains below is only what Bootstrap does
   NOT provide, or where this design system deliberately differs from it.
   ========================================================================== */

/* Bootstrap styles `.badge` as a small square label. The panel uses pills
   everywhere else (.ui-badge), and 84 uses of the plain `.badge` class survive
   in views that predate this design system — so they are restyled to match
   rather than left looking like a different product. Loaded after Bootstrap, so
   no !important is needed. */
.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--ui-space-1);
    padding: 3px 10px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.5;
    text-align: center;
    white-space: nowrap;
    border-radius: 999px;
}

.badge-primary { background: var(--ui-primary-soft); color: var(--ui-primary); }
.badge-success { background: var(--ui-success-soft); color: #15803D; }
.badge-danger  { background: var(--ui-danger-soft);  color: #DC2626; }
.badge-info    { background: var(--ui-info-soft);    color: #0284C7; }
.badge-warning { background: var(--ui-warning-soft); color: #B45309; }

/* The country-code + phone pair is one control split in two. Bootstrap's
   `.form-control { width: 100% }` would make each half fill the row; the flex
   sizing in section 6 is what should decide their widths. */
.ui-input-group > input.form-control,
.ui-input-group > select.form-control {
    width: auto;
}

/* A checkbox inside .ui-checkbox-grid is a 16px control, not a full-width one. */
.ui-checkbox-grid input[type="checkbox"],
.ui-checkbox-grid input[type="radio"] {
    width: 16px;
    max-width: 16px;
}


/* ==========================================================================
   22. Product picker (choice groups)
   --------------------------------------------------------------------------
   Two-pane transfer control: searchable list on one side, chosen products as
   cards on the other. Lifted out of choice_groups/create.blade.php and
   choice_groups/edit.blade.php, which carried ~145 lines of identical
   page-level <style> each — the two differed only by a comment.

   Ported rather than pasted:

     - #D95525 appeared hardcoded five times (search focus ring, add button,
       count badge, selected-card border, and the divider). That is --ui-primary.
       The same codebase runs several restaurants, so a literal brand colour in
       a stylesheet is a latent bug, not just untidiness;

     - `border-right` on .picker-left and `right: 4px` on the remove button are
       physical properties on an RTL page — the divider fell on the wrong side
       of the pane and the remove badge on the wrong corner of the card. Both
       are logical now;

     - #EAEAEA / #fafafa / #f3f3f3 / #bbb / #ccc / #666 / #333 are the token
       palette's --ui-border / --ui-bg / --ui-hairline / --ui-text-faint /
       --ui-text-muted / --ui-text;

     - the panes were fixed at 42% / 58% with no breakpoint, so on a narrow
       screen the list column became unusably tight. They stack below 768px.
   ========================================================================== */

.product-picker {
    display: flex;
    min-height: 340px;
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius-lg);
    overflow: hidden;
    background: var(--ui-surface);
}

/* --- Left pane: searchable list ----------------------------------------- */

.picker-left {
    display: flex;
    flex-direction: column;
    width: 42%;
    border-inline-end: 1px solid var(--ui-border);
}

.picker-search {
    padding: var(--ui-space-2) var(--ui-space-3);
    border-bottom: 1px solid var(--ui-border);
    background: var(--ui-bg);
}

.picker-search input {
    width: 100%;
    padding: 7px var(--ui-space-3);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius-sm);
    background: var(--ui-surface);
    font-size: 13px;
    outline: 0;
}

.picker-search input:focus {
    border-color: var(--ui-primary);
    box-shadow: var(--ui-ring);
}

.picker-list {
    flex: 1;
    overflow-y: auto;
}

.picker-row {
    display: flex;
    align-items: center;
    gap: var(--ui-space-2);
    padding: 9px var(--ui-space-4);
    border-bottom: 1px solid var(--ui-hairline);
    cursor: pointer;
    user-select: none;
    transition: background-color .12s ease;
}

.picker-row:hover {
    background: var(--ui-primary-soft);
}

.picker-row.is-selected {
    opacity: .4;
    pointer-events: none;
}

.picker-row img {
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border-radius: var(--ui-radius-sm);
    object-fit: cover;
    background: var(--ui-bg);
}

.picker-row-name {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    line-height: 1.3;
    overflow-wrap: anywhere;
}

.picker-row-add {
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: var(--ui-primary);
    color: #FFFFFF;
    font-size: 18px;
    font-weight: 300;
    line-height: 1;
    transition: transform .1s ease;
}

.picker-row:hover .picker-row-add {
    transform: scale(1.15);
}

.picker-empty {
    padding: 40px var(--ui-space-4);
    text-align: center;
    color: var(--ui-text-faint);
    font-size: 13px;
}

/* --- Right pane: chosen cards ------------------------------------------- */

.picker-right {
    display: flex;
    flex-direction: column;
    width: 58%;
    background: var(--ui-bg);
}

.picker-right-header {
    display: flex;
    align-items: center;
    gap: var(--ui-space-1);
    padding: var(--ui-space-2) var(--ui-space-4);
    border-bottom: 1px solid var(--ui-border);
    font-size: 12px;
    font-weight: 600;
    color: var(--ui-text-muted);
}

.picker-right-header .badge-count {
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--ui-primary);
    color: #FFFFFF;
    font-size: 11px;
}

.picker-cards {
    flex: 1;
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    gap: var(--ui-space-2);
    padding: var(--ui-space-3);
    overflow-y: auto;
}

.picker-card {
    position: relative;
    width: 82px;
    text-align: center;
}

.picker-card img {
    display: block;
    width: 70px;
    height: 70px;
    margin: 0 auto;
    border: 2px solid var(--ui-primary);
    border-radius: var(--ui-radius);
    object-fit: cover;
}

.picker-card-name {
    margin-top: 5px;
    font-size: 11px;
    line-height: 1.3;
    color: var(--ui-text);
    overflow-wrap: anywhere;
}

.picker-card-remove {
    position: absolute;
    top: -7px;
    inset-inline-end: 4px;
    width: 22px;
    height: 22px;
    padding: 0;
    border: 2px solid var(--ui-surface);
    border-radius: 50%;
    background: var(--ui-danger);
    color: #FFFFFF;
    font-size: 13px;
    line-height: 18px;
    text-align: center;
    cursor: pointer;
    transition: background-color .12s ease;
}

.picker-card-remove:hover {
    background: #B02A37;
}

.picker-placeholder {
    width: 100%;
    padding: 60px var(--ui-space-5);
    text-align: center;
    color: var(--ui-text-faint);
    font-size: 13px;
}

.picker-placeholder i {
    display: block;
    margin-bottom: var(--ui-space-2);
    font-size: 32px;
}

/* The picker is one control, so an error on `meals` has to mark the whole
   thing — there is no single input to put .is-invalid on. */
.picker-invalid .product-picker {
    border-color: var(--ui-danger);
}

@media (max-width: 767.98px) {
    .product-picker {
        flex-direction: column;
    }

    .picker-left,
    .picker-right {
        width: 100%;
    }

    .picker-left {
        border-inline-end: 0;
        border-bottom: 1px solid var(--ui-border);
    }
}

/* ==========================================================================
   23. Permission matrix (roles create / edit)
   ==========================================================================

   The roles form renders one card per Module, each holding that module's
   permission checkboxes plus a "select all" toggle in its header.

   The old markup used `<div class="card col-3">` for these — a Bootstrap
   column that is also a card. `col-3` has no breakpoint, so it stayed at 25%
   from 320px up: four permission lists side by side on a phone, each about
   70px wide. It also gave the cards no vertical rhythm, because `.card`'s
   own margin-bottom is what separates cards and a grid column overrides the
   horizontal box. This is a grid instead, so the column count follows the
   available width and the gap is uniform in both axes. */

.ui-perm-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--ui-space-4);
    align-items: start;
}

.ui-perm-module {
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius);
    background: var(--ui-surface);
    overflow: hidden;
}

.ui-perm-module__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ui-space-3);
    padding: var(--ui-space-3) var(--ui-space-4);
    background: var(--ui-bg);
    border-bottom: 1px solid var(--ui-hairline);
}

.ui-perm-module__title {
    font-size: 13px;
    font-weight: 700;
    color: var(--ui-text);
    margin: 0;
}

/* The select-all control is a label wrapping its own checkbox, so the whole
   "تحديد الكل" text is a hit target. The old markup put the <label for=…>
   after the input as a sibling, which works, but the `.cr` class it carried
   belongs to the theme's custom-checkbox skin and was never styled here. */
.ui-perm-module__all {
    display: inline-flex;
    align-items: center;
    gap: var(--ui-space-2);
    margin: 0;
    font-size: 12px;
    font-weight: 600;
    color: var(--ui-text-muted);
    cursor: pointer;
    white-space: nowrap;
}

.ui-perm-module__all input {
    width: 15px;
    height: 15px;
    margin: 0;
    accent-color: var(--ui-primary);
    cursor: pointer;
}

.ui-perm-module__body {
    padding: var(--ui-space-3);
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-height: 260px;
    overflow-y: auto;
}

/* A permission row is the same object as .ui-checkbox-card but always full
   width, since it lives in a one-column list rather than the auto-fill grid. */
.ui-perm-item {
    display: flex;
    align-items: center;
    gap: var(--ui-space-2);
    padding: 7px var(--ui-space-3);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius-sm);
    margin: 0;
    cursor: pointer;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ui-text-label);
    transition: border-color .15s ease, background-color .15s ease;
}

.ui-perm-item:hover {
    border-color: var(--ui-border-strong);
}

.ui-perm-item input {
    width: 15px;
    height: 15px;
    margin: 0;
    flex: 0 0 auto;
    accent-color: var(--ui-primary);
    cursor: pointer;
}

.ui-perm-item:has(input:checked) {
    border-color: var(--ui-primary);
    background: var(--ui-primary-soft);
    color: var(--ui-primary);
}

.ui-perm-module__empty {
    font-size: 12px;
    color: var(--ui-text-faint);
    text-align: center;
    padding: var(--ui-space-3) 0;
}

/* ==========================================================================
   24. AJAX modal loading state
   ==========================================================================

   Invoices share one status modal across every row and fill it over AJAX. The
   original markup left .modal-content completely empty, so the gap between
   opening the modal and the response arriving showed a blank white rectangle
   with no border, no title and no indication that anything was happening — on
   a slow connection it read as a broken page. */

.ui-modal-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--ui-space-2);
    padding: var(--ui-space-6);
    color: var(--ui-text-muted);
    font-size: 13px;
    font-weight: 600;
}

.ui-modal-loading i {
    font-size: 18px;
    color: var(--ui-primary);
    animation: ui-spin 1s linear infinite;
}

@keyframes ui-spin {
    to { transform: rotate(360deg); }
}

/* Respect the OS "reduce motion" setting — a permanently spinning icon is a
   known trigger for vestibular discomfort. */
@media (prefers-reduced-motion: reduce) {
    .ui-modal-loading i {
        animation: none;
    }
}

/* What the modal is about, above the control that changes it. The status modal
   gave no clue which invoice it had been opened for. */
.ui-modal-subject {
    margin: 0 0 var(--ui-space-4);
    padding-bottom: var(--ui-space-3);
    border-bottom: 1px solid var(--ui-hairline);
    font-size: 13px;
    font-weight: 600;
    color: var(--ui-text-muted);
}

.ui-modal-subject .ui-ltr {
    color: var(--ui-text);
}

/* A customer's free-text note on an order line. The invoices show page printed
   these with style="font-weight: bold; color: red" — alarm colouring for what
   is ordinary information ("no onions"), and red-on-white at 700 weight is the
   same treatment the panel uses for destructive actions. */
.ui-cell-note {
    display: inline-block;
    max-width: 220px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ui-text);
    white-space: normal;
}


/* ==========================================================================
   25. Meal show page (show-meal/{id})
   ==========================================================================

   Lifted verbatim out of a 460-line inline <style> block in
   products/view.blade.php. Only the meal-specific rules moved; the rest of that
   block is the shared legacy form/select2/modal blob that products/create,
   products/edit and the price partials all carry their own copy of, and it stays
   inline there until those pages are migrated.

   Deliberately NOT globalised with them: rules like
       .form-group input { height: 50px !important; border: 1px solid #EAEAEA !important }
   Promoting those to a global stylesheet would override the control sizing this
   file already defines, on every page already migrated. They are page-scoped
   today and that is the only thing keeping them harmless. */

.product_images {
            border-radius: 50px;
            width: 225px;
            height: 170px;
        }

.profile-img-photo .p-image input {
            width: 100%;
            height: 100% !important;
        }

.profile-img-photo .circle {
            overflow: hidden;
            width: 100%;
            height: 100%;
            border: 2px solid rgba(255, 255, 255, 0.2);
            top: 0px;
            position: relative;
        }

.profile-img-photo .profile_pic {
            width: 100%;
            max-height: 200px;
            display: inline-block;
        }

.profile-img-photo .p-image {
            position: absolute;
            top: 0;
            left: 10px;
            color: #666666;
            transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
            width: 100%;
            height: 100%;
        }

.profile-img-photo .upload-button {
            font-size: 1.2em;
        }

.profile-img-photo img {
            max-width: 100%;
            height: auto;
        }

.add-new-price button {
            border-radius: 6px;
            border: 0.5px solid var(--2-e-6-dd-3, #2E6DD3);
            background: var(--ffffff, #FFF);
            padding: 10px 20px;
            font-size: 14px;
            color: #2E6DD3;
            font-weight: 700;
            cursor: pointer;
        }

.add-new-price {
            margin-bottom: 20px;
        }

.show-meal-tabs {
            background: #fff;
            border: 1px solid #e7edf5;
            border-radius: 8px;
            padding: 14px 16px;
            box-shadow: 0 8px 24px rgba(23, 39, 65, 0.04);
        }

.show-meal-tabs .nav-link {
            border-radius: 6px;
            color: #6b7280;
            font-size: 14px !important;
            font-weight: 600;
            padding: 10px 18px;
        }

.show-meal-tabs .nav-link.active {
            background: #10aee8;
            color: #fff;
            box-shadow: 0 8px 18px rgba(16, 174, 232, 0.22);
        }

.meal-show-panel {
            background: #fff;
            border: 1px solid #e7edf5;
            border-radius: 8px;
            padding: 0;
            box-shadow: 0 4px 16px rgba(23, 39, 65, 0.035);
            overflow: hidden;
        }

#pills-prices.meal-show-panel,
        #pills-profile.meal-show-panel {
            padding: 22px;
        }

.meal-show-summary {
            display: flex;
            align-items: center;
            gap: 16px;
            padding: 18px 22px;
            border-bottom: 1px solid #edf1f6;
        }

.meal-show-thumb {
            width: 76px;
            height: 76px;
            border: 1px solid #e5edf6;
            border-radius: 8px;
            background: #fff;
            overflow: hidden;
            flex: 0 0 76px;
            display: flex;
            align-items: center;
            justify-content: center;
        }

.meal-show-thumb img {
            width: 100%;
            height: 100%;
            object-fit: contain;
            display: block;
        }

.meal-show-title {
            flex: 1;
            min-width: 0;
        }

.meal-show-title h4 {
            color: #1f2937;
            font-size: 18px;
            font-weight: 700;
            margin-bottom: 4px;
        }

.meal-show-title p {
            color: #6b7280;
            font-size: 13px;
            margin: 0;
        }

.meal-status-row {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            margin-top: 10px;
        }

.meal-status-badge {
            border-radius: 6px;
            font-size: 11px;
            font-weight: 700;
            padding: 6px 10px;
            display: inline-flex;
            align-items: center;
            gap: 6px;
        }

.meal-status-badge.is-success {
            background: #eaf8ef;
            color: #24a148;
        }

.meal-status-badge.is-danger {
            background: #fff0f1;
            color: #dc3545;
        }

.meal-status-badge.is-info {
            background: #eef6ff;
            color: #2e6dd3;
        }

.meal-detail-table {
            padding: 4px 22px 20px;
        }

.meal-detail-row {
            display: grid;
            grid-template-columns: repeat(2, minmax(0, 1fr));
            border-bottom: 1px solid #edf1f6;
        }

.meal-detail-row:last-child {
            border-bottom: 0;
        }

.meal-detail-cell {
            display: grid;
            grid-template-columns: minmax(130px, 34%) 1fr;
            gap: 12px;
            padding: 14px 0;
        }

.meal-detail-cell:nth-child(2n) {
            padding-inline-start: 24px;
            border-inline-start: 1px solid #edf1f6;
        }

.meal-detail-label {
            color: #7b8494;
            display: block;
            font-size: 12px;
            font-weight: 600;
        }

.meal-detail-value {
            color: #263244;
            display: block;
            font-size: 13px;
            font-weight: 700;
            line-height: 1.6;
            overflow-wrap: anywhere;
        }

@media (max-width: 991.98px) {
            .meal-detail-row {
                grid-template-columns: 1fr;
            }

            .meal-detail-cell:nth-child(2n) {
                padding-inline-start: 0;
                border-inline-start: 0;
            }
        }

@media (max-width: 575.98px) {
            .meal-show-summary {
                align-items: flex-start;
                padding: 18px;
            }

            .meal-detail-cell {
                grid-template-columns: 1fr;
                gap: 6px;
            }

            .meal-detail-table {
                padding: 4px 18px 18px;
            }
        }

/* A single image on a show page — the offer's ministry-approval scan, and the
   same shape wherever a record has one representative image. The offer page had
   this at style="width:50px;height:50px", which squashed anything not square
   into a thumbnail too small to read the document in. */
.ui-detail-image {
    display: block;
    max-width: 320px;
    width: 100%;
    height: auto;
    border-radius: var(--ui-radius);
    border: 1px solid var(--ui-border);
}

/* A row of page-level actions above a table — the three campaign channels
   (notification / SMS / email).

   The original strip was <div class="row container">, which puts Bootstrap's
   negative row margin and the container's positive padding on the same element.
   That is why it sat inset from every other block on the page, and why
   justify-content had to be forced inline to do anything. */
.ui-toolbar-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ui-space-2);
    padding: var(--ui-space-4) var(--ui-space-4) 0;
}

.ui-toolbar-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}


/* ==========================================================================
   26. Dashboard
   --------------------------------------------------------------------------
   The home page used to carry a 127-line <style> block of its own, most of it
   re-styling .form-group inputs and select2 for a form with two date fields —
   rules that sections 6 and 7 already own, and that leaked to nothing else
   because they were scoped to this page only.

   What is genuinely dashboard-specific lives here: the KPI grid, the chart
   frames and the channel-split bar.
   ========================================================================== */

.ui-kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: var(--ui-space-3);
    margin-bottom: var(--ui-space-4);
}

.ui-kpi {
    display: flex;
    align-items: flex-start;
    gap: var(--ui-space-3);
    padding: var(--ui-space-4);
    background: var(--ui-surface);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius-lg);
    box-shadow: var(--ui-shadow);
}

/* The old cards ended every tile with
       <div class="progress"><div class="progress-bar" style="width: 70%"></div></div>
   on all four tiles, on every load, whatever the numbers were. A bar that never
   moves reads as a measurement and is not one, so it is gone rather than
   rescaled — nothing in $data expresses these counts as a proportion of
   anything. The accent rail below is the same visual weight without the false
   claim. */
.ui-kpi__icon {
    flex: 0 0 44px;
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    font-size: 20px;
    line-height: 1;
}

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

.ui-kpi__label {
    margin: 0 0 4px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ui-text-muted);
}

.ui-kpi__value {
    margin: 0;
    font-size: 26px;
    font-weight: 700;
    line-height: 1.15;
    color: var(--ui-text);
    /* Counts and money are Latin digits in both locales; without this they
       reflow oddly next to an RTL label. */
    direction: ltr;
    unicode-bidi: isolate;
    text-align: start;
}

.ui-kpi__hint {
    margin: 4px 0 0;
    font-size: 12px;
    color: var(--ui-text-faint);
}

/* Tone variants — each is the icon chip only, so the card itself stays white
   and the page does not turn into a block of saturated tiles. */
.ui-kpi--success .ui-kpi__icon { background: var(--ui-success-soft); color: var(--ui-success); }
.ui-kpi--warning .ui-kpi__icon { background: var(--ui-warning-soft); color: var(--ui-warning); }
.ui-kpi--danger  .ui-kpi__icon { background: var(--ui-danger-soft);  color: var(--ui-danger); }
.ui-kpi--info    .ui-kpi__icon { background: var(--ui-info-soft);    color: var(--ui-info); }
.ui-kpi--primary .ui-kpi__icon { background: var(--ui-primary-soft); color: var(--ui-primary); }

/* Chart frames. Height lives here, not in a style="" on each <div>, so all the
   charts on the page stay the same size when one is changed. */
.ui-chart {
    width: 100%;
    height: 320px;
}

.ui-chart--tall {
    height: 380px;
}

.ui-chart--short {
    height: 260px;
}

/* Shown until ECharts paints, and left in place if it never loads — an empty
   grey rectangle gives no clue that anything was meant to be there. */
.ui-chart__fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: var(--ui-text-faint);
    font-size: 14px;
}

/* Order-channel split: delivery / pickup / dine-in as one stacked bar with a
   legend, rather than three separate cards each repeating the same total. */
.ui-split {
    padding: var(--ui-space-4);
}

.ui-split__bar {
    display: flex;
    height: 14px;
    border-radius: 999px;
    overflow: hidden;
    background: var(--ui-hairline);
    margin-bottom: var(--ui-space-3);
}

.ui-split__seg {
    height: 100%;
    transition: width .3s ease;
}

.ui-split__legend {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: var(--ui-space-3);
}

.ui-split__item {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: 13px;
}

.ui-split__dot {
    flex: 0 0 10px;
    width: 10px;
    height: 10px;
    border-radius: 3px;
    transform: translateY(-1px);
}

.ui-split__name {
    color: var(--ui-text-muted);
}

.ui-split__num {
    margin-inline-start: auto;
    font-weight: 700;
    color: var(--ui-text);
    direction: ltr;
    unicode-bidi: isolate;
}

/* Thumbnail inside a table cell. The settings content table used
   style="width: 150px" on a raw <img>, which let a portrait image push the row
   to 400px tall because only the width was constrained. */
.ui-thumb-img {
    width: 72px;
    height: 48px;
    object-fit: cover;
    border-radius: var(--ui-radius-sm);
    border: 1px solid var(--ui-border);
    background: var(--ui-hairline);
}

/* A switch with its caption beside it, as a single click target. */
.ui-inline-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--ui-space-2);
    margin: 0;
    cursor: pointer;
    font-weight: 600;
    color: var(--ui-text-label);
}


/* ==========================================================================
   27. Support thread
   --------------------------------------------------------------------------
   The ticket conversation. The old markup built this out of .media inside a
   <ul class="media-list">, with each message's attachments wrapped in bare
   <td> elements that were not inside any table — the parser drops a <td> with
   no <tr> ancestor, so every style set on them was inert.

   Message spacing was `class="mt-{{ $sup->id }}"`, a Bootstrap margin utility
   built from a database id: mt-1…mt-5 exist, mt-47 does not, so the gap
   between two replies depended on their primary keys.
   ========================================================================== */

.ui-thread {
    display: flex;
    flex-direction: column;
    gap: var(--ui-space-4);
    padding: var(--ui-space-4);
}

.ui-msg {
    display: flex;
    gap: var(--ui-space-3);
    align-items: flex-start;
}

/* Staff replies sit on the opposite side, so a long thread reads as a
   conversation rather than as one flat list. */
.ui-msg--own {
    flex-direction: row-reverse;
}

.ui-msg__avatar {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid var(--ui-border);
    background: var(--ui-hairline);
}

.ui-msg__bubble {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 78%;
    padding: var(--ui-space-3);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius-lg);
    background: var(--ui-surface);
}

.ui-msg--own .ui-msg__bubble {
    background: var(--ui-primary-soft);
    border-color: transparent;
}

.ui-msg__head {
    display: flex;
    align-items: baseline;
    gap: var(--ui-space-2);
    margin-bottom: 6px;
}

.ui-msg__author {
    font-weight: 700;
    color: var(--ui-text);
}

.ui-msg__time {
    font-size: 12px;
    color: var(--ui-text-faint);
    direction: ltr;
    unicode-bidi: isolate;
}

.ui-msg__body {
    margin: 0;
    color: var(--ui-text);
    /* A pasted ticket body is plain text with real newlines in it; without this
       the whole message collapsed onto one line. */
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.ui-msg__files {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ui-space-2);
    margin-top: var(--ui-space-3);
}

.ui-msg__file {
    position: relative;
    display: block;
    width: 104px;
    height: 72px;
    border-radius: var(--ui-radius-sm);
    overflow: hidden;
    border: 1px solid var(--ui-border);
}

.ui-msg__file img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Was an <a> with inline `color: red; margin-left: 3px` floating beside the
   thumbnail, so it moved as the image resized. */
.ui-msg__file-remove {
    position: absolute;
    inset-block-start: 4px;
    inset-inline-end: 4px;
    width: 22px;
    height: 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(15, 23, 42, .65);
    color: #fff;
    font-size: 12px;
    line-height: 1;
}

.ui-msg__file-remove:hover,
.ui-msg__file-remove:focus-visible {
    background: var(--ui-danger);
    color: #fff;
}

.ui-msg__actions {
    margin-top: var(--ui-space-2);
}


/* ==========================================================================
   28. Product price modal
   --------------------------------------------------------------------------
   The add/edit-price dialog and the product create/edit forms that share its
   markup. This lived as an inline <style> block repeated across
   products/view (219 lines) and products/create + products/edit (339 lines,
   byte-identical to each other).

   Two reasons it had to move:

   1. It hardcoded #2E6DD3 — blue — for the active tab, the tab underline, the
      "add category" button and the save button, on a panel whose brand token is
      --ui-primary (#D95525, orange). The price modal's tabs were the only blue
      tabs in the panel, which is why show-meal's tabs looked like they belonged
      to a different product. CLAUDE.md is explicit that the same codebase runs
      several restaurants off separate .env/VENDOR_ID, so a literal brand colour
      in a template is wrong for every deployment but one.

   2. Several selectors were unscoped — `.form-group input`, `.form-group label`,
      `button:focus`, `input.select2-search__field` — so a page-level block was
      restyling every input and every label on the page, overriding section 6.
      They are scoped to the modal's own container here.

   @yield('styles') is emitted BEFORE this file in layout.blade.php, so these
   rules win over the inline blocks that remain in products/create and
   products/edit until those pages are migrated.
   ========================================================================== */

/* Tab strip inside the price modal and the product forms. */
._add_cat_sm_p {
    background-color: transparent !important;
    border-bottom: 2px solid var(--ui-hairline);
}

._add_cat_sm_p .nav-link {
    color: var(--ui-text-muted);
    border: 0;
    border-bottom: 2px solid transparent;
    background: transparent;
    cursor: pointer;
}

._add_cat_sm_p .nav-link.active {
    /* Was #2E6DD3 with a matching rgba(46,109,211,.05) wash. */
    color: var(--ui-primary) !important;
    border-bottom-color: var(--ui-primary) !important;
    background: var(--ui-primary-soft) !important;
}

/* Was `button.btn-add-cat { color: #2E6DD3 }`. */
button.btn-add-cat {
    color: var(--ui-primary);
    background: none;
    border: 0;
    margin: 5px 0;
    cursor: pointer;
    font-size: 12px;
    font-weight: 600;
}

/* Was `button.f-save { background: #2E6DD3 }`, applied with three declarations
   because the third had !important and the first two did not. */
button.f-save {
    background-color: var(--ui-primary) !important;
    color: #fff;
    border: 0;
}

button.f-save:hover,
button.f-save:focus-visible {
    background-color: var(--ui-primary-hover) !important;
}

.footer-form- button {
    border-radius: var(--ui-radius-sm);
    background-color: var(--ui-hairline);
    border: 0;
    padding: 10px 40px;
    /* `margin: 0 10px` followed by `margin-inline-end: 0 !important` — the
       shorthand set a physical left/right margin and the logical property then
       had to fight it back off on one side. */
    margin-inline-start: var(--ui-space-2);
    font-size: 14px;
    cursor: pointer;
}

.footer-button button {
    margin-inline-start: var(--ui-space-2);
}

.modal-header.f-model-h {
    padding: var(--ui-space-2) var(--ui-space-4);
}

.modal-header.f-model-h h5 {
    color: var(--ui-text);
    font-size: 14px;
    font-weight: 700;
}

.row-one {
    margin-top: 10px;
    margin-bottom: 30px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--ui-hairline);
}

.add-cat-name {
    padding: var(--ui-space-2) 0;
}

.add-cat-name label {
    color: var(--ui-text);
    font-weight: 600;
    padding-bottom: 5px;
    font-size: 14px;
}

.add-cat-name input {
    border-radius: var(--ui-radius);
    background: var(--ui-bg) !important;
    border: 0 !important;
    font-size: 12px;
    color: var(--ui-text-muted);
}

._show_save {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
}

.form-btns a,
.form-btns button {
    border-radius: var(--ui-radius-sm);
    padding: 10px 35px;
}

/* Image upload box. `span.close-wind` was positioned with top/right, which puts
   the remove button on the wrong corner under RTL. */
.uploadt.nd-upload-img {
    border-radius: var(--ui-radius-lg);
    padding: 20px 10px;
}

.small-12.medium-2.large-2.columns {
    position: relative;
    border: 1.5px dashed var(--ui-hairline);
}

.chose_img_ {
    margin-top: 10px;
}

.chose_img_ span {
    border-radius: var(--ui-radius);
    border: 1px solid var(--ui-primary);
    padding: 5px 15px;
    color: var(--ui-primary);
    font-size: 12px;
}

.form-row-one.form-ulpoad-img .upload-box input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100% !important;
}

div#imagePreviewContainerLogo img {
    position: absolute;
    inset-block-start: 0;
    inset-inline-start: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

span.close-wind {
    position: absolute;
    inset-block-start: -7px;
    inset-inline-end: -7px;
    display: none;
}

span.close-wind.active {
    display: block;
    z-index: 2;
}

/* Scoped to the price modal rather than every .form-group on the page. */
.form-row-one input,
.form-row-one textarea {
    height: 50px !important;
}

.sm-form-g span.select2.select2-container.select2-container--default {
    height: auto;
}


/* ==========================================================================
   29. Empty state
   --------------------------------------------------------------------------
   Lifted from partial/empty-state.blade.php, which is included on every listing
   page — the same 30 lines were re-parsed on every page load, and its colours
   were hardcoded literals of tokens defined at the top of this file.
   ========================================================================== */

.admin-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 52px 20px;
    text-align: center;
    background: var(--ui-surface);
}

.admin-empty-state__icon {
    width: 104px;
    height: 84px;
    margin-bottom: 6px;
}

.admin-empty-state__title {
    color: var(--ui-text-label);
    font-size: 15px;
    font-weight: 700;
}

.admin-empty-state__text {
    max-width: 320px;
    color: var(--ui-text-faint);
    font-size: 13px;
    font-weight: 500;
}


/* ==========================================================================
   30. Top bar
   --------------------------------------------------------------------------
   partial/quick-actions.blade.php — the fixed header.

   What was there: the signed-in name wrapped in three nested elements each
   carrying style="color: red" (and a <span> that was never closed); the
   notification count positioned with `top:55px; right:98%; margin-right:-42px;
   margin-top:-38px` — four physical offsets, two negative, on a panel whose
   body direction is RTL, which is why it floated away from the bell; the
   account menu behind a cog icon; and the theme's default .pro-head, a flat
   blue that matches nothing else in the panel.

   ── On the selectors below ────────────────────────────────────────────────

   These are deliberately written as `.pcoded-header .navbar-nav.ui-topbar …`
   rather than the shorter `.ui-topbar …`. style.css lays this bar out with

       .pcoded-header .navbar-nav      { display: inline-block }   (0,2,0)
       .pcoded-header .navbar-nav > li { display: inline-block;
                                         line-height: 70px }       (0,2,1)

   A plain `.ui-topbar` is (0,1,0) and `.ui-topbar .nav-item` is (0,2,0), so
   both LOSE to the theme even though this file loads later — specificity is
   compared before source order. The first version of this section was written
   that way and had no effect at all: the items stayed inline-block at a 70px
   line-height inside a 60px header, which pushed the avatar-and-name block onto
   a second row and broke the bar in two.
   ========================================================================== */

.ui-brand__logo {
    display: block;
    max-width: 132px;
    max-height: 38px;
    width: auto;
    height: auto;
    object-fit: contain;
}

/* The bar itself needs room for a 32px avatar plus its padding. */
.pcoded-header {
    height: 64px;
}

.pcoded-header .collapse.navbar-collapse {
    display: flex;
    align-items: center;
    width: 100%;
    height: 100%;
}

/* (0,3,0) — beats .pcoded-header .navbar-nav (0,2,0). */
.pcoded-header .navbar-nav.ui-topbar {
    display: flex;
    align-items: center;
    gap: var(--ui-space-1);
    height: 100%;
    /* The theme floats .ml-auto right, which is a no-op inside a flex row and
       is the wrong side under RTL regardless. */
    float: none;
    margin-inline-start: auto;
}

/* (0,3,1) — beats .pcoded-header .navbar-nav > li (0,2,1). */
.pcoded-header .navbar-nav.ui-topbar > li {
    display: flex;
    align-items: center;
    /* line-height: 70px on a 64px bar is what made the row overflow. */
    line-height: 1;
    padding: 0 4px;
}

/* The theme pads the first and last item with physical left/right values, and
   repeats them inside two media queries. Under RTL those land on the wrong
   sides. (0,3,2) beats all four. */
.pcoded-header .navbar-nav.ui-topbar > li:first-child,
.pcoded-header .navbar-nav.ui-topbar > li:last-child {
    padding-inline: 4px;
}

.pcoded-header .navbar-nav.ui-topbar > li:last-child {
    padding-inline-end: var(--ui-space-4);
}

/* Icon buttons — bell, and anything added later. Sized as a real hit target
   rather than a bare <i>. */
.pcoded-header .navbar-nav.ui-topbar .ui-topbar__btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: var(--ui-text-muted);
    font-size: 18px;
    line-height: 1;
    transition: background-color .15s ease, color .15s ease;
}

.pcoded-header .navbar-nav.ui-topbar .ui-topbar__btn:hover,
.pcoded-header .navbar-nav.ui-topbar .ui-topbar__btn:focus-visible {
    background: var(--ui-hairline);
    color: var(--ui-text);
}

/* The theme draws a ::after caret on every .dropdown-toggle, which landed
   between the bell and its badge. */
.pcoded-header .ui-topbar__btn.dropdown-toggle::after,
.pcoded-header .ui-topbar__user.dropdown-toggle::after {
    display: none;
}

/* Anchored to the button, so it stays on the bell in both directions instead of
   being nudged there with negative physical margins. */
.ui-topbar__badge {
    position: absolute;
    inset-block-start: 2px;
    inset-inline-end: 2px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: var(--ui-danger);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
}

.pcoded-header .navbar-nav.ui-topbar .ui-topbar__lang {
    display: inline-flex;
    align-items: center;
    height: 34px;
    padding: 0 12px;
    border: 1px solid var(--ui-border);
    border-radius: 999px;
    color: var(--ui-text-muted);
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
}

.pcoded-header .navbar-nav.ui-topbar .ui-topbar__lang:hover,
.pcoded-header .navbar-nav.ui-topbar .ui-topbar__lang:focus-visible {
    border-color: var(--ui-primary);
    color: var(--ui-primary);
}

/* The account trigger. Replaces a bare cog with the avatar + name, which is
   what the separate red <li> beside it was already trying to show. */
.pcoded-header .navbar-nav.ui-topbar .ui-topbar__user {
    display: inline-flex;
    align-items: center;
    gap: var(--ui-space-2);
    padding-inline: 4px 10px;
    border-radius: 999px;
    color: var(--ui-text);
    line-height: 1;
    transition: background-color .15s ease;
}

.pcoded-header .navbar-nav.ui-topbar .ui-topbar__user:hover,
.pcoded-header .navbar-nav.ui-topbar .ui-topbar__user:focus-visible {
    background: var(--ui-hairline);
    color: var(--ui-text);
}

.ui-topbar__user > .feather {
    color: var(--ui-text-faint);
    font-size: 14px;
}

.ui-topbar__avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--ui-hairline);
}

.ui-topbar__name {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
    font-size: 14px;
    font-weight: 600;
    /* Was style="color: red" on the <li>, on a <div> inside it and on a <span>
       inside that — three declarations of the same thing, on an element whose
       job is to say who is signed in. */
    color: var(--ui-text);
    white-space: nowrap;
}

.ui-topbar__name small {
    color: var(--ui-text-faint);
    font-size: 11px;
    font-weight: 500;
}

@media (max-width: 991px) {
    .ui-topbar__name {
        display: none;
    }
}

/* ── The dropdown panels ───────────────────────────────────────────────────

   Position, not just colour. The theme leaves these to Bootstrap's default
   `.dropdown-menu-right`, which rtl.css then rewrites to `right: auto; left: 0`
   — a physical pair, so the panel anchored to whichever edge happened to be
   "left" rather than to the trigger. Logical properties anchor it to the same
   edge of the trigger in both directions, which keeps it on screen whether the
   bar sits at the start or the end of the row.
   ------------------------------------------------------------------------- */

.pcoded-header {
    /* .pcoded-header is transparent in the base theme; the white came from the
       header-lightblue variant that layout.blade.php no longer applies. */
    background: var(--ui-surface);
    border-bottom: 1px solid var(--ui-border);
}

.pcoded-header .navbar-nav.ui-topbar .dropdown-menu {
    position: absolute;
    inset-inline-end: 0;
    inset-inline-start: auto;
    /* Was margin-top: -6px, which tucked the panel up under the bar. */
    inset-block-start: calc(100% + 10px);
    margin: 0;
    min-width: 280px;
    max-width: calc(100vw - 2 * var(--ui-space-4));
    padding: 0;
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius-lg);
    box-shadow: 0 12px 32px rgba(15, 23, 42, .12);
    overflow: hidden;
}

.pcoded-header .navbar-nav.ui-topbar .notification.dropdown-menu {
    min-width: 340px;
}

/* The theme draws a pointer with `content: "\63"` in a font called "pct",
   positioned `left: -5px; top: 60px` — physical offsets measured against a
   70px bar. On the 64px bar, in RTL, it landed in the middle of the panel as a
   stray white curve. */
.pcoded-header .navbar-nav.ui-topbar .dropdown.show::before,
.pcoded-header .navbar-nav.ui-topbar .dropdown-menu.show::before {
    display: none;
}

/* Dropdown head — brand, not the variant's #23b7e5. */
.pcoded-header .navbar-nav.ui-topbar .profile-notification .ui-topbar__prohead.pro-head {
    display: flex;
    align-items: center;
    gap: var(--ui-space-3);
    padding: var(--ui-space-4);
    background: var(--ui-primary);
    color: #fff;
    line-height: 1.3;
    border-radius: 0;
}

.pcoded-header .navbar-nav.ui-topbar .profile-notification .ui-topbar__prohead.pro-head > span {
    display: flex;
    flex-direction: column;
    font-weight: 700;
    color: #fff;
}

.pcoded-header .navbar-nav.ui-topbar .profile-notification .ui-topbar__prohead.pro-head small {
    font-weight: 500;
    opacity: .85;
}

.ui-topbar__prohead-avatar {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid rgba(255, 255, 255, .6);
}

/* Menu items. The variant set `color: #888` on these, which is the washed-out
   grey the items rendered in. */
.pcoded-header .navbar-nav.ui-topbar .profile-notification .pro-body {
    padding: var(--ui-space-2) 0;
    margin: 0;
    list-style: none;
}

.pcoded-header .navbar-nav.ui-topbar .profile-notification .pro-body > li {
    line-height: 1;
    padding: 0;
}

.pcoded-header .navbar-nav.ui-topbar .profile-notification .pro-body > li > a {
    display: flex;
    align-items: center;
    gap: var(--ui-space-2);
    padding: 11px var(--ui-space-4);
    color: var(--ui-text-label);
    font-size: 14px;
    line-height: 1.4;
}

.pcoded-header .navbar-nav.ui-topbar .profile-notification .pro-body > li > a:hover,
.pcoded-header .navbar-nav.ui-topbar .profile-notification .pro-body > li > a:focus-visible {
    background: var(--ui-primary-soft);
    color: var(--ui-primary);
}

.pcoded-header .navbar-nav.ui-topbar .profile-notification .pro-body > li > a .feather {
    font-size: 16px;
    color: var(--ui-text-faint);
}

.pcoded-header .navbar-nav.ui-topbar .profile-notification .pro-body > li > a:hover .feather {
    color: var(--ui-primary);
}

.ui-topbar__empty {
    padding: var(--ui-space-4);
    text-align: center;
    color: var(--ui-text-faint);
    font-size: 13px;
    line-height: 1.5;
}

/* Branch open/closed switch, for branch staff only. */
.pcoded-header .ui-branch-status {
    display: inline-flex;
    align-items: center;
    gap: var(--ui-space-2);
    padding-inline-start: var(--ui-space-4);
}

.ui-branch-status__text {
    font-size: 13px;
    font-weight: 600;
    color: var(--ui-text-muted);
}


/* ==========================================================================
   31. Auth pages (login / reset / change password)
   --------------------------------------------------------------------------
   These three pages do NOT extend admin/layout — they are standalone documents
   — and none of them loaded this file. Each carried its own <style> block
   instead: 145 lines on login, and one apiece on reset_password and
   change_password. The login block hardcoded #D95525 eight times, which is
   --ui-primary; the same codebase runs several restaurants off separate
   .env/VENDOR_ID, so a literal brand colour is wrong for every deployment but
   one.
   ========================================================================== */

.ui-auth {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: var(--ui-space-4);
    position: relative;
    background-color: var(--ui-bg);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

/* The scrim over the photo. Was `body::before` with `top/left/right/bottom: 0`
   — four physical offsets where `inset` says the same thing once — on a rule
   that also gave <body> a 100vh min-height and a position, so the page could
   not scroll on a short viewport. */
.ui-auth::before {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(23, 37, 53, .45);
}

.ui-auth__card {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 420px;
    padding: var(--ui-space-6);
    background: var(--ui-surface);
    border-radius: var(--ui-radius-lg);
    box-shadow: 0 20px 50px rgba(15, 23, 42, .18);
}

.ui-auth__logo {
    display: block;
    max-width: 150px;
    max-height: 64px;
    width: auto;
    margin: 0 auto var(--ui-space-5);
    object-fit: contain;
}

.ui-auth__title {
    margin: 0 0 4px;
    font-size: 22px;
    font-weight: 700;
    color: var(--ui-text);
    text-align: center;
}

.ui-auth__subtitle {
    margin: 0 0 var(--ui-space-5);
    font-size: 14px;
    color: var(--ui-text-muted);
    text-align: center;
}

.ui-auth__field {
    margin-bottom: var(--ui-space-4);
}

.ui-auth__field label {
    display: block;
    margin-bottom: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ui-text-label);
}

.ui-auth__card .form-control {
    width: 100%;
    height: 48px;
    padding: 10px var(--ui-space-4);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius);
    background: var(--ui-bg);
    font-size: 15px;
    color: var(--ui-text);
    /* Was text-align set from a Blade ternary on the locale. The document
       already carries dir, so the browser resolves this on its own. */
    text-align: start;
    transition: border-color .2s ease, background-color .2s ease, box-shadow .2s ease;
}

.ui-auth__card .form-control:focus {
    outline: none;
    border-color: var(--ui-primary);
    background: var(--ui-surface);
    box-shadow: 0 0 0 4px var(--ui-primary-soft);
}

.ui-auth__options {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ui-space-3);
    margin-bottom: var(--ui-space-5);
    font-size: 14px;
}

.ui-auth__remember {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    color: var(--ui-text-muted);
    font-weight: 600;
    cursor: pointer;
}

.ui-auth__remember input {
    width: 16px;
    height: 16px;
    margin: 0;
    cursor: pointer;
    accent-color: var(--ui-primary);
}

.ui-auth__link {
    color: var(--ui-primary);
    font-weight: 600;
}

.ui-auth__link:hover,
.ui-auth__link:focus-visible {
    color: var(--ui-primary-hover);
    text-decoration: underline;
}

.ui-auth__submit {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 48px;
    border: 0;
    border-radius: var(--ui-radius);
    background: var(--ui-primary);
    color: #fff;
    font-size: 16px;
    font-weight: 700;
    cursor: pointer;
    transition: background-color .2s ease;
}

.ui-auth__submit:hover,
.ui-auth__submit:focus-visible {
    background: var(--ui-primary-hover);
    color: #fff;
}

/* Errors were shown only as a toastr popup, which disappears — and never
   pointed at the field that failed. */
.ui-auth__errors {
    margin-bottom: var(--ui-space-4);
    padding: 10px var(--ui-space-4);
    border-radius: var(--ui-radius);
    background: var(--ui-danger-soft);
    color: var(--ui-danger);
    font-size: 13px;
    line-height: 1.5;
}

.ui-auth__errors ul {
    margin: 0;
    padding-inline-start: 18px;
}

/* "Back to login" under the submit button. Was `.back-link`, defined separately
   in reset_password and change_password with the brand colour written out. */
.ui-auth__back {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    margin-top: var(--ui-space-4);
    color: var(--ui-text-muted);
    font-size: 14px;
    font-weight: 600;
}

.ui-auth__back:hover,
.ui-auth__back:focus-visible {
    color: var(--ui-primary);
}
