/* ============================================================
   TOP END LIQUOR — Reusable Components
   ============================================================ */

/* ---- Buttons ---- */
/* The primary action button.
   The brand green is unchanged — it is still #79C142, still the action
   color. What changed is the label: white on #79C142 measures 2.21:1 and on
   the gradient's dark end 2.72:1, both far under the 4.50:1 AA floor, which
   made the single most important control on the site the least legible text
   on it. The near-black ink measures 6.99:1 / 5.68:1 across the same
   gradient. See --on-primary in base.css. */
.btn-premium {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    background: linear-gradient(135deg, var(--primary-green), var(--primary-green-hover));
    color: var(--on-primary);
    font-weight: 700;
    padding: 0.6rem 1.4rem;
    min-height: 40px;
    border-radius: var(--radius-md);
    font-size: 0.9rem;
    box-shadow: var(--shadow-green);
    transition: all var(--transition-bounce);
    cursor: pointer;
    border: none;
    white-space: nowrap;
}

.btn-premium:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(121, 193, 66, 0.35);
    color: var(--on-primary);
}

.btn-premium:active {
    transform: translateY(0);
}

.btn-premium.btn-sm {
    padding: 0.4rem 0.9rem;
    font-size: 0.8rem;
    border-radius: var(--radius-sm);
}

.btn-premium.btn-lg {
    padding: 0.85rem 2rem;
    font-size: 1.05rem;
}

/* Outline button: the label is green text on white, so it must be the dark
   green (5.24:1). It was #79C142 — 2.21:1, i.e. unreadable. The border keeps
   the brand green so the control still reads as the action color. */
.btn-outline {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    border: 1.5px solid var(--primary-green);
    color: var(--dark-green);
    font-weight: 600;
    padding: 0.55rem 1.3rem;
    min-height: 40px;
    border-radius: var(--radius-md);
    font-size: 0.9rem;
    transition: all var(--transition-base);
    cursor: pointer;
    background: transparent;
    white-space: nowrap;
}

.btn-outline:hover {
    background-color: var(--primary-green);
    border-color: var(--primary-green);
    color: var(--on-primary);
    box-shadow: var(--shadow-green);
}

.btn-outline.btn-sm {
    padding: 0.35rem 0.85rem;
    font-size: 0.8rem;
}

.btn-dark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    background-color: var(--text-main);
    color: #ffffff;
    font-weight: 600;
    padding: 0.6rem 1.4rem;
    border-radius: var(--radius-md);
    font-size: 0.9rem;
    transition: all var(--transition-base);
    cursor: pointer;
    border: none;
}

.btn-dark:hover {
    background-color: #343a40;
    color: #ffffff;
}

.btn-red {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: var(--accent-red);
    color: #ffffff;
    font-weight: 600;
    padding: 0.55rem 1.3rem;
    border-radius: var(--radius-md);
    font-size: 0.85rem;
    transition: all var(--transition-base);
    cursor: pointer;
    border: none;
}

.btn-red:hover {
    background: var(--accent-red-hover);
    color: #ffffff;
}

/* 36px was below the 44px touch minimum, and white on the brand green is
   2.21:1 for the glyph. Both fixed. */
.btn-icon {
    width: 44px;
    height: 44px;
    border-radius: var(--radius-full);
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--primary-green);
    color: var(--on-primary);
    font-size: 0.9rem;
    cursor: pointer;
    border: none;
    transition: all var(--transition-fast);
    flex-shrink: 0;
}

.btn-icon:hover {
    transform: scale(1.08);
    box-shadow: var(--shadow-green);
}

/* ---- Cards ---- */
.card {
    background: var(--bg-secondary);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    transition: all var(--transition-base);
    position: relative;
    overflow: hidden;
}

.card:hover {
    border-color: var(--border-muted);
    box-shadow: var(--shadow-md);
}

.card-premium {
    background: var(--bg-secondary);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    transition: all var(--transition-base);
    position: relative;
    overflow: hidden;
}

.card-premium:hover {
    transform: translateY(-3px);
    border-color: var(--primary-green);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.06);
}

/* ---- Badges ---- */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.7rem;
    font-weight: 700;
    padding: 3px 8px;
    border-radius: 4px;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    line-height: 1.3;
}

/* Badges are 0.7rem uppercase — the smallest text on the page, so they need
   contrast most. White on brand green was 2.21:1; the ink is 6.99:1.
   badge-red is white on #C1272D = 5.84:1 and was already fine. */
.badge-green {
    background-color: var(--primary-green);
    color: var(--on-primary);
}

.badge-red {
    background-color: var(--accent-red);
    color: #ffffff;
}

.badge-outline {
    background: transparent;
    border: 1px solid var(--primary-green);
    color: var(--dark-green);
}

.badge-muted {
    background-color: var(--bg-tertiary);
    color: var(--text-muted);
}

/* ---- Form Controls ---- */
.form-group {
    margin-bottom: var(--space-lg);
}

.form-label {
    display: block;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-main);
    margin-bottom: 0.4rem;
}

.form-input {
    width: 100%;
    background-color: var(--bg-secondary);
    border: 1px solid var(--border-muted);
    padding: 0.7rem 1rem;
    border-radius: var(--radius-md);
    font-size: 0.92rem;
    color: var(--text-main);
    transition: all var(--transition-fast);
}

.form-input:focus {
    border-color: var(--primary-green);
    box-shadow: 0 0 0 3px var(--border-glow);
}

.form-input::placeholder {
    color: var(--text-light);
}

.form-select {
    width: 100%;
    background-color: var(--bg-secondary);
    border: 1px solid var(--border-muted);
    padding: 0.7rem 1rem;
    border-radius: var(--radius-md);
    font-size: 0.92rem;
    color: var(--text-main);
    transition: all var(--transition-fast);
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%236c757d' d='M6 8.5L1 3.5h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 2.5rem;
}

.form-select:focus {
    border-color: var(--primary-green);
    box-shadow: 0 0 0 3px var(--border-glow);
}

textarea.form-input {
    min-height: 100px;
    resize: vertical;
}

.form-error {
    font-size: 0.78rem;
    color: var(--accent-red);
    margin-top: 0.3rem;
}

/* ---- Search Bar ---- */
.search-box {
    position: relative;
    width: 100%;
}

.search-input {
    width: 100%;
    background-color: var(--bg-secondary);
    border: 1px solid var(--border-muted);
    padding: 0.75rem 1rem 0.75rem 2.75rem;
    border-radius: var(--radius-full);
    font-size: 0.92rem;
    color: var(--text-main);
    transition: all var(--transition-fast);
}

.search-input:focus {
    border-color: var(--primary-green);
    box-shadow: 0 0 0 3px var(--border-glow);
}

.search-input::placeholder {
    color: var(--text-light);
}

.search-icon {
    position: absolute;
    left: 1rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-light);
    font-size: 0.95rem;
    pointer-events: none;
}

/* ---- Price Display ---- */
.price-current {
    font-size: 1.1rem;
    font-weight: 800;
    color: var(--text-main);
}

.price-sale {
    font-size: 1.1rem;
    font-weight: 800;
    color: var(--accent-red);
}

.price-old {
    font-size: 0.82rem;
    text-decoration: line-through;
    color: var(--text-light);
    font-weight: 500;
}

/* ---- Empty State ---- */
.empty-state {
    text-align: center;
    padding: var(--space-3xl) var(--space-xl);
    color: var(--text-muted);
}

.empty-state-icon {
    font-size: 3rem;
    color: var(--border-muted);
    margin-bottom: var(--space-lg);
}

.empty-state h3 {
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--text-main);
    margin-bottom: var(--space-sm);
}

.empty-state p {
    font-size: 0.9rem;
    color: var(--text-muted);
}

/* ---- Pagination ---- */
.pagination-container {
    padding: var(--space-xl) 0;
}

.custom-pagination {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    flex-wrap: wrap;
    gap: 1rem;
}

.pagination-info {
    font-size: 0.9rem;
    color: var(--text-muted);
}

.pagination-info span {
    font-weight: 700;
    color: var(--text-main);
}

.pagination-links {
    display: flex;
    list-style: none;
    padding-left: 0;
    margin: 0;
    gap: 0.35rem;
}

.pagination-links .page-item {
    display: inline-block;
}

.pagination-links .page-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Was 38px (34px below 480px) — under the 44px touch minimum on the one
       control a phone user taps repeatedly while browsing a long catalog. */
    min-width: 44px;
    height: 44px;
    padding: 0 12px;
    border: 1px solid var(--border-light);
    border-radius: var(--radius-sm);
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--text-muted);
    transition: all var(--transition-fast);
    background: var(--bg-secondary);
    text-decoration: none;
    box-sizing: border-box;
}

.pagination-links .page-link:hover {
    border-color: var(--primary-green);
    color: var(--dark-green);
    background-color: var(--dark-green-light);
}

/* The current page is the one number that must be unambiguous; it was white
   on brand green (2.21:1). Bold dark ink on the same green reads at 6.99:1. */
.pagination-links .page-item.active .page-link {
    background-color: var(--primary-green);
    color: var(--on-primary);
    border-color: var(--primary-green);
    font-weight: 800;
}

.pagination-links .page-item.disabled .page-link {
    color: var(--text-light);
    border-color: var(--border-light);
    background-color: var(--bg-tertiary);
    cursor: not-allowed;
    opacity: 0.6;
}



/* ---- Divider ---- */
.divider {
    border: none;
    height: 1px;
    background: var(--border-light);
    margin: var(--space-xl) 0;
}

/* ---- Tag / Chip ---- */
.tag {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 5px 12px;
    border-radius: var(--radius-full);
    font-size: 0.8rem;
    font-weight: 600;
    border: 1px solid var(--border-muted);
    color: var(--text-muted);
    cursor: pointer;
    transition: all var(--transition-fast);
    background: var(--bg-secondary);
}

.tag:hover,
.tag.active {
    background: var(--primary-green);
    color: var(--on-primary);
    border-color: var(--primary-green);
}

/* ============================================================
   Shared component vocabulary — storefront + admin + manager
   ------------------------------------------------------------
   One definition per component. The admin panel previously
   re-declared buttons, tables and badges inside every blade's
   <style> block, so the three surfaces drifted apart. Anything
   below is used verbatim by all three.
   ============================================================ */

/* ---- Status pills (driven by Enum::tone()) ---- */
.pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.22rem 0.6rem;
    border-radius: var(--radius-full);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.2px;
    line-height: 1.4;
    border: 1px solid transparent;
    white-space: nowrap;
}

.pill::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}

.pill-success { background: var(--tone-success-bg); color: var(--tone-success-fg); border-color: var(--tone-success-br); }
.pill-warning { background: var(--tone-warning-bg); color: var(--tone-warning-fg); border-color: var(--tone-warning-br); }
.pill-danger  { background: var(--tone-danger-bg);  color: var(--tone-danger-fg);  border-color: var(--tone-danger-br); }
.pill-info    { background: var(--tone-info-bg);    color: var(--tone-info-fg);    border-color: var(--tone-info-br); }
.pill-muted   { background: var(--tone-muted-bg);   color: var(--tone-muted-fg);   border-color: var(--tone-muted-br); }

/* ---- Buttons: neutral + ghost + danger-outline + block ---- */
.btn-neutral {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    border: 1px solid var(--border-muted);
    background: var(--bg-secondary);
    color: var(--text-main);
    font-weight: 600;
    font-size: 0.88rem;
    padding: 0.55rem 1.1rem;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
    white-space: nowrap;
}
.btn-neutral:hover { border-color: var(--dark-green); color: var(--dark-green); }
.btn-neutral.btn-sm { padding: 0.35rem 0.8rem; font-size: 0.8rem; }

.btn-ghost {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: transparent;
    border: none;
    color: var(--dark-green);
    font-weight: 600;
    font-size: 0.85rem;
    padding: 0.35rem 0.5rem;
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.btn-ghost:hover { background: var(--dark-green-light); color: var(--dark-green-hover); }

.btn-red-outline {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    border: 1.5px solid var(--accent-red);
    color: var(--accent-red);
    background: transparent;
    font-weight: 600;
    font-size: 0.85rem;
    padding: 0.5rem 1.1rem;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
    white-space: nowrap;
}
.btn-red-outline:hover { background: var(--accent-red); color: #fff; }
.btn-red.btn-sm, .btn-red-outline.btn-sm { padding: 0.35rem 0.8rem; font-size: 0.8rem; }

.btn-block { width: 100%; }

.btn-premium:disabled,
.btn-outline:disabled,
.btn-neutral:disabled,
.btn-red:disabled {
    opacity: 0.55;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
}

/* Spinner shown inside a button while a request is in flight. */
.btn-spinner {
    width: 14px;
    height: 14px;
    /* Drawn from the button's own text color so it stays visible whichever
       button it sits in. It was hard-coded white, which is invisible on the
       green and neutral buttons now that their labels are dark ink. */
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: tl-spin 0.7s linear infinite;
    display: none;
}
.is-busy .btn-spinner { display: inline-block; }

/* While a request is in flight the label should say so, not just spin.
   Paired with [data-busy-label] handling in app.js. */
.is-busy { cursor: progress; }
@keyframes tl-spin { to { transform: rotate(360deg); } }

/* ---- Panel: the single container used for every boxed section ---- */
.panel {
    background: var(--bg-secondary);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}

.panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    flex-wrap: wrap;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--border-light);
    background: var(--bg-secondary);
}

.panel-head h2, .panel-head h3 {
    font-size: 0.98rem;
    font-weight: 800;
    color: var(--text-main);
    margin: 0;
    letter-spacing: 0.2px;
}

.panel-body { padding: 1.25rem; }
.panel-body.tight { padding: 0; }
.panel-foot {
    padding: 0.9rem 1.25rem;
    border-top: 1px solid var(--border-light);
    background: var(--bg-tertiary);
    display: flex;
    gap: var(--space-sm);
    flex-wrap: wrap;
    justify-content: flex-end;
}

/* ---- Stat tiles ---- */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--space-md);
}

.stat-tile {
    background: var(--bg-secondary);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    padding: 1.1rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    min-width: 0;
}

.stat-tile .stat-label {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
}

.stat-tile .stat-value {
    font-size: 1.6rem;
    font-weight: 800;
    color: var(--text-main);
    line-height: 1.15;
}

.stat-tile .stat-note { font-size: 0.78rem; color: var(--text-light); }
.stat-tile.accent { border-left: 3px solid var(--primary-green); }
.stat-tile.alert  { border-left: 3px solid var(--accent-red); }
.stat-tile.alert .stat-value { color: var(--accent-red); }

/* ---- Data table (one definition for all three surfaces) ---- */
.table-wrap {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.86rem;
    min-width: 680px;
}

.data-table thead th {
    text-align: left;
    padding: 0.75rem 1rem;
    background: var(--bg-tertiary);
    color: var(--text-muted);
    font-weight: 700;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border-bottom: 1px solid var(--border-light);
    white-space: nowrap;
}

.data-table tbody td {
    padding: 0.8rem 1rem;
    border-bottom: 1px solid var(--border-light);
    color: var(--text-main);
    vertical-align: middle;
}

.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover { background: rgba(121, 193, 66, 0.04); }
.data-table td.numeric, .data-table th.numeric { text-align: right; font-variant-numeric: tabular-nums; }
.data-table td.actions { white-space: nowrap; text-align: right; }
.data-table .cell-strong { font-weight: 700; }
.data-table .cell-sub { display: block; font-size: 0.76rem; color: var(--text-muted); }

/* Below 768 the table becomes a stack of labelled rows. Every td
   carries data-label so no header context is lost. Admin tables were
   previously unusable on a phone — this is TL-085. */
@media (max-width: 768px) {
    .data-table.stack-mobile { min-width: 0; }
    .data-table.stack-mobile thead { display: none; }
    .data-table.stack-mobile tbody tr {
        display: block;
        border: 1px solid var(--border-light);
        border-radius: var(--radius-md);
        margin-bottom: 0.75rem;
        padding: 0.35rem 0;
        background: var(--bg-secondary);
    }
    .data-table.stack-mobile tbody td {
        display: flex;
        justify-content: space-between;
        gap: 1rem;
        align-items: baseline;
        border-bottom: none;
        padding: 0.4rem 0.9rem;
        text-align: left;
    }
    .data-table.stack-mobile tbody td::before {
        content: attr(data-label);
        font-size: 0.7rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.4px;
        color: var(--text-muted);
        flex: 0 0 40%;
    }
    .data-table.stack-mobile tbody td.actions { justify-content: flex-end; }
    .data-table.stack-mobile tbody td.actions::before { content: ''; flex: 0; }
}

/* ---- Toolbar / filter bar ---- */
.toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: flex-end;
}
.toolbar .form-group { margin-bottom: 0; flex: 1 1 180px; min-width: 0; }
.toolbar .toolbar-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }

/* ---- Definition list used by every detail view ---- */
.def-list { display: grid; grid-template-columns: minmax(120px, 34%) 1fr; gap: 0.55rem 1rem; }
.def-list dt { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px; color: var(--text-muted); }
.def-list dd { font-size: 0.9rem; color: var(--text-main); margin: 0; word-break: break-word; }
@media (max-width: 480px) { .def-list { grid-template-columns: 1fr; gap: 0.2rem 0; } .def-list dd { margin-bottom: 0.6rem; } }

/* ---- Inline notices (not the floating toast) ---- */
.notice {
    display: flex;
    gap: 0.7rem;
    align-items: flex-start;
    padding: 0.85rem 1rem;
    border-radius: var(--radius-md);
    font-size: 0.87rem;
    border: 1px solid transparent;
    line-height: 1.5;
}
.notice i { margin-top: 0.15rem; flex-shrink: 0; }
.notice-success { background: var(--tone-success-bg); color: var(--tone-success-fg); border-color: var(--tone-success-br); }
.notice-warning { background: var(--tone-warning-bg); color: var(--tone-warning-fg); border-color: var(--tone-warning-br); }
.notice-danger  { background: var(--tone-danger-bg);  color: var(--tone-danger-fg);  border-color: var(--tone-danger-br); }
.notice-info    { background: var(--tone-info-bg);    color: var(--tone-info-fg);    border-color: var(--tone-info-br); }
.notice-muted   { background: var(--tone-muted-bg);   color: var(--tone-muted-fg);   border-color: var(--tone-muted-br); }

/* ---- Form extras ---- */
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0 var(--space-md); }
.form-hint { font-size: 0.78rem; color: var(--text-muted); margin-top: 0.3rem; }
.form-input.is-invalid, .form-select.is-invalid { border-color: var(--accent-red); }
.form-input[readonly] { background: var(--bg-tertiary); color: var(--text-muted); }

.check-row { display: flex; align-items: flex-start; gap: 0.6rem; margin-bottom: 0.6rem; }

/* Several short checkboxes that belong together — the days an offer runs on.
   Wraps rather than scrolls, so seven of them fit a phone. */
.check-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem 1.25rem;
}
.check-grid .check-row { margin-bottom: 0.35rem; min-width: 7.5rem; }
.check-row input[type="checkbox"], .check-row input[type="radio"] {
    width: 17px; height: 17px; accent-color: var(--primary-green);
    margin-top: 0.15rem; flex-shrink: 0; cursor: pointer;
}
.check-row label { font-size: 0.88rem; cursor: pointer; }

.switch { display: inline-flex; align-items: center; gap: 0.65rem; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .switch-track {
    width: 42px; height: 24px; border-radius: var(--radius-full);
    background: var(--border-muted); position: relative; transition: background var(--transition-fast); flex-shrink: 0;
}
.switch .switch-track::after {
    content: ''; position: absolute; top: 3px; left: 3px;
    width: 18px; height: 18px; border-radius: 50%; background: #fff;
    box-shadow: var(--shadow-sm); transition: transform var(--transition-fast);
}
.switch input:checked + .switch-track { background: var(--primary-green); }
.switch input:checked + .switch-track::after { transform: translateX(18px); }
.switch input:focus-visible + .switch-track { box-shadow: var(--focus-ring); }

.field-required::after { content: ' *'; color: var(--accent-red); }

/* The counterpart: a field that is genuinely optional says so, rather than
   leaving the absence of a red asterisk to carry the message. */
.form-optional { font-weight: 400; font-size: 0.78rem; color: var(--text-muted); }

/* ---- Tabs ---- */
.tabs {
    display: flex;
    gap: 0.25rem;
    border-bottom: 1px solid var(--border-light);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
.tabs a, .tabs button {
    padding: 0.6rem 1rem;
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--text-muted);
    border-bottom: 2px solid transparent;
    white-space: nowrap;
    background: none;
}
.tabs a.active, .tabs button.active { color: var(--dark-green); border-bottom-color: var(--primary-green); }

/* ---- Toast container (JS-driven, shared) ---- */
.toast-stack {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 2000;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-width: min(380px, calc(100vw - 2rem));
}
.toast {
    background: #fff;
    border: 1px solid var(--border-light);
    border-left-width: 4px;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    padding: 0.8rem 1rem;
    font-size: 0.87rem;
    display: flex;
    gap: 0.6rem;
    align-items: flex-start;
    animation: toast-in 0.25s ease;
}
.toast.success { border-left-color: var(--primary-green); }
.toast.error   { border-left-color: var(--accent-red); }
.toast.info    { border-left-color: var(--tone-info-fg); }
@keyframes toast-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

/* ---- Avatar ---- */
.avatar {
    width: 36px; height: 36px; border-radius: 50%;
    background: var(--dark-green-light); color: var(--dark-green);
    display: inline-flex; align-items: center; justify-content: center;
    font-weight: 800; font-size: 0.9rem; flex-shrink: 0;
}

/* ---- Breadcrumb ---- */
.breadcrumb { display: flex; flex-wrap: wrap; gap: 0.4rem; font-size: 0.8rem; color: var(--text-muted); margin-bottom: var(--space-md); }
.breadcrumb a { color: var(--dark-green); font-weight: 600; }
.breadcrumb span[aria-current] { color: var(--text-main); font-weight: 600; }

/* ---- Responsive component behavior ---- */
@media (max-width: 768px) {
    .btn-premium, .btn-outline, .btn-neutral, .btn-red { padding: 0.6rem 1.05rem; }
    .panel-body { padding: 1rem; }
    .panel-head { padding: 0.85rem 1rem; }
    .stat-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0.75rem; }
    .stat-tile { padding: 0.9rem 1rem; }
    .stat-tile .stat-value { font-size: 1.35rem; }
    .toolbar .form-group { flex-basis: 100%; }
    .toolbar .toolbar-actions { width: 100%; }
    .toolbar .toolbar-actions .btn-premium,
    .toolbar .toolbar-actions .btn-neutral { flex: 1 1 auto; justify-content: center; }
}

@media (max-width: 480px) {
    .stat-grid { grid-template-columns: 1fr 1fr; }
    .panel-foot { justify-content: stretch; }
    .panel-foot > * { flex: 1 1 auto; justify-content: center; }
    .custom-pagination { justify-content: center; }
    .pagination-links .page-link { min-width: 34px; height: 34px; padding: 0 8px; font-size: 0.8rem; }
}

/* ============================================================
   Forms, states and touch sizing — UX audit
   ------------------------------------------------------------
   Findings this block addresses:

   1. Every text control was 0.92rem (~13.8px). iOS Safari zooms the
      viewport whenever a focused input is under 16px, so tapping any
      field on the checkout, the address form or the login page threw
      the layout sideways and left the user pinched in. Controls are
      raised to 16px at phone widths only, so the desktop density is
      unchanged.

   2. Controls measured ~40px tall against a 44px touch minimum.

   3. .form-error was a bare red line with no icon and no association
      to its field; screen readers got a color-only error signal.
   ============================================================ */

.form-input,
.form-select,
.search-input {
    min-height: 44px;
}

textarea.form-input {
    min-height: 96px;
}

@media (max-width: 768px) {
    /* 16px is the threshold below which iOS zooms on focus. */
    .form-input,
    .form-select,
    .search-input,
    .newsletter-input {
        font-size: 16px;
    }
}

/* An error message is a sentence about what to do next, not a red flag.
   The icon gives the message a second, non-color channel. */
.form-error {
    display: flex;
    align-items: flex-start;
    gap: 0.35rem;
    font-size: 0.79rem;
    font-weight: 600;
    color: var(--tone-danger-fg);
    margin-top: 0.35rem;
}

.form-error::before {
    content: '\f06a';               /* fa-circle-exclamation */
    font-family: 'Font Awesome 6 Free';
    font-weight: 900;
    flex-shrink: 0;
    line-height: 1.5;
}

.form-input.is-invalid,
.form-select.is-invalid {
    border-color: var(--accent-red);
    /* Color alone must not carry the state — WCAG 1.4.1. */
    background-color: var(--tone-danger-bg);
}

.form-input.is-invalid:focus,
.form-select.is-invalid:focus {
    box-shadow: 0 0 0 3px rgba(193, 39, 45, 0.18);
}

/* Checkbox and radio rows: the label is the target, so give the whole row
   a comfortable height rather than relying on the 17px box. */
.check-row {
    min-height: 32px;
    align-items: center;
}

.check-row label {
    line-height: 1.45;
}

/* ---- Empty states ---------------------------------------- */
/* The icon is decoration; the heading and the next action carry the
   meaning. The action was optional and several lists rendered a dead end. */
.empty-state {
    border: 1px dashed var(--border-muted);
    border-radius: var(--radius-lg);
    background: var(--bg-secondary);
}

.empty-state h3 {
    margin-bottom: var(--space-sm);
}

.empty-state p {
    max-width: 46ch;
    margin-left: auto;
    margin-right: auto;
}

.empty-state .empty-actions {
    display: flex;
    gap: var(--space-sm);
    justify-content: center;
    flex-wrap: wrap;
    margin-top: var(--space-lg);
}

/* An empty state nested inside a .panel-body already has the panel's
   border; a second dashed box inside it reads as a mistake. */
.panel-body > .empty-state,
.panel > .empty-state {
    border: none;
    background: transparent;
}

/* ---- Loading ---------------------------------------------- */
/* A skeleton row set, used while a list is being fetched. Matches the
   height of the real rows so nothing shifts when the data lands. */
.skeleton-row {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-md) 0;
    border-bottom: 1px solid var(--border-light);
}

.skeleton-row:last-child { border-bottom: none; }
.skeleton-block { height: 44px; width: 44px; flex-shrink: 0; }
.skeleton-lines { flex: 1 1 auto; min-width: 0; }

/* Respect a reduced-motion preference: a shimmer is decorative motion. */
@media (prefers-reduced-motion: reduce) {
    .skeleton { animation: none; }
    .btn-spinner { animation-duration: 2s; }
    *, *::before, *::after { transition-duration: 0.01ms !important; }
    html { scroll-behavior: auto; }
}

/* ---- Notices that carry their own action ------------------ */
/* A blocker that only says what is wrong makes the reader hunt for the
   fix. Each one now carries the control that resolves it. */
.notice-body { min-width: 0; flex: 1 1 auto; }
.notice-body > :last-child { margin-bottom: 0; }

.notice-actions {
    display: flex;
    gap: var(--space-sm);
    flex-wrap: wrap;
    margin-top: 0.6rem;
}

.notice ul {
    margin: 0.35rem 0 0;
    padding-left: 1.1rem;
    list-style: disc;
}

.notice li { margin-bottom: 0.25rem; }

/* ---- Utility: an inline form that must not break the row --- */
.form-inline { display: inline; }
