/* ============================================================================
   SIPS component-rule stylesheet (FE-04 / CODE_REVIEW F4)
   Relocated byte-for-byte from base.html's inline <style> blocks, in source
   order, to shrink base.html. Theme TOKENS (:root + html[data-theme] CSS
   variable overrides) stay INLINE in base.html so first paint is themed (D-07,
   no FOUC); this sheet is loaded via a render-blocking {% static %} <link> in
   <head> AFTER the inline token <style>, so the var(--*) references below resolve.
   Do not reorder: same-specificity later rules override earlier ones.
   ============================================================================ */

/* ===== Component rules relocated from the head <style> block ===== */
        /* Helpers texte (compatible light/dark) */
        .text-strong { color: var(--text); }
        .text-muted  { color: var(--muted); }

        /* ====== Cards (Stripe-inspired: subtle radius, layered shadows) ====== */
        .glass-card{
            background: var(--glass-bg);
            border: 1px solid var(--glass-border);
            box-shadow: var(--glass-shadow);
            border-radius: var(--radius-md);
            transition: border-color 0.15s ease, box-shadow 0.15s ease;
        }
        .glass-card:hover{
            border-color: var(--hover-border);
            box-shadow: var(--hover-shadow);
        }
        .glass-soft{
            background: var(--soft-bg);
            border: 1px solid var(--soft-border);
            border-radius: 6px;
        }

        /* ====== Glass-soft input field (folds the repeated input utility cluster) ======
           Computes identically to the Tailwind run
           `w-full px-3 py-2 rounded-lg bg-transparent outline-none focus:ring-2 focus:ring-emerald-400/30`.
           `text-strong` and `glass-soft` stay as SEPARATE classes on each element so the
           load-bearing webkit backdrop-blur prefix inside `.glass-soft` is never moved. */
        .ui-field{
            width: 100%;                 /* w-full */
            padding: 0.5rem 0.75rem;     /* py-2 px-3 */
            border-radius: 0.5rem;       /* rounded-lg */
            background-color: transparent; /* bg-transparent */
            outline: none;               /* outline-none */
        }
        .ui-field:focus{
            /* focus:ring-2 focus:ring-emerald-400/30 -> emerald-400 rgb(52,211,153) @ 0.3, 2px, no offset */
            box-shadow: 0 0 0 2px rgba(52, 211, 153, 0.3);
        }


        /* ====== Sidebar theme-aware (Stripe-clean) ====== */
        .sidebar-shell{
            background: var(--sidebar-bg);
            border-inline-end: 1px solid var(--sidebar-border);
            box-shadow: var(--sidebar-shadow);
        }
        .sidebar-divider{
            border-color: var(--divider) !important;
        }

        /* Nav items: Stripe-style (no border, subtle bg on hover, left accent) */
        .nav-item{
            display:flex;
            align-items:center;
            padding:0.5rem 0.75rem;
            border-radius: 0.5rem;
            background: var(--nav-bg);
            border: 1px solid var(--nav-border);
            border-inline-start: 2px solid transparent;
            transition: all 0.15s ease;
            color: var(--text);
            font-size: 0.875rem;
        }
        .nav-item:hover{
            background: var(--nav-hover-bg);
            border-color: var(--nav-hover-border);
            border-inline-start-color: var(--nav-active-accent);
            box-shadow: none;
        }

        .nav-icon-btn{
            width: 1rem;
            height: 1rem;
            display:flex;
            align-items:center;
            justify-content:center;
            border-radius: 6px;
            /* background: var(--soft-bg); */
            /* border: 1px solid var(--soft-border); */
            transition: all 0.15s ease;
            color: var(--text);
        }
        .nav-icon-btn:hover{
            /* background: var(--nav-hover-bg); */
            /* border-color: var(--nav-hover-border); */
        }

        .sidebar-toggle{
            <!-- background: var(--glass-bg); -->
            <!-- border: 1px solid var(--glass-border); -->
            color: var(--text);
            box-shadow: var(--glass-shadow);
            backdrop-filter: blur(12px);
            -webkit-backdrop-filter: blur(12px);
        }
        .sidebar-toggle:hover{
            <!-- border-color: var(--hover-border); -->
            box-shadow: var(--hover-shadow);
        }
        .sidebar-toggle:active{ transform: scale(0.96); }

        /* Unified emerald-600 accent in light mode */
        html[data-theme="light"] .text-emerald-200,
        html[data-theme="light"] .text-emerald-300,
        html[data-theme="light"] .text-emerald-400,
        html[data-theme="light"] .text-emerald-500{
            color: #059669 !important;   /* emerald-600 — single accent */
        }

        /* Light theme: normalize Tailwind white text utilities */
        html[data-theme="light"] .text-white\/90{
            color: var(--text) !important;
        }
        html[data-theme="light"] .text-white\/70,
        html[data-theme="light"] .text-white\/60,
        html[data-theme="light"] .text-white\/45,
        html[data-theme="light"] .text-white\/40{
            color: var(--muted) !important;
        }
        html[data-theme="light"] .bg-white\/5{
            background-color: rgba(15,23,42,0.04) !important;
        }
        html[data-theme="light"] .border-white\/10{
            border-color: var(--soft-border) !important;
        }

        /* ====== Stripe-style table rows ====== */
        .stripe-row{
            border-bottom: 1px solid var(--divider);
            transition: background 0.12s ease;
        }
        .stripe-row:hover{
            background: var(--row-hover);
        }
        .stripe-row:last-child{
            border-bottom: none;
        }

        /* ====== Stripe-style stat card ====== */
        .stat-card{
            background: var(--glass-bg);
            border: 1px solid var(--glass-border);
            border-radius: var(--radius-md);
            padding: 1.25rem 1.5rem;
            box-shadow: var(--glass-shadow);
            transition: border-color 0.15s ease, box-shadow 0.15s ease;
        }
        .stat-card:hover{
            border-color: var(--hover-border);
            box-shadow: var(--hover-shadow);
        }
        .stat-label{
            font-size: 0.8125rem;
            font-weight: 500;
            color: var(--muted);
            text-transform: uppercase;
            letter-spacing: 0.03em;
        }
        .stat-value{
            font-size: 1.75rem;
            font-weight: 600;
            color: var(--text);
            line-height: 1.2;
            margin-top: 0.25rem;
        }

        /* ====== Finance widget (Uiverse original structure) ====== */
        .theme-light{
            --color-dark-subtle: linear-gradient(135deg, color-mix(in oklab, var(--brand-700) 24%, transparent), color-mix(in oklab, var(--bg-1) 94%, transparent));
            --color-dark: var(--surface);
            --color-light: var(--text-main);
            --color-white: #ffffff;
            --color-red: color-mix(in oklab, var(--brand-600) 78%, var(--bg-2));
            --color-red-light: var(--error);
            --color-shadow-dark: color-mix(in oklab, var(--bg-3) 88%, transparent);
            --color-shadow-text: color-mix(in oklab, var(--bg-3) 65%, transparent);
            --color-accent-bg: var(--brand-soft);
            --shadow-light: -5px -5px 9px color-mix(in oklab, var(--bg-2) 65%, transparent);
            --shadow-dark: 5px 5px 9px color-mix(in oklab, var(--bg-3) 75%, transparent);
            --shadow-bar: -5px -5px 9px color-mix(in oklab, var(--bg-2) 70%, transparent), 5px 5px 9px color-mix(in oklab, var(--bg-3) 70%, transparent);
            display: flex;
            justify-content: center;
            width: 100%;
        }
        html[data-theme="light"] .theme-light{
            --color-dark-subtle: linear-gradient(135deg, color-mix(in oklab, var(--brand-700) 16%, transparent), color-mix(in oklab, #ffffff 94%, transparent));
            --color-dark: #ffffff;
            --color-light: var(--text-main);
            --color-shadow-dark: color-mix(in oklab, var(--text-main) 14%, transparent);
            --shadow-light: -5px -5px 9px rgba(255,255,255,0.6);
            --shadow-dark: 5px 5px 9px color-mix(in oklab, var(--text-main) 14%, transparent);
            --shadow-bar: -5px -5px 9px color-mix(in oklab, var(--text-main) 6%, transparent), 5px 5px 9px color-mix(in oklab, var(--text-main) 10%, transparent);
        }
        .theme-light .card{
            border-radius: 16px;
            padding: 10px;
            width: 100%;
            max-width: none;
            background: var(--glass-bg);
            border: 1px solid var(--glass-border);
            box-shadow: var(--glass-shadow);
            position: relative;
            transition-duration: 0.2s;
            user-select: none;
        }
        .theme-light .card.is-animated{
            animation: financeFadeIn 0.6s ease both;
        }
        .finance-card{
            cursor: pointer;
        }
        .theme-light .flex{
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 18px;
        }
        .theme-light .bar-label{
            text-shadow: 1px 1px 3px var(--color-shadow-text);
            font-size: 12px;
        }
        .theme-light .flex .tag{
            fill: var(--color-white);
            display: flex;
            align-items: center;
            justify-content: center;
            height: 25px;
            width: 25px;
            box-shadow: 4px 4px 3px var(--color-shadow-dark);
        }
        .theme-light .bg-custom{
            background: var(--color-dark-subtle);
            padding: 18px;
            margin-bottom: 10px;
            border-radius: 10px;
            box-shadow: inset var(--shadow-light), inset var(--shadow-dark);
        }
        .theme-light .bg-custom-2{
            font-weight: 600;
        }
        .theme-light .pr-day{
            position: absolute;
            top: -25px;
            font-size: 12px;
            font-weight: 700;
            color: var(--color-white);
        }
        .theme-light .text-red{
            color: var(--color-red-light);
        }
        .theme-light .text-light{
            color: var(--color-light);
        }
        .theme-light .text-green{
            color: var(--color-white);
        }
        .theme-light .card .heading{
            margin: 0;
            font-size: 16px;
            font-weight: 500;
            color: var(--color-light);
            text-shadow: 4px 4px 3px var(--color-shadow-dark);
        }
        .theme-light .amount{
            font-size: 24px;
            font-weight: bold;
            margin: 10px 0;
            line-height: 1.2;
            text-shadow: 4px 4px 3px var(--color-shadow-dark);
            display: inline-flex;
            align-items: center;
        }
        .theme-light .typing{
            overflow: hidden;
            white-space: nowrap;
            border-inline-end: 3px solid var(--color-white);
            display: inline-block;
        }
        .theme-light .card.is-animated .typing,
        .theme-light .card:hover .typing{
            animation: typing 8s steps(20) 1, blink 1.2s step-end 1;
        }
        @keyframes typing{
            0%{ width: 0; }
            40%{ width: 128px; }
            60%{ width: 128px; }
            100%{ width: 0; }
        }
        @keyframes blink{
            50%{ border-color: transparent; }
        }
        .theme-light .amount .main-pr{
            font-size: 14px;
            color: var(--color-white);
            margin-inline-start: 6px;
            font-weight: 500;
            background: var(--brand-soft);
            border-radius: 5px;
            padding: 2px 4px;
        }
        .theme-light .amount .main-pr.negative{
            color: var(--error);
            background: var(--error-soft);
        }
        .theme-light .compare{
            font-size: 12px;
            text-shadow: 4px 4px 3px var(--color-shadow-dark);
            letter-spacing: 1px;
        }
        .theme-light .chart{
            display: flex;
            justify-content: space-between;
            align-items: flex-end;
            width: 300px;
            height: 140px;
            padding: 10px;
            border-radius: 12px;
        }
        .theme-light .finance-split{
            display: flex;
            gap: 12px;
            align-items: stretch;
        }
        .theme-light .finance-left{
            flex: 1;
            min-width: 0;
        }
        .theme-light .finance-split .chart{
            flex: 1;
            width: 100%;
        }
        @media (max-width: 720px){
            .theme-light .finance-split{
                flex-direction: column;
            }
            .theme-light .finance-split .chart{
                width: 300px;
            }
        }
        .theme-light .bar{
            width: 20px;
            font-size: 15px;
            background: linear-gradient(180deg, color-mix(in oklab, var(--brand-600) 92%, transparent), color-mix(in oklab, var(--brand-700) 70%, var(--bg-2)));
            color: var(--color-dark);
            border-radius: 4px 4px 0 0;
            display: flex;
            justify-content: center;
            align-items: flex-end;
            position: relative;
            transform: scaleY(0);
            transform-origin: bottom;
            box-shadow: var(--shadow-bar);
            transition: height 0.6s ease;
        }
        .theme-light .chart.is-animated .bar{
            animation: barIntro 2.5s ease-out both;
        }
        .theme-light .chart.bars-ready .bar{
            transform: scaleY(1);
        }
        .theme-light .chart.is-hovering .bar:nth-child(1){ animation: rippleA 21s ease-in-out infinite 0.05s; }
        .theme-light .chart.is-hovering .bar:nth-child(2){ animation: rippleB 27s ease-in-out infinite 0.15s; }
        .theme-light .chart.is-hovering .bar:nth-child(3){ animation: rippleC 22s ease-in-out infinite 0.25s; }
        .theme-light .chart.is-hovering .bar:nth-child(4){ animation: rippleA 28s ease-in-out infinite 0.1s; }
        .theme-light .chart.is-hovering .bar:nth-child(5){ animation: rippleB 22s ease-in-out infinite 0.3s; }
        .theme-light .chart.is-hovering .bar:nth-child(6){ animation: rippleC 25s ease-in-out infinite 0.2s; }
        .theme-light .chart.is-hovering .bar:nth-child(7){ animation: rippleA 30s ease-in-out infinite 0.08s; }
        .theme-light .bar.positive{
            background: linear-gradient(180deg, color-mix(in oklab, var(--brand-600) 92%, transparent), color-mix(in oklab, var(--brand-700) 75%, var(--bg-2)));
        }
        .theme-light .bar.negative{
            background: var(--color-white);
        }
        @keyframes rippleA{
            0%{ transform: scaleY(0.6); }
            12%{ transform: scaleY(1.1); }
            26%{ transform: scaleY(0.7); }
            40%{ transform: scaleY(1.05); }
            55%{ transform: scaleY(0.65); }
            70%{ transform: scaleY(1.12); }
            85%{ transform: scaleY(0.72); }
            100%{ transform: scaleY(0.6); }
        }
        @keyframes rippleB{
            0%{ transform: scaleY(0.7); }
            10%{ transform: scaleY(1.15); }
            24%{ transform: scaleY(0.6); }
            38%{ transform: scaleY(1.05); }
            52%{ transform: scaleY(0.72); }
            66%{ transform: scaleY(1.1); }
            80%{ transform: scaleY(0.62); }
            92%{ transform: scaleY(1.08); }
            100%{ transform: scaleY(0.7); }
        }
        @keyframes rippleC{
            0%{ transform: scaleY(0.65); }
            15%{ transform: scaleY(1.08); }
            28%{ transform: scaleY(0.6); }
            42%{ transform: scaleY(1.15); }
            58%{ transform: scaleY(0.68); }
            72%{ transform: scaleY(1.05); }
            88%{ transform: scaleY(0.62); }
            100%{ transform: scaleY(0.65); }
        }
        @keyframes barIntro{
            0%{ transform: scaleY(0); }
            60%{ transform: scaleY(1.15); }
            80%{ transform: scaleY(0.95); }
            100%{ transform: scaleY(1); }
        }
        @keyframes financeFadeIn{
            from{ opacity: 0; transform: translateY(8px); }
            to{ opacity: 1; transform: translateY(0); }
        }
        .theme-light .chart.is-animated .bar:nth-child(1){ animation-delay: 0.12s; }
        .theme-light .chart.is-animated .bar:nth-child(2){ animation-delay: 0.22s; }
        .theme-light .chart.is-animated .bar:nth-child(3){ animation-delay: 0.32s; }
        .theme-light .chart.is-animated .bar:nth-child(4){ animation-delay: 0.42s; }
        .theme-light .chart.is-animated .bar:nth-child(5){ animation-delay: 0.52s; }
        .theme-light .chart.is-animated .bar:nth-child(6){ animation-delay: 0.62s; }
        .theme-light .chart.is-animated .bar:nth-child(7){ animation-delay: 0.72s; }
        .theme-light .bar:nth-child(1){ height: 30px; animation-delay: 0.2s; }
        .theme-light .bar:nth-child(2){ height: 80px; animation-delay: 0.4s; }
        .theme-light .bar:nth-child(3){ height: 50px; animation-delay: 0.6s; }
        .theme-light .bar:nth-child(4){ height: 85px; animation-delay: 0.8s; }
        .theme-light .bar:nth-child(5){ height: 70px; animation-delay: 1s; }
        .theme-light .bar:nth-child(6){ height: 80px; animation-delay: 1.2s; }
        .theme-light .bar:nth-child(7){ height: 60px; animation-delay: 1.4s; }
        .theme-light .card .more-button{
            font-size: 16px;
            padding: 12px;
            border-radius: 10px;
            color: var(--color-dark);
            border: 0;
            width: 100%;
            margin-top: 10px;
            outline: none;
            background-color: var(--color-white);
            box-shadow: var(--shadow-bar);
            transition: ease all 0.3s;
            cursor: pointer;
        }
        .theme-light .card .more-button:hover{
            transform: translateY(-3px);
        }
        .theme-light .card .more-button:active{
            transform: scale(0.9);
        }
        .theme-light .tags{
            display: flex;
            margin-bottom: 8px;
            justify-content: end;
            color: var(--color-light);
            font-size: 12px;
            font-weight: 500;
            gap: 4px;
            text-shadow: 2px 3px 3px var(--color-shadow-dark);
        }
        .theme-light .tags span{
            padding: 3px 10px;
            background-color: rgba(15,23,42,0.45);
            border-radius: 3px;
        }

        /* ====== Stripe-style section headers ====== */
        .section-header{
            font-size: 0.72rem;
            font-weight: 600;
            color: var(--muted);
            text-transform: uppercase;
            letter-spacing: 0.08em;
            padding-bottom: 0.65rem;
            border-bottom: 1px solid var(--divider);
            margin-bottom: 0.9rem;
        }

        /* ====== Layout: decale le main quand sidebar ouverte (desktop) ====== */
        @media (min-width: 1024px) {
            body.sidebar-open #app-main {
                padding-inline-start: 20rem;
                transition: padding-inline-start .3s ease;
            }
            /* Compact rail: sidebar collapsed to icons only */
            body.sidebar-open.sidebar-collapsed #app-main {
                padding-inline-start: 7rem;
            }
        }

        .animate-spin-slow { animation: spin 4s linear infinite; }
        @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

        /* ====== Mobile enhancements ====== */
        @media (max-width: 639px) {
            .glass-card { padding: 1rem; }
            .glass-soft { padding: 0.75rem; }
            h1 { font-size: 1.5rem !important; }
            h2 { font-size: 1.25rem !important; }
            table { font-size: 0.8rem; }
            table th, table td { padding: 0.5rem 0.25rem; }
        }

        /* Input and select styling for mobile */
        @media (max-width: 639px) {
            input, select, textarea {
                font-size: 16px !important; /* Prevents zoom on iOS */
            }
        }

        /* Status badges responsive */
        @media (max-width: 639px) {
            .status-badge {
                font-size: 0.65rem;
                padding: 0.25rem 0.5rem;
            }
        }

        /* ====== Light theme: global card overrides ====== */
        html[data-theme="light"] .glass-card {
            background: #ffffff;
            border: 1px solid #cbd8d1;
            box-shadow: 0 1px 3px rgba(15,23,42,0.04),
                        0 4px 24px rgba(15,23,42,0.08);
        }
        html[data-theme="light"] .glass-card:hover {
            border-color: #b8d4c4;
            box-shadow: 0 1px 3px rgba(15,23,42,0.06),
                        0 6px 28px rgba(15,23,42,0.12);
        }
        html[data-theme="light"] .stat-card {
            background: #ffffff;
            border: 1px solid #cbd8d1;
            box-shadow: 0 1px 3px rgba(15,23,42,0.04),
                        0 4px 24px rgba(15,23,42,0.08);
        }
        html[data-theme="light"] .stat-card:hover {
            border-color: #b8d4c4;
            box-shadow: 0 1px 3px rgba(15,23,42,0.06),
                        0 6px 28px rgba(15,23,42,0.12);
        }
        html[data-theme="light"] .stat-label {
            color: #334155;
            font-weight: 600;
        }
        html[data-theme="light"] .stat-value {
            color: #0f172a;
        }
        html[data-theme="light"] .glass-soft {
            background: #e8eeeb;
            border: 1px solid #cbd8d1;
        }

        /* Text hierarchy */
        html[data-theme="light"] .text-strong,
        html[data-theme="light"] [style*="color: var(--text)"] {
            color: #0f172a !important;
        }
        html[data-theme="light"] .text-muted {
            color: #334155 !important;
        }
        html[data-theme="light"] h1,
        html[data-theme="light"] h2,
        html[data-theme="light"] h3 {
            color: #0f172a;
        }

        /* Stripe rows */
        html[data-theme="light"] .stripe-row {
            border-color: #cbd8d1;
        }
        html[data-theme="light"] .stripe-row:hover {
            background: rgba(5,150,105,0.05);
        }

        /* Unread dot */
        html[data-theme="light"] .bg-emerald-400 {
            background-color: #059669 !important;
        }

        /* ====== Light theme: emerald glow background (mirrors dark) ====== */
        html[data-theme="light"] body{
            background: var(--bg-1);
        }
        html[data-theme="light"] .fixed.-z-10{
            background: radial-gradient(circle at 18% 12%, rgba(5,150,105,0.08), transparent 48%),
                        radial-gradient(circle at 84% 78%, rgba(5,150,105,0.05), transparent 56%),
                        linear-gradient(160deg, #f5f8f6, #eef3f0 55%, #e8eeeb 100%) !important;
        }

        /* Better light theme inputs */
        html[data-theme="light"] input,
        html[data-theme="light"] select,
        html[data-theme="light"] textarea{
            background: #ffffff;
            border-color: var(--border);
            color: var(--text-main);
        }
        html[data-theme="light"] input::placeholder,
        html[data-theme="light"] textarea::placeholder{
            color: #64748b;
        }

        /* Light theme table headers */
        html[data-theme="light"] th{
            color: var(--text-muted);
            font-weight: 600;
        }

        /* ====== Light theme: inner blocks (nested) — subtle tint ====== */
        html[data-theme="light"] .glass-card .stat-card {
            background: #f4f7f5;
        }
        html[data-theme="light"] .glass-card .glass-soft {
            background: #f4f7f5;
        }
        html[data-theme="light"] .glass-card .glass-soft:hover {
            background: #eef3f0;
        }

        /* ======================================================================
           LIGHT THEME — Comprehensive Tailwind utility overrides
           All pages inherit these. Converts dark-mode-oriented utility classes
           to readable light-mode equivalents.
           ====================================================================== */

        /* ── Status badge text colors (light-on-dark → dark-on-light) ── */
        html[data-theme="light"] .text-amber-200,
        html[data-theme="light"] .text-amber-300 {
            color: #92400e !important;
        }
        html[data-theme="light"] .text-yellow-200,
        html[data-theme="light"] .text-yellow-300 {
            color: #854d0e !important;
        }
        html[data-theme="light"] .text-yellow-400 {
            color: #a16207 !important;
        }
        html[data-theme="light"] .text-blue-200,
        html[data-theme="light"] .text-blue-300 {
            color: #1e40af !important;
        }
        html[data-theme="light"] .text-purple-200,
        html[data-theme="light"] .text-purple-300 {
            color: #7c3aed !important;
        }
        html[data-theme="light"] .text-red-200,
        html[data-theme="light"] .text-red-300 {
            color: #dc2626 !important;
        }
        html[data-theme="light"] .text-red-400 {
            color: #dc2626 !important;
        }
        html[data-theme="light"] .text-gray-300 {
            color: #334155 !important;
        }
        html[data-theme="light"] .text-sky-400 {
            color: #0284c7 !important;
        }
        html[data-theme="light"] .text-blue-400 {
            color: #0284c7 !important; /* secondary-500 from palette */
        }
        html[data-theme="light"] .text-amber-400 {
            color: #d97706 !important; /* amber-600: readable on light bg */
        }
        html[data-theme="light"] .text-emerald-100 {
            color: #059669 !important;
        }

        /* ── White-overlay → dark-overlay equivalents ── */
        html[data-theme="light"] .bg-white\/10 {
            background-color: rgba(15,23,42,0.07) !important;
        }
        html[data-theme="light"] .border-white\/10 {
            border-color: rgba(15,23,42,0.10) !important;
        }
        html[data-theme="light"] .border-white\/20 {
            border-color: rgba(15,23,42,0.14) !important;
        }
        html[data-theme="light"] .text-white\/60 {
            color: #334155 !important;
        }
        html[data-theme="light"] .hover\:bg-white\/5:hover {
            background-color: rgba(15,23,42,0.04) !important;
        }
        html[data-theme="light"] .hover\:bg-white\/10:hover {
            background-color: rgba(15,23,42,0.06) !important;
        }

        /* ── Amber badge / button backgrounds ── */
        html[data-theme="light"] .bg-amber-500\/15 {
            background-color: rgba(245,158,11,0.10) !important;
        }
        html[data-theme="light"] .border-amber-500\/20 {
            border-color: rgba(245,158,11,0.25) !important;
        }

        /* ── Yellow badge / button backgrounds ── */
        html[data-theme="light"] .bg-yellow-500\/15,
        html[data-theme="light"] .bg-yellow-500\/20 {
            background-color: rgba(234,179,8,0.10) !important;
        }
        html[data-theme="light"] .border-yellow-500\/20 {
            border-color: rgba(234,179,8,0.25) !important;
        }
        html[data-theme="light"] .border-yellow-400\/25 {
            border-color: rgba(234,179,8,0.25) !important;
        }
        html[data-theme="light"] .hover\:bg-yellow-500\/30:hover {
            background-color: rgba(234,179,8,0.16) !important;
        }
        html[data-theme="light"] .bg-yellow-500\/10 {
            background-color: rgba(234,179,8,0.08) !important;
        }

        /* ── Blue badge / button backgrounds ── */
        html[data-theme="light"] .bg-blue-500\/15,
        html[data-theme="light"] .bg-blue-500\/20 {
            background-color: rgba(59,130,246,0.10) !important;
        }
        html[data-theme="light"] .border-blue-500\/20 {
            border-color: rgba(59,130,246,0.25) !important;
        }
        html[data-theme="light"] .border-blue-400\/25 {
            border-color: rgba(59,130,246,0.25) !important;
        }

        /* ── Purple badge / button backgrounds ── */
        html[data-theme="light"] .bg-purple-500\/15,
        html[data-theme="light"] .bg-purple-500\/20 {
            background-color: rgba(168,85,247,0.10) !important;
        }
        html[data-theme="light"] .border-purple-500\/20 {
            border-color: rgba(168,85,247,0.25) !important;
        }
        html[data-theme="light"] .border-purple-400\/25 {
            border-color: rgba(168,85,247,0.25) !important;
        }

        /* ── Red badge / button backgrounds ── */
        html[data-theme="light"] .bg-red-500\/15 {
            background-color: rgba(220,38,38,0.08) !important;
        }
        html[data-theme="light"] .border-red-500\/20 {
            border-color: rgba(220,38,38,0.25) !important;
        }
        html[data-theme="light"] .border-red-400\/25 {
            border-color: rgba(220,38,38,0.25) !important;
        }
        html[data-theme="light"] .hover\:bg-red-500\/10:hover {
            background-color: rgba(220,38,38,0.06) !important;
        }
        html[data-theme="light"] .hover\:text-red-300:hover {
            color: #dc2626 !important;
        }

        /* ── Gray badge backgrounds ── */
        html[data-theme="light"] .bg-gray-500\/20 {
            background-color: rgba(100,116,139,0.10) !important;
        }
        html[data-theme="light"] .border-gray-400\/25 {
            border-color: rgba(100,116,139,0.25) !important;
        }

        /* ── Emerald badge / button backgrounds ── */
        html[data-theme="light"] .bg-emerald-500\/15,
        html[data-theme="light"] .bg-emerald-500\/20 {
            background-color: rgba(5,150,105,0.10) !important;
        }
        html[data-theme="light"] .border-emerald-500\/20 {
            border-color: rgba(5,150,105,0.25) !important;
        }
        html[data-theme="light"] .border-emerald-400\/25 {
            border-color: rgba(5,150,105,0.25) !important;
        }
        html[data-theme="light"] .border-emerald-400\/20 {
            border-color: rgba(5,150,105,0.22) !important;
        }
        html[data-theme="light"] .hover\:bg-emerald-500\/10:hover {
            background-color: rgba(5,150,105,0.08) !important;
        }
        html[data-theme="light"] .hover\:bg-emerald-500\/25:hover {
            background-color: rgba(5,150,105,0.18) !important;
        }
        html[data-theme="light"] .hover\:bg-emerald-500\/30:hover {
            background-color: rgba(5,150,105,0.16) !important;
        }
        html[data-theme="light"] .bg-emerald-500\/20 {
            background-color: rgba(5,150,105,0.10) !important;
        }
        html[data-theme="light"] .bg-emerald-700\/40,
        html[data-theme="light"] .bg-emerald-700\/30,
        html[data-theme="light"] .bg-emerald-700\/20 {
            background-color: rgba(5,150,105,0.12) !important;
        }

        /* ── Select option backgrounds (dark dropdown → white) ── */
        html[data-theme="light"] select option {
            background: #ffffff;
            color: #0f172a;
        }

        /* ── Sidebar notification badges (text-white → dark text) ── */
        html[data-theme="light"] #sidebar .text-white {
            color: #dc2626 !important;
        }

        /* ── Users list: status badge override ── */
        html[data-theme="light"] .role-badge.admin {
            color: #dc2626;
        }
        html[data-theme="light"] .role-badge.pharma {
            color: #059669;
        }
        html[data-theme="light"] .role-badge.supplier {
            color: #0284c7;
        }

        /* ── Chat: message bubbles ── */
        html[data-theme="light"] .bg-white\/5 {
            background-color: rgba(15,23,42,0.04) !important;
        }

        /* ── Black/60 overlay stays fine, but backdrop blur might need adjustment ── */
        html[data-theme="light"] .bg-black\/60 {
            background-color: rgba(15,23,42,0.40) !important;
        }

        /* ── Focus rings ── */
        html[data-theme="light"] .focus\:ring-emerald-400\/30:focus {
            --tw-ring-color: rgba(5,150,105,0.30) !important;
        }

        /* ── Loading spinners ── */
        html[data-theme="light"] .border-emerald-400\/30 {
            border-color: rgba(5,150,105,0.30) !important;
        }
        html[data-theme="light"] .border-t-emerald-400 {
            border-top-color: #059669 !important;
        }

        /* Fond HTML — défini en haut du <head> (anti-flash), voir bootstrap. */

        /* ====== Typography ====== */
        /* Self-hosted OFL Cairo (Arabic subset). Scoped by unicode-range so it is
           consulted ONLY for Arabic codepoints — Latin/English rendering is
           byte-identical and English-only pages never fetch the file. Static .css:
           {% static %} does NOT resolve here, so the src is a relative ../fonts/ url
           (collectstatic preserves the tree under STATIC_ROOT). No dir/RTL swap — Phase 31. */
        @font-face {
            font-family: 'Cairo';
            src: url("../fonts/cairo-arabic.4d90a59cb181.woff2") format('woff2');
            font-weight: 200 1000;
            font-display: swap;
            unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;
        }
        body {
            font-family: 'DM Sans', 'Cairo', system-ui, -apple-system, sans-serif;
            animation: bodyEnter .45s ease both;
        }
        @keyframes bodyEnter {
            from { opacity: 0; }
            to   { opacity: 1; }
        }
        @media (prefers-reduced-motion: reduce) {
            body, #app-main { animation: none !important; }
        }
        h1, h2, h3, h4, h5, h6 {
            font-family: 'Outfit', 'Cairo', system-ui, sans-serif;
        }

        /* ====== Page entrance animation ====== */
        @keyframes pageIn {
            from { transform: translateY(10px); }
            to   { transform: translateY(0); }
        }
        #app-main {
            /* `backwards` (not `both`): the entrance still plays translateY(10px)→0,
               but the end-state transform is NOT retained. `both`/`forwards` would
               leave a permanent `transform: translateY(0)` on #app-main, which makes
               it the containing block for every `position: fixed` descendant — that
               trapped the included modals (user/company/stock) inside the tall main
               element, so they centered mid-page and fell off-screen on phones
               instead of centering in the viewport. translateY(0) ≡ no offset, so
               dropping the retained transform is visually identical. */
            animation: pageIn 0.4s cubic-bezier(.22,1,.36,1) backwards;
        }

        /* ====== Active sidebar nav item ====== */
        .nav-item.active {
            background: var(--nav-hover-bg);
            border-inline-start-color: var(--nav-active-accent);
        }

        /* ====== Page title h1 accent underline ====== */
        .page-title {
            letter-spacing: -0.02em;
        }
        .page-title::after {
            content: '';
            display: block;
            width: 2rem;
            height: 3px;
            background: var(--brand-700);
            border-radius: 2px;
            margin-top: 0.45rem;
        }
        html[data-theme="light"] .page-title::after {
            background: #059669;
        }

        /* ====== Stat card semantic accent (top border) ====== */
        .stat-card-accent-emerald { border-top: 2px solid var(--brand-700); }
        .stat-card-accent-blue    { border-top: 2px solid #0284c7; }
        .stat-card-accent-amber   { border-top: 2px solid #f59e0b; }
        .stat-card-accent-red     { border-top: 2px solid #ef4444; }
        html[data-theme="light"] .stat-card-accent-emerald { border-top-color: #059669; }
        html[data-theme="light"] .stat-card-accent-amber   { border-top-color: #d97706; }
        html[data-theme="light"] .stat-card-accent-red     { border-top-color: #dc2626; }

        /* ====== Primary button ====== */
        .btn-primary {
            display: inline-flex;
            align-items: center;
            gap: 0.5rem;
            padding: 0.5rem 1rem;
            border-radius: 0.5rem;
            font-size: 0.875rem;
            font-weight: 600;
            font-family: inherit;
            background: var(--brand-700);
            color: #ffffff;
            border: none;
            cursor: pointer;
            text-decoration: none;
            transition: background 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
        }
        .btn-primary:hover {
            background: var(--brand-600);
            box-shadow: 0 2px 10px rgba(16,185,129,0.28);
            transform: translateY(-1px);
        }
        .btn-primary:active { transform: translateY(0); }
        html[data-theme="light"] .btn-primary          { background: #059669; color: #ffffff; }
        html[data-theme="light"] .btn-primary:hover    { background: #047857; box-shadow: 0 2px 10px rgba(5,150,105,0.22); }

        /* ====== Empty state ====== */
        .empty-state {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 3rem 1.5rem;
            text-align: center;
        }
        .empty-state-icon {
            font-size: 2.5rem;
            color: var(--brand-500);
            opacity: 0.25;
            margin-bottom: 0.75rem;
        }
        .empty-state-title {
            font-size: 0.9375rem;
            font-weight: 600;
            color: var(--text);
            margin-bottom: 0.25rem;
        }
        .empty-state-desc {
            font-size: 0.8125rem;
            color: var(--muted);
            max-width: 280px;
            line-height: 1.5;
        }

        /* ====== Minimalist panel vocabulary (clean / declutter pass) ======
           Shared building blocks so every page uses ONE calm visual language:
           quiet section headers, hairline-separated rows, flat hover lists,
           and small neutral pills. Color is reserved for state, not decoration. */
        .ui-panel-head {
            display: flex; align-items: center; justify-content: space-between;
            gap: 0.75rem; margin-bottom: 1.1rem;
        }
        .ui-panel-title {
            font-size: 1rem; font-weight: 600; color: var(--text);
            letter-spacing: -0.01em;
        }
        .ui-panel-sub { font-size: 0.75rem; color: var(--muted); }
        .ui-panel-link {
            font-size: 0.75rem; font-weight: 500; color: var(--muted);
            text-decoration: none; transition: color 0.15s ease;
        }
        .ui-panel-link:hover { color: var(--text); }

        /* Static rows separated by a hairline (no nested cards) */
        .ui-row {
            display: flex; align-items: center; justify-content: space-between;
            gap: 0.75rem; padding: 0.625rem 0;
        }
        .ui-row-divide + .ui-row-divide { border-top: 1px solid var(--soft-border); }
        .ui-dot { width: 0.5rem; height: 0.5rem; border-radius: 9999px; flex: none; display: inline-block; }

        /* Interactive list rows: flat, subtle hover */
        .ui-list { display: flex; flex-direction: column; gap: 0.125rem; }
        .ui-list-row {
            display: flex; align-items: center; justify-content: space-between;
            gap: 0.75rem; padding: 0.5rem; margin: 0 -0.5rem;
            border-radius: 0.5rem; text-decoration: none;
            transition: background 0.15s ease;
        }
        .ui-list-row:hover { background: var(--soft-bg); }
        .ui-list-icon { width: 1rem; text-align: center; font-size: 0.75rem; color: var(--muted); flex: none; }
        .ui-rank { width: 1.25rem; flex: none; font-size: 0.75rem; color: var(--muted); font-variant-numeric: tabular-nums; }

        /* Small count pill — neutral by default; semantic variants only when meaningful */
        .ui-badge {
            display: inline-flex; align-items: center;
            font-size: 0.6875rem; font-weight: 600; line-height: 1;
            padding: 0.25rem 0.5rem; border-radius: 9999px;
            background: var(--soft-bg); color: var(--muted);
        }
        /* Badge text tokens (CLR-04): each theme supplies a value that passes
           >=4.5:1 against its soft background. Dark uses the bright glass mints
           (they pass on the dark surface); light remaps to darker shades because
           the bright mints fail 4.5:1 on the near-white soft fills. */
        .ui-badge-attn   { background: var(--warning-soft); color: var(--ui-badge-attn-text); }
        .ui-badge-danger { background: var(--error-soft);   color: var(--ui-badge-danger-text); }
        .ui-badge-ok     { background: var(--success-soft); color: var(--ui-badge-ok-text); }

        /* Muted-metadata class (CLR-04) — de-emphasis for secondary metadata
           (timestamps, IDs, counts). Consumed by DTL-05 / DASH-01. Never bold. */
        .ui-meta {
            color: var(--muted);
            font-size: var(--text-meta);
            font-weight: 500;
            line-height: 1.4;
        }

        /* Status component (CLR-03/CLR-04) — ALWAYS pairs color + a text label so
           color is never the only signal. Wrap a .ui-badge / .ui-badge-{token}
           (token = the lifecycle map's `color` field) with the human label text:
             <span class="ui-status">
               <span class="ui-badge ui-badge-ok"></span>
               <span class="ui-status-label">Received</span>
             </span>
           The label is mandatory — the static guard (Plan 04) asserts its presence. */
        .ui-status {
            display: inline-flex; align-items: center; gap: 0.375rem;
        }
        .ui-status-label {
            font-size: var(--text-meta);
            font-weight: 600;
            color: var(--text);
            line-height: 1.4;
        }

        /* ====== Disclosure primitives (CLR-02) — native <details>/<summary> ====== */
        /* Visible summary label; >=44px touch target; theme through glass vars. */
        .ui-accordion-summary,
        .ui-show-more-summary {
            display: flex; align-items: center; gap: 0.5rem;
            min-height: 44px;                 /* mobile touch target (CLAUDE.md) */
            font-size: var(--text-body); font-weight: 600; color: var(--text);
        }
        .ui-accordion-summary::-webkit-details-marker,
        .ui-show-more-summary::-webkit-details-marker { display: none; }
        .ui-accordion-summary::before,
        .ui-show-more-summary::before {
            content: "\25B8";                 /* ▸ disclosure caret */
            color: var(--muted); font-size: 0.75rem;
            transition: transform 0.15s ease; flex: none;
        }
        details[open] > .ui-accordion-summary::before,
        details[open] > .ui-show-more-summary::before { transform: rotate(90deg); }
        .ui-accordion-body { padding-top: 0.625rem; }
        .ui-show-more-summary {
            font-size: var(--text-meta); font-weight: 600; color: var(--muted);
            min-height: 44px;
        }
        .ui-show-more-summary:hover { color: var(--text); }
        .ui-show-more-body { padding-top: 0.5rem; }

        /* ====== Shared right-side drawer (CLR-02) — ONE <dialog id="ui-drawer"> ====== */
        .ui-drawer {
            margin-inline-start: auto;        /* pin to the inline-end (right in LTR) */
            margin-inline-end: 0;
            height: 100dvh; max-height: 100dvh;
            width: min(440px, 100vw);
            max-width: 100vw;
            padding: 1.5rem;                  /* lg spacing — drawer inner padding */
            background: var(--glass-bg);
            color: var(--text);
            border: none;
            border-inline-start: 1px solid var(--glass-border);
            box-shadow: var(--glass-shadow);
            overflow-y: auto;
        }
        .ui-drawer::backdrop {
            background: var(--sidebar-overlay);
            backdrop-filter: blur(2px);
        }
        .ui-drawer[open] { display: flex; flex-direction: column; gap: 1rem; }
        .ui-drawer-title {
            font-size: var(--text-heading); font-weight: 600; color: var(--text);
            line-height: 1.3; margin: 0;
        }
        .ui-drawer-trigger {
            display: inline-flex; align-items: center; gap: 0.375rem;
            min-height: 44px;                 /* touch target */
            font-size: var(--text-body); font-weight: 600; color: var(--brand-700);
            background: none; border: none; cursor: pointer;
        }
        .ui-drawer-trigger:hover { color: var(--text); }

        /* ====== Global iPhone-style notification toasts (J08-TOAST) ======
           iOS-notification anatomy (app-icon tile · title + relative time ·
           message) rendered on the SIPS emerald-glass surface. When several
           arrive together they collapse into a peeking stack that fans open on
           hover / keyboard focus — the real iOS interaction, not a decorative
           layer. All colour via theme tokens, so it reads AA in both themes;
           --dy/--s/--op are driven by the stacking JS in base.html. */
        .sips-toast-container {
            position: fixed;
            top: 1rem;
            inset-inline-end: 1rem;
            z-index: 9999;
            display: flex;
            flex-direction: column;
            gap: 0.625rem;
            width: min(360px, calc(100vw - 2rem));
            pointer-events: none;
        }
        .sips-toast {
            --dy: 0px;
            --s: 1;
            --op: 1;
            position: relative;
            pointer-events: auto;
            display: flex;
            align-items: flex-start;
            gap: 0.75rem;
            padding: 0.8rem 0.85rem;
            background: var(--glass-bg);
            border: 1px solid var(--glass-border);
            box-shadow: var(--glass-shadow), 0 20px 44px -26px rgba(0, 0, 0, 0.6);
            border-radius: 1.15rem;
            -webkit-backdrop-filter: blur(16px) saturate(1.4);
            backdrop-filter: blur(16px) saturate(1.4);
            transform: translateY(var(--dy)) scale(var(--s));
            transform-origin: top center;
            opacity: var(--op);
            animation: sips-toast-in 0.42s cubic-bezier(0.16, 1, 0.3, 1);
        }
        @media (prefers-reduced-motion: no-preference) {
            .sips-toast {
                transition: transform 0.46s cubic-bezier(0.16, 1, 0.3, 1),
                            opacity 0.32s ease, border-color 0.2s ease;
            }
        }
        .sips-toast.is-clickable { cursor: pointer; }
        .sips-toast.is-clickable:hover { border-color: var(--border-strong); }

        /* App-icon tile — iOS squircle, emerald identity in both themes */
        .sips-toast-icon {
            flex: 0 0 auto;
            width: 2.4rem;
            height: 2.4rem;
            border-radius: 0.72rem;
            display: grid;
            place-items: center;
            background: var(--brand-soft);
            border: 1px solid var(--glass-border);
            color: var(--brand-600);
            font-size: 1.05rem;
        }
        [data-theme="light"] .sips-toast-icon { color: var(--brand-800); }

        .sips-toast-body { min-width: 0; flex: 1 1 auto; }
        .sips-toast-head {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            gap: 0.5rem;
        }
        .sips-toast-title {
            min-width: 0;
            font-size: 0.86rem;
            font-weight: 600;
            color: var(--text);
            line-height: 1.3;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        .sips-toast-time {
            flex: 0 0 auto;
            font-size: 0.72rem;
            color: var(--muted);
            font-variant-numeric: tabular-nums;
        }
        .sips-toast-message {
            margin-top: 0.15rem;
            font-size: 0.8rem;
            color: var(--muted);
            line-height: 1.4;
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
            overflow: hidden;
        }
        .sips-toast-close {
            position: absolute;
            top: 0.35rem;
            inset-inline-end: 0.4rem;
            width: 1.25rem;
            height: 1.25rem;
            border-radius: 999px;
            display: grid;
            place-items: center;
            background: none;
            border: none;
            color: var(--muted);
            font-size: 0.95rem;
            line-height: 1;
            cursor: pointer;
            opacity: 0;
            transition: opacity 0.2s ease, background 0.2s ease, color 0.2s ease;
        }
        .sips-toast:hover .sips-toast-close,
        .sips-toast:focus-within .sips-toast-close { opacity: 0.75; }
        .sips-toast-close:hover { opacity: 1; color: var(--text); background: var(--soft-bg); }
        .sips-toast.is-leaving {
            opacity: 0 !important;
            transform: translateY(var(--dy)) scale(0.94) !important;
            transition: opacity 0.28s ease, transform 0.28s ease;
        }
        @keyframes sips-toast-in {
            from { opacity: 0; transform: translateX(110%); }
            to   { opacity: 1; transform: translateX(0); }
        }
        @media (max-width: 640px) {
            .sips-toast-container {
                left: 0.75rem;
                right: 0.75rem;
                width: auto;
            }
        }

        /* ====== Lifecycle stepper (CLR-02) — detail-only; accent = active step ====== */
        .ui-stepper { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.25rem; }
        .ui-step {
            display: inline-flex; align-items: center; gap: 0.375rem;
            min-height: 44px; padding: 0 0.625rem;       /* touch target */
            font-size: var(--text-meta); font-weight: 600; color: var(--muted);
            border-radius: 9999px; background: var(--soft-bg);
            cursor: default;
        }
        .ui-step[aria-current="step"] {
            color: var(--brand-700);                     /* accent ONLY on active */
            background: var(--brand-soft);
        }
        .ui-step-index {
            width: 1.25rem; height: 1.25rem; flex: none;
            display: inline-flex; align-items: center; justify-content: center;
            border-radius: 9999px; font-size: 0.6875rem;
            background: var(--glass-border);
        }
        .ui-step[aria-current="step"] .ui-step-index { background: var(--brand-700); color: #fff; }

        /* ====== Tabs (CLR-02) — role=tablist/tab/tabpanel; accent = active tab ====== */
        .ui-tablist { display: flex; flex-wrap: wrap; gap: 0.25rem; border-bottom: 1px solid var(--soft-border); }
        .ui-tab {
            min-height: 44px; padding: 0 0.875rem;       /* touch target */
            font-size: var(--text-body); font-weight: 600; color: var(--muted);
            background: none; border: none; cursor: pointer;
            border-bottom: 2px solid transparent; margin-bottom: -1px;
        }
        .ui-tab:hover { color: var(--text); }
        .ui-tab[aria-selected="true"] {
            color: var(--brand-700);                     /* accent ONLY on active */
            border-bottom-color: var(--brand-700);
        }
        .ui-tabpanel { padding-top: 1rem; }
        .ui-tabpanel[hidden] { display: none; }

        /* ====== Table sort headers ====== */
        .th-sort {
            cursor: pointer;
            user-select: none;
            white-space: nowrap;
        }
        .th-sort::after {
            content: ' ⇅';
            font-size: 0.65em;
            opacity: 0.35;
            margin-inline-start: 2px;
            font-family: system-ui;
        }
        .th-sort.asc::after  { content: ' ↑'; opacity: 1; color: var(--brand-500); }
        .th-sort.desc::after { content: ' ↓'; opacity: 1; color: var(--brand-500); }

        /* ====== Focus rings (uniform keyboard nav) ====== */
        :focus-visible {
            outline: 2px solid var(--brand-700);
            outline-offset: 2px;
            border-radius: 4px;
        }
        html[data-theme="light"] :focus-visible {
            outline-color: #059669;
        }

        /* ====== Shared bento container-query grid (FND-01) ======
           Generalized verbatim from .dash-root/.dash-grid in admin_dashboard_v2.html
           (lines 163-233). container-name renamed dash→bento so pages nesting a
           .dash-root child don't mis-resolve the @container queries. */
        .bento {
            container-type: inline-size;
            container-name: bento;
            display: grid;
            grid-template-columns: 1fr;
            gap: 1rem;
            align-items: start;
        }
        .bento > * { min-width: 0; }       /* prevents grid overflow blowups */

        /* Tier 1 — 2-column layout */
        @container bento (min-width: 700px) {
            .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem; }
            .bento > * { order: 0; }        /* natural reading order once 2-up */
        }

        /* Tier 2 — 3-column layout */
        @container bento (min-width: 1120px) {
            .bento { grid-template-columns: repeat(3, minmax(0, 1fr)); }
        }

        /* ====== KPI strip (FND-01) ======
           Generalized from .dash-kpis (admin_dashboard_v2 lines 168-227).
           Reuses existing .stat-card/.stat-label/.stat-value — do not reinvent. */
        .kpi-strip {
            display: grid;
            grid-template-columns: repeat(2, minmax(0, 1fr));
            gap: 0.625rem;
        }

        /* KPI Tier 1 — 3 columns */
        @container bento (min-width: 560px) {
            .kpi-strip { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.75rem; }
        }

        /* KPI Tier 2 — 5-up full strip */
        @container bento (min-width: 1000px) {
            .kpi-strip { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 1rem; }
        }

        /* ====== Detail-page header band (DTL-01) ======
           Shared glass band for every Phase-8 detail page: reference + status pill
           row, lifecycle stepper, owed-action string, KPI band, single primary
           action. Declares its OWN container (container-type: inline-size +
           container-name: detailhdr) — copied verbatim from .bento (above) — so it
           reflows when the sidebar opens/closes, following CONTENT width, NOT the
           viewport. Reuses --radius-md (12px) + the established glass surface vars;
           lg (1.5rem) block padding, xl (2rem) gap to line items. Existing tokens
           (.ui-badge*, .ui-status, .ui-stepper/.ui-step, .ui-meta, .ui-drawer) are
           consumed as-is — never redefined here. */
        .ui-detail-header {
            container-type: inline-size;
            container-name: detailhdr;
            display: flex;
            flex-direction: column;
            gap: 1rem;
            padding: 1.5rem;                          /* lg block padding */
            margin-bottom: 2rem;                      /* xl gap to line items */
            background: var(--glass-bg);
            border: 1px solid var(--glass-border);
            box-shadow: var(--glass-shadow);
            border-radius: var(--radius-md);
        }
        .ui-detail-header > * { min-width: 0; }       /* prevents reflow overflow */
        /* Reference + status pill row — stacks on narrow, justifies wide. */
        .ui-detail-header-top {
            display: flex; flex-wrap: wrap; align-items: center;
            justify-content: space-between; gap: 0.75rem;
        }
        /* Owed-action string — body weight, muted, NEVER accent (IC-1). */
        .ui-detail-header-owed {
            font-size: var(--text-body); color: var(--muted); line-height: 1.4;
        }
        /* Single primary action — full-width on narrow, intrinsic on wide; the
           >=44px min-height satisfies the mobile touch-target rule (CLAUDE.md). */
        .ui-detail-header-action {
            display: inline-flex; align-items: center; justify-content: center;
            gap: 0.5rem; min-height: 44px; padding: 0 1.25rem;
            border-radius: var(--radius-md); border: none; cursor: pointer;
            font-size: var(--text-body); font-weight: 600;
            background: var(--brand-700); color: #fff;
        }
        .ui-detail-header-action:hover { filter: brightness(1.05); }
        /* Wide container: lay the action beside the owed-action string. */
        @container detailhdr (min-width: 560px) {
            .ui-detail-header-action { align-self: flex-start; }
        }

        /* Condensed-stepper rule (IC-2 / Pitfall 6): below ~560px container width
           collapse the stepper to the active step ± 1 neighbour. The hidden steps
           use display:none ONLY visually — the full <ol> stays in the DOM so the
           keyboard / AT reading order is intact. Callers flag neighbours with
           .ui-step-edge (active ± 1); everything not adjacent and not active hides.
           At >=560px every step shows and wraps (flex-wrap on .ui-stepper), never
           horizontal-scrolls. Scoped under .ui-detail-header so it only affects the
           detail-page stepper, not other .ui-stepper usages. */
        @container detailhdr (max-width: 559.98px) {
            .ui-detail-header .ui-stepper .ui-step {
                display: none;
            }
            .ui-detail-header .ui-stepper .ui-step[aria-current="step"],
            .ui-detail-header .ui-stepper .ui-step.ui-step-edge {
                display: inline-flex;                 /* active ± 1 stay visible */
            }
        }

        /* ====== Detail-page KPI band (DTL-03) ======
           Reuses the .kpi-strip grid + its container-query breakpoints but CAPS at
           4 tiles: 2-up at base, 4-up at wide container width — never the 5th
           column. Lives inside .ui-detail-header so it answers the detailhdr
           container, reflowing on sidebar toggle like the band itself. */
        .ui-kpi-band {
            display: grid;
            grid-template-columns: repeat(2, minmax(0, 1fr));
            gap: 0.625rem;
        }
        @container detailhdr (min-width: 560px) {
            .ui-kpi-band { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; }
        }
        @container detailhdr (min-width: 1000px) {
            .ui-kpi-band { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1rem; }
        }

        /* ====== .rcard table-to-card primitive (FND-02) ======
           Net-new — no in-repo analog. Uses display:flex (NOT block) so table/row/cell
           roles stay in the a11y tree (QUAL-02, adrianroselli.com gotcha).
           data-label is emitted by markup/renderRows JS helper per cell. */
        .rcard {
            width: 100%;
            container-type: inline-size;
            container-name: rcard;
        }
        .rcard th, .rcard td {
            padding: 0.625rem 0.75rem;
            text-align: start;
            border-bottom: 1px solid var(--divider);
            color: var(--text);
        }
        .rcard th {
            font-size: 0.75rem;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.04em;
            color: var(--text-muted);
        }

        /* Collapse threshold: rows → stacked labeled cards */
        @container rcard (max-width: 640px) {
            /* Visually hide thead but keep it in the a11y tree (NOT display:none) */
            .rcard thead {
                position: absolute;
                width: 1px;
                height: 1px;
                overflow: hidden;
                clip: rect(0 0 0 0);
            }
            /* FLEX not block — preserves table/row/cell roles (Chrome 80+) */
            .rcard tr { display: flex; flex-direction: column; border-bottom: 1px solid var(--divider); }
            .rcard tr:last-child { border-bottom: none; }
            .rcard td {
                display: flex;
                justify-content: space-between;
                align-items: center;
                gap: 1rem;
                border-bottom: none;
            }
            /* Label revealed from data-label attribute — color uses theme token (QUAL-01) */
            .rcard td::before {
                content: attr(data-label);
                color: var(--text-muted);
                font-weight: 500;
                font-size: 0.75rem;
                flex-shrink: 0;
            }
        }

        /* ====== .rec-grid record-card grid (FND-06) ======
           Companion to .rcard for pages that LIST records. Where .rcard keeps
           one column of rows (wastes wide screens, blurs on phones), .rec-grid
           flows records into 1→4 columns driven by CONTENT width (container
           query) — fills big screens, degrades to framed cards on phones.
           Wrapper owns the container; the grid is a descendant (same shape as
           the proven .dash-root/.dash-grid on the admin dashboard). */
        .rec-scope { container-type: inline-size; container-name: recgrid; }
        .rec-grid {
            display: grid;
            grid-template-columns: 1fr;
            gap: 0.875rem;
            align-items: start;
        }
        .rec-grid > * { min-width: 0; }
        @container recgrid (min-width: 540px)  { .rec-grid { grid-template-columns: repeat(2, minmax(0,1fr)); gap: 1rem; } }
        @container recgrid (min-width: 880px)  { .rec-grid { grid-template-columns: repeat(3, minmax(0,1fr)); } }
        @container recgrid (min-width: 1220px) { .rec-grid { grid-template-columns: repeat(4, minmax(0,1fr)); } }
        /* Responsive column priority (LIST-04): at the narrowest container width the
           least-essential Layer-2 muted meta drops before Layer-1 fields. Container
           query (not viewport media) so it follows content width like the grid above;
           cards already stack to 1-col, so this only hides the data-priority="low"
           meta cells — #id, status pill, owed-action, total, primary name are untouched. */
        @container recgrid (max-width: 360px) { .rec-grid .rec-meta-item[data-priority="low"] { display: none; } }

        .rec-card {
            position: relative; overflow: hidden;
            display: flex; flex-direction: column;
            background: var(--glass-bg);
            border: 1px solid var(--glass-border);
            box-shadow: var(--glass-shadow);
            border-radius: var(--radius-md);
            padding: 0.9rem 1rem 0.8rem 1.15rem;
            text-decoration: none; color: inherit;
            transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
        }
        .rec-card:hover { border-color: var(--hover-border); box-shadow: var(--hover-shadow); transform: translateY(-2px); }
        /* Status spine — color set per-card via inline --rec-accent */
        .rec-card::before {
            content: ""; position: absolute; inset-inline-start: 0; top: 0; bottom: 0; width: 3px;
            background: var(--rec-accent, var(--brand-600));
        }
        .rec-head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
        .rec-id {
            font-family: 'Outfit', system-ui, sans-serif; font-weight: 700; font-size: 1.02rem;
            letter-spacing: -0.01em; color: var(--text);
            display: inline-flex; align-items: baseline; gap: 0.35rem;
        }
        .rec-id .hash { color: var(--muted); font-weight: 500; font-size: 0.8em; }
        /* Optional card title (schema.title): a prominent name with the id demoted
           to a small muted subtitle. Absent → original id-as-headline behavior. */
        .rec-headings { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
        .rec-title {
            font-family: 'Outfit', system-ui, sans-serif; font-weight: 700; font-size: 1.02rem;
            letter-spacing: -0.01em; color: var(--text);
            white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
        }
        .rec-id.rec-id-sub { font-size: 0.75rem; font-weight: 500; }
        .rec-prio { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.6875rem; font-weight: 600; color: var(--muted); white-space: nowrap; }
        .rec-prio .dot { width: 0.5rem; height: 0.5rem; border-radius: 999px; background: currentColor; }
        .rec-prio.urgent { color: var(--error); }
        .rec-prio.high   { color: var(--warning); }
        .rec-prio.normal { color: var(--muted); }
        .rec-meta { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 0.6rem 0.9rem; margin-top: 0.85rem; }
        .rec-meta-item { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
        .rec-meta-label { font-size: 0.625rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
        .rec-meta-val { font-size: 0.8125rem; font-weight: 500; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .rec-meta-val.tabular { font-variant-numeric: tabular-nums; }
        .rec-foot { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-top: 0.9rem; padding-top: 0.7rem; border-top: 1px solid var(--soft-border); }
        .rec-link { font-size: 0.8125rem; font-weight: 600; color: var(--brand-600); display: inline-flex; align-items: center; gap: 0.35rem; }
        .rec-card:hover .rec-link { gap: 0.5rem; }
        .rec-link i { transition: transform 0.15s ease; font-size: 0.7rem; }
        .rec-card:hover .rec-link i { transform: translateX(2px); }
        .rec-when { font-size: 0.6875rem; color: var(--muted); white-space: nowrap; }
        @keyframes recIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
        .rec-card { animation: recIn 0.42s cubic-bezier(0.22,0.61,0.36,1) both; }
        @media (prefers-reduced-motion: reduce) { .rec-card { animation: none; } .rec-card:hover { transform: none; } }

        /* ====== Secondary-screen container-query reflow (CQ-01) ======
           Additive polish for 8 secondary screens: makes their existing Tailwind
           grids answer CONTENT width (sidebar open / closed) instead of the
           viewport, mirroring the proven .bento / .rec-grid pattern above.
           The .cq-scope wrapper owns the query context (container-type: inline-size
           + container-name: cq — copied verbatim from .rec-scope). Each column rule
           is scoped UNDER .cq-scope so its specificity (0,2,0) deterministically
           beats the co-existing Tailwind grid-cols-* / col-span-* utilities (0,1,0)
           that stay in the DOM untouched (existing markup + guard-test contract).
           Only grid-template-columns / grid-column are set here — display:grid and
           every gap-* keep coming from the Tailwind classes, so spacing is unchanged
           and only the reflow follows content width. Base rules restate each grid's
           current mobile column count so nothing shifts on phones. */
        .cq-scope { container-type: inline-size; container-name: cq; }
        .cq-scope > * { min-width: 0; }

        /* Base (narrow container) — mirrors each grid's existing mobile columns */
        .cq-scope .cq-2-4        { grid-template-columns: repeat(2, minmax(0, 1fr)); }
        .cq-scope .cq-1-2        { grid-template-columns: 1fr; }
        .cq-scope .cq-1-3        { grid-template-columns: 1fr; }
        .cq-scope .cq-1-2-3      { grid-template-columns: 1fr; }
        .cq-scope .cq-1-2-4      { grid-template-columns: 1fr; }
        .cq-scope .cq-ann-compose{ grid-template-columns: 1fr; }

        @container cq (min-width: 560px) {
            .cq-scope .cq-1-2-3  { grid-template-columns: repeat(2, minmax(0, 1fr)); }
            .cq-scope .cq-1-2-4  { grid-template-columns: repeat(2, minmax(0, 1fr)); }
        }
        @container cq (min-width: 640px) {
            .cq-scope .cq-1-2    { grid-template-columns: repeat(2, minmax(0, 1fr)); }
            .cq-scope .cq-1-3    { grid-template-columns: repeat(3, minmax(0, 1fr)); }
            /* Compose row (announcements): restore the 3-1-1 span rhythm by CONTENT
               width. nth-child (0,2,1) beats the Tailwind lg:col-span-* on the kids. */
            .cq-scope .cq-ann-compose { grid-template-columns: repeat(5, minmax(0, 1fr)); }
            .cq-scope .cq-ann-compose > :nth-child(1) { grid-column: span 3; }
            .cq-scope .cq-ann-compose > :nth-child(2) { grid-column: span 1; }
            .cq-scope .cq-ann-compose > :nth-child(3) { grid-column: span 1; }
        }
        @container cq (min-width: 900px) {
            .cq-scope .cq-2-4    { grid-template-columns: repeat(4, minmax(0, 1fr)); }
        }
        @container cq (min-width: 960px) {
            .cq-scope .cq-1-2-3  { grid-template-columns: repeat(3, minmax(0, 1fr)); }
        }
        @container cq (min-width: 1000px) {
            .cq-scope .cq-1-2-4  { grid-template-columns: repeat(4, minmax(0, 1fr)); }
        }

/* ===== Help FAB (HELP-01) — relocated from the body-level <style> block ===== */
      /* ── Help FAB (HELP-01) — pure-CSS popover, glass DNA, bottom-right, safe-area aware ── */
      .help-fab-wrap { /* container only; children are position:fixed */ }
      /* Hidden checkbox drives the reveal; visually hidden but still keyboard-focusable */
      .help-fab-input { position: fixed; bottom: 0; inset-inline-end: 0; opacity: 0; pointer-events: none; }

      /* The floating round action button — owns the otherwise-empty bottom-right corner */
      .help-fab {
        position: fixed;
        inset-inline-end: 1.25rem;
        bottom: max(1.25rem, env(safe-area-inset-bottom));
        z-index: 60;                 /* above z-50 cart toast, below the z-[99999] toast stacks (D-08) */
        display: inline-flex; align-items: center; justify-content: center;
        width: 3.25rem; height: 3.25rem; border-radius: 9999px;
        cursor: pointer; user-select: none;
        background: var(--glass-bg);
        border: 1px solid var(--glass-border);
        box-shadow: var(--glass-shadow);
        backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
        transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
      }
      .help-fab:hover { transform: translateY(-1px); border-color: var(--hover-border); box-shadow: var(--hover-shadow); }
      .help-fab-icon { color: var(--brand-600); font-size: 1.25rem; }
      /* Keyboard focus visibility on the label (the checkbox itself is offscreen) */
      .help-fab-input:focus-visible ~ .help-fab { outline: 2px solid var(--brand-600); outline-offset: 2px; }

      /* Popover — hidden by default, revealed by the checked checkbox (pure-CSS, D-02) */
      .help-popover {
        display: none;
        position: fixed;
        inset-inline-end: 1.25rem;
        bottom: calc(max(1.25rem, env(safe-area-inset-bottom)) + 4rem);
        z-index: 60;
        min-width: 14rem;
        padding: 0.375rem;
        background: var(--glass-bg);
        border: 1px solid var(--glass-border);
        box-shadow: var(--glass-shadow);
        backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
        border-radius: 0.875rem;
      }
      .help-fab-input:checked ~ .help-popover { display: block; }

      .help-popover-link {
        display: flex; align-items: center; gap: 0.625rem;
        padding: 0.625rem 0.75rem; min-height: 2.75rem;
        font-size: 0.875rem; font-weight: 500; color: var(--text-main);
        border-radius: 0.625rem; text-decoration: none;
        transition: background 0.15s ease;
      }
      .help-popover-link:hover { background: var(--soft-bg); }
      .help-popover-link + .help-popover-link { margin-top: 0.125rem; }
      .help-popover-icon { color: var(--brand-600); width: 1.125rem; text-align: center; flex: none; }

      /* Mobile (D-09): smaller diameter, stays bottom-right + safe-area aware */
      @media (max-width: 640px) {
        .help-fab { width: 2.75rem; height: 2.75rem; inset-inline-end: 1rem; }
        .help-fab-icon { font-size: 1.125rem; }
        .help-popover {
          inset-inline-end: 1rem;
          bottom: calc(max(1.25rem, env(safe-area-inset-bottom)) + 3.5rem);
          min-width: 12rem;
        }
      }

      /* Respect reduced-motion (mirror faq.html L388/L400) */
      @media (prefers-reduced-motion: reduce) {
        .help-fab { transition: none; }
        .help-popover-link { transition: none; }
      }

/* ===== Worklist + next-step vocabulary (SPEC §3.10/§3.11) =====
   Tokens only — every color/size below resolves through the base.html token
   sheet in BOTH themes (no literal colors except the established light-theme
   emerald pair used by .btn-primary). Container queries (not viewport) follow
   CONTENT width per the admin-dashboard pattern. */

/* ── .wl-head — worklist section header (renderWorklist) ──
   Uppercase .ui-meta voice + a count-badge slot (.ui-badge / .ui-badge-attn). */
.wl-head {
    display: flex; align-items: center; gap: 0.5rem;
    font-size: var(--text-meta); font-weight: 600; color: var(--muted);
    text-transform: uppercase; letter-spacing: 0.06em;
    margin: 1.5rem 0 0.75rem;
}
.wl-head:first-child { margin-top: 0; }
/* One-line .ui-meta companions emitted by renderWorklist */
.wl-empty, .wl-sub { margin: 0 0 0.75rem; }
/* "Open archive →" link under the finished bucket — quiet, 44px target */
.wl-archive-link {
    display: inline-flex; align-items: center;
    min-height: 44px;                            /* touch target */
    font-size: var(--text-meta); font-weight: 600; color: var(--muted);
    text-decoration: none; transition: color 0.15s ease;
}
.wl-archive-link:hover { color: var(--text); }

/* ── .ui-next-card — client-hydrated "what happens next" card (nextStepCard) ──
   Glass-soft base + a 3px left tone spine. Tone modifiers set --next-tone:
     .act  var(--warning)        — the viewer holds the ball
     .wait var(--border-strong)  — someone else holds it
     .done var(--success)        — terminal, nothing owed
   Declares its OWN container (like .ui-detail-header) so the action slot
   answers the CARD's width, not the viewport. */
.ui-next-card {
    container-type: inline-size;
    container-name: nextcard;
    position: relative; overflow: hidden;
    display: flex; flex-direction: column; gap: 0.5rem;
    padding: 1rem 1.15rem;
    background: var(--soft-bg);
    border: 1px solid var(--soft-border);
    border-radius: var(--radius-md);
}
.ui-next-card::before {
    content: ""; position: absolute; inset-inline-start: 0; top: 0; bottom: 0; width: 3px;
    background: var(--next-tone, var(--border-strong));
}
.ui-next-card.act  { --next-tone: var(--warning); }
.ui-next-card.wait { --next-tone: var(--border-strong); }
.ui-next-card.done { --next-tone: var(--success); }
/* Kicker row — stage label in the uppercase .ui-meta voice + tone dot */
.ui-next-kicker {
    display: flex; align-items: center; gap: 0.4rem;
    font-size: var(--text-meta); font-weight: 600; color: var(--muted);
    text-transform: uppercase; letter-spacing: 0.06em;
}
.ui-next-dot {
    width: 0.5rem; height: 0.5rem; border-radius: 9999px; flex: none;
    background: var(--next-tone, var(--border-strong));
}
.ui-next-headline {
    font-family: 'Outfit', system-ui, sans-serif;
    font-size: 1rem; font-weight: 600; color: var(--text); line-height: 1.35;
}
.ui-next-body { margin: 0; }
/* Action slot — intrinsic beside content on wide cards; ≥44px target */
.ui-next-action {
    display: inline-flex; align-items: center; justify-content: center;
    gap: 0.5rem; min-height: 44px; padding: 0 1.25rem;
    margin-top: 0.25rem; align-self: flex-start;
    border-radius: 0.5rem; border: none; cursor: pointer;
    font-size: var(--text-body); font-weight: 600; font-family: inherit;
    background: var(--brand-700); color: #ffffff; text-decoration: none;
    transition: background 0.15s ease;
}
.ui-next-action:hover { background: var(--brand-600); }
html[data-theme="light"] .ui-next-action        { background: #059669; }  /* matches .btn-primary */
html[data-theme="light"] .ui-next-action:hover  { background: #047857; }
/* Narrow card: the action goes full-width (CONTAINER query, not viewport) */
@container nextcard (max-width: 479.98px) {
    .ui-next-action { align-self: stretch; width: 100%; }
}
/* Optional thin progress bar — 1.5px track, tone-colored fill */
.ui-next-progress {
    height: 1.5px; border-radius: 9999px; overflow: hidden;
    background: var(--soft-border); margin-top: 0.5rem;
}
.ui-next-progress-bar {
    display: block; height: 100%;
    background: var(--next-tone, var(--brand-600));
    border-radius: inherit;
    transition: width 0.3s ease;
}
@media (prefers-reduced-motion: reduce) {
    .ui-next-action, .ui-next-progress-bar, .wl-archive-link { transition: none; }
}

/* ── .ui-sticky-actions — form action bar (SPEC §3.11) ──
   Static normal flow on wide containers; under 640px CONTAINER width it
   becomes a sticky glass-soft bottom bar with safe-area padding. The unnamed
   @container resolves against the NEAREST ancestor container — wrap forms in
   .ui-form-scope (below) when no .bento/.rec-scope/.ui-detail-header ancestor
   already provides one (no ancestor container ⇒ the rule never engages and
   the bar simply stays static). */
.ui-form-scope { container-type: inline-size; container-name: formscope; }
.ui-sticky-actions {
    display: flex; flex-wrap: wrap; align-items: center;
    justify-content: flex-end; gap: 0.625rem;
    padding: 0.75rem 0;
}
@container (max-width: 639.98px) {
    .ui-sticky-actions {
        position: sticky; bottom: 0; z-index: 30;
        padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom));
        background: var(--soft-bg);
        border-top: 1px solid var(--soft-border);
        border-radius: 0.75rem 0.75rem 0 0;
        backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
    }
    /* Buttons stretch to comfortable full-width touch targets when stuck */
    .ui-sticky-actions > a,
    .ui-sticky-actions > button {
        flex: 1 1 auto; min-height: 44px;
        display: inline-flex; align-items: center; justify-content: center;
    }
}

/* ── .ui-stepper-vertical — labelled vertical stepper variant (SPEC §3.11) ──
   For narrow containers where the horizontal .ui-stepper condenses: a column
   of full-width pills with labels ALWAYS visible. Reuses .ui-step tokens. */
.ui-stepper.ui-stepper-vertical {
    flex-direction: column; align-items: stretch; gap: 0.125rem;
}
.ui-stepper.ui-stepper-vertical .ui-step {
    display: flex; justify-content: flex-start;
    border-radius: 0.625rem;
}
/* Labels always visible: out-specificity the detailhdr condensed rule
   (which display:none's non-adjacent steps under 560px) — 4 classes beat
   its 3 regardless of @container order. */
.ui-detail-header .ui-stepper.ui-stepper-vertical .ui-step { display: flex; }

/* ── .seg-tabs / .seg-tab base (renderFilterPills) ──
   Byte-mirror of partials/restock_tabs.html so pill markup emitted by
   renderFilterPills() is styled on pages that DON'T include that partial.
   Where both load, the partial's body-level <style> comes later in document
   order and wins every same-specificity tie with identical declarations —
   zero visual drift. */
.seg-tabs { display: inline-flex; gap: .25rem; padding: .25rem; border-radius: .75rem; }
.seg-tab {
    display: inline-flex; align-items: center; gap: .5rem;
    padding: .5rem .9rem; border-radius: .55rem;
    font-size: .875rem; font-weight: 500; color: var(--muted);
    white-space: nowrap; transition: background .2s ease, color .2s ease;
}
.seg-tab:hover { color: var(--text); }
.seg-tab i { font-size: .8rem; }
.seg-tab.is-active { background: var(--brand-600); color: #fff; font-weight: 600; }
.seg-tab.is-active i { color: #fff; }
@media (max-width: 480px) {
    .seg-tabs { display: flex; width: 100%; }
    .seg-tab { flex: 1; justify-content: center; }
}
/* Filter-pill buttons only (.ui-filter-pills wrapper from renderFilterPills):
   reset UA <button> chrome + enforce the 44px touch target. Scoped so the
   partial's <a>-based tabs keep their exact current look. */
.ui-filter-pills .seg-tab {
    background: none; border: none; cursor: pointer; font-family: inherit;
    min-height: 44px;                            /* touch target */
}
.ui-filter-pills .seg-tab.is-active { background: var(--brand-600); color: #fff; font-weight: 600; }

/* ===== Scan (sips-scan) =====
   Camera scan sheet rendered by static/js/sips-scan.js into a native
   top-layer <dialog id="sips-scan-modal"> (immune to #app-main transforms
   and stacks above an open #ui-drawer). Tokens only: both themes for free. */
.sips-scan-modal {
    margin: auto;
    width: min(560px, calc(100vw - 2rem));
    max-width: 100vw;
    padding: 1rem;
    background: var(--glass-bg);
    color: var(--text);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-md);
    box-shadow: var(--glass-shadow);
}
.sips-scan-modal::backdrop {
    background: var(--sidebar-overlay);
    backdrop-filter: blur(2px);
}
.sips-scan-modal[open] { display: flex; flex-direction: column; gap: 0.75rem; }
@media (max-width: 640px) {
    /* bottom-sheet feel on phones */
    .sips-scan-modal {
        margin: auto 0 0 0;
        width: 100vw;
        border-bottom-left-radius: 0;
        border-bottom-right-radius: 0;
        border-left: none; border-right: none; border-bottom: none;
    }
}
.sips-scan-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.sips-scan-title { font-size: var(--text-heading); font-weight: 600; color: var(--text); margin: 0; line-height: 1.3; }
.sips-scan-stage {
    position: relative;
    overflow: hidden;
    border-radius: var(--radius-md);
    background: #000;                       /* live video letterbox, theme-invariant */
}
.sips-scan-video { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.sips-scan-reticle { position: absolute; inset: 12%; pointer-events: none; }
.sips-scan-reticle::before {
    content: ""; position: absolute; inset: 0;
    border: 2px solid var(--brand-600);
    border-radius: var(--radius-md);
    opacity: 0.85;
    /* corner marks: mask away the edge midsections */
    -webkit-mask: linear-gradient(#000 0 0) top left / 28px 28px no-repeat,
                  linear-gradient(#000 0 0) top right / 28px 28px no-repeat,
                  linear-gradient(#000 0 0) bottom left / 28px 28px no-repeat,
                  linear-gradient(#000 0 0) bottom right / 28px 28px no-repeat;
    mask: linear-gradient(#000 0 0) top left / 28px 28px no-repeat,
          linear-gradient(#000 0 0) top right / 28px 28px no-repeat,
          linear-gradient(#000 0 0) bottom left / 28px 28px no-repeat,
          linear-gradient(#000 0 0) bottom right / 28px 28px no-repeat;
}
.sips-scan-reticle::after {
    content: ""; position: absolute; left: 6%; right: 6%; top: 50%; height: 2px;
    background: var(--brand-600);
    opacity: 0.6;
    animation: sipsScanline 2.2s ease-in-out infinite;
}
@keyframes sipsScanline {
    0%, 100% { transform: translateY(-2.6rem); }
    50%      { transform: translateY(2.6rem); }
}
.sips-scan-reticle.sips-scan-flash::before {
    border-color: var(--success, var(--brand-600));
    opacity: 1;
    transition: opacity 120ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
    .sips-scan-reticle::after { animation: none; display: none; }
}
.sips-scan-hint { color: var(--muted); font-size: 0.8125rem; margin: 0; }
.sips-scan-status {
    color: var(--muted); font-size: 0.8125rem; margin: 0;
    min-height: 1.25rem;                    /* keep layout stable across updates */
}
.sips-scan-actions { display: flex; align-items: center; justify-content: flex-end; gap: 0.5rem; }
.sips-scan-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 0.375rem;
    min-height: 44px; min-width: 44px;      /* touch target */
    padding: 0.5rem 0.875rem;
    background: var(--glass-bg);
    color: var(--text);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-md);
    font-size: 0.8125rem; font-weight: 500; font-family: inherit;
    cursor: pointer;
    transition: border-color 150ms ease-out, background 150ms ease-out;
}
.sips-scan-btn:hover { border-color: var(--brand-600); }
.sips-scan-btn:focus-visible { outline: 2px solid var(--brand-600); outline-offset: 2px; }
.sips-scan-btn[aria-pressed="true"] { background: var(--brand-600); color: #fff; }
@media (prefers-reduced-motion: reduce) {
    .sips-scan-btn { transition: none; }
}

/* ==========================================================================
   RTL affordances (Phase 31) — additive, inert in LTR.
   Every rule below is scoped to [dir="rtl"] so the English (LTR) computed
   style is byte-equivalent; the logical-property migration above mirrors the
   layout for free, and these blocks handle the three things logical props
   can't: glyph flipping, JS-set numeric isolation, and transform sign-flips.
   ========================================================================== */

/* RTL-03 — directional FontAwesome glyphs mirror horizontally.
   CRITICAL (MEMORY app-main-traps-fixed-modals): scaleX(-1) is scoped to the
   .fa-* glyph classes ONLY — never a content wrapper. A retained transform on
   #app-main becomes the containing block for every position:fixed modal/drawer
   and traps them. */
[dir="rtl"] .fa-arrow-left,   [dir="rtl"] .fa-arrow-right,
[dir="rtl"] .fa-chevron-left, [dir="rtl"] .fa-chevron-right,
[dir="rtl"] .fa-angle-left,   [dir="rtl"] .fa-angle-right,
[dir="rtl"] .fa-angles-left,  [dir="rtl"] .fa-angles-right,
[dir="rtl"] .fa-caret-left,   [dir="rtl"] .fa-caret-right {
    transform: scaleX(-1);
}

/* The rec-link hover nudge points along the reading direction — flip its sign
   (do NOT logical-swap a transform value). */
[dir="rtl"] .rec-card:hover .rec-link i { transform: translateX(-2px); }

/* RTL-04 — numeric isolation net. JS sets prices/qty/ids via textContent
   (T-31-01: the XSS posture stays textContent/escapeHtml — no <bdi> injected,
   no innerHTML). unicode-bidi does the isolation purely in CSS so Western-digit
   numerics stay LTR and un-reordered inside RTL flow. */
[dir="rtl"] .rcard td,
[dir="rtl"] .amount,
[dir="rtl"] .ui-meta,
[dir="rtl"] .stat-value,
[dir="rtl"] .rec-id { unicode-bidi: plaintext; }

/* RTL-05 — toast slides in from the inline-end under RTL. Sign-flip the
   transform (mirror of sips-toast-in), never a logical swap. (The exit is now a
   direction-neutral fade + shrink shared by both directions.) */
@keyframes sips-toast-in-rtl {
    from { opacity: 0; transform: translateX(-110%); }
    to   { opacity: 1; transform: translateX(0); }
}
[dir="rtl"] .sips-toast { animation-name: sips-toast-in-rtl; }
