/* ─────────────────────────────────────────────────────────────────────────────
   style.next.css — the new look for everything that loaded style.css.
   Served only to visitors who opted in with ?ui=next (includes/ui.php).

   Rules for this file (UI_REVAMP_PLAN.md §5–§6):
   • Every selector style.css had is kept — JavaScript and page markup depend on
     them. Values change, names do not.
   • Values come from tokens.next.css. No gradients, no backdrop blur, no hover
     lifts, no `transition: all`, nothing animated for 300ms or more.
   • `!important` appears only where a rule must beat an inline style="" that
     Phase 4 has not migrated yet. Each such block is marked BRIDGE.
   ───────────────────────────────────────────────────────────────────────────── */

@import url('tokens.next.css');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&display=swap');

/* ── The old token names, pointed at the new palette ─────────────────────────
   About 200 inline style="" declarations and the page <style> blocks ask for
   these names. Aliasing them here re-colours all of them at once, without
   touching a single page. Removed at Phase 6, once nothing asks for them. */
:root {
    --primary:         var(--color-money);
    --primary-hover:   var(--color-money-hover);
    --primary-light:   var(--color-money-subtle);
    --primary-dark:    var(--till-800);
    --secondary:       var(--stone-600);   /* teal is retired */
    --secondary-light: var(--stone-100);
    --success:         var(--color-success-fg);
    --success-light:   var(--color-success-bg);
    --warning:         var(--color-warning-fg);
    --warning-light:   var(--color-warning-bg);
    --warning-dark:    var(--amber-700);
    --danger:          var(--color-danger-fg);
    --danger-light:    var(--color-danger-bg);
    --error:           var(--danger);
    --error-light:     var(--danger-light);

    --gray-50:  var(--stone-50);
    --gray-100: var(--stone-200);
    --gray-200: var(--stone-300);
    --gray-300: var(--stone-400);
    --gray-400: var(--stone-500);
    --gray-500: var(--stone-600);
    --gray-600: var(--stone-700);
    --gray-700: var(--stone-800);
    --gray-800: var(--stone-900);
    --gray-900: var(--stone-900);
    --white:    var(--stone-0);

    --shadow-sm: var(--shadow-xs);
    --shadow:    var(--shadow-xs);
    --shadow-md: var(--shadow-floating);
    --shadow-lg: var(--shadow-overlay);
    --radius:    var(--radius-md);
    /* --radius-md and --radius-lg keep their names and take the new ladder from tokens.next.css. */
    --transition: color var(--duration-fast) var(--ease-out),
                  background-color var(--duration-fast) var(--ease-out),
                  border-color var(--duration-fast) var(--ease-out),
                  box-shadow var(--duration-fast) var(--ease-out),
                  opacity var(--duration-fast) var(--ease-out),
                  transform var(--duration-fast) var(--ease-out);

    /* Input boundaries must reach 3:1 against white (WCAG 1.4.11); stone-400 is 2.5:1. */
    --color-border-input: #8f8883;
}

/* ── Base ──────────────────────────────────────────────────────────────────── */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scrollbar-color: var(--stone-300) transparent;
    -webkit-text-size-adjust: 100%;
}

body {
    font-family: var(--font-sans);
    font-size: var(--text-body);
    background-color: var(--color-bg-page);
    color: var(--color-fg-default);
    line-height: var(--leading-body);
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

::selection {
    background: var(--till-100);
    color: var(--stone-900);
}

a {
    color: var(--color-money);
    text-decoration: none;
    text-underline-offset: 3px;
    transition: var(--transition);
}

@media (hover: hover) and (pointer: fine) {
    a:hover { color: var(--color-money-hover); text-decoration: underline; }
}

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--color-money);
    outline-offset: 2px;
}

/* Numbers line up. Plex's figures are tabular by default; this keeps them so if
   another face ever stands in for it. */
table, .value, .num, .amt, .kpi, .v-kpi, .total-row {
    font-variant-numeric: tabular-nums;
}

/* The classic look draws a WebGL wireframe here; the new look draws nothing. */
#dash-canvas,
#auth-canvas {
    display: none;
}

/* ── Login and the password pages ─────────────────────────────────────────── */
.login-page {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background: var(--color-bg-page);
    padding: var(--space-6);
    position: relative;
}

.login-container {
    width: 100%;
    max-width: 440px;
    position: relative;
}

.login-box {
    background: var(--color-bg-surface);
    padding: var(--space-8);
    border-radius: var(--radius-lg);
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow-xs);
    /* login.php still runs its classic entrance script; the box must be visible without it. */
    opacity: 1;
    transform: none;
}

.login-brand {
    text-align: center;
    margin-bottom: var(--space-6);
}

.login-brand h1 {
    font-size: var(--text-h1);
    font-weight: 600;
    line-height: var(--leading-tight);
    color: var(--color-fg-default);
    letter-spacing: -0.01em;
}

.login-box .subtitle {
    text-align: center;
    color: var(--color-fg-muted);
    font-size: var(--text-ui);
    margin-bottom: var(--space-6);
}

.login-footer {
    text-align: center;
    margin-top: var(--space-6);
    font-size: var(--text-ui);
    color: var(--color-fg-muted);
}

/* Nothing on the sign-in pages moves money, so their inline var(--primary) links are ink. */
.login-page {
    --primary: var(--color-fg-default);
    --primary-hover: var(--color-fg-default);
}

.login-alert {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--color-danger-border);
    border-radius: var(--radius-md);
    background: var(--color-danger-bg);
    color: var(--color-danger-fg);
    font-size: var(--text-ui);
}

.login-alert svg { flex-shrink: 0; margin-top: 0.125rem; }

/* BRIDGE — login.php, forgot_password.php and reset_password.php size the logo with
   style="max-height:120–140px", and the PNG carries wide transparent margins. */
.login-brand img { max-height: 4.5rem !important; }

/* ── Forms ─────────────────────────────────────────────────────────────────── */
.form-group {
    margin-bottom: var(--space-4);
    position: relative;
}

.form-group label {
    display: block;
    margin-bottom: var(--space-2);
    font-weight: 500;
    font-size: var(--text-ui);
    color: var(--color-fg-default);
}

.form-group input,
.form-group select,
.form-group textarea {
    width: 100%;
    min-height: var(--control-md);
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--color-border-input);
    border-radius: var(--radius-sm);
    font: inherit;
    font-size: var(--text-ui);
    color: var(--color-fg-default);
    background: var(--color-bg-surface);
    box-shadow: var(--shadow-xs);
    transition: border-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    outline: none;
    border-color: var(--color-money);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

.form-group input[aria-invalid="true"],
.form-group select[aria-invalid="true"],
.form-group textarea[aria-invalid="true"] {
    border-color: var(--color-danger-fg);
}

.form-group input::placeholder,
.form-group textarea::placeholder {
    color: var(--color-fg-subtle);
}

.form-group input:disabled,
.form-group select:disabled,
.form-group textarea:disabled {
    background: var(--color-bg-muted);
    color: var(--color-fg-muted);
    cursor: not-allowed;
}

/* Password field (assets/js/password-toggle.js builds this markup) */
.password-field {
    position: relative;
    display: block;
    width: 100%;
}

.password-field input[type="password"],
.password-field input[type="text"] {
    width: 100%;
    padding-right: 3rem;
}

.password-toggle {
    position: absolute;
    right: var(--space-1);
    top: 50%;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--control-md);
    height: var(--control-md);
    padding: 0;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-fg-muted);
    cursor: pointer;
    transition: var(--transition);
}

@media (hover: hover) and (pointer: fine) {
    .password-toggle:hover { color: var(--color-fg-default); background: var(--color-bg-muted); }
}

.password-toggle:focus-visible {
    outline: 2px solid var(--color-money);
    outline-offset: 0;
}

.password-toggle-icon {
    display: block;
    flex-shrink: 0;
}

/* ── Buttons ───────────────────────────────────────────────────────────────────
   .btn on its own has always been the page's primary button, so it stays ink.
   Green (.btn-success) is for actions that move money. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: var(--control-md);
    padding: 0 var(--space-4);
    background: var(--color-action);
    color: var(--color-action-fg);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    cursor: pointer;
    font-family: inherit;
    font-size: var(--text-ui);
    font-weight: 500;
    line-height: 1.25;
    white-space: nowrap;
    text-decoration: none;
    transition: var(--transition);
}

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

.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none;
}

.btn-primary {
    background: var(--color-action);
    color: var(--color-action-fg);
}

.btn-block {
    display: flex;
    width: 100%;
}

.btn-success {
    background: var(--color-money);
    color: var(--color-money-fg);
}

.btn-warning {
    background: var(--color-warning-fg);
    color: var(--stone-0);
}

.btn-danger {
    background: var(--color-danger-fg);
    color: var(--stone-0);
}

.btn-secondary {
    background: var(--color-bg-muted);
    color: var(--color-fg-default);
}

.btn-outline {
    background: var(--color-bg-surface);
    border-color: var(--color-border-strong);
    color: var(--color-fg-default);
    box-shadow: var(--shadow-xs);
}

.btn-sm {
    min-height: var(--control-sm);
    padding: 0 var(--space-3);
    font-size: var(--text-small);
}

@media (hover: hover) and (pointer: fine) {
    .btn:hover,
    .btn-primary:hover { background: var(--color-action-hover); color: var(--color-action-fg); text-decoration: none; }
    .btn-success:hover { background: var(--color-money-hover); color: var(--color-money-fg); }
    .btn-warning:hover { background: #854d0e; color: var(--stone-0); }
    .btn-danger:hover  { background: var(--color-danger-hover); color: var(--stone-0); }
    .btn-secondary:hover { background: var(--stone-200); color: var(--color-fg-default); }
    .btn-outline:hover { background: var(--color-bg-muted); border-color: var(--color-border-input); color: var(--color-fg-default); }
}

/* ── Alerts ────────────────────────────────────────────────────────────────── */
.alert {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    margin-bottom: var(--space-4);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-size: var(--text-ui);
}

.alert-error {
    background: var(--color-danger-bg);
    color: var(--color-danger-fg);
    border-color: var(--color-danger-border);
}

.alert-success {
    background: var(--color-success-bg);
    color: var(--color-success-fg);
    border-color: var(--color-success-border);
}

.alert-info {
    background: var(--color-bg-muted);
    color: var(--color-fg-default);
    border-color: var(--color-border);
}

/* ── Panel shell: sidebar + content ────────────────────────────────────────── */
.app-container {
    display: flex;
    min-height: 100vh;
}

.sidebar {
    width: 16rem;
    background: var(--color-bg-page);
    border-right: 1px solid var(--color-border);
    padding: var(--space-4) 0;
    position: fixed;
    height: 100vh;
    overflow-y: auto;
    z-index: var(--z-overlay);
    display: flex;
    flex-direction: column;
}

.sidebar-brand {
    padding: 0 var(--space-4) var(--space-4);
    border-bottom: 1px solid var(--color-border);
    margin-bottom: var(--space-3);
}

.sidebar-brand h2 {
    font-size: var(--text-h3);
    font-weight: 600;
    color: var(--color-fg-default);
}

.sidebar-nav {
    list-style: none;
    padding: 0 var(--space-2);
}

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

.sidebar-nav li a,
.sidebar-nav a {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--control-sm);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    color: var(--color-fg-muted);
    font-size: var(--text-ui);
    font-weight: 400;
    transition: var(--transition);
}

@media (hover: hover) and (pointer: fine) {
    .sidebar-nav li a:hover { background: var(--color-bg-muted); color: var(--color-fg-default); text-decoration: none; }
}

.sidebar-nav li a.active,
.sidebar-nav a.active {
    background: var(--stone-200);
    color: var(--color-fg-default);
    font-weight: 500;
}

.sidebar-nav li a svg {
    width: 1rem;
    height: 1rem;
}

/* Collapsible groups (toggleNavGroup() in includes/layout.php flips .open) */
.sidebar-nav .nav-group-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: var(--control-sm);
    margin-top: var(--space-2);
    padding: var(--space-1) var(--space-3);
    color: var(--color-fg-muted);
    font-size: var(--text-small);
    font-weight: 500;
    cursor: pointer;
    user-select: none;
    border-radius: var(--radius-sm);
}

@media (hover: hover) and (pointer: fine) {
    .sidebar-nav .nav-group-header:hover { color: var(--color-fg-default); }
}

.sidebar-nav .nav-group-header .chev {
    font-size: 1.1rem;
    line-height: 1;
    transition: transform var(--duration-fast) var(--ease-out);
}

.sidebar-nav .nav-group.open > .nav-group-header .chev { transform: rotate(90deg); }
.sidebar-nav .nav-sub { list-style: none; margin: 0; padding: 0; display: none; }
.sidebar-nav .nav-group.open > .nav-sub { display: block; }
.sidebar-nav .nav-sub a { padding-left: var(--space-6); }

.sidebar-nav a.logout-link {
    margin-top: var(--space-4);
    border-top: 1px solid var(--color-border);
    border-radius: 0;
    padding-top: var(--space-3);
    color: var(--color-danger-fg);
}

@media (hover: hover) and (pointer: fine) {
    .sidebar-nav a.logout-link:hover { background: var(--color-danger-bg); color: var(--color-danger-hover); }
}

.main-content {
    flex: 1;
    min-width: 0; /* let the column shrink below its widest table so tables scroll inside it */
    margin-left: 16rem;
    padding: var(--space-8);
    /* A column, so the builder's credit strip can sit at the FOOT of the page rather than
       directly under the content. On a short page (Categories with a handful of rows) it
       was landing mid-screen with empty column beneath it. Only two children take part:
       .mc-flow and .tk-credit - see includes/layout.php. */
    display: flex;
    flex-direction: column;
}

/* The page's own content. flex:1 makes it take the slack, which is what pushes the credit
   strip down; min-width:0 repeats .main-content's reason - without it a wide table stops
   the column shrinking and the whole page scrolls sideways instead of the table. */
.mc-flow {
    flex: 1 0 auto;
    min-width: 0;
}

/* ── Page header ───────────────────────────────────────────────────────────── */
.page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-4);
    margin-bottom: var(--space-6);
    padding-bottom: var(--space-4);
    border-bottom: 1px solid var(--color-border);
}

.page-header h2 {
    font-size: var(--text-h1);
    font-weight: 600;
    line-height: var(--leading-tight);
    color: var(--color-fg-default);
    letter-spacing: -0.01em;
}

.page-header .breadcrumb {
    font-size: var(--text-ui);
    color: var(--color-fg-muted);
    margin-top: var(--space-1);
}

/* ── Summary figures ───────────────────────────────────────────────────────────
   Flat and bordered. No hover lift, no tinted icon tiles, no all-caps labels. */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--space-3);
    margin-bottom: var(--space-8);
}

.stat-card {
    background: var(--color-bg-surface);
    padding: var(--space-4);
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
}

.stat-card-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--space-2);
}

.stat-card h3 {
    color: var(--color-fg-muted);
    font-size: var(--text-small);
    font-weight: 500;
}

.stat-card .icon {
    width: 1.25rem;
    height: 1.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-fg-subtle);
}

.stat-card .icon svg {
    width: 1.125rem;
    height: 1.125rem;
}

.stat-card .icon.primary,
.stat-card .icon.success,
.stat-card .icon.warning,
.stat-card .icon.danger { background: transparent; }
.stat-card .icon.success { color: var(--color-success-fg); }
.stat-card .icon.warning { color: var(--color-warning-fg); }
.stat-card .icon.danger  { color: var(--color-danger-fg); }

.stat-card .value {
    font-size: 1.75rem;
    font-weight: 600;
    color: var(--color-fg-default);
    line-height: var(--leading-tight);
    letter-spacing: -0.01em;
}

.stat-card .trend {
    font-size: var(--text-small);
    margin-top: var(--space-2);
    color: var(--color-fg-muted);
}

/* shop_admin/sales.php builds its figures from .stat-icon (an emoji) + .stat-info in its own
   <style>, which loads after this file — hence the .stats-grid prefix. The today card
   (.stat-card--today) drops its brown gradient and reads like the rest. */
.stats-grid .stat-card {
    gap: var(--space-3);
    padding: var(--space-4);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-bg-surface);
    box-shadow: none;
    color: var(--color-fg-default);
}

.stats-grid .stat-card .stat-icon { display: none; }

/* Report hub tabs — .rpt-tab (shop_admin/reports.php, admin/reports.php) and .vr-tab
   (store/reports.php), defined in each page's own <style>, which loads after this file — hence
   the container prefix. Text-only: the emoji spans are hidden, the active tab is ink. */
.rpt-tabs .rpt-tab-ico,
.vr-tabs .vr-tab-ico { display: none; }

.rpt-tabs,
.vr-tabs { gap: var(--space-2); margin-bottom: var(--space-6); }

.rpt-tabs .rpt-tab,
.vr-tabs .vr-tab {
    min-height: var(--control-md);
    padding: 0 var(--space-3);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-bg-surface);
    box-shadow: none;
    color: var(--color-fg-muted);
    font-size: var(--text-ui);
    font-weight: 500;
    transition: background-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}

.vr-tabs .vr-tab.away { border-style: dashed; }

.rpt-tabs .rpt-tab.active,
.vr-tabs .vr-tab.active { border-color: var(--color-action); background: var(--color-action); box-shadow: none; color: var(--color-action-fg); }

@media (hover: hover) and (pointer: fine) {
    .rpt-tabs .rpt-tab:hover,
    .vr-tabs .vr-tab:hover { border-color: var(--color-border-strong); color: var(--color-fg-default); }
    .rpt-tabs .rpt-tab.active:hover,
    .vr-tabs .vr-tab.active:hover { border-color: var(--color-action-hover); background: var(--color-action-hover); color: var(--color-action-fg); }
}

/* admin/shops.php's .btn-glow (a purple gradient pill, defined in the page's own <style>, which
   loads after this file — hence button.btn-glow). Ink like every primary action; the delete
   confirm is red. */
button.btn-glow {
    min-height: var(--control-md);
    padding: 0 var(--space-4);
    border: 1px solid var(--color-action);
    border-radius: var(--radius-md);
    background: var(--color-action);
    box-shadow: none;
    color: var(--color-action-fg);
    font-size: var(--text-ui);
    font-weight: 500;
    transition: background-color var(--duration-fast) var(--ease-out);
}

button.btn-glow.btn-glow--danger { border-color: var(--color-danger-fg); background: var(--color-danger-fg); }
button.btn-glow:disabled { opacity: 0.5; cursor: not-allowed; }

@media (hover: hover) and (pointer: fine) {
    button.btn-glow:hover { transform: none; box-shadow: none; background: var(--color-action-hover); color: var(--color-action-fg); }
    button.btn-glow.btn-glow--danger:hover { background: var(--color-danger-fg); }
}
.stats-grid .stat-card .stat-info h4 { color: var(--color-fg-muted); font-size: var(--text-small); font-weight: 500; letter-spacing: 0; text-transform: none; }
.stats-grid .stat-card .stat-info .val { color: var(--color-fg-default); font-size: 1.75rem; font-weight: 600; letter-spacing: -0.01em; line-height: var(--leading-tight); }

/* ── Tables ────────────────────────────────────────────────────────────────── */
.table-container {
    background: var(--color-bg-surface);
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    overflow-x: auto;
}

.table-header {
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--color-border);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-3);
}

.table-header h3 {
    font-size: var(--text-body);
    font-weight: 600;
    color: var(--color-fg-default);
}

table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-ui);
}

table th,
table td {
    padding: var(--space-3) var(--space-4);
    text-align: left;
    border-bottom: 1px solid var(--color-border);
}

table th {
    background: var(--color-bg-page);
    font-weight: 500;
    color: var(--color-fg-muted);
    font-size: var(--text-small);
    white-space: nowrap;
}

table tr:last-child td {
    border-bottom: none;
}

@media (hover: hover) and (pointer: fine) {
    table tbody tr:hover { background: var(--color-bg-page); }
}

/* ── Status badges ─────────────────────────────────────────────────────────── */
.status {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 0.125rem var(--space-2);
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.5;
    white-space: nowrap;
}

.status-available, .status-active, .status-completed {
    background: var(--color-success-bg);
    color: var(--color-success-fg);
    border-color: var(--color-success-border);
}

.status-rented {
    background: var(--color-warning-bg);
    color: var(--color-warning-fg);
    border-color: var(--color-warning-border);
}

.status-maintenance, .status-pending {
    background: var(--color-danger-bg);
    color: var(--color-danger-fg);
    border-color: var(--color-danger-border);
}

/* A shelf the shop keeps for itself (migration 312) — its own look, because
   "rented" is money coming in and "house" is space taken out of the letting market. */
.status-house {
    background: var(--stone-800);
    color: var(--stone-50);
}

.status-expired, .status-cancelled, .status-failed {
    background: var(--color-bg-muted);
    color: var(--color-fg-muted);
    border-color: var(--color-border);
}

/* ── Cards ─────────────────────────────────────────────────────────────────── */
.card {
    background: var(--color-bg-surface);
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    padding: var(--space-6);
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
    padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--color-border);
}

.card h3 {
    font-size: var(--text-body);
    font-weight: 600;
    color: var(--color-fg-default);
}

/* ── Modal (pages toggle .active on #xModal) ───────────────────────────────── */
.modal {
    display: none;
    position: fixed;
    inset: 0;
    background: var(--color-bg-overlay);
    justify-content: center;
    align-items: center;
    padding: var(--space-4);
    z-index: var(--z-modal);
}

.modal.active {
    display: flex;
}

.modal-content {
    background: var(--color-bg-surface);
    padding: var(--space-6);
    border-radius: var(--radius-lg);
    max-width: 500px;
    width: 100%;
    max-height: calc(100vh - var(--space-8));
    overflow-y: auto;
    box-shadow: var(--shadow-overlay);
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
}

.modal-header h3 {
    font-size: var(--text-h3);
    font-weight: 600;
    color: var(--color-fg-default);
}

.modal-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--control-sm);
    min-height: var(--control-sm);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    color: var(--color-fg-muted);
    border-radius: var(--radius-sm);
    transition: var(--transition);
}

@media (hover: hover) and (pointer: fine) {
    .modal-close:hover { color: var(--color-fg-default); background: var(--color-bg-muted); }
}

/* ── Small shared pieces ───────────────────────────────────────────────────── */
.actions {
    display: flex;
    flex-wrap: wrap; /* a row's buttons wrap inside their cell instead of pushing the table past its container */
    gap: var(--space-2);
}

.empty-state {
    text-align: center;
    padding: var(--space-12) var(--space-6);
    color: var(--color-fg-muted);
}

.empty-state svg {
    width: 2.5rem;
    height: 2.5rem;
    color: var(--color-fg-subtle);
    margin-bottom: var(--space-3);
}

.filter-bar {
    display: flex;
    gap: var(--space-3);
    margin-bottom: var(--space-6);
    align-items: flex-end;
    flex-wrap: wrap;
}

.filter-bar .form-group {
    margin-bottom: 0;
    min-width: 150px;
}

.quick-actions {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--space-3);
    margin-bottom: var(--space-8);
}

.quick-action-card {
    background: var(--color-bg-surface);
    padding: var(--space-4);
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    cursor: pointer;
    transition: border-color var(--duration-fast) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
    .quick-action-card:hover { border-color: var(--color-border-input); }
}

.quick-action-card svg {
    width: 1.25rem;
    height: 1.25rem;
    color: var(--color-fg-default);
    margin-bottom: var(--space-2);
}

.quick-action-card h4 {
    font-size: var(--text-ui);
    font-weight: 600;
    color: var(--color-fg-default);
    margin-bottom: var(--space-1);
}

.quick-action-card p {
    font-size: var(--text-small);
    color: var(--color-fg-muted);
}

/* User menu (foot of the sidebar) */
.user-menu {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin: auto var(--space-2) 0;
    padding: var(--space-3) var(--space-2) 0;
    border-top: 1px solid var(--color-border);
}

.user-avatar {
    width: var(--control-md);
    height: var(--control-md);
    border-radius: var(--radius-full);
    background: var(--stone-200);
    color: var(--color-fg-default);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: var(--text-ui);
    flex-shrink: 0;
}

.user-info { flex: 1; min-width: 0; }

.user-name {
    font-size: var(--text-ui);
    font-weight: 500;
    color: var(--color-fg-default);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.user-role {
    font-size: var(--text-small);
    color: var(--color-fg-muted);
}

/* Mobile top bar (hamburger + page title) */
.mobile-topbar {
    display: none;
    align-items: center;
    gap: var(--space-2);
    margin: calc(-1 * var(--space-4)) calc(-1 * var(--space-4)) var(--space-4);
    padding: var(--space-2) var(--space-4);
    background: var(--color-bg-page);
    border-bottom: 1px solid var(--color-border);
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
}

.mobile-topbar-title {
    font-size: var(--text-body);
    font-weight: 600;
    color: var(--color-fg-default);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.desktop-hidden { display: none; }

.mobile-nav-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    min-width: var(--control-lg);
    min-height: var(--control-lg);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--color-fg-default);
    cursor: pointer;
}

.mobile-nav-toggle svg { width: 1.5rem; height: 1.5rem; }

.sidebar-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: var(--color-bg-overlay);
    z-index: calc(var(--z-overlay) - 1);
}

.sidebar-overlay.active {
    display: block;
}

/* Flash toast (includes/layout.php). Ink for a confirmation, red for an error; its script
   slides it in and out by setting style.transform. */
.flash-toast {
    position: fixed;
    top: var(--space-6);
    right: var(--space-6);
    z-index: var(--z-toast);
    display: flex;
    align-items: center;
    gap: var(--space-3);
    max-width: 26rem;
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    background: var(--color-bg-inverse);
    color: var(--color-fg-inverse);
    box-shadow: var(--shadow-overlay);
    font-size: var(--text-ui);
    font-weight: 500;
    transform: translateX(150%);
    transition: transform var(--duration-base) var(--ease-out);
}

.flash-toast svg { flex-shrink: 0; width: 1.25rem; height: 1.25rem; }
.flash-toast--success svg { color: var(--till-100); }
.flash-toast--error { background: var(--color-danger-fg); }

/* Subscription countdown banner (includes/layout.php, shop owners only). "Pay now" moves
   money, so it is the till green. */
.sub-countdown {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-bottom: var(--space-6);
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--color-warning-border);
    border-radius: var(--radius-md);
    background: var(--color-warning-bg);
    color: var(--color-warning-fg);
}

.sub-countdown--critical {
    border-color: var(--color-danger-border);
    background: var(--color-danger-bg);
    color: var(--color-danger-fg);
}

/* A trial with more than a week left (includes/layout.php): one quiet line, not a warning. */
.sub-countdown--calm {
    margin-bottom: var(--space-4);
    padding: var(--space-2) var(--space-4);
    border-color: var(--color-border);
    background: var(--color-bg-muted);
    color: var(--color-fg-muted);
}
.sub-countdown-link { font-size: var(--text-ui); font-weight: 500; color: var(--color-fg-default); white-space: nowrap; }

.sub-countdown-icon { flex-shrink: 0; width: 1.25rem; height: 1.25rem; }
.sub-countdown-text { flex: 1; min-width: 12.5rem; font-size: var(--text-ui); line-height: 1.5; color: inherit; }

.sub-countdown-btn {
    display: inline-flex;
    align-items: center;
    min-height: var(--control-md);
    padding: 0 var(--space-4);
    border-radius: var(--radius-md);
    background: var(--color-money);
    color: var(--color-money-fg);
    font-size: var(--text-ui);
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color var(--duration-fast) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
    .sub-countdown-btn:hover { background: var(--color-money-hover); color: var(--color-money-fg); text-decoration: none; }
}

/* Dashboard "New here?" guide link (shop_admin/dashboard.php). A quiet card, not a gradient:
   it is help, not the main job of the page. */
.guide-banner {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3) var(--space-4);
    margin-bottom: var(--space-6);
    padding: var(--space-4);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-bg-surface);
    color: var(--color-fg-default);
    text-decoration: none;
    transition: border-color var(--duration-fast) var(--ease-out);
}

.guide-banner-icon {
    display: flex;
    flex: 0 0 2.5rem;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--radius-md);
    background: var(--color-bg-muted);
    color: var(--color-fg-muted);
}

.guide-banner-icon svg { width: 1.25rem; height: 1.25rem; }
.guide-banner-body { flex: 1 1 14rem; min-width: 0; }
.guide-banner-title { font-size: var(--text-ui); font-weight: 600; }
.guide-banner-sub { margin-top: 0.125rem; color: var(--color-fg-muted); font-size: var(--text-ui); }
.guide-banner-cta { display: inline-flex; align-items: center; gap: var(--space-1); color: var(--color-action); font-size: var(--text-ui); font-weight: 500; white-space: nowrap; }

@media (hover: hover) and (pointer: fine) {
    .guide-banner:hover { border-color: var(--color-border-strong); color: var(--color-fg-default); text-decoration: none; }
}

/* Money and state colours (vendor_remittances, rentals). Green and red are feedback here, not
   actions; "your own" and "no rent" are plain ink — nothing is wrong or owed. */
.ink-paid  { color: var(--color-success-fg); }
.ink-owed  { color: var(--color-danger-fg); }
.ink-none  { color: var(--color-fg-subtle); }
.ink-house { color: var(--color-fg-default); }
.ink-due   { color: var(--color-warning-fg); }
.card-owed { border-color: var(--color-danger-border); }
.card-own  { border-left: 1px solid var(--color-border); }
.house-tag { padding: 0.0625rem 0.375rem; border-radius: var(--radius-sm); background: var(--color-bg-muted); color: var(--color-fg-muted); font-weight: 600; letter-spacing: 0.02em; }
.emoji-deco { display: none; }

.btn.btn-remind { border: 1px solid var(--color-border-strong); background: var(--color-bg-surface); color: var(--color-fg-default); font-weight: 500; }
.btn.btn-remind-send,
.btn.btn-remind-send:hover { border: 0; border-radius: var(--radius-md); background: var(--color-action); box-shadow: none; color: var(--color-action-fg); font-weight: 500; }

@media (hover: hover) and (pointer: fine) {
    .btn.btn-remind:hover { background: var(--color-bg-muted); color: var(--color-fg-default); }
    .btn.btn-remind-send:hover { background: var(--color-action-hover); }
}

/* shop_admin/subscription.php. "Pay via M-Pesa" moves money, so it is the one till-green control;
   cancelling is a quiet red outline. */
.sub-panel { padding: var(--space-6); border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-bg-surface); box-shadow: none; }
.sub-panel--exempt { border-color: var(--color-border); }
.sub-panel-title { margin: 0 0 var(--space-4); padding-bottom: var(--space-3); border-bottom: 1px solid var(--color-border); color: var(--color-fg-default); font-size: 1rem; font-weight: 600; }
.sub-label { color: var(--color-fg-muted); font-size: var(--text-small); font-weight: 500; letter-spacing: 0; text-transform: none; }
.sub-label--field { display: block; margin-bottom: var(--space-2); }
.sub-plan-name { color: var(--color-fg-default); font-size: 1.25rem; font-weight: 600; }
.sub-trial { margin-left: var(--space-2); padding: 0.0625rem 0.375rem; border-radius: var(--radius-sm); background: var(--color-warning-bg); color: var(--color-warning-fg); font-size: var(--text-small); font-weight: 500; vertical-align: middle; }
.sub-status { display: inline-block; padding: 0.125rem var(--space-2); border-radius: var(--radius-sm); font-size: var(--text-small); font-weight: 500; }
.sub-status--ok  { background: var(--color-success-bg); color: var(--color-success-fg); }
.sub-status--bad { background: var(--color-danger-bg); color: var(--color-danger-fg); }
.sub-valid { color: var(--color-fg-default); font-size: 1rem; font-weight: 500; }
.sub-note { margin-bottom: var(--space-4); padding: var(--space-3) var(--space-4); border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-bg-muted); }
.sub-note--danger { border-color: var(--color-danger-border); background: var(--color-danger-bg); }
.sub-note-lead { color: var(--color-fg-default); }
.sub-note-danger-text { color: var(--color-danger-fg); }
.sub-cancel-btn { width: 100%; min-height: var(--control-md); border: 1px solid var(--color-danger-border); border-radius: var(--radius-md); background: var(--color-bg-surface); color: var(--color-danger-fg); font-weight: 500; cursor: pointer; transition: background-color var(--duration-fast) var(--ease-out); }
.sub-modal-box { width: 90%; max-width: 25rem; padding: var(--space-6); border-radius: var(--radius-lg); background: var(--color-bg-surface); box-shadow: var(--shadow-overlay); }
.sub-modal-ico { display: flex; align-items: center; justify-content: center; width: 3rem; height: 3rem; margin: 0 auto var(--space-4); border-radius: 50%; background: var(--color-danger-bg); color: var(--color-danger-fg); }
.sub-modal-ico svg { width: 1.5rem; height: 1.5rem; }
.sub-exempt-lead { color: var(--color-success-fg); }
.sub-input { width: 100%; min-height: var(--control-lg); padding: 0 var(--space-3); border: 1px solid var(--color-border-strong); border-radius: var(--radius-md); background: var(--color-bg-surface); font-family: inherit; font-size: 1rem; }
.sub-cancel-btn,
.sub-pay-btn { font-family: inherit; }
.sub-input:focus-visible { outline: 2px solid var(--color-action); outline-offset: 1px; }
.action-header.sub-header { margin-bottom: var(--space-6); padding: 0 0 var(--space-4); border: 0; border-bottom: 1px solid var(--color-border); border-radius: 0; background: none; backdrop-filter: none; }
.sub-alert { display: flex; align-items: flex-start; gap: var(--space-3); margin-bottom: var(--space-6); padding: var(--space-4); border-radius: var(--radius-md); }
.sub-alert--warn      { border: 1px solid var(--color-warning-border); background: var(--color-warning-bg); color: var(--color-warning-fg); }
.sub-alert--cancelled { border: 1px solid var(--color-danger-border); background: var(--color-danger-bg); color: var(--color-danger-fg); }
.sub-alert-ico { width: auto; height: auto; background: none; color: inherit; }
.sub-alert-ico svg { width: 1.25rem; height: 1.25rem; }
.sub-alert-title { margin: 0 0 var(--space-1); color: inherit; font-size: var(--text-ui); font-weight: 600; }
.sub-alert-text { color: inherit; font-size: var(--text-ui); }
.sub-pay-btn { width: 100%; min-height: var(--control-lg); border: 0; border-radius: var(--radius-md); background: var(--color-money); box-shadow: none; color: var(--color-money-fg); font-size: 1rem; font-weight: 600; cursor: pointer; transition: background-color var(--duration-fast) var(--ease-out); }

@media (hover: hover) and (pointer: fine) {
    .sub-cancel-btn:hover { background: var(--color-danger-bg); color: var(--color-danger-fg); }
    .sub-pay-btn:hover { background: var(--color-money-hover); }
}

/* The shopper's cart (assets/js/cart.js) is styled by assets/css/cart.css, linked by the pages
   that load the cart. The POS has its own cart and does not use it. */

/* ── Public header — the marketplace pages' top bar ────────────────────────────
   One definition for index.php, pricing.php and the storefront, which all render the
   same .landing-nav markup. Panel pages never render it. Page sheets size their own
   content against --nav-height, --page-max and --page-gutter. */
:root {
    --nav-height: 4.5rem;
    --page-max: 75rem;
    --page-gutter: 5%;
}

.landing-nav {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: var(--z-sticky);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    min-height: var(--nav-height);
    padding: var(--space-2) var(--page-gutter);
    background: var(--color-bg-surface);
    border-bottom: 1px solid var(--color-border);
}

.landing-nav.scrolled { box-shadow: var(--shadow-xs); }

/* The logo PNG carries wide transparent margins, so it is sized larger than the mark looks. */
.landing-logo {
    display: block;
    height: 4.25rem;
    width: auto;
    max-width: 14rem;
    margin-block: -0.5rem;
}

.nav-links {
    display: flex;
    align-items: center;
    gap: var(--space-6);
}

.nav-links a {
    color: var(--color-fg-default);
    font-size: var(--text-ui);
    font-weight: 500;
    text-decoration: none;
}

@media (hover: hover) and (pointer: fine) {
    .nav-links a:not(.btn-modern):hover { color: var(--color-fg-default); text-decoration: underline; text-underline-offset: 4px; }
}

.landing-nav .mobile-nav-toggle svg { stroke: var(--color-fg-default); }

.search-form {
    flex: 1 1 auto;
    max-width: 28rem;
    display: flex;
    align-items: center;
    min-height: var(--control-md);
    margin: 0 var(--space-6);
    padding: 0 var(--space-1) 0 var(--space-3);
    background: var(--color-bg-surface);
    border: 1px solid var(--color-border-input);
    border-radius: var(--radius-md);
    transition: border-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
}

.search-form:focus-within {
    border-color: var(--color-money);
    box-shadow: 0 0 0 3px var(--color-focus-ring);
}

.search-input {
    flex: 1 1 auto;
    min-width: 0;
    border: none;
    background: transparent;
    padding: var(--space-2) 0;
    font: inherit;
    font-size: var(--text-ui);
    color: var(--color-fg-default);
    outline: none;
}

.search-input::placeholder { color: var(--color-fg-subtle); }

/* Live search suggestions are styled by assets/css/suggest.css. */

/* ── Results pager ─────────────────────────────────────────────────────────────
   One definition for the marketplace results (index.php) and the vendor storefront. */
.pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin: var(--space-8) 0 0;
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-border);
}

.pager-count { font-size: var(--text-ui); color: var(--color-fg-muted); font-variant-numeric: tabular-nums; }
.pager-links { display: flex; align-items: center; gap: var(--space-1); flex-wrap: wrap; }

.pager-links a,
.pager-now {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--control-md);
    height: var(--control-md);
    padding: 0 var(--space-3);
    border-radius: var(--radius-sm);
    font-size: var(--text-ui);
    font-weight: 500;
    text-decoration: none;
    font-variant-numeric: tabular-nums;
}

.pager-links a { color: var(--color-fg-default); border: 1px solid var(--color-border-strong); background: var(--color-bg-surface); }
.pager-now { background: var(--color-action); color: var(--color-action-fg); }
.pager-gap { color: var(--color-fg-subtle); padding: 0 0.125rem; }

@media (hover: hover) and (pointer: fine) {
    .pager-links a:hover { border-color: var(--color-border-input); text-decoration: none; }
}

@media (max-width: 768px) {
    .pager { flex-direction: column; align-items: stretch; }
    .pager-links { justify-content: center; }
}

.search-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: var(--control-md);
    min-height: var(--control-sm);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--color-fg-muted);
    cursor: pointer;
}

/* The public pages' primary button. Ink, not green: nothing on these pages moves money. */
.btn-modern,
.nav-links a.btn-modern {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--control-md);
    padding: 0 var(--space-4);
    border: none;
    border-radius: var(--radius-md);
    background: var(--color-action);
    color: var(--color-action-fg);
    font-family: inherit;
    font-size: var(--text-ui);
    font-weight: 500;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}

.btn-modern:active { transform: scale(0.97); }

@media (hover: hover) and (pointer: fine) {
    .btn-modern:hover { background: var(--color-action-hover); color: var(--color-action-fg); text-decoration: none; }
}

@media (max-width: 768px) {
    :root { --page-gutter: 4%; --nav-height: 7.25rem; }

    .landing-nav {
        flex-wrap: wrap;
        row-gap: var(--space-2);
        padding: var(--space-2) var(--page-gutter);
    }

    .landing-logo { height: 2.75rem; margin-block: 0; }

    .search-form {
        order: 3;
        width: 100%;
        max-width: 100%;
        margin: 0;
        min-height: var(--control-lg);
    }

    .search-input { font-size: 16px; } /* no iOS zoom on focus */

    .nav-links a.btn-modern { width: 100%; }
}

/* ── Marketplace pieces — category chips and product cards ─────────────────────
   One definition for the homepage and the vendor storefront, whose markup uses the same
   class names. Each page sheet adds only what that page renders (the homepage's store
   badge and card actions; the storefront's stock line, SKU and add button) and the
   layout of the sections around them. */
.cat-pills-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: var(--space-2);
}

.cat-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--control-md);
    padding: 0 var(--space-3);
    background: var(--color-bg-surface);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    color: var(--color-fg-default);
    font-size: var(--text-ui);
    font-weight: 500;
    text-decoration: none;
    transition: border-color var(--duration-fast) var(--ease-out), background-color var(--duration-fast) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
    .cat-pill:hover { border-color: var(--color-border-input); color: var(--color-fg-default); text-decoration: none; }
}

.cat-pill.active {
    background: var(--color-action);
    border-color: var(--color-action);
    color: var(--color-action-fg);
}

.cat-pill-icon { display: inline-flex; align-items: center; }
.cat-ic { width: 1rem; height: 1rem; flex-shrink: 0; }

.cat-pill-count {
    padding: 0 0.375rem;
    border-radius: var(--radius-sm);
    background: var(--color-bg-muted);
    color: var(--color-fg-muted);
    font-size: var(--text-small);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.cat-pill.active .cat-pill-count {
    background: rgb(255 255 255 / 0.16);
    color: var(--color-fg-inverse);
}

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
    gap: var(--space-3);
}

.product-card {
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 0;
    background: var(--color-bg-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    /* The classic pages hide cards until an animation reveals them; here they are simply there. */
    opacity: 1;
    transform: none;
    transition: border-color var(--duration-fast) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
    .product-card:hover { border-color: var(--color-border-input); }
}

.product-image-container {
    position: relative;
    width: 100%;
    padding-top: 100%;
    background: var(--color-bg-muted);
    overflow: hidden;
}

.product-image-container img {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    object-fit: contain;
}

/* The no-photo placeholder is a lone <div> sized 100% × 100% inline; inside a padding-top
   box that is zero height, so it fell below the square. Pin it to the square instead. */
.product-image-container > div:only-child {
    position: absolute;
    inset: 0;
}

.product-info {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    padding: var(--space-3);
}

.product-title {
    margin: 0 0 var(--space-1);
    min-height: 2.6em;
    font-size: var(--text-ui);
    font-weight: 500;
    line-height: 1.3;
    color: var(--color-fg-default);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.product-price {
    margin-bottom: var(--space-1);
    font-size: var(--text-body);
    font-weight: 600;
    color: var(--color-fg-default);
    font-variant-numeric: tabular-nums;
}

/* ═════════════════════════════════════════════════════════════════════════════
   RESPONSIVE — same breakpoints and the same behaviour as style.css.
   ═════════════════════════════════════════════════════════════════════════════ */

@media (min-width: 769px) and (max-width: 1024px) {
    .sidebar { width: 14rem; }
    .main-content { margin-left: 14rem; padding: var(--space-6); }
    .stats-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 768px) {
    .mobile-nav-toggle { display: flex; }
    .mobile-topbar { display: flex; }
    /* Only the layout's own title header; page-drawn .page-header blocks carry actions. */
    .page-header.layout-page-header { display: none; }

    .sidebar {
        width: 17.5rem;
        background: var(--color-bg-surface);
        transform: translateX(-100%);
        transition: transform var(--duration-base) var(--ease-out);
    }

    .sidebar.active {
        transform: translateX(0);
        box-shadow: var(--shadow-overlay);
    }

    .main-content {
        margin-left: 0;
        padding: var(--space-4);
    }

    .stats-grid {
        grid-template-columns: 1fr 1fr;
        gap: var(--space-2);
    }

    /* Public header's menu becomes a dropdown on a phone. The bar itself is sized in the
       Public header section above; nothing here may restate it, or it wins by source order. */
    .nav-links {
        display: none !important;
        position: absolute;
        top: 100%;
        left: 0;
        width: 100%;
        background: var(--color-bg-surface);
        flex-direction: column;
        padding: var(--space-4);
        border-bottom: 1px solid var(--color-border);
        box-shadow: var(--shadow-floating);
        z-index: var(--z-dropdown);
    }

    .nav-links.active {
        display: flex !important;
    }

    .nav-links a {
        margin: var(--space-2) 0 !important;
        width: 100%;
        text-align: center;
    }

    /* Tables scroll inside their container, never the page */
    .table-container {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    .table-container table {
        min-width: 600px;
    }

    table th,
    table td {
        padding: var(--space-2) var(--space-3);
        white-space: nowrap;
    }

    .table-header,
    .card-header {
        flex-direction: column;
        align-items: flex-start;
    }

    .filter-bar {
        flex-direction: column;
        gap: var(--space-3);
    }

    .filter-bar .form-group,
    .filter-bar select,
    .filter-bar input[type="date"],
    .filter-bar input[type="text"],
    .filter-bar .filter-group,
    .filter-bar .filter-group input,
    .filter-bar .filter-group select {
        width: 100%;
        min-width: 0;
    }

    /* 16px text stops iOS zooming into a focused field; 44px is a thumb. */
    .form-group input,
    .form-group select,
    .form-group textarea {
        font-size: 16px;
        min-height: var(--control-lg);
    }

    .btn { min-height: var(--control-lg); }
    .btn-sm { min-height: var(--control-md); }

    .actions {
        flex-wrap: wrap;
    }

    .modal { align-items: flex-end; padding: 0; }

    /* BRIDGE — several pages size their modal box in style="". */
    .modal-content {
        width: 100% !important;
        max-width: 100vw !important;
        max-height: 90vh;
        padding: var(--space-4) !important;
        border-radius: var(--radius-lg) var(--radius-lg) 0 0 !important;
    }

    .stat-card { padding: var(--space-3); }
    .stat-card .value { font-size: 1.375rem; }

    .card { padding: var(--space-4); }

    .dashboard-panels,
    .payments-summary,
    .shelves-grid,
    .stores-grid,
    .shops-grid,
    .plans-grid,
    .subscription-grid,
    .form-grid,
    .receipt-info {
        grid-template-columns: 1fr !important;
    }

    .quick-actions {
        grid-template-columns: 1fr 1fr;
        gap: var(--space-2);
    }

    .report-tabs {
        overflow-x: auto;
        white-space: nowrap;
        -webkit-overflow-scrolling: touch;
        padding-bottom: var(--space-1);
    }

    .report-tabs a {
        display: inline-block;
        font-size: var(--text-ui);
        padding: var(--space-2) var(--space-3);
    }

    .login-page { padding: var(--space-4); }
    .login-box { padding: var(--space-6) var(--space-4); }

    /* BRIDGE — inline grid and flex layouts that must stack on a phone.
       Kept from style.css verbatim in behaviour; they go as Phase 4 migrates each page. */
    div[style*="grid-template-columns: 1fr 1fr"],
    div[style*="grid-template-columns:1fr 1fr"],
    div[style*="grid-template-columns: 2fr 1fr"],
    div[style*="grid-template-columns:2fr 1fr"],
    div[style*="grid-template-columns: 1fr 2fr"],
    div[style*="grid-template-columns:1fr 2fr"],
    div[style*="grid-template-columns: repeat(auto-fit"],
    div[style*="grid-template-columns:repeat(auto-fit"],
    div[style*="grid-template-columns: repeat(auto-fill"],
    div[style*="grid-template-columns:repeat(auto-fill"] {
        grid-template-columns: 1fr !important;
    }

    div[style*="display:flex"][style*="gap:2rem"],
    div[style*="display: flex"][style*="gap: 2rem"],
    div[style*="display:flex"][style*="gap:1rem"],
    div[style*="display: flex"][style*="gap: 1rem"] {
        flex-wrap: wrap !important;
    }

    div[style*="grid-template-columns:repeat(4, 1fr)"],
    div[style*="grid-template-columns: repeat(4, 1fr)"] {
        grid-template-columns: 1fr 1fr !important;
        gap: var(--space-3) !important;
    }

    .shop-card { min-width: 0 !important; }

    .action-header {
        flex-direction: column;
        gap: var(--space-3);
    }

    div[style*="width: 56px"][style*="height: 56px"] {
        width: 44px !important;
        height: 44px !important;
        border-radius: var(--radius-md) !important;
    }

    div[style*="width: 56px"][style*="height: 56px"] svg {
        width: 22px !important;
        height: 22px !important;
    }

    div[style*="font-size: 1.6rem"] { font-size: 1.3rem !important; }

    div[style*="border-radius: 24px"][style*="padding: 1.5rem"] {
        padding: var(--space-4) !important;
        border-radius: var(--radius-md) !important;
    }

    div[style*="height: 300px"] { height: 220px !important; }

    .stat-icon {
        width: 40px !important;
        height: 40px !important;
        font-size: 1.2rem !important;
    }

    .stat-info .val { font-size: 1.2rem !important; }

    .modal-box {
        width: 95% !important;
        padding: var(--space-4) !important;
    }

    #viewModalContent {
        grid-template-columns: 1fr !important;
        gap: var(--space-4) !important;
    }

    div[style*="position: fixed"][style*="inset: 0"] > div {
        width: 92% !important;
        padding: var(--space-6) !important;
    }

    #global-toast-notification {
        top: 12px !important;
        right: 12px !important;
        left: 12px !important;
        max-width: calc(100vw - 24px) !important;
        padding: 12px 16px !important;
    }

    #toast-container {
        top: 12px !important;
        right: 12px !important;
        left: 12px !important;
    }

    .card-actions {
        flex-wrap: wrap;
        gap: var(--space-2);
    }

    .card-actions button,
    .card-actions form,
    .card-actions a {
        flex: 1 1 calc(50% - var(--space-2)) !important;
        min-width: 0;
    }

    .btn-action {
        font-size: 0.78rem !important;
        padding: 8px 6px !important;
    }

    .empty-state { padding: var(--space-6) var(--space-4); }
}

@media (max-width: 480px) {
    .main-content { padding: var(--space-3); }
    .mobile-topbar { margin: calc(-1 * var(--space-3)) calc(-1 * var(--space-3)) var(--space-3); }
    .stats-grid { grid-template-columns: 1fr; }
    .quick-actions { grid-template-columns: 1fr; }
    .card { padding: var(--space-3); }
    .login-box { padding: var(--space-6) var(--space-3); }
}

@media (max-width: 768px) and (orientation: landscape) {
    .sidebar { max-height: 100vh; overflow-y: auto; }
    .modal-content { max-height: 85vh; }
}

@media (hover: none) and (pointer: coarse) {
    .sidebar-nav li a { min-height: var(--control-lg); }
    .btn { min-height: var(--control-lg); }
    .btn-sm { min-height: var(--control-md); }
}

@media print {
    .sidebar,
    .mobile-topbar,
    .sidebar-overlay,
    .mobile-nav-toggle {
        display: none !important;
    }

    .main-content {
        margin-left: 0 !important;
        padding: 0 !important;
    }

    .app-container { display: block; }
}
