/* ==========================================================================
   Apan Store — design system

   Structure comes from borders, spacing and weight rather than shadow.
   A single 1px hairline separates surfaces; the only elevation in the system
   is a 1px/2px shadow reserved for things that genuinely float (dropdowns,
   the sticky cart bar). Nothing else casts.
   ========================================================================== */

/* --- Tokens ------------------------------------------------------------- */

:root {
    --paper:        #fbfbfa;
    --surface:      #ffffff;
    --surface-sunk: #f5f5f2;
    --surface-hover:#f7f7f5;

    --ink:          #1b1b19;
    --ink-2:        #55554f;
    --ink-3:        #83837a;
    --ink-invert:   #ffffff;

    --line:         #e6e5e0;
    --line-strong:  #d5d4cd;

    /* Overridden per store from the tenant's accent_color. */
    --accent:       #2f6f4e;
    --accent-ink:   #ffffff;
    --accent-soft:  color-mix(in srgb, var(--accent) 8%, var(--surface));
    --accent-line:  color-mix(in srgb, var(--accent) 24%, var(--line));
    --accent-deep:  color-mix(in srgb, var(--accent) 82%, #000);

    /* Status — reserved, never reused as a decorative hue. */
    --success:      #1a7a4c;
    --success-bg:   #e9f4ee;
    --warning:      #8a5a00;
    --warning-bg:   #fbf1de;
    --danger:       #a72b25;
    --danger-bg:    #fbecea;
    --info:         #1f5fa8;
    --info-bg:      #e9f1fa;
    --purple:       #64409c;
    --purple-bg:    #f1ebfa;

    /* Single-series chart hue: chroma floor + 3:1 contrast validated. */
    --series-1:     #12855f;

    --r-xs: 4px;
    --r-sm: 6px;
    --r:    10px;
    --r-lg: 14px;
    --r-pill: 999px;

    --lift:      0 1px 2px rgba(28, 28, 25, 0.05);
    --lift-pop:  0 2px 8px rgba(28, 28, 25, 0.09);

    --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

    --sidebar-w: 244px;
    --topbar-h:  60px;
}

/* --- Base --------------------------------------------------------------- */

*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    font-family: var(--sans);
    font-size: 15px;
    line-height: 1.55;
    color: var(--ink);
    background: var(--paper);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5 {
    margin: 0;
    font-weight: 600;
    letter-spacing: -0.011em;
    line-height: 1.25;
}

h1 { font-size: 1.55rem; }
h2 { font-size: 1.2rem; }
h3 { font-size: 1.02rem; }
h4 { font-size: 0.92rem; }

p { margin: 0 0 0.9rem; }
p:last-child { margin-bottom: 0; }

a {
    color: var(--accent-deep);
    text-decoration: none;
    text-underline-offset: 2px;
}
a:hover { text-decoration: underline; }

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

/* A QR is rendered as inline SVG at a fixed pixel size. Without this it
   overflows a narrow phone screen; with it, it scales down cleanly and the
   modules stay square. */
svg { max-width: 100%; height: auto; }

hr {
    border: 0;
    border-top: 1px solid var(--line);
    margin: 1.5rem 0;
}

code, kbd, pre { font-family: var(--mono); font-size: 0.88em; }

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--r-xs);
}

::selection { background: color-mix(in srgb, var(--accent) 20%, transparent); }

.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* --- Typography helpers ------------------------------------------------- */

.muted   { color: var(--ink-3); }
.dim     { color: var(--ink-2); }
.small   { font-size: 0.84rem; }
.tiny    { font-size: 0.76rem; }
.strong  { font-weight: 600; }
.mono    { font-family: var(--mono); }
.nowrap  { white-space: nowrap; }
.center  { text-align: center; }
.right   { text-align: right; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.eyebrow {
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.page-title { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; }
.page-lede  { color: var(--ink-2); margin-top: 0.3rem; max-width: 62ch; }

/* --- Layout primitives -------------------------------------------------- */

.stack       { display: flex; flex-direction: column; gap: 1.25rem; }
.stack-sm    { display: flex; flex-direction: column; gap: 0.6rem; }
.stack-xs    { display: flex; flex-direction: column; gap: 0.3rem; }
.row         { display: flex; align-items: center; gap: 0.75rem; }
.row-tight   { display: flex; align-items: center; gap: 0.4rem; }
.row-wrap    { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.row-end     { display: flex; align-items: center; justify-content: flex-end; gap: 0.6rem; flex-wrap: wrap; }
.grow        { flex: 1 1 auto; min-width: 0; }
.spacer      { flex: 1 1 auto; }

.grid { display: grid; gap: 1rem; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-auto { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }

.split { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 1.25rem; align-items: start; }
.split-even { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem; align-items: start; }

.mt-0 { margin-top: 0; }
.mt-1 { margin-top: 0.5rem; }
.mt-2 { margin-top: 1rem; }
.mt-3 { margin-top: 1.5rem; }
.mb-1 { margin-bottom: 0.5rem; }
.mb-2 { margin-bottom: 1rem; }
.mb-3 { margin-bottom: 1.5rem; }

/* --- App shell ---------------------------------------------------------- */

.shell { min-height: 100vh; display: flex; }

.sidebar {
    width: var(--sidebar-w);
    flex: 0 0 var(--sidebar-w);
    background: var(--surface);
    border-right: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}

.sidebar-brand {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 1.05rem 1.15rem;
    border-bottom: 1px solid var(--line);
    min-height: var(--topbar-h);
    color: var(--ink);
}
.sidebar-brand:hover { text-decoration: none; }

.brand-mark {
    width: 30px; height: 30px;
    flex: 0 0 30px;
    border-radius: 8px;
    background: var(--accent);
    color: var(--accent-ink);
    display: grid;
    place-items: center;
    font-weight: 700;
    font-size: 0.82rem;
    letter-spacing: -0.02em;
    overflow: hidden;
}
.brand-mark img { width: 100%; height: 100%; object-fit: cover; }

.brand-text { min-width: 0; }
.brand-name { font-weight: 600; font-size: 0.93rem; line-height: 1.2; }
.brand-sub  { font-size: 0.72rem; color: var(--ink-3); line-height: 1.3; }

.sidebar-nav { padding: 0.8rem 0.6rem; flex: 1 1 auto; }

.nav-group-label {
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-3);
    padding: 0.9rem 0.55rem 0.35rem;
}

.nav-link {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.55rem;
    border-radius: var(--r-sm);
    color: var(--ink-2);
    font-size: 0.88rem;
    font-weight: 500;
    line-height: 1.3;
}
.nav-link:hover { background: var(--surface-sunk); color: var(--ink); text-decoration: none; }
.nav-link.is-active { background: var(--accent-soft); color: var(--accent-deep); font-weight: 600; }
.nav-link .nav-icon { flex: 0 0 18px; width: 18px; text-align: center; font-size: 0.95rem; opacity: 0.85; }
.nav-link .nav-count {
    margin-left: auto;
    font-size: 0.72rem;
    font-weight: 600;
    background: var(--surface-sunk);
    color: var(--ink-2);
    border-radius: var(--r-pill);
    padding: 0.05rem 0.4rem;
    min-width: 20px;
    text-align: center;
}
.nav-link.is-active .nav-count { background: var(--accent); color: var(--accent-ink); }

.sidebar-foot { padding: 0.7rem; border-top: 1px solid var(--line); }

.main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

.topbar {
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1.4rem;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    position: sticky;
    top: 0;
    z-index: 30;
}

.content { padding: 1.6rem 1.4rem 3rem; max-width: 1360px; width: 100%; }

.content-narrow { max-width: 860px; }

/* --- Cards & panels ----------------------------------------------------- */

.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r);
}

.card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.95rem 1.1rem;
    border-bottom: 1px solid var(--line);
}
.card-head h2, .card-head h3 { font-size: 0.97rem; }

.card-body { padding: 1.1rem; }
.card-body-flush { padding: 0; }
.card-foot {
    padding: 0.8rem 1.1rem;
    border-top: 1px solid var(--line);
    background: var(--surface-sunk);
    border-radius: 0 0 var(--r) var(--r);
}

.panel {
    background: var(--surface-sunk);
    border: 1px solid var(--line);
    border-radius: var(--r);
    padding: 0.9rem 1rem;
}

.callout {
    display: flex;
    gap: 0.7rem;
    padding: 0.85rem 1rem;
    border: 1px solid var(--line);
    border-left: 3px solid var(--ink-3);
    border-radius: var(--r-sm);
    background: var(--surface);
    font-size: 0.88rem;
    color: var(--ink-2);
}
.callout-icon { flex: 0 0 auto; font-size: 1rem; line-height: 1.4; }
.callout.tone-success { border-left-color: var(--success); background: var(--success-bg); color: #15452e; }
.callout.tone-warning { border-left-color: var(--warning); background: var(--warning-bg); color: #5c3d00; }
.callout.tone-danger  { border-left-color: var(--danger);  background: var(--danger-bg);  color: #6f1f1b; }
.callout.tone-info    { border-left-color: var(--info);    background: var(--info-bg);    color: #163f6e; }
.callout.tone-accent  { border-left-color: var(--accent);  background: var(--accent-soft); color: var(--accent-deep); }

/* --- Stat tiles --------------------------------------------------------- */

.stat-grid { display: grid; gap: 0.9rem; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }

.stat {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r);
    padding: 0.95rem 1.05rem;
}
.stat-label {
    font-size: 0.76rem;
    font-weight: 500;
    color: var(--ink-3);
    letter-spacing: 0.01em;
    display: flex;
    align-items: center;
    gap: 0.35rem;
}
.stat-value {
    font-size: 1.6rem;
    font-weight: 650;
    letter-spacing: -0.02em;
    margin-top: 0.25rem;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}
.stat-value.sm { font-size: 1.25rem; }
.stat-foot { font-size: 0.78rem; color: var(--ink-3); margin-top: 0.2rem; }
.stat-foot .up   { color: var(--success); font-weight: 600; }
.stat-foot .down { color: var(--danger);  font-weight: 600; }

/* --- Buttons ------------------------------------------------------------ */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.5rem 0.9rem;
    font: inherit;
    font-size: 0.87rem;
    font-weight: 550;
    line-height: 1.3;
    border-radius: var(--r-sm);
    border: 1px solid var(--line-strong);
    background: var(--surface);
    color: var(--ink);
    cursor: pointer;
    white-space: nowrap;
    transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.btn:hover { background: var(--surface-hover); text-decoration: none; }
.btn:active { background: var(--surface-sunk); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }

.btn-primary {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-ink);
}
.btn-primary:hover { background: var(--accent-deep); border-color: var(--accent-deep); }

.btn-danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn-danger:hover { background: #8e211c; border-color: #8e211c; }

.btn-ghost { background: transparent; border-color: transparent; color: var(--ink-2); }
.btn-ghost:hover { background: var(--surface-sunk); color: var(--ink); }

.btn-quiet { background: var(--surface-sunk); border-color: var(--line); color: var(--ink-2); }
.btn-quiet:hover { background: var(--line); color: var(--ink); }

.btn-sm { padding: 0.32rem 0.6rem; font-size: 0.8rem; border-radius: var(--r-xs); }
.btn-lg { padding: 0.68rem 1.25rem; font-size: 0.95rem; }
.btn-block { display: flex; width: 100%; }
.btn-icon { padding: 0.4rem; width: 32px; height: 32px; }

.btn-group { display: inline-flex; }
.btn-group .btn { border-radius: 0; margin-left: -1px; }
.btn-group .btn:first-child { border-radius: var(--r-sm) 0 0 var(--r-sm); margin-left: 0; }
.btn-group .btn:last-child  { border-radius: 0 var(--r-sm) var(--r-sm) 0; }

/* --- Badges ------------------------------------------------------------- */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.28rem;
    padding: 0.13rem 0.48rem;
    border-radius: var(--r-pill);
    font-size: 0.74rem;
    font-weight: 600;
    line-height: 1.5;
    letter-spacing: 0.005em;
    background: var(--surface-sunk);
    color: var(--ink-2);
    border: 1px solid transparent;
    white-space: nowrap;
}
.badge::before {
    content: "";
    width: 5px; height: 5px;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 5px;
}
.badge.no-dot::before { display: none; }

.badge.tone-success { background: var(--success-bg); color: #145c3a; }
.badge.tone-warning { background: var(--warning-bg); color: #7a4f00; }
.badge.tone-danger  { background: var(--danger-bg);  color: #92251f; }
.badge.tone-info    { background: var(--info-bg);    color: #1b5493; }
.badge.tone-purple  { background: var(--purple-bg);  color: #573689; }
.badge.tone-accent  { background: var(--accent-soft); color: var(--accent-deep); }
.badge.tone-muted   { background: var(--surface-sunk); color: var(--ink-3); }

.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.22rem 0.6rem;
    border: 1px solid var(--line);
    border-radius: var(--r-pill);
    background: var(--surface);
    font-size: 0.8rem;
    color: var(--ink-2);
}
.chip:hover { border-color: var(--line-strong); text-decoration: none; color: var(--ink); }
.chip.is-active { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

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

.field { display: flex; flex-direction: column; gap: 0.32rem; margin-bottom: 1rem; }
.field:last-child { margin-bottom: 0; }

.label {
    font-size: 0.83rem;
    font-weight: 550;
    color: var(--ink-2);
    display: flex;
    align-items: center;
    gap: 0.3rem;
}
.label .req { color: var(--danger); font-weight: 400; }

.input, .select, .textarea {
    width: 100%;
    padding: 0.5rem 0.65rem;
    font: inherit;
    font-size: 0.9rem;
    color: var(--ink);
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--r-sm);
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.input::placeholder, .textarea::placeholder { color: #a9a99f; }

.input:focus, .select:focus, .textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
}

.input:disabled, .select:disabled, .textarea:disabled {
    background: var(--surface-sunk);
    color: var(--ink-3);
    cursor: not-allowed;
}

.textarea { min-height: 92px; resize: vertical; line-height: 1.5; }

.select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%2383837a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.6rem center;
    padding-right: 1.9rem;
}

.field.has-error .input,
.field.has-error .select,
.field.has-error .textarea { border-color: var(--danger); }

.field-error { font-size: 0.79rem; color: var(--danger); }
.field-hint  { font-size: 0.79rem; color: var(--ink-3); }

.input-group { display: flex; align-items: stretch; }
.input-group .input { border-radius: var(--r-sm) 0 0 var(--r-sm); }
.input-group .input:not(:first-child) { border-radius: 0; }
.input-affix {
    display: inline-flex;
    align-items: center;
    padding: 0 0.65rem;
    background: var(--surface-sunk);
    border: 1px solid var(--line-strong);
    color: var(--ink-3);
    font-size: 0.85rem;
    white-space: nowrap;
}
.input-affix:first-child { border-right: 0; border-radius: var(--r-sm) 0 0 var(--r-sm); }
.input-affix:last-child  { border-left: 0;  border-radius: 0 var(--r-sm) var(--r-sm) 0; }

.check {
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
    font-size: 0.88rem;
    color: var(--ink-2);
    cursor: pointer;
    padding: 0.15rem 0;
}
.check input { margin: 0.22rem 0 0; accent-color: var(--accent); width: 15px; height: 15px; flex: 0 0 15px; }
.check-title { color: var(--ink); font-weight: 500; }

.check-card {
    border: 1px solid var(--line-strong);
    border-radius: var(--r-sm);
    padding: 0.7rem 0.85rem;
    background: var(--surface);
}
.check-card:hover { border-color: var(--accent-line); }
.check-card:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }

.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 1rem; }
.form-grid .full { grid-column: 1 / -1; }

fieldset { border: 0; padding: 0; margin: 0 0 1.5rem; }
fieldset:last-of-type { margin-bottom: 0; }
legend {
    padding: 0;
    font-size: 0.83rem;
    font-weight: 600;
    color: var(--ink);
    margin-bottom: 0.7rem;
    border-bottom: 1px solid var(--line);
    width: 100%;
    padding-bottom: 0.45rem;
}

.form-actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    padding-top: 1.1rem;
    margin-top: 1.1rem;
    border-top: 1px solid var(--line);
}

/* --- Impersonation bar -------------------------------------------------- */
/* Intentionally the loudest thing on the page. An admin who forgets they are
   inside someone else's account will change real data by accident. */

.impersonation-bar {
    position: sticky;
    top: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.55rem 1.1rem;
    background: #3d2b00;
    color: #ffe9b3;
    font-size: 0.85rem;
    line-height: 1.4;
    border-bottom: 2px solid #8a5a00;
}

.impersonation-bar strong { color: #fff; }
.impersonation-bar .btn {
    background: #ffe9b3;
    border-color: #ffe9b3;
    color: #3d2b00;
    font-weight: 600;
}
.impersonation-bar .btn:hover { background: #fff; border-color: #fff; }

body.is-impersonating { border-top: 0; }

@media (max-width: 620px) {
    .impersonation-bar { flex-wrap: wrap; font-size: 0.8rem; }
}

@media print {
    .impersonation-bar { display: none !important; }
}

/* --- Icon picker -------------------------------------------------------- */
/* Radio inputs styled as tiles: no JavaScript, keyboard navigable, and the
   selected state comes from :checked so it survives a failed form submit. */

.icon-picker {
    border: 1px solid var(--line-strong);
    border-radius: var(--r-sm);
    background: var(--surface);
    overflow: hidden;
}

.icon-picker-scroll {
    max-height: 260px;
    overflow-y: auto;
    padding: 0.6rem 0.7rem 0.75rem;
    overscroll-behavior: contain;
}

.icon-group + .icon-group { margin-top: 0.7rem; }

.icon-group-label {
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--ink-3);
    margin-bottom: 0.35rem;
    position: sticky;
    top: -0.6rem;
    background: var(--surface);
    padding: 0.25rem 0;
    z-index: 1;
}

.icon-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(40px, 1fr));
    gap: 4px;
}

.icon-option {
    position: relative;
    display: grid;
    place-items: center;
    aspect-ratio: 1;
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    /* Emoji are the colour here — the tile itself stays quiet so the picker
       does not turn into a patchwork. */
    background: var(--surface-sunk);
    font-size: 1.35rem;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.12s ease, border-color 0.12s ease, transform 0.08s ease;
    user-select: none;
}

.icon-option:hover { background: var(--accent-soft); border-color: var(--accent-line); }
.icon-option:active { transform: scale(0.94); }

/* The radio itself is invisible but still focusable and clickable. */
.icon-option input {
    position: absolute;
    inset: 0;
    opacity: 0;
    margin: 0;
    cursor: pointer;
}

.icon-option:has(input:checked) {
    background: var(--accent-soft);
    border-color: var(--accent);
    box-shadow: inset 0 0 0 1px var(--accent);
}

.icon-option:has(input:focus-visible) {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

.icon-option.is-none {
    font-size: 0.95rem;
    color: var(--ink-3);
    background: var(--surface);
    border-color: var(--line);
}
.icon-option.is-none:has(input:checked) { color: var(--accent-deep); }

/* Fallback for browsers without :has() — the tile still works, it just does
   not highlight, so give the focused radio a visible ring instead. */
@supports not selector(:has(*)) {
    .icon-option input:checked { opacity: 1; appearance: auto; inset: auto; bottom: 2px; right: 2px; }
}

.icon-preview {
    display: inline-grid;
    place-items: center;
    width: 34px;
    height: 34px;
    flex: 0 0 34px;
    border-radius: var(--r-sm);
    background: var(--surface-sunk);
    font-size: 1.1rem;
    line-height: 1;
}

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

.table-wrap { overflow-x: auto; }

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
}
.table th {
    text-align: left;
    font-size: 0.73rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-3);
    padding: 0.6rem 0.85rem;
    border-bottom: 1px solid var(--line);
    background: var(--surface-sunk);
    white-space: nowrap;
}
.table td {
    padding: 0.7rem 0.85rem;
    border-bottom: 1px solid var(--line);
    vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--surface-hover); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table .shrink { width: 1%; white-space: nowrap; }
.table-fixed { table-layout: fixed; }

.cell-title { font-weight: 550; color: var(--ink); }
.cell-sub   { font-size: 0.78rem; color: var(--ink-3); }

/* --- Lists -------------------------------------------------------------- */

.list { list-style: none; margin: 0; padding: 0; }
.list > li {
    padding: 0.75rem 1.1rem;
    border-bottom: 1px solid var(--line);
    display: flex;
    align-items: center;
    gap: 0.75rem;
}
.list > li:last-child { border-bottom: 0; }

.dl { display: grid; grid-template-columns: minmax(110px, auto) 1fr; gap: 0.45rem 1rem; margin: 0; font-size: 0.87rem; }
.dl dt { color: var(--ink-3); }
.dl dd { margin: 0; color: var(--ink); }

/* --- Avatar ------------------------------------------------------------- */

.avatar {
    width: 32px; height: 32px;
    flex: 0 0 32px;
    border-radius: 50%;
    background: var(--surface-sunk);
    border: 1px solid var(--line);
    color: var(--ink-2);
    display: grid;
    place-items: center;
    font-size: 0.73rem;
    font-weight: 600;
    overflow: hidden;
}
.avatar.lg { width: 42px; height: 42px; flex-basis: 42px; font-size: 0.85rem; }
.avatar.accent { background: var(--accent-soft); color: var(--accent-deep); border-color: var(--accent-line); }

/* --- Flash messages ----------------------------------------------------- */

.flash-stack { display: flex; flex-direction: column; gap: 0.55rem; margin-bottom: 1.25rem; }

.flash {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.7rem 0.9rem;
    border-radius: var(--r-sm);
    border: 1px solid;
    font-size: 0.88rem;
}
.flash-success { background: var(--success-bg); border-color: #bcdccb; color: #14522f; }
.flash-danger  { background: var(--danger-bg);  border-color: #eec4c1; color: #7d211c; }
.flash-warning { background: var(--warning-bg); border-color: #e8d3a8; color: #654200; }
.flash-info    { background: var(--info-bg);    border-color: #c3d8ee; color: #17457a; }
.flash-icon { flex: 0 0 auto; }

/* --- Empty states ------------------------------------------------------- */

.empty {
    text-align: center;
    padding: 3rem 1.5rem;
    color: var(--ink-3);
}
.empty-icon { font-size: 1.9rem; margin-bottom: 0.6rem; opacity: 0.55; }
.empty-title { font-weight: 600; color: var(--ink-2); font-size: 0.98rem; margin-bottom: 0.25rem; }
.empty-text { font-size: 0.87rem; max-width: 38ch; margin: 0 auto 1.1rem; }

/* --- Tabs & filters ----------------------------------------------------- */

.tabs {
    display: flex;
    gap: 0.15rem;
    border-bottom: 1px solid var(--line);
    overflow-x: auto;
    margin-bottom: 1.25rem;
}
.tab {
    padding: 0.55rem 0.8rem;
    font-size: 0.87rem;
    font-weight: 500;
    color: var(--ink-3);
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    white-space: nowrap;
}
.tab:hover { color: var(--ink); text-decoration: none; }
.tab.is-active { color: var(--accent-deep); border-bottom-color: var(--accent); font-weight: 600; }
.tab .count { font-size: 0.76rem; color: var(--ink-3); margin-left: 0.25rem; }

.filter-bar {
    display: flex;
    align-items: flex-end;
    gap: 0.6rem;
    flex-wrap: wrap;
    padding: 0.85rem 1.1rem;
    border-bottom: 1px solid var(--line);
    background: var(--surface-sunk);
    border-radius: var(--r) var(--r) 0 0;
}
.filter-bar .field { margin: 0; min-width: 0; }
.filter-bar .input, .filter-bar .select { min-width: 150px; }
.filter-bar .search { min-width: 220px; flex: 1 1 220px; }

/* --- Pagination --------------------------------------------------------- */

.pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.8rem 1.1rem;
    border-top: 1px solid var(--line);
    font-size: 0.83rem;
    color: var(--ink-3);
}
.page-links { display: flex; gap: 0.25rem; flex-wrap: wrap; }
.page-link {
    min-width: 30px;
    padding: 0.25rem 0.5rem;
    text-align: center;
    border: 1px solid var(--line);
    border-radius: var(--r-xs);
    background: var(--surface);
    color: var(--ink-2);
    font-size: 0.83rem;
}
.page-link:hover { background: var(--surface-hover); text-decoration: none; color: var(--ink); }
.page-link.is-active { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 600; }
.page-link.is-disabled { opacity: 0.4; pointer-events: none; }

/* --- Dropdown (details/summary, no JS) ---------------------------------- */

.dropdown { position: relative; }
.dropdown > summary {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}
.dropdown > summary::-webkit-details-marker { display: none; }
.dropdown-menu {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    min-width: 200px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    box-shadow: var(--lift-pop);
    padding: 0.3rem;
    z-index: 60;
}

/* A menu inside a scrolling container — a wide table, the sidebar — is clipped
   by that container, because an absolutely positioned box cannot escape an
   ancestor with overflow. Switching to fixed positioning takes it out of that
   box entirely; app.js measures the button and sets the coordinates, and flips
   the menu above or aligns it left when there is not enough room. */
.dropdown-menu.is-floating {
    position: fixed;
    right: auto;
    bottom: auto;
    top: 0;
    left: 0;
    z-index: 300;
    max-height: min(60vh, 420px);
    overflow-y: auto;
    overscroll-behavior: contain;
}
.dropdown-menu.left { right: auto; left: 0; }
.dropdown-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.42rem 0.55rem;
    border-radius: var(--r-xs);
    font-size: 0.86rem;
    color: var(--ink-2);
    background: none;
    border: 0;
    text-align: left;
    font-family: inherit;
    cursor: pointer;
}
.dropdown-item:hover { background: var(--surface-sunk); color: var(--ink); text-decoration: none; }
.dropdown-item.danger { color: var(--danger); }
.dropdown-divider { height: 1px; background: var(--line); margin: 0.3rem 0; }
.dropdown-label { padding: 0.4rem 0.55rem 0.25rem; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.07em; color: var(--ink-3); font-weight: 600; }

/* --- Timeline ----------------------------------------------------------- */

.timeline { list-style: none; margin: 0; padding: 0 0 0 1.15rem; position: relative; }
.timeline::before {
    content: "";
    position: absolute;
    left: 4px; top: 6px; bottom: 6px;
    width: 1px;
    background: var(--line);
}
.timeline li { position: relative; padding: 0 0 1.05rem 0.35rem; }
.timeline li:last-child { padding-bottom: 0; }
.timeline li::before {
    content: "";
    position: absolute;
    left: -1.15rem; top: 6px;
    width: 9px; height: 9px;
    border-radius: 50%;
    background: var(--surface);
    border: 2px solid var(--line-strong);
}
.timeline li.is-current::before { border-color: var(--accent); background: var(--accent); }
.timeline-title { font-size: 0.88rem; font-weight: 550; }
.timeline-meta  { font-size: 0.78rem; color: var(--ink-3); }

/* --- Stepper (order progress) ------------------------------------------ */

.stepper { display: flex; gap: 0; margin: 0; padding: 0; list-style: none; }
.stepper li {
    flex: 1 1 0;
    text-align: center;
    font-size: 0.75rem;
    color: var(--ink-3);
    position: relative;
    padding-top: 1.6rem;
}
.stepper li::before {
    content: "";
    position: absolute;
    top: 5px; left: 50%;
    transform: translateX(-50%);
    width: 11px; height: 11px;
    border-radius: 50%;
    background: var(--surface);
    border: 2px solid var(--line-strong);
    z-index: 2;
}
.stepper li::after {
    content: "";
    position: absolute;
    top: 10px; left: -50%;
    width: 100%;
    height: 2px;
    background: var(--line);
    z-index: 1;
}
.stepper li:first-child::after { display: none; }
.stepper li.done { color: var(--ink-2); font-weight: 550; }
.stepper li.done::before { background: var(--accent); border-color: var(--accent); }
.stepper li.done::after  { background: var(--accent); }
.stepper li.cancelled::before { background: var(--danger); border-color: var(--danger); }

/* --- Charts (single series) --------------------------------------------- */

.chart {
    display: flex;
    align-items: flex-end;
    gap: 2px;                 /* 2px surface gap between adjacent bars */
    height: 148px;
    padding-top: 0.5rem;
}
.chart-col {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    height: 100%;
    position: relative;
    min-width: 0;
}
.chart-bar {
    width: 100%;
    max-width: 34px;
    background: var(--series-1);
    border-radius: 4px 4px 0 0;   /* rounded data end, anchored to baseline */
    min-height: 2px;
    transition: opacity 0.12s ease;
}
.chart-col:hover .chart-bar { opacity: 0.78; }
.chart-col.is-empty .chart-bar { background: var(--line); }

.chart-tip {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    background: var(--ink);
    color: #fff;
    font-size: 0.72rem;
    line-height: 1.4;
    padding: 0.3rem 0.5rem;
    border-radius: var(--r-xs);
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.12s ease;
    z-index: 20;
    box-shadow: var(--lift-pop);
}
.chart-col:hover .chart-tip, .chart-col:focus-within .chart-tip { opacity: 1; }

.chart-axis {
    display: flex;
    gap: 2px;
    border-top: 1px solid var(--line);
    padding-top: 0.4rem;
    margin-top: 0;
}
.chart-axis span {
    flex: 1 1 0;
    text-align: center;
    font-size: 0.68rem;
    color: var(--ink-3);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Horizontal ranked bars — for "top products" style lists. */
.rank-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.7rem; }
.rank-row { display: grid; grid-template-columns: 1fr auto; gap: 0.15rem 0.8rem; align-items: baseline; }
.rank-name { font-size: 0.86rem; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rank-value { font-size: 0.82rem; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.rank-track { grid-column: 1 / -1; height: 6px; background: var(--surface-sunk); border-radius: var(--r-pill); overflow: hidden; }
.rank-fill { height: 100%; background: var(--series-1); border-radius: var(--r-pill); }

/* --- Progress meter ----------------------------------------------------- */

.meter { height: 6px; background: var(--surface-sunk); border-radius: var(--r-pill); overflow: hidden; }
.meter-fill { height: 100%; background: var(--accent); border-radius: var(--r-pill); transition: width 0.2s ease; }
.meter-fill.tone-warning { background: var(--warning); }
.meter-fill.tone-danger  { background: var(--danger); }

/* --- Storefront --------------------------------------------------------- */

.shop-header {
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    position: sticky;
    top: 0;
    z-index: 40;
}
.shop-header-inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0.7rem 1.2rem;
    display: flex;
    align-items: center;
    gap: 1rem;
}
.shop-nav {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 1.2rem 0.6rem;
    display: flex;
    gap: 0.4rem;
    overflow-x: auto;
}

.shop-search { flex: 1 1 320px; max-width: 460px; position: relative; }
.shop-search .input { padding-left: 2.1rem; border-radius: var(--r-pill); background: var(--surface-sunk); }
.shop-search .input:focus { background: var(--surface); }
.shop-search-icon { position: absolute; left: 0.75rem; top: 50%; transform: translateY(-50%); color: var(--ink-3); font-size: 0.9rem; pointer-events: none; }

.shop-main { max-width: 1200px; margin: 0 auto; padding: 1.5rem 1.2rem 4rem; }

.hero {
    background: var(--accent-soft);
    border: 1px solid var(--accent-line);
    border-radius: var(--r-lg);
    padding: 2rem 1.9rem;
    margin-bottom: 1.75rem;
}
.hero h1 { font-size: 1.75rem; max-width: 22ch; }
.hero p { color: var(--ink-2); max-width: 52ch; margin-top: 0.5rem; }

/* With an uploaded banner the hero becomes the photograph. The scrim is what
   keeps the heading legible over whatever the shop happened to upload — a
   bright photo of fresh produce would otherwise swallow the text. */
.hero.has-banner {
    position: relative;
    border: 0;
    padding: 0;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    min-height: 260px;
    display: flex;
    align-items: flex-end;
    overflow: hidden;
}

.hero.has-banner::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.72) 0%, rgba(0, 0, 0, 0.35) 45%, rgba(0, 0, 0, 0.08) 100%);
}

.hero.has-banner .hero-body {
    position: relative;
    padding: 1.75rem 1.9rem;
    color: #fff;
    width: 100%;
}

.hero.has-banner h1 { color: #fff; text-shadow: 0 1px 12px rgba(0, 0, 0, 0.35); }
.hero.has-banner p  { color: rgba(255, 255, 255, 0.92); text-shadow: 0 1px 8px rgba(0, 0, 0, 0.3); }
.hero.has-banner .small { color: rgba(255, 255, 255, 0.92); }

@media (max-width: 620px) {
    .hero.has-banner { min-height: 200px; }
    .hero.has-banner .hero-body { padding: 1.25rem 1.1rem; }
}

.product-grid { display: grid; gap: 0.9rem; grid-template-columns: repeat(auto-fill, minmax(178px, 1fr)); }

.product-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    transition: border-color 0.12s ease;
}
.product-card:hover { border-color: var(--line-strong); }

.product-thumb {
    aspect-ratio: 1 / 1;
    background: var(--surface-sunk);
    display: grid;
    place-items: center;
    font-size: 2.2rem;
    position: relative;
    overflow: hidden;
}
.product-thumb img { width: 100%; height: 100%; object-fit: cover; }

.product-flag {
    position: absolute;
    top: 0.5rem; left: 0.5rem;
    background: var(--danger);
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    padding: 0.1rem 0.4rem;
    border-radius: var(--r-xs);
    letter-spacing: 0.02em;
}
.product-flag.out { background: var(--ink-2); }

.product-body { padding: 0.7rem 0.75rem 0.8rem; display: flex; flex-direction: column; gap: 0.15rem; flex: 1 1 auto; }
.product-name { font-size: 0.87rem; font-weight: 550; line-height: 1.3; color: var(--ink); }
.product-name:hover { text-decoration: none; color: var(--accent-deep); }
.product-pack { font-size: 0.76rem; color: var(--ink-3); }
.product-price { display: flex; align-items: baseline; gap: 0.35rem; margin-top: 0.3rem; }
.price-now { font-size: 0.98rem; font-weight: 650; font-variant-numeric: tabular-nums; }
.price-was { font-size: 0.78rem; color: var(--ink-3); text-decoration: line-through; }
.product-action { margin-top: 0.55rem; }

.qty-stepper { display: inline-flex; align-items: stretch; border: 1px solid var(--accent); border-radius: var(--r-sm); overflow: hidden; }
.qty-stepper button {
    width: 30px;
    border: 0;
    background: var(--accent-soft);
    color: var(--accent-deep);
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    line-height: 1;
}
.qty-stepper button:hover { background: color-mix(in srgb, var(--accent) 16%, var(--surface)); }
.qty-stepper .qty-value {
    min-width: 34px;
    display: grid;
    place-items: center;
    font-size: 0.85rem;
    font-weight: 600;
    background: var(--surface);
    font-variant-numeric: tabular-nums;
}

.cart-bar {
    position: sticky;
    bottom: 0;
    background: var(--surface);
    border-top: 1px solid var(--line);
    box-shadow: 0 -2px 8px rgba(28, 28, 25, 0.06);
    padding: 0.75rem 1.2rem;
    z-index: 45;
}
.cart-bar-inner { max-width: 1200px; margin: 0 auto; display: flex; align-items: center; gap: 1rem; }

.cart-line {
    display: grid;
    grid-template-columns: 56px 1fr auto auto;
    gap: 0.85rem;
    align-items: center;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--line);
}
.cart-line:last-child { border-bottom: 0; }
.cart-thumb { width: 56px; height: 56px; border-radius: var(--r-sm); background: var(--surface-sunk); display: grid; place-items: center; font-size: 1.4rem; overflow: hidden; }
.cart-thumb img { width: 100%; height: 100%; object-fit: cover; }

.summary-row { display: flex; justify-content: space-between; gap: 1rem; font-size: 0.88rem; padding: 0.32rem 0; }
.summary-row.total {
    border-top: 1px solid var(--line);
    margin-top: 0.45rem;
    padding-top: 0.7rem;
    font-size: 1rem;
    font-weight: 650;
}
.summary-row .num { font-variant-numeric: tabular-nums; }

.category-strip { display: flex; gap: 0.6rem; overflow-x: auto; padding-bottom: 0.4rem; }
.category-tile {
    flex: 0 0 auto;
    width: 104px;
    padding: 0.85rem 0.5rem;
    text-align: center;
    border: 1px solid var(--line);
    border-radius: var(--r);
    background: var(--surface);
    color: var(--ink-2);
    font-size: 0.78rem;
    font-weight: 500;
    line-height: 1.3;
}
.category-tile:hover { border-color: var(--accent-line); background: var(--accent-soft); text-decoration: none; color: var(--accent-deep); }
.category-tile.is-active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-deep); }
.category-emoji { font-size: 1.5rem; display: block; margin-bottom: 0.3rem; }

/* --- Auth pages --------------------------------------------------------- */

.auth-page {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 2rem 1.2rem;
    background: var(--paper);
}
.auth-card {
    width: 100%;
    max-width: 400px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    padding: 1.9rem 1.75rem;
}
.auth-brand { display: flex; align-items: center; gap: 0.6rem; justify-content: center; margin-bottom: 1.4rem; }
.auth-title { text-align: center; margin-bottom: 0.35rem; font-size: 1.2rem; }
.auth-sub { text-align: center; color: var(--ink-3); font-size: 0.87rem; margin-bottom: 1.5rem; }
.auth-foot { text-align: center; margin-top: 1.3rem; font-size: 0.86rem; color: var(--ink-3); }

.demo-creds {
    margin-top: 1.2rem;
    padding: 0.7rem 0.85rem;
    background: var(--surface-sunk);
    border: 1px dashed var(--line-strong);
    border-radius: var(--r-sm);
    font-size: 0.78rem;
    color: var(--ink-2);
}
.demo-creds code { background: var(--surface); padding: 0.05rem 0.28rem; border-radius: 3px; border: 1px solid var(--line); }

/* --- Marketing / landing ------------------------------------------------ */

.site-header {
    border-bottom: 1px solid var(--line);
    background: var(--surface);
    position: sticky;
    top: 0;
    z-index: 40;
}
.site-header-inner { max-width: 1120px; margin: 0 auto; padding: 0.85rem 1.4rem; display: flex; align-items: center; gap: 1.2rem; }
.site-main { max-width: 1120px; margin: 0 auto; padding: 0 1.4rem; }
.site-footer { border-top: 1px solid var(--line); margin-top: 4rem; padding: 2rem 1.4rem; background: var(--surface); }
.site-footer-inner { max-width: 1120px; margin: 0 auto; display: flex; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; font-size: 0.85rem; color: var(--ink-3); }

.landing-hero { padding: 4.5rem 0 3.5rem; text-align: center; }
.landing-hero h1 { font-size: clamp(2rem, 5vw, 2.9rem); letter-spacing: -0.028em; max-width: 18ch; margin: 0 auto; }
.landing-hero p { font-size: 1.05rem; color: var(--ink-2); max-width: 56ch; margin: 1rem auto 1.75rem; }

.pill-note {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.25rem 0.75rem;
    border: 1px solid var(--accent-line);
    background: var(--accent-soft);
    color: var(--accent-deep);
    border-radius: var(--r-pill);
    font-size: 0.8rem;
    font-weight: 550;
    margin-bottom: 1.4rem;
}

.feature-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.feature {
    padding: 1.3rem;
    border: 1px solid var(--line);
    border-radius: var(--r);
    background: var(--surface);
}
.feature-icon { font-size: 1.4rem; margin-bottom: 0.6rem; }
.feature h3 { font-size: 0.97rem; margin-bottom: 0.3rem; }
.feature p { font-size: 0.88rem; color: var(--ink-2); margin: 0; }

.section { padding: 3.5rem 0; }
.section-head { text-align: center; margin-bottom: 2rem; }
.section-head h2 { font-size: 1.6rem; letter-spacing: -0.02em; }
.section-head p { color: var(--ink-2); margin-top: 0.5rem; }

.plan-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); align-items: start; }
.plan-card {
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: var(--surface);
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
}
.plan-card.is-featured { border-color: var(--accent); }
.plan-name { font-size: 1rem; font-weight: 650; }
.plan-desc { font-size: 0.86rem; color: var(--ink-3); margin: 0.3rem 0 1rem; min-height: 2.6em; }
.plan-price { display: flex; align-items: baseline; gap: 0.3rem; margin-bottom: 1.1rem; }
.plan-amount { font-size: 2rem; font-weight: 680; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.plan-cycle { font-size: 0.83rem; color: var(--ink-3); }
.plan-features { list-style: none; margin: 0 0 1.4rem; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; font-size: 0.87rem; color: var(--ink-2); flex: 1 1 auto; }
.plan-features li { display: flex; gap: 0.5rem; align-items: flex-start; }
.plan-features li::before { content: "✓"; color: var(--success); font-weight: 700; flex: 0 0 auto; }

/* --- Utilities ---------------------------------------------------------- */

.divider-y { width: 1px; align-self: stretch; background: var(--line); }
.border-top { border-top: 1px solid var(--line); }
.hide { display: none !important; }
.scroll-x { overflow-x: auto; }

.form-inline { display: inline; }

/* --- Print (invoices, pick lists) --------------------------------------- */

@media print {
    .sidebar, .topbar, .no-print, .cart-bar, .shop-header { display: none !important; }
    body { background: #fff; font-size: 12px; }
    .content { padding: 0; max-width: none; }
    .card { border-color: #ccc; break-inside: avoid; }
    a { color: inherit; text-decoration: none; }
}

/* --- Responsive --------------------------------------------------------- */

@media (max-width: 1080px) {
    .split { grid-template-columns: minmax(0, 1fr); }
    .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 860px) {
    .sidebar {
        position: fixed;
        z-index: 100;
        transform: translateX(-100%);
        transition: transform 0.2s ease;
        box-shadow: var(--lift-pop);
    }
    .shell.nav-open .sidebar { transform: translateX(0); }
    .shell.nav-open::after {
        content: "";
        position: fixed;
        inset: 0;
        background: rgba(28, 28, 25, 0.32);
        z-index: 99;
    }
    .nav-toggle { display: inline-flex !important; }
    .split-even, .grid-3, .form-grid { grid-template-columns: minmax(0, 1fr); }
    .content { padding: 1.1rem 1rem 3rem; }
}

@media (max-width: 620px) {
    body { font-size: 14.5px; }
    .grid-2, .grid-4 { grid-template-columns: minmax(0, 1fr); }
    .stat-value { font-size: 1.4rem; }
    .cart-line { grid-template-columns: 48px 1fr auto; }
    .cart-line .cart-line-total { grid-column: 2 / -1; text-align: right; }
    .product-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
    .filter-bar .search { flex-basis: 100%; }
    .hero { padding: 1.5rem 1.25rem; }
    .table th, .table td { padding: 0.6rem 0.65rem; }
}

.nav-toggle { display: none; }

/* ==========================================================================
   Mobile app layer

   Everything below is inside a max-width media query, so the desktop layout
   is untouched — not adjusted, not overridden, simply never reached.

   The aim is that a phone gets something that behaves like an installed app
   rather than a shrunken web page: primary navigation on a fixed bottom bar
   where a thumb can reach it, a compact app bar with a back affordance,
   full-bleed content, menus that arrive as sheets from the bottom edge, and
   the whole thing sitting inside the safe area on a notched handset.

   The tab bar is set at 860px to match the breakpoint where the sidebar
   already turns into a drawer, so the two never disagree about which
   navigation is on screen.
   ========================================================================== */

/* Both are mobile-only controls, so they are off until the media query below
   turns them on. Declared here rather than inside it, because a rule that only
   exists inside a media query leaves the element visible everywhere else. */
.tabbar { display: none; }
.appbar-back { display: none; }
.action-bar { display: none; }
.action-bar-spacer { display: none; }

/* The other half of the pair: shown everywhere, hidden once the sticky bar
   below takes over. */
.hide-mobile { display: block; }

@media (max-width: 860px) {

    /* --- Foundations ---------------------------------------------------- */

    :root {
        --tabbar-h: 56px;
        --appbar-h: 52px;
        /* env() is 0 on hardware without a notch, so this is safe everywhere. */
        --safe-b: env(safe-area-inset-bottom, 0px);
        --safe-t: env(safe-area-inset-top, 0px);
    }

    body {
        /* A grey page behind white cards reads as a document. Edge-to-edge
           white reads as an app screen. */
        background: var(--surface);
        overscroll-behavior-y: none;
    }

    /* The grey flash when a link is tapped is the clearest giveaway that
       something is a web page. Replaced below with a deliberate press state. */
    a, button, summary, label, [role="button"] {
        -webkit-tap-highlight-color: transparent;
    }

    /* iOS zooms the whole page in when a field smaller than 16px is focused,
       and never zooms back out. */
    .input, input, select, textarea { font-size: 16px; }

    /* --- Bottom tab bar -------------------------------------------------- */

    .tabbar {
        display: flex;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 90;
        background: color-mix(in srgb, var(--surface) 88%, transparent);
        -webkit-backdrop-filter: saturate(180%) blur(18px);
        backdrop-filter: saturate(180%) blur(18px);
        border-top: 1px solid var(--line);
        padding-bottom: var(--safe-b);
    }

    .tabbar-item {
        flex: 1 1 0;
        min-width: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 2px;
        height: var(--tabbar-h);
        padding: 0 2px;
        color: var(--ink-3);
        font-size: 0.66rem;
        font-weight: 500;
        letter-spacing: 0.01em;
        background: none;
        border: 0;
        font-family: inherit;
        cursor: pointer;
        position: relative;
        -webkit-user-select: none;
        user-select: none;
    }
    .tabbar-item:hover { text-decoration: none; color: var(--ink-3); }
    .tabbar-item:active { background: var(--surface-sunk); }

    .tabbar-icon {
        font-size: 1.15rem;
        line-height: 1;
        display: block;
        transition: transform 0.12s ease;
    }
    .tabbar-item:active .tabbar-icon { transform: scale(0.9); }

    .tabbar-label {
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .tabbar-item.is-active { color: var(--accent-deep); font-weight: 600; }
    .tabbar-item.is-active .tabbar-icon { transform: none; }

    /* The count of new orders or basket items, as a badge on the icon. */
    .tabbar-badge {
        position: absolute;
        top: 4px;
        left: 50%;
        margin-left: 4px;
        min-width: 16px;
        height: 16px;
        padding: 0 4px;
        border-radius: var(--r-pill);
        background: var(--danger);
        color: #fff;
        font-size: 0.6rem;
        font-weight: 700;
        line-height: 16px;
        text-align: center;
    }

    /* Nothing must end up underneath the bar — least of all a submit button. */
    body.has-tabbar .content,
    body.has-tabbar .shop-main,
    body.has-tabbar .site-main {
        padding-bottom: calc(var(--tabbar-h) + var(--safe-b) + 1.5rem);
    }

    body.has-tabbar .site-footer,
    body.has-tabbar .is-shop footer {
        margin-bottom: calc(var(--tabbar-h) + var(--safe-b));
    }

    /* --- App bar --------------------------------------------------------- */

    .topbar,
    .shop-header,
    .site-header {
        padding-top: var(--safe-t);
        background: color-mix(in srgb, var(--surface) 88%, transparent);
        -webkit-backdrop-filter: saturate(180%) blur(18px);
        backdrop-filter: saturate(180%) blur(18px);
    }

    .topbar {
        height: auto;
        min-height: calc(var(--appbar-h) + var(--safe-t));
        padding: var(--safe-t) 0.75rem 0.5rem 0.5rem;

        /* Two rows: Back and the title on the first, whatever actions the page
           contributes on the second.

           Products contributes three buttons — Categories, Import / export,
           Add product — and on one line they squeeze the heading until it
           reads "Produc" with a button sitting on top of it. The break below
           makes that impossible however many buttons a page adds.

           Row gap is zero and the second row carries its own margin, so a page
           with no actions at all gets no empty band. */
        flex-wrap: wrap;
        gap: 0 0.4rem;
    }

    /* A zero-height item with a full-width basis: the standard way to force a
       wrap at a chosen point. Ordered between the title and the actions.
       Cannot be done with :has(), which older Android browsers ignore. */
    .topbar::after {
        content: "";
        order: 2;
        flex: 0 0 100%;
        height: 0;
    }

    .topbar > .appbar-back { order: 0; }

    .topbar > .grow {
        flex: 1 1 auto;
        min-width: 0;
        order: 1;
    }

    .topbar > *:not(.grow):not(.appbar-back) {
        order: 3;
        margin-top: 0.45rem;
    }

    .topbar .grow strong {
        font-size: 1.02rem !important;
        font-weight: 650;
        letter-spacing: -0.015em;
        display: block;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* The drawer is reachable from the More tab, so the hamburger would be a
       second door to the same room. The top-left slot goes to Back instead. */
    .nav-toggle { display: none !important; }

    .appbar-back {
        flex: 0 0 auto;
        width: 38px;
        height: 38px;
        display: inline-grid;
        place-items: center;
        border-radius: var(--r-pill);
        color: var(--ink);
        font-size: 1.25rem;
        line-height: 1;
        background: none;
        border: 0;
        cursor: pointer;
    }
    .appbar-back:active { background: var(--surface-sunk); }

    /* Top-bar actions shrink to icons-and-short-words so the title keeps room. */
    .topbar .btn { padding: 0.34rem 0.6rem; font-size: 0.8rem; }

    /* --- Storefront header ------------------------------------------------ */

    .shop-header-inner {
        padding: 0.5rem 0.85rem;
        gap: 0.5rem;
        flex-wrap: wrap;
    }

    /* Search earns a full row of its own: it is the main way anyone finds
       anything in a shop, and squeezed beside a logo it fits nothing. */
    .shop-search {
        order: 3;
        flex: 1 0 100%;
        max-width: none;
    }
    .shop-search .input { height: 40px; }

    /* Cart and account live on the tab bar now. */
    .shop-header-inner > .spacer { display: none; }
    .shop-header-inner .dropdown,
    .shop-header-inner > .btn-primary,
    .shop-header-inner > .btn-quiet { display: none; }

    .shop-nav { padding: 0 0.85rem 0.55rem; scrollbar-width: none; }
    .shop-nav::-webkit-scrollbar { display: none; }

    .shop-main { padding: 1rem 0.85rem 2rem; }

    /* --- Site header ------------------------------------------------------ */

    .site-header-inner { padding: 0.55rem 0.85rem; }
    .site-header-inner > nav { display: none; }
    .site-header-inner > .btn-quiet { display: none; }

    /* --- Full-bleed cards -------------------------------------------------- */

    /* An app screen is a sheet of content with dividers, not a stack of
       floating rectangles. Side borders and corners come off so cards run to
       both edges; the top and bottom rules become the separators. */
    .content > .card,
    .shop-main > .card,
    .content > .split > .card {
        border-radius: 0;
        border-left: 0;
        border-right: 0;
        margin-left: -0.85rem;
        margin-right: -0.85rem;
        width: calc(100% + 1.7rem);
    }

    .content { padding: 0.85rem 0.85rem 3rem; }

    .card-head { padding: 0.8rem 0.85rem; }
    .card-body { padding: 0.85rem; }
    .card-foot { padding: 0.75rem 0.85rem; }

    /* --- Touch targets ----------------------------------------------------- */

    /* 44px is the smallest thing most people can hit reliably while walking
       around a shop with one hand full. */
    .btn { min-height: 40px; }
    .btn-sm { min-height: 34px; }
    .btn-lg { min-height: 48px; font-size: 1rem; }
    .btn:active { transform: scale(0.985); }

    .dropdown-item, .nav-link { min-height: 44px; }

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

    /* Hover styling is meaningless on a touch screen and, worse, sticks after
       a tap on iOS — a row stays highlighted long after you have moved on. */
    .nav-link:hover { background: none; color: var(--ink-2); }
    .nav-link.is-active:hover { background: var(--accent-soft); color: var(--accent-deep); }
    .dropdown-item:hover { background: none; color: var(--ink-2); }
    .dropdown-item:active { background: var(--surface-sunk); }
    .list-row:hover, .table tbody tr:hover { background: none; }

    /* --- Menus as bottom sheets -------------------------------------------- */

    /* A 200px menu pinned under a button in the corner is a desktop idiom. On
       a phone the same choices arrive as a sheet from the bottom edge, where
       the thumb already is.

       This deliberately includes .is-floating — the menus inside a scrolling
       table. Excluding them left the row menu in the product list positioned
       by JS against a button near the page edge, drawn half off its own card.
       The !important beats the inline top/left a resize from desktop width can
       leave behind; app.js no longer sets them at this width. */
    .dropdown[open] > .dropdown-menu {
        position: fixed !important;
        left: 0 !important;
        right: 0 !important;
        bottom: 0 !important;
        top: auto !important;
        width: 100%;
        min-width: 0;
        max-height: 72vh;
        overflow-y: auto;
        overscroll-behavior: contain;
        border: 0;
        border-top: 1px solid var(--line);
        border-radius: var(--r-lg) var(--r-lg) 0 0;
        padding: 0.35rem 0.6rem calc(0.6rem + var(--safe-b));
        box-shadow: 0 -8px 32px rgba(28, 28, 25, 0.18);
        z-index: 200;
        animation: sheet-up 0.18s ease-out;
    }

    /* The grab handle every mobile sheet has. Purely a signal that this
       panel belongs to the bottom edge. */
    .dropdown[open] > .dropdown-menu::before {
        content: "";
        display: block;
        width: 36px;
        height: 4px;
        margin: 0.35rem auto 0.5rem;
        border-radius: var(--r-pill);
        background: var(--line-strong);
    }

    .dropdown[open]::after {
        content: "";
        position: fixed;
        inset: 0;
        background: rgba(28, 28, 25, 0.32);
        z-index: 199;
    }

    .dropdown[open] > .dropdown-menu .dropdown-item { font-size: 0.95rem; padding: 0.7rem 0.6rem; }

    @keyframes sheet-up {
        from { transform: translateY(100%); }
        to   { transform: translateY(0); }
    }

    /* --- Sticky action bar -------------------------------------------------- */

    /* For the one action a screen exists for — check out, place the order,
       save the product. It sits above the tab bar and stays put. */
    .action-bar {
        position: fixed;
        left: 0;
        right: 0;
        bottom: calc(var(--tabbar-h) + var(--safe-b));
        z-index: 80;
        display: flex;
        align-items: center;
        gap: 0.7rem;
        padding: 0.6rem 0.85rem;
        background: color-mix(in srgb, var(--surface) 92%, transparent);
        -webkit-backdrop-filter: saturate(180%) blur(18px);
        backdrop-filter: saturate(180%) blur(18px);
        border-top: 1px solid var(--line);
    }
    body:not(.has-tabbar) .action-bar { bottom: 0; padding-bottom: calc(0.6rem + var(--safe-b)); }
    .action-bar .btn { flex: 1 1 auto; margin: 0; }
    .action-bar .action-bar-total { flex: 0 0 auto; line-height: 1.15; }

    .hide-mobile { display: none !important; }

    /* The sticky bar is fixed, so it takes no room in the flow and would sit
       on top of the last thing on the page. This reserves its height in the
       document itself — deterministic, unlike a :has() selector that older
       Android browsers ignore, and unlike a body class the layout would
       overwrite when it sets its own. */
    .action-bar-spacer { display: block; height: 4.25rem; }

    /* --- Sidebar drawer ----------------------------------------------------- */

    .sidebar {
        width: min(86vw, 320px);
        flex-basis: min(86vw, 320px);
        padding-top: var(--safe-t);
        padding-bottom: var(--safe-b);
        border-right: 0;
        box-shadow: none;
    }
    .shell.nav-open .sidebar { box-shadow: var(--lift-pop); }

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

    .table-wrap { -webkit-overflow-scrolling: touch; }
    .table th, .table td { white-space: nowrap; }

    /* A six-column table cannot fit a phone, so it scrolls sideways — and the
       moment it does, the column that says which row you are looking at is the
       first thing to leave the screen. Pinning it keeps the product name
       beside its price and its buttons. */
    .table th:first-child,
    .table td:first-child {
        white-space: normal;
        position: sticky;
        left: 0;
        z-index: 1;
        background: var(--surface);
        box-shadow: 1px 0 0 var(--line);
    }
    .table thead th:first-child { background: var(--surface-sunk); }

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

    .page-lede { font-size: 0.9rem; }

    /* A flash message reads as a system toast rather than a banner in the flow. */
    .flash { border-radius: var(--r); margin: 0.6rem 0.85rem; }

    /* Forms are one column already at this width; make the actions full width
       so the primary button is a proper target. */
    .form-actions { flex-wrap: wrap; }
    .form-actions .btn { flex: 1 1 auto; }
}

/* Very small handsets: the tab labels are the first thing to give. */
@media (max-width: 340px) {
    .tabbar-label { display: none; }
    .tabbar-item { gap: 0; }
}

/* Installed to the home screen. Without browser chrome there is no back
   button of its own, so the app bar's own back control matters more, and the
   status-area padding has to come from us. */
@media (display-mode: standalone) {
    .topbar, .shop-header, .site-header { padding-top: env(safe-area-inset-top, 0px); }
}

@media print {
    .tabbar, .action-bar, .appbar-back { display: none !important; }
}
