/* =========================================================================
   EGL — Phase 08A theme overlay
   =========================================================================

   WHY THIS FILE EXISTS AND WHY IT IS PLAIN CSS
   --------------------------------------------
   The design system lives in resources/css/app.css and is compiled by Vite
   into public/build/assets/app-*.css. That toolchain is not installed on this
   machine (no node, no npm, no node_modules, no vite.config.js), so the
   bundle CANNOT be rebuilt right now — editing app.css would have no effect
   in the browser at all.

   Phase 08A therefore adds Light mode with the smallest possible blast
   radius:
     * the compiled bundle is never touched, so DARK MODE STAYS BYTE-FOR-BYTE
       IDENTICAL to the frozen Phase 07D-D2 UI;
     * every light rule below is scoped under html[data-theme="light"], so it
       is completely inert unless the user opts in;
     * deleting this file and its <link> tag is a complete rollback.

   Consequence to be aware of: styling now lives in two places. When the
   frontend toolchain is restored in a later phase these overrides should be
   folded back into app.css as proper Tailwind variants and this file deleted.

   NOTHING HERE CHANGES BEHAVIOUR — no business logic, no routing, no data.
   ========================================================================= */

/* ---------------------------------------------------------------- tokens */
html[data-theme='light'] {
    --egl-bg-1: #eef2f8;
    --egl-bg-2: #f7f9fc;
    --egl-bg-3: #e8eef7;

    --egl-surface: #ffffff;
    --egl-surface-2: #f8fafc;
    --egl-surface-3: #f1f5f9;

    --egl-border: #e2e8f0;
    --egl-border-strong: #cbd5e1;

    --egl-text: #0f172a;
    --egl-text-2: #334155;
    --egl-text-3: #475569;
    --egl-text-muted: #64748b;

    --egl-primary: #2563eb;
    --egl-primary-soft: #eff6ff;
    --egl-primary-border: #bfdbfe;

    /* Phase 10A - one token per MEANING, not per colour. A card asks for
       "ok" or "danger" and gets the right shade in either appearance. */
    --egl-ok: #059669;
    --egl-ok-soft: #ecfdf5;
    --egl-ok-border: #a7f3d0;
    --egl-warn: #d97706;
    --egl-warn-soft: #fffbeb;
    --egl-warn-border: #fde68a;
    --egl-danger: #dc2626;
    --egl-danger-soft: #fef2f2;
    --egl-danger-border: #fecaca;

    /* Phase 13C-3d - the ORDER's own facts: how many pieces, and the SMV.
       A meaning of its own, not a borrowed one. Amber already means "look at
       this, something is unset or closed" all through this module, and green
       already means machines; an order quantity is neither a warning nor a
       machine count. Orange, and its own token, so the theme pass can move it
       without moving a warning with it. */
    --egl-order: #ea580c;
    --egl-order-soft: #fff7ed;
    --egl-order-border: #fed7aa;
    --egl-info: #2563eb;
    --egl-info-soft: #eff6ff;
    --egl-info-border: #bfdbfe;
    --egl-muted-tone: #475569;
    --egl-muted-soft: #f1f5f9;
    --egl-muted-border: #cbd5e1;

    /* Phase 10J — one colour per sidebar entry. They are declared for both
       appearances, so the sidebar is coloured the same way in each without a
       single rule having to know which appearance is on. The light values are
       darker than the dark ones on purpose: a pale mint that reads well on
       navy disappears on white. */
    --egl-nav-blue: #2563eb;
    --egl-nav-teal: #0d9488;
    --egl-nav-violet: #7c3aed;
    --egl-nav-red: #dc2626;
    --egl-nav-amber: #b45309;
    --egl-nav-sky: #0284c7;
    --egl-nav-green: #059669;
    --egl-nav-rose: #db2777;
    --egl-nav-slate: #475569;
    /* Phase 13B — the tenth entry. Nine colours were already spoken for, and
       reusing one would undo exactly what 10J-2 fixed: a menu you count down
       instead of read. */
    --egl-nav-indigo: #4f46e5;
    /* Phase 14A — the eleventh entry, Schedule Maintenance. Ten were spoken
       for, so it gets its own rather than borrowing one. */
    --egl-nav-orange: #c2410c;
    /* Phase 17A — the twelfth entry, QCO Status. Eleven were spoken for. */
    --egl-nav-cyan: #0e7490;
    /* Phase 19A-1 — the thirteenth entry, Loan from Group Factories. */
    --egl-nav-lime: #4d7c0f;
    --egl-nav-emerald: #047857;
    /* Phase 26 - the fifteenth entry, Style Layout Split. */
    --egl-nav-purple: #7e22ce;
    /* Phase 48 - the sixteenth entry, Machine Space. */
    --egl-nav-stone: #57534e;
    /* Phase 60 - the seventeenth entry, Monthly Planned Item Details. */
    --egl-nav-fuchsia: #a21caf;

    --egl-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 8px 24px rgba(15, 23, 42, .06);
    --egl-shadow-lg: 0 2px 4px rgba(15, 23, 42, .05), 0 16px 40px rgba(15, 23, 42, .10);

    color-scheme: light;
}

/* Phase 10A — dark is no longer rule-free.
   ---------------------------------------------------------------------------
   Until now the compiled bundle simply WAS the dark theme, and light was 147
   patches laid on top of it. That is why new work never felt like a real
   theme: anything written for one appearance had to be written again for the
   other, and a forgotten colour stayed dark in light mode.

   Dark now declares the SAME token names as light, with dark values. Nothing
   existing changes: every rule that reads these tokens is already scoped under
   html[data-theme='light'] (checked - the only rules outside that scope are
   the .egl-login-* family, and they read their own --egl-login-* tokens). So
   these declarations are inert for the frozen UI and only serve components
   written from here on, which take every colour from a token and therefore
   work in BOTH appearances with one set of rules.

   ThemeTokenParityTest fails the suite if the two blocks ever drift apart. */
html[data-theme='dark'] {
    --egl-bg-1: #0b1220;
    --egl-bg-2: #0f172a;
    --egl-bg-3: #111c2f;

    --egl-surface: #0f172a;
    --egl-surface-2: #141f36;
    --egl-surface-3: #1a2740;

    --egl-border: #1e293b;
    --egl-border-strong: #334155;

    --egl-text: #e2e8f0;
    --egl-text-2: #cbd5e1;
    --egl-text-3: #94a3b8;
    --egl-text-muted: #64748b;

    --egl-primary: #60a5fa;
    --egl-primary-soft: rgba(37, 99, 235, .16);
    --egl-primary-border: rgba(96, 165, 250, .35);

    --egl-ok: #34d399;
    --egl-ok-soft: rgba(16, 185, 129, .14);
    --egl-ok-border: rgba(52, 211, 153, .32);
    --egl-warn: #fbbf24;
    --egl-warn-soft: rgba(245, 158, 11, .14);
    --egl-warn-border: rgba(251, 191, 36, .32);
    --egl-danger: #f87171;
    --egl-danger-soft: rgba(239, 68, 68, .14);
    --egl-danger-border: rgba(248, 113, 113, .32);
    --egl-order: #fb923c;
    --egl-order-soft: rgba(249, 115, 22, .16);
    --egl-order-border: rgba(251, 146, 60, .35);
    --egl-info: #60a5fa;
    --egl-info-soft: rgba(59, 130, 246, .16);
    --egl-info-border: rgba(96, 165, 250, .35);
    --egl-muted-tone: #94a3b8;
    --egl-muted-soft: rgba(148, 163, 184, .12);
    --egl-muted-border: rgba(148, 163, 184, .28);

    /* Phase 10J — the same nine sidebar colours, lifted for a dark ground. */
    --egl-nav-blue: #60a5fa;
    --egl-nav-teal: #2dd4bf;
    --egl-nav-violet: #a78bfa;
    --egl-nav-red: #f87171;
    --egl-nav-amber: #fbbf24;
    --egl-nav-sky: #38bdf8;
    --egl-nav-green: #34d399;
    --egl-nav-rose: #f472b6;
    --egl-nav-slate: #94a3b8;
    /* Phase 13B — lifted for a dark ground, like the nine above it. */
    --egl-nav-indigo: #818cf8;
    /* Phase 14A — lifted for a dark ground, like the ten above it. */
    --egl-nav-orange: #fb923c;
    /* Phase 17A — lifted for a dark ground, like the eleven above it. */
    --egl-nav-cyan: #22d3ee;
    /* Phase 19A-1 — lifted for a dark ground, like the twelve above it. */
    --egl-nav-lime: #a3e635;
    --egl-nav-emerald: #34d399;
    --egl-nav-purple: #c084fc;
    /* Phase 48 - lifted for a dark ground, like the fifteen above it. */
    --egl-nav-stone: #d6d3d1;
    /* Phase 60 - lifted the same way, like the sixteen above it. */
    --egl-nav-fuchsia: #e879f9;

    --egl-shadow: 0 1px 2px rgba(0, 0, 0, .40), 0 8px 24px rgba(0, 0, 0, .32);
    --egl-shadow-lg: 0 2px 4px rgba(0, 0, 0, .45), 0 16px 40px rgba(0, 0, 0, .40);

    color-scheme: dark;
}

/* ============================ shell: body, sidebar, header, cards ======= */
html[data-theme='light'] .egl-body {
    background: linear-gradient(145deg, var(--egl-bg-1) 0%, var(--egl-bg-2) 45%, var(--egl-bg-3) 100%);
    color: var(--egl-text-2);
}

html[data-theme='light'] .egl-sidebar {
    background: linear-gradient(180deg, #ffffff 0%, #f6f9fd 100%);
    border-right-color: var(--egl-border);
    box-shadow: 1px 0 0 rgba(15, 23, 42, .04), 0 10px 30px rgba(15, 23, 42, .05);
}

html[data-theme='light'] .egl-header {
    background: linear-gradient(90deg, rgba(255, 255, 255, .96) 0%, rgba(255, 255, 255, .92) 100%);
    border-bottom-color: var(--egl-border);
}

html[data-theme='light'] .egl-card,
html[data-theme='light'] .egl-card-hover {
    background-color: var(--egl-surface);
    border-color: var(--egl-border);
    box-shadow: var(--egl-shadow);
}

html[data-theme='light'] .egl-card-hover:hover {
    border-color: var(--egl-border-strong);
    box-shadow: var(--egl-shadow-lg);
}

html[data-theme='light'] .egl-card-header {
    border-bottom-color: var(--egl-border);
}

html[data-theme='light'] .egl-section-title {
    color: var(--egl-text);
}

html[data-theme='light'] .egl-section-subtitle {
    color: var(--egl-text-muted);
}

/* ---------------------------------------------------------- navigation */
html[data-theme='light'] .egl-nav-link-inactive {
    color: var(--egl-text-3);
}

html[data-theme='light'] .egl-nav-link-inactive:hover {
    background-color: var(--egl-surface-3);
    color: var(--egl-text);
    border-color: var(--egl-border);
}

html[data-theme='light'] .egl-nav-link-active {
    background-image: linear-gradient(to right, rgba(37, 99, 235, .10), rgba(241, 245, 249, .9));
    color: #1d4ed8;
    border-color: var(--egl-primary-border);
}

html[data-theme='light'] .egl-nav-badge {
    color: #ffffff;
}

/* -------------------------------------------------------------- buttons */
html[data-theme='light'] .egl-btn {
    --tw-ring-offset-color: #ffffff;
}

html[data-theme='light'] .egl-btn-secondary {
    background-color: var(--egl-surface);
    color: var(--egl-text-2);
    border-color: var(--egl-border-strong);
}

html[data-theme='light'] .egl-btn-secondary:hover {
    background-color: var(--egl-surface-3);
    color: var(--egl-text);
}

html[data-theme='light'] .egl-btn-danger {
    background-color: #fef2f2;
    color: #b91c1c;
    border-color: #fecaca;
}

html[data-theme='light'] .egl-btn-danger:hover {
    background-color: #fee2e2;
    color: #991b1b;
}

/* primary / success / alarm already read well on light — only the ring
   offset changes, handled by .egl-btn above. */

/* --------------------------------------------------------- form controls */
html[data-theme='light'] .egl-input {
    background-color: var(--egl-surface);
    border-color: var(--egl-border-strong);
    color: var(--egl-text);
}

html[data-theme='light'] .egl-input::placeholder {
    color: #94a3b8;
}

html[data-theme='light'] .egl-label {
    color: var(--egl-text-3);
}

html[data-theme='light'] select.egl-input option {
    background-color: var(--egl-surface);
    color: var(--egl-text);
}

/* --------------------------------------------------------------- tables */
html[data-theme='light'] .egl-table thead {
    background-color: var(--egl-surface-3);
    color: var(--egl-text-muted);
}

html[data-theme='light'] .egl-table tbody > :not([hidden]) ~ :not([hidden]) {
    border-color: var(--egl-border);
}

html[data-theme='light'] .egl-table tbody tr:hover {
    background-color: #f8fafc;
}

html[data-theme='light'] .egl-table td {
    color: var(--egl-text-2);
}

/* --------------------------------------------------------- alerts, badges */
html[data-theme='light'] .egl-alert-success {
    background-color: #ecfdf5;
    border-color: #a7f3d0;
    color: #047857;
}

html[data-theme='light'] .egl-alert-error {
    background-color: #fef2f2;
    border-color: #fecaca;
    color: #b91c1c;
}

html[data-theme='light'] .egl-alert-warning {
    background-color: #fffbeb;
    border-color: #fde68a;
    color: #b45309;
}

html[data-theme='light'] .egl-badge-success,
html[data-theme='light'] .egl-badge-free {
    background-color: #ecfdf5;
    color: #047857;
    border-color: #a7f3d0;
}

html[data-theme='light'] .egl-badge-warning {
    background-color: #fffbeb;
    color: #b45309;
    border-color: #fde68a;
}

html[data-theme='light'] .egl-badge-danger {
    background-color: #fef2f2;
    color: #b91c1c;
    border-color: #fecaca;
}

html[data-theme='light'] .egl-badge-info,
html[data-theme='light'] .egl-badge-released {
    background-color: var(--egl-primary-soft);
    color: #1d4ed8;
    border-color: var(--egl-primary-border);
}

html[data-theme='light'] .egl-badge-neutral {
    background-color: var(--egl-surface-3);
    color: var(--egl-text-3);
    border-color: var(--egl-border);
}

html[data-theme='light'] .egl-badge-engaged {
    background-color: #fff7ed;
    color: #c2410c;
    border-color: #fed7aa;
}

/* ------------------------------------------------------ progress, guest */
html[data-theme='light'] .egl-progress-track {
    background-color: var(--egl-surface-3);
    border-color: var(--egl-border);
}

html[data-theme='light'] .egl-guest-card {
    background: linear-gradient(160deg, #ffffff 0%, #fbfdff 100%);
    border-color: var(--egl-border);
    box-shadow: var(--egl-shadow-lg);
}

html[data-theme='light'] .egl-guest-card label {
    color: var(--egl-text-3);
}

html[data-theme='light'] .egl-login-divider::before,
html[data-theme='light'] .egl-login-divider::after {
    background-color: var(--egl-border);
}

/* =========================================================================
   Raw Tailwind utilities used directly in the Blade markup.

   The Blade files were authored for a dark-only UI, so they use utilities
   like text-white / bg-slate-800 / border-slate-700 inline. Those cannot be
   recompiled, so they are remapped here for light mode only. Selector
   specificity (html[data-theme] + class) beats the single-class utility in
   the bundle, so no !important is needed anywhere.
   ========================================================================= */

/* ------------------------------------------------------------------ text */
html[data-theme='light'] .text-white { color: var(--egl-text); }
html[data-theme='light'] .text-slate-200 { color: var(--egl-text-2); }
html[data-theme='light'] .text-slate-300 { color: var(--egl-text-2); }
html[data-theme='light'] .text-slate-400 { color: var(--egl-text-3); }
html[data-theme='light'] .text-slate-500 { color: var(--egl-text-muted); }
html[data-theme='light'] .text-slate-600 { color: #94a3b8; }

html[data-theme='light'] .hover\:text-white:hover { color: var(--egl-text); }
html[data-theme='light'] .hover\:text-slate-300:hover { color: var(--egl-text-2); }
html[data-theme='light'] .group:hover .group-hover\:text-white { color: var(--egl-text); }

/* Safety net: if any element ever combines a saturated background with
   text-white, keep the white so the label can never disappear. (Verified: no
   such combination exists in the current Blade files — this only guards
   future markup.) */
html[data-theme='light'] [class*='bg-blue-6'].text-white,
html[data-theme='light'] [class*='bg-blue-7'].text-white,
html[data-theme='light'] [class*='bg-red-6'].text-white,
html[data-theme='light'] [class*='bg-red-7'].text-white,
html[data-theme='light'] [class*='bg-emerald-6'].text-white,
html[data-theme='light'] [class*='bg-emerald-7'].text-white,
html[data-theme='light'] [class*='bg-amber-6'].text-white,
html[data-theme='light'] [class*='bg-orange-6'].text-white,
html[data-theme='light'] [class*='bg-indigo-6'].text-white {
    color: #ffffff;
}

/* ------------------------------------------------------------ backgrounds */
html[data-theme='light'] .bg-slate-800 { background-color: var(--egl-surface-3); }
html[data-theme='light'] .bg-slate-800\/30 { background-color: rgba(241, 245, 249, .6); }
html[data-theme='light'] .bg-slate-800\/40 { background-color: rgba(241, 245, 249, .7); }
html[data-theme='light'] .bg-slate-800\/50 { background-color: rgba(241, 245, 249, .8); }
html[data-theme='light'] .bg-slate-800\/60 { background-color: rgba(241, 245, 249, .85); }
html[data-theme='light'] .bg-slate-800\/80 { background-color: rgba(241, 245, 249, .95); }
html[data-theme='light'] .bg-slate-700 { background-color: #e2e8f0; }
html[data-theme='light'] .bg-slate-700\/10 { background-color: rgba(226, 232, 240, .5); }
html[data-theme='light'] .bg-slate-700\/60 { background-color: rgba(226, 232, 240, .8); }
html[data-theme='light'] .bg-slate-900\/40 { background-color: rgba(248, 250, 252, .8); }
html[data-theme='light'] .bg-slate-900\/60 { background-color: rgba(248, 250, 252, .9); }

html[data-theme='light'] .hover\:bg-slate-800:hover { background-color: var(--egl-surface-3); }
html[data-theme='light'] .hover\:bg-slate-800\/60:hover { background-color: rgba(241, 245, 249, .85); }
html[data-theme='light'] .hover\:bg-slate-800\/70:hover { background-color: rgba(241, 245, 249, .9); }

/* Scrims stay dark in both themes so overlaid panels keep their contrast. */
html[data-theme='light'] .bg-black\/60 { background-color: rgba(15, 23, 42, .38); }
html[data-theme='light'] .bg-black\/70 { background-color: rgba(15, 23, 42, .45); }

/* --------------------------------------------------------------- borders */
html[data-theme='light'] .border-slate-600 { border-color: var(--egl-border-strong); }
html[data-theme='light'] .border-slate-700,
html[data-theme='light'] .border-slate-700\/40,
html[data-theme='light'] .border-slate-700\/50,
html[data-theme='light'] .border-slate-700\/60,
html[data-theme='light'] .border-slate-800,
html[data-theme='light'] .border-slate-800\/60,
html[data-theme='light'] .border-slate-800\/80,
html[data-theme='light'] .border-slate-500\/30 { border-color: var(--egl-border); }

html[data-theme='light'] .hover\:border-slate-600\/60:hover,
html[data-theme='light'] .hover\:border-slate-600\/80:hover,
html[data-theme='light'] .hover\:border-slate-700\/50:hover { border-color: var(--egl-border-strong); }

html[data-theme='light'] .divide-slate-800\/80 > :not([hidden]) ~ :not([hidden]) { border-color: var(--egl-border); }

html[data-theme='light'] .placeholder-slate-500::placeholder { color: #94a3b8; }

/* ------------------------------------------------------------- gradients */
html[data-theme='light'] .from-slate-700 { --tw-gradient-from: #e2e8f0; --tw-gradient-to: rgba(226, 232, 240, 0); }
html[data-theme='light'] .from-slate-800\/60 { --tw-gradient-from: rgba(241, 245, 249, .7); --tw-gradient-to: rgba(241, 245, 249, 0); }
html[data-theme='light'] .from-slate-800\/80 { --tw-gradient-from: rgba(241, 245, 249, .9); --tw-gradient-to: rgba(241, 245, 249, 0); }
html[data-theme='light'] .to-slate-700 { --tw-gradient-to: #e2e8f0; }
html[data-theme='light'] .to-slate-800 { --tw-gradient-to: #eef2f7; }
html[data-theme='light'] .to-slate-800\/20 { --tw-gradient-to: rgba(241, 245, 249, .35); }
html[data-theme='light'] .to-slate-900 { --tw-gradient-to: #e9eef6; }

/* --------------------------------------------------------- focus rings */
html[data-theme='light'] .focus\:ring-offset-slate-900:focus { --tw-ring-offset-color: #ffffff; }

/* =========================================================================
   Settings > Appearance
   -------------------------------------------------------------------------
   Self-contained styles. The Settings page is new in Phase 08A, and the
   compiled Tailwind bundle only contains classes that existed when it was
   built, so this page deliberately uses its own egl-settings-* classes plus
   the pre-existing egl-* components. Dark values are the default; the
   html[data-theme='light'] block that follows adapts them.
   ========================================================================= */
.egl-settings-grid {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr;
}

@media (min-width: 640px) {
    .egl-settings-grid { grid-template-columns: 1fr 1fr; }
}

.egl-theme-option {
    position: relative;
    display: block;
    cursor: pointer;
    border-radius: .875rem;
    border: 1px solid rgba(51, 65, 85, .8);
    background-color: rgba(15, 23, 42, .5);
    padding: 1rem;
    transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}

.egl-theme-option:hover { border-color: rgba(71, 85, 105, .9); }

.egl-theme-option input[type='radio'] {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    pointer-events: none;
}

.egl-theme-option.is-selected {
    border-color: #3b82f6;
    box-shadow: 0 0 0 1px #3b82f6 inset, 0 8px 24px rgba(37, 99, 235, .18);
    background-color: rgba(30, 58, 138, .18);
}

.egl-theme-option:focus-within {
    outline: 2px solid #60a5fa;
    outline-offset: 2px;
}

.egl-theme-option__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin-top: .875rem;
}

.egl-theme-option__name {
    font-size: .875rem;
    font-weight: 600;
    color: #ffffff;
}

.egl-theme-option__desc {
    font-size: .75rem;
    color: #94a3b8;
    margin-top: .125rem;
}

.egl-theme-option__check {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
    border-radius: 9999px;
    border: 1px solid rgba(71, 85, 105, .9);
    color: transparent;
    font-size: .7rem;
    line-height: 1;
    flex-shrink: 0;
}

.egl-theme-option.is-selected .egl-theme-option__check {
    background-color: #2563eb;
    border-color: #2563eb;
    color: #ffffff;
}

/* Miniature preview of each theme, drawn with plain CSS so it stays accurate
   without shipping screenshots. */
.egl-theme-preview {
    border-radius: .625rem;
    overflow: hidden;
    border: 1px solid rgba(51, 65, 85, .7);
    display: flex;
    height: 88px;
}

.egl-theme-preview__side { width: 34%; padding: .5rem; }
.egl-theme-preview__main { flex: 1; padding: .5rem; display: flex; flex-direction: column; gap: .375rem; }
.egl-theme-preview__bar { height: 6px; border-radius: 3px; }
.egl-theme-preview__card { height: 26px; border-radius: 5px; border: 1px solid; }

.egl-theme-preview--dark { background: linear-gradient(145deg, #020617 0%, #0f172a 45%, #0c1929 100%); }
.egl-theme-preview--dark .egl-theme-preview__side { background: linear-gradient(180deg, #0f172a 0%, #0b1220 100%); }
.egl-theme-preview--dark .egl-theme-preview__bar { background-color: #334155; }
.egl-theme-preview--dark .egl-theme-preview__bar--accent { background-color: #2563eb; }
.egl-theme-preview--dark .egl-theme-preview__card { background-color: rgba(15, 23, 42, .8); border-color: rgba(30, 41, 59, .8); }

.egl-theme-preview--light { background: linear-gradient(145deg, #eef2f8 0%, #f7f9fc 45%, #e8eef7 100%); }
.egl-theme-preview--light .egl-theme-preview__side { background: linear-gradient(180deg, #ffffff 0%, #f6f9fd 100%); }
.egl-theme-preview--light .egl-theme-preview__bar { background-color: #cbd5e1; }
.egl-theme-preview--light .egl-theme-preview__bar--accent { background-color: #2563eb; }
.egl-theme-preview--light .egl-theme-preview__card { background-color: #ffffff; border-color: #e2e8f0; }

.egl-settings-note {
    font-size: .75rem;
    color: #64748b;
    margin-top: 1rem;
    line-height: 1.6;
}

/* ------------------------------- Settings page, light theme adaptations */
html[data-theme='light'] .egl-theme-option {
    border-color: var(--egl-border);
    background-color: var(--egl-surface-2);
}

html[data-theme='light'] .egl-theme-option:hover { border-color: var(--egl-border-strong); }

html[data-theme='light'] .egl-theme-option.is-selected {
    border-color: #2563eb;
    background-color: var(--egl-primary-soft);
    box-shadow: 0 0 0 1px #2563eb inset, 0 8px 24px rgba(37, 99, 235, .12);
}

html[data-theme='light'] .egl-theme-option__name { color: var(--egl-text); }
html[data-theme='light'] .egl-theme-option__desc { color: var(--egl-text-muted); }
html[data-theme='light'] .egl-theme-option__check { border-color: var(--egl-border-strong); }
html[data-theme='light'] .egl-theme-preview { border-color: var(--egl-border); }
html[data-theme='light'] .egl-settings-note { color: var(--egl-text-muted); }

/* --------------------------------------------------- misc light polish */
html[data-theme='light'] ::selection { background-color: #bfdbfe; color: #0f172a; }

html[data-theme='light'] ::-webkit-scrollbar-track { background-color: var(--egl-surface-3); }
html[data-theme='light'] ::-webkit-scrollbar-thumb { background-color: var(--egl-border-strong); border-radius: 9999px; }

/* =========================================================================
   Phase 08B — Mechanic Contact List cards
   -------------------------------------------------------------------------
   Presentation only. Every value shown comes from data the page already had
   (Mechanic columns plus the model's own activeEngagementAlarm()); no field
   is invented, no controller, query or business rule is changed.

   Same reasoning as Phase 08A: the Tailwind bundle cannot be rebuilt, so a
   card design cannot rely on utility classes that were not already compiled.
   These egl-mech-* classes are new, exist nowhere in the bundle, and
   therefore cannot repaint any frozen UI. Dark values are the default; the
   light block at the end adapts them.
   ========================================================================= */
.egl-mech-grid {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr;
}

@media (min-width: 768px) {
    .egl-mech-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1280px) {
    .egl-mech-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.egl-mech-card {
    position: relative;
    display: flex;
    flex-direction: column;
    border-radius: .875rem;
    border: 1px solid rgba(30, 41, 59, .8);
    background-color: rgba(15, 23, 42, .8);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .12);
    overflow: hidden;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}

.egl-mech-card:hover {
    border-color: rgba(51, 65, 85, .9);
    box-shadow: 0 16px 40px rgba(0, 0, 0, .2);
}

/* The left edge carries availability at a glance, so a wall of cards can be
   scanned without reading a single word. */
.egl-mech-card::before {
    content: '';
    position: absolute;
    inset: 0 auto 0 0;
    width: 4px;
    background-color: #475569;
}

.egl-mech-card--free::before { background-color: #10b981; }
.egl-mech-card--engaged::before { background-color: #f97316; }
.egl-mech-card--off::before { background-color: #64748b; }

.egl-mech-card__top {
    display: flex;
    align-items: flex-start;
    gap: .875rem;
    padding: 1.125rem 1.125rem .875rem 1.375rem;
}

.egl-mech-avatar {
    width: 3.25rem;
    height: 3.25rem;
    border-radius: 9999px;
    flex-shrink: 0;
    overflow: hidden;
    border: 2px solid rgba(51, 65, 85, .9);
    background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    color: #64748b;
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: .02em;
}

.egl-mech-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.egl-mech-identity { min-width: 0; flex: 1; }

.egl-mech-identity__name {
    display: block;
    font-size: .9375rem;
    font-weight: 600;
    color: #ffffff;
    line-height: 1.3;
    overflow-wrap: anywhere;
}

.egl-mech-identity__meta {
    display: block;
    font-size: .75rem;
    color: #94a3b8;
    margin-top: .1875rem;
    overflow-wrap: anywhere;
}

.egl-mech-identity__id {
    display: inline-block;
    font-size: .6875rem;
    letter-spacing: .04em;
    color: #64748b;
    margin-top: .25rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* Availability pill — the single most important thing on the card. */
.egl-mech-state {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    flex-shrink: 0;
    padding: .25rem .5625rem;
    border-radius: 9999px;
    border: 1px solid transparent;
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .01em;
    white-space: nowrap;
}

.egl-mech-state__dot {
    width: .4375rem;
    height: .4375rem;
    border-radius: 9999px;
    background-color: currentColor;
    flex-shrink: 0;
}

.egl-mech-state--free {
    background-color: rgba(6, 78, 59, .5);
    border-color: rgba(6, 95, 70, .5);
    color: #6ee7b7;
}

.egl-mech-state--engaged {
    background-color: rgba(124, 45, 18, .5);
    border-color: rgba(154, 52, 18, .5);
    color: #fdba74;
}

.egl-mech-state--leave {
    background-color: rgba(30, 58, 138, .45);
    border-color: rgba(30, 64, 175, .45);
    color: #93c5fd;
}

.egl-mech-state--inactive {
    background-color: rgba(30, 41, 59, .8);
    border-color: rgba(51, 65, 85, .7);
    color: #cbd5e1;
}

.egl-mech-body {
    padding: 0 1.125rem .875rem 1.375rem;
    display: flex;
    flex-direction: column;
    gap: .5rem;
    flex: 1;
}

.egl-mech-row {
    display: flex;
    align-items: baseline;
    gap: .75rem;
    font-size: .8125rem;
}

.egl-mech-row__label {
    width: 4.5rem;
    flex-shrink: 0;
    font-size: .625rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: #64748b;
    font-weight: 500;
}

.egl-mech-row__value {
    color: #cbd5e1;
    min-width: 0;
    overflow-wrap: anywhere;
}

.egl-mech-row__value a { color: inherit; text-decoration: none; }
.egl-mech-row__value a:hover { color: #ffffff; text-decoration: underline; }

.egl-mech-blocks { display: flex; flex-wrap: wrap; gap: .3125rem; }

.egl-mech-chip {
    display: inline-flex;
    align-items: center;
    padding: .0625rem .4375rem;
    border-radius: .3125rem;
    font-size: .6875rem;
    background-color: rgba(30, 41, 59, .9);
    border: 1px solid rgba(51, 65, 85, .7);
    color: #cbd5e1;
}

/* Shown only while the mechanic is engaged: which breakdown is holding them. */
.egl-mech-job {
    margin: 0 1.125rem .875rem 1.375rem;
    padding: .625rem .75rem;
    border-radius: .625rem;
    border: 1px solid rgba(154, 52, 18, .4);
    background-color: rgba(124, 45, 18, .22);
    font-size: .75rem;
    color: #fdba74;
    display: block;
    text-decoration: none;
    transition: background-color .15s ease;
}

.egl-mech-job:hover { background-color: rgba(124, 45, 18, .35); }

.egl-mech-job__label {
    display: block;
    font-size: .625rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    opacity: .8;
    margin-bottom: .1875rem;
}

.egl-mech-job__value { display: block; font-weight: 600; overflow-wrap: anywhere; }

.egl-mech-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    padding: .8125rem 1.125rem .8125rem 1.375rem;
    border-top: 1px solid rgba(30, 41, 59, .8);
    background-color: rgba(2, 6, 23, .3);
    margin-top: auto;
}

.egl-mech-actions form { display: inline-flex; }

.egl-mech-empty {
    grid-column: 1 / -1;
    padding: 3rem 1rem;
    text-align: center;
    color: #64748b;
    font-size: .875rem;
    border: 1px dashed rgba(51, 65, 85, .7);
    border-radius: .875rem;
}

/* ---------------------------------------- mechanic cards, light theme */
html[data-theme='light'] .egl-mech-card {
    background-color: var(--egl-surface);
    border-color: var(--egl-border);
    box-shadow: var(--egl-shadow);
}

html[data-theme='light'] .egl-mech-card:hover {
    border-color: var(--egl-border-strong);
    box-shadow: var(--egl-shadow-lg);
}

html[data-theme='light'] .egl-mech-avatar {
    background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
    border-color: var(--egl-border);
    color: var(--egl-text-muted);
}

html[data-theme='light'] .egl-mech-identity__name { color: var(--egl-text); }
html[data-theme='light'] .egl-mech-identity__meta { color: var(--egl-text-muted); }
html[data-theme='light'] .egl-mech-identity__id { color: #94a3b8; }
html[data-theme='light'] .egl-mech-row__label { color: #94a3b8; }
html[data-theme='light'] .egl-mech-row__value { color: var(--egl-text-2); }
html[data-theme='light'] .egl-mech-row__value a:hover { color: var(--egl-text); }

html[data-theme='light'] .egl-mech-chip {
    background-color: var(--egl-surface-3);
    border-color: var(--egl-border);
    color: var(--egl-text-3);
}

html[data-theme='light'] .egl-mech-state--free {
    background-color: #ecfdf5;
    border-color: #a7f3d0;
    color: #047857;
}

html[data-theme='light'] .egl-mech-state--engaged {
    background-color: #fff7ed;
    border-color: #fed7aa;
    color: #c2410c;
}

html[data-theme='light'] .egl-mech-state--leave {
    background-color: var(--egl-primary-soft);
    border-color: var(--egl-primary-border);
    color: #1d4ed8;
}

html[data-theme='light'] .egl-mech-state--inactive {
    background-color: var(--egl-surface-3);
    border-color: var(--egl-border);
    color: var(--egl-text-3);
}

html[data-theme='light'] .egl-mech-job {
    background-color: #fff7ed;
    border-color: #fed7aa;
    color: #c2410c;
}

html[data-theme='light'] .egl-mech-job:hover { background-color: #ffedd5; }

html[data-theme='light'] .egl-mech-actions {
    border-top-color: var(--egl-border);
    background-color: var(--egl-surface-2);
}

html[data-theme='light'] .egl-mech-empty {
    color: var(--egl-text-muted);
    border-color: var(--egl-border-strong);
}


/* ============================================================================
   PHASE 08F - LOGIN / GUEST PAGES
   ============================================================================
   A two-column shell: a brand panel carrying the sewing-machine line art and
   the credits, beside the form column. It collapses to a single column on
   narrow screens, where the brand panel becomes a compact header.

   Every selector below starts with .egl-login- on purpose. None of these
   classes exist in the compiled Vite bundle, so they cannot repaint any frozen
   screen, and they can safely be styled for both themes in one place instead
   of being split across a light-only block.

   The artwork is inline SVG rather than an image file: nothing to upload,
   nothing that can 404, sharp at any density, and it inherits currentColor so
   it recolours itself for light and dark with no second asset.
   ========================================================================= */

.egl-login-shell {
    --egl-login-ink: #eef4ff;
    --egl-login-muted: #93a9ca;
    --egl-login-dim: #63799e;
    --egl-login-line: rgba(96, 150, 235, 0.18);
    --egl-login-panel-a: #081428;
    --egl-login-panel-b: #050d1e;
    --egl-login-accent: #2f7dfb;
    --egl-login-accent-2: #5aa2ff;
    --egl-login-glow: rgba(47, 125, 251, 0.4);

    min-height: 100vh;
    display: grid;
    grid-template-columns: 1.05fr 0.95fr;
}

html[data-theme='light'] .egl-login-shell {
    --egl-login-muted: #4d6488;
    --egl-login-dim: #7d90ad;
    --egl-login-line: rgba(25, 80, 165, 0.16);
    --egl-login-accent: #1a63e0;
    --egl-login-accent-2: #2f7dfb;
    --egl-login-glow: rgba(26, 99, 224, 0.2);
}

/* --- brand panel --------------------------------------------------------- */

.egl-login-brand {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    padding: 46px 44px;
    color: var(--egl-login-ink);
    background:
        radial-gradient(900px 500px at 20% 15%, rgba(47, 125, 251, 0.22), transparent 62%),
        linear-gradient(160deg, var(--egl-login-panel-a), var(--egl-login-panel-b));
}

.egl-login-art {
    position: absolute;
    inset: 0;
    opacity: 0.5;
    pointer-events: none;
    color: rgba(120, 175, 255, 0.24);
}

.egl-login-art__dots {
    position: absolute;
    inset: 0;
    background-image: radial-gradient(rgba(120, 175, 255, 0.16) 1px, transparent 1px);
    background-size: 26px 26px;
    mask-image: linear-gradient(160deg, #000, transparent 70%);
    -webkit-mask-image: linear-gradient(160deg, #000, transparent 70%);
}

.egl-login-art__big {
    position: absolute;
    bottom: -18px;
    left: -40px;
    width: 430px;
    max-width: 70%;
}

.egl-login-art__small {
    position: absolute;
    top: 70px;
    right: -30px;
    width: 230px;
    transform: scaleX(-1);
}

.egl-login-eyebrow {
    position: relative;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.34em;
    text-transform: uppercase;
    color: var(--egl-login-accent-2);
}

/* Phase 45 — the factory's own name, under the portal's name on the login
   page. It reads its colour from the same login tokens as everything else in
   this panel, so light mood is already handled where those tokens are
   redefined; nothing here is a hard-coded colour. */

.egl-login-factory {
    position: relative;
    max-width: 30ch;
    margin: 0 0 14px;
    font-size: 27px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.2px;
    color: var(--egl-login-accent-2);
    /* A factory name is somebody else's words and can be long, or one long
       word. It wraps onto a second line rather than running off the panel. */
    overflow-wrap: break-word;
}

/* ===================================================================
   Phase 48 - Machine Space. A line's floor shown the way a phone shows
   its storage, which is how Aomith asked for it: "space over hoye gele
   warning dekhabe jevabe mobile er space over hoye gele warning dei".

   Every colour here is a meaning token, so light mood is already handled
   where those tokens are redefined. Nothing is a hard-coded colour, and no rule
   here shouts over the compiled bundle.
   =================================================================== */
.egl-msp-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px;
    margin-top: 14px;
}

.egl-msp-tile {
    display: block;
    padding: 14px 16px;
    border: 1px solid var(--egl-border);
    border-radius: 14px;
    background: var(--egl-surface-2);
}

.egl-msp-tile--over {
    border-color: var(--egl-danger-border);
    background: var(--egl-danger-soft);
}

.egl-msp-tile--tight {
    border-color: var(--egl-warn-border);
    background: var(--egl-warn-soft);
}

.egl-msp-tile-n {
    display: block;
    font-size: 26px;
    font-weight: 800;
    line-height: 1.1;
    color: var(--egl-text);
}

.egl-msp-tile-l {
    display: block;
    margin-top: 3px;
    font-size: 12px;
    line-height: 1.35;
    color: var(--egl-text-muted);
}

.egl-msp-bar {
    position: relative;
    height: 12px;
    border-radius: 999px;
    background: var(--egl-surface-3);
    border: 1px solid var(--egl-border);
    overflow: hidden;
}

.egl-msp-bar-fill {
    height: 100%;
    border-radius: 999px;
    background: var(--egl-ok);
    transition: width 420ms ease;
}

.egl-msp-bar-fill--tight { background: var(--egl-warn); }

.egl-msp-bar-fill--over {
    background: var(--egl-danger);
    animation: egl-msp-pulse 1.6s ease-in-out infinite;
}

@keyframes egl-msp-pulse {
    0%   { opacity: 1; }
    50%  { opacity: 0.55; }
    100% { opacity: 1; }
}

.egl-msp-row {
    padding: 14px 16px;
    border: 1px solid var(--egl-border);
    border-radius: 14px;
    background: var(--egl-surface-2);
    margin-bottom: 10px;
}

.egl-msp-row--over {
    border-color: var(--egl-danger-border);
    box-shadow: 0 0 0 3px var(--egl-danger-soft);
}

.egl-msp-row--tight { border-color: var(--egl-warn-border); }

.egl-msp-line {
    font-size: 17px;
    font-weight: 700;
    color: var(--egl-text);
}

.egl-msp-sub {
    font-size: 12px;
    color: var(--egl-text-muted);
}

.egl-msp-pct {
    font-size: 20px;
    font-weight: 800;
    color: var(--egl-text);
}

.egl-msp-pct--over { color: var(--egl-danger); }

.egl-msp-pct--tight { color: var(--egl-warn); }

.egl-msp-alert {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    margin-top: 10px;
    padding: 10px 12px;
    border: 1px solid var(--egl-danger-border);
    border-radius: 10px;
    background: var(--egl-danger-soft);
    font-size: 13px;
    line-height: 1.5;
    color: var(--egl-text-2);
}

.egl-msp-alert--warn {
    border-color: var(--egl-warn-border);
    background: var(--egl-warn-soft);
}

.egl-msp-alert--info {
    border-color: var(--egl-info-border);
    background: var(--egl-info-soft);
}

.egl-msp-alert-dot {
    flex: none;
    width: 10px;
    height: 10px;
    margin-top: 5px;
    border-radius: 999px;
    background: var(--egl-danger);
    animation: egl-msp-pulse 1.6s ease-in-out infinite;
}

.egl-msp-alert--warn .egl-msp-alert-dot { background: var(--egl-warn); animation: none; }

.egl-msp-alert--info .egl-msp-alert-dot { background: var(--egl-info); animation: none; }

.egl-msp-mode {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border: 1px solid var(--egl-border);
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--egl-text-muted);
}

.egl-msp-mode--idle {
    border-color: var(--egl-warn-border);
    background: var(--egl-warn-soft);
    color: var(--egl-warn);
}

@media (prefers-reduced-motion: reduce) {
    .egl-msp-bar-fill--over,
    .egl-msp-alert-dot { animation: none; }
}

/* Phase 53 - the module's three pages as one strip. Colours are meaning
   tokens, so light mood needs nothing extra. */
.egl-msp-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.egl-msp-tab {
    display: inline-flex;
    align-items: center;
    padding: 7px 14px;
    border: 1px solid var(--egl-border);
    border-radius: 999px;
    background: var(--egl-surface-2);
    color: var(--egl-text-muted);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}

.egl-msp-tab:hover {
    background: var(--egl-surface-3);
    color: var(--egl-text);
}

.egl-msp-tab--on {
    background: var(--egl-info-soft);
    border-color: var(--egl-info);
    color: var(--egl-info);
}

/* Phase 52 - the measurements page. A row of small numbered boxes that wraps
   on a phone instead of squeezing, with each box's label above it. The boxes
   are egl-input, which is width:100%, so each one needs a width of its own
   here or a three-character number takes the whole row. */
.egl-msp-form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px;
}

.egl-msp-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    width: 8.5rem;
}

.egl-msp-field .egl-label {
    margin: 0;
}

.egl-msp-form .egl-btn-primary,
.egl-msp-form .egl-btn-secondary {
    margin-bottom: 1px;
}

@media (max-width: 480px) {
    .egl-msp-field { width: calc(50% - 5px); }
}

.egl-login-title {
    position: relative;
    margin: 12px 0 6px;
    font-size: 54px;
    font-weight: 800;
    line-height: 1.04;
    letter-spacing: -1.2px;
}

.egl-login-tagline {
    position: relative;
    max-width: 34ch;
    font-size: 16px;
    line-height: 1.55;
    color: #a9c1e4;
}

.egl-login-stats {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 34px;
}

.egl-login-stat {
    min-width: 104px;
    padding: 14px 18px;
    border-radius: 13px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(140, 190, 255, 0.18);
}

.egl-login-stat b {
    display: block;
    font-size: 23px;
    font-weight: 800;
}

.egl-login-stat span {
    font-size: 11px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #9fb8dd;
}

.egl-login-spacer {
    flex: 1;
    min-height: 26px;
}

.egl-login-credits {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    gap: 28px;
    padding-top: 22px;
    border-top: 1px solid rgba(140, 190, 255, 0.16);
}

.egl-login-credit {
    max-width: 210px;
}

.egl-login-credit__cap {
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--egl-login-accent-2);
}

.egl-login-credit__name {
    margin: 5px 0 2px;
    font-size: 13px;
    font-weight: 600;
    color: var(--egl-login-ink);
}

.egl-login-credit__role {
    font-size: 11px;
    line-height: 1.5;
    color: #8ba4c8;
}

/* --- form column --------------------------------------------------------- */

.egl-login-main {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 44px 22px;
}

.egl-login-col {
    width: 100%;
    max-width: 412px;
}

.egl-login-apk {
    display: flex;
    align-items: center;
    gap: 13px;
    margin-bottom: 22px;
    padding: 13px 15px;
    border-radius: 13px;
    color: #fff;
    text-decoration: none;
    background: linear-gradient(100deg, var(--egl-login-accent), var(--egl-login-accent-2));
    box-shadow: 0 10px 28px -12px var(--egl-login-glow);
    transition: transform 0.16s ease, box-shadow 0.16s ease;
}

.egl-login-apk:hover,
.egl-login-apk:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 16px 34px -14px var(--egl-login-glow);
}

.egl-login-apk__icon {
    flex: none;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    display: grid;
    place-items: center;
    background: rgba(255, 255, 255, 0.18);
}

.egl-login-apk__text {
    flex: 1;
    min-width: 0;
}

.egl-login-apk__text b {
    display: block;
    font-size: 14px;
    font-weight: 700;
}

.egl-login-apk__text span {
    font-size: 11.5px;
    opacity: 0.86;
}

.egl-login-apk__go {
    flex: none;
    display: grid;
    place-items: center;
}

.egl-login-card {
    padding: 28px 26px;
}

.egl-login-head {
    margin-bottom: 24px;
}

.egl-login-head__title {
    font-size: 27px;
    font-weight: 800;
    letter-spacing: -0.4px;
    color: var(--egl-login-ink);
}

html[data-theme='light'] .egl-login-head__title {
    color: #0e1b30;
}

.egl-login-head__lead {
    margin-top: 7px;
    font-size: 14px;
    color: var(--egl-login-muted);
}

.egl-login-pw {
    position: relative;
}

.egl-login-pw input {
    padding-right: 42px;
}

.egl-login-pw__eye {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--egl-login-dim);
    cursor: pointer;
    transition: color 0.15s ease;
}

.egl-login-pw__eye:hover,
.egl-login-pw__eye.is-revealed {
    color: var(--egl-login-accent-2);
}

.egl-login-link {
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    color: var(--egl-login-accent-2);
    transition: opacity 0.15s ease;
}

.egl-login-link:hover {
    opacity: 0.8;
}

.egl-login-submit {
    font-size: 15px;
}

.egl-login-copy {
    margin-top: 24px;
    text-align: center;
    font-size: 11px;
    color: var(--egl-login-dim);
}

/* --- narrow screens ------------------------------------------------------ */

@media (max-width: 900px) {
    .egl-login-shell {
        grid-template-columns: 1fr;
    }

    .egl-login-brand {
        padding: 34px 24px 30px;
    }

    .egl-login-title {
        font-size: 36px;
    }

    .egl-login-factory {
        max-width: none;
        font-size: 20px;
    }

    .egl-login-tagline {
        font-size: 14px;
    }

    .egl-login-stats {
        margin-top: 24px;
    }

    .egl-login-spacer {
        display: none;
    }

    .egl-login-credits {
        display: none;
    }

    .egl-login-art__small {
        display: none;
    }

    .egl-login-art__big {
        bottom: -30px;
        left: -50px;
        width: 300px;
    }

    .egl-login-main {
        padding: 26px 18px 40px;
    }
}

@media (max-width: 420px) {
    .egl-login-stat {
        min-width: 88px;
        padding: 11px 14px;
    }

    .egl-login-card {
        padding: 24px 20px;
    }
}


/* --- optional photograph behind the brand panel -------------------------- *
 * Drop a picture at public/images/login-floor.jpg and the panel switches from
 * the drawn artwork to that photograph on its own. Nothing else changes, and
 * if the file is absent the line art simply stays - so the page never depends
 * on an image being uploaded first.
 *
 * The photo sits under two layers on purpose: it is dimmed, then a diagonal
 * scrim is laid over it. That is what keeps the white brand text readable no
 * matter how bright or busy the picture turns out to be, which a photograph
 * alone can never guarantee.
 */

.egl-login-brand--photo::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    background-image: var(--egl-login-photo);
    background-size: cover;
    /* The supplied photograph is a wide frame with the machine on its left and
       open, almost empty darkness on its right. The panel it has to fill is a
       tall column with all the wording down the left edge, so the picture is
       mirrored: the machine lands on the open right side of the panel and its
       own dark negative space becomes the bed the text sits on. The 26% offset
       keeps the whole machine inside the crop at both column and banner
       proportions instead of slicing through it. */
    background-position: 26% center;
    transform: scaleX(-1);
    opacity: 0.9;
}

.egl-login-brand--photo::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    /* Two scrims. The first darkens hard where the text is and releases toward
       the machine so it stays visible; the second guards the top and bottom
       edges, which is where the layout lands on narrow screens. */
    background:
        linear-gradient(
            105deg,
            rgba(4, 11, 26, 0.94) 0%,
            rgba(4, 11, 26, 0.8) 32%,
            rgba(4, 11, 26, 0.36) 66%,
            rgba(4, 11, 26, 0.58) 100%
        ),
        linear-gradient(
            180deg,
            rgba(4, 11, 26, 0.45) 0%,
            rgba(4, 11, 26, 0) 26%,
            rgba(4, 11, 26, 0) 72%,
            rgba(4, 11, 26, 0.6) 100%
        );
}

/* Everything the panel actually says must sit above both layers. */
.egl-login-brand > * {
    position: relative;
    z-index: 1;
}

/* With a photograph in place the drawn machines would only fight it. */
.egl-login-brand--photo .egl-login-art {
    display: none;
}


/* ============================================================================
   PHASE 08G - LOGIN MOTION
   ============================================================================
   Two quiet pieces of movement, deliberately kept apart.

   The motes drift over the photograph on the brand side, where they read as
   dust in the factory light. The halo breathes slowly far behind the card on
   the form side, so the card feels lit rather than outlined - a hard ring
   around the card was tried first and rejected, because it kept pulling the
   eye back while someone was typing.

   Both layers are inert (pointer-events: none), both animate only transform
   and opacity so the work happens on the GPU and costs nothing on a cheap
   handset, and both stop completely for anyone whose device asks for reduced
   motion. Every selector and every animation name starts with egl-login- so
   nothing here can reach a frozen screen or collide with the compiled bundle.
   ========================================================================= */

.egl-login-motes {
    position: absolute;
    inset: 0;
    z-index: 1;
    overflow: hidden;
    pointer-events: none;
}

.egl-login-motes span {
    position: absolute;
    border-radius: 50%;
    background: rgba(150, 200, 255, 0.9);
    box-shadow: 0 0 8px 2px rgba(90, 162, 255, 0.55);
    opacity: 0;
    animation-name: egl-login-rise;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}

@keyframes egl-login-rise {
    0% {
        transform: translate3d(0, 26px, 0) scale(0.6);
        opacity: 0;
    }
    14% {
        opacity: 0.85;
    }
    74% {
        opacity: 0.55;
    }
    100% {
        transform: translate3d(14px, -130px, 0) scale(1);
        opacity: 0;
    }
}

.egl-login-halo {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 640px;
    height: 640px;
    max-width: 130vw;
    max-height: 130vw;
    border-radius: 50%;
    pointer-events: none;
    z-index: 0;
    background: radial-gradient(circle, var(--egl-login-glow), transparent 62%);
    animation: egl-login-breathe 7s ease-in-out infinite;
}

@keyframes egl-login-breathe {
    0%,
    100% {
        transform: translate(-50%, -50%) scale(0.86);
        opacity: 0.5;
    }
    50% {
        transform: translate(-50%, -50%) scale(1.06);
        opacity: 0.95;
    }
}

/* The halo lives in the form column, which needs to clip it and to stack the
   card above it. */
.egl-login-main {
    position: relative;
    overflow: hidden;
}

.egl-login-col {
    position: relative;
    z-index: 1;
}

/* Someone who has asked their device to reduce motion gets the same design,
   perfectly still. No !important needed - these rules simply come later. */
@media (prefers-reduced-motion: reduce) {
    .egl-login-motes span {
        animation: none;
        opacity: 0.5;
    }

    .egl-login-halo {
        animation: none;
        opacity: 0.7;
    }
}


/* ============================================================================
   PHASE 08H - PROFILE
   ============================================================================
   The profile page now sits on the application's own dashboard shell, so these
   rules are written dark-first like the rest of the UI and are remapped for
   light mode at the bottom of this block.

   Every selector starts with .egl-profile- and none of them exist in the
   compiled Vite bundle, so nothing here can reach a frozen screen.
   ========================================================================= */

/* ------------------------------------------------------- large portrait */
.egl-profile-portrait {
    width: 128px;
    height: 128px;
    border-radius: 50%;
    overflow: hidden;
    display: grid;
    place-items: center;
    background: #1e293b;
    border: 1px solid #334155;
}

.egl-profile-portrait img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.egl-profile-portrait__initials {
    font-size: 44px;
    font-weight: 700;
    color: #94a3b8;
    line-height: 1;
}

/* ------------------------------------------------ upload row on the form */
.egl-profile-photo {
    display: flex;
    align-items: center;
    gap: 18px;
    flex-wrap: wrap;
}

.egl-profile-photo__preview {
    flex: none;
    width: 84px;
    height: 84px;
    border-radius: 50%;
    overflow: hidden;
    display: grid;
    place-items: center;
    background: #1e293b;
    border: 1px solid #334155;
}

.egl-profile-photo__preview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.egl-profile-photo__initials {
    font-size: 30px;
    font-weight: 700;
    color: #94a3b8;
}

.egl-profile-photo__controls {
    flex: 1;
    min-width: 220px;
}

.egl-profile-photo__input {
    display: block;
    width: 100%;
    margin-top: 6px;
    font-size: 13px;
    color: #cbd5e1;
}

/* The browser paints the "Choose file" button itself; without this it stays
   the default light-grey chip and looks pasted onto a dark panel. */
.egl-profile-photo__input::file-selector-button {
    margin-right: 12px;
    padding: 6px 12px;
    border-radius: 8px;
    border: 1px solid #334155;
    background: #1e293b;
    color: #e2e8f0;
    font-size: 13px;
    cursor: pointer;
}

.egl-profile-photo__input::file-selector-button:hover {
    background: #273449;
}

.egl-profile-photo__hint {
    margin-top: 4px;
    font-size: 12px;
    color: #64748b;
}

/* ------------------------------------------------------------- avatars */
/* Sidebar (36px, matches the icon tile it replaces). */
.egl-profile-avatar {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    object-fit: cover;
    display: block;
    flex: none;
}

/* Beside the header "Profile" link. */
.egl-profile-avatar-sm {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    object-fit: cover;
    display: block;
    flex: none;
    border: 1px solid #334155;
}

/* User Management list, replacing the 32px icon tile. */
.egl-profile-avatar-md {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    object-fit: cover;
    display: block;
    flex: none;
}

/* ---------------------------------------------------------- light mode */
html[data-theme='light'] .egl-profile-portrait,
html[data-theme='light'] .egl-profile-photo__preview {
    background: #eef2f7;
    border-color: #d3ddec;
}

html[data-theme='light'] .egl-profile-portrait__initials,
html[data-theme='light'] .egl-profile-photo__initials {
    color: #64748b;
}

html[data-theme='light'] .egl-profile-photo__input {
    color: #475569;
}

html[data-theme='light'] .egl-profile-photo__input::file-selector-button {
    border-color: #cbd5e1;
    background: #f1f5f9;
    color: #334155;
}

html[data-theme='light'] .egl-profile-photo__input::file-selector-button:hover {
    background: #e2e8f0;
}

html[data-theme='light'] .egl-profile-photo__hint {
    color: #94a3b8;
}

html[data-theme='light'] .egl-profile-avatar-sm {
    border-color: #cbd5e1;
}


/* ============================================================================
   PHASE 09B-1 - FOUR THINGS FOUND WHILE TESTING THE DEV DEPLOY
   ============================================================================
   1. the header Profile link vanished on a phone
   2. the Remember me checkbox was drawn far larger than its own label
   3. that row sat out of line because of it
   4. the admin user forms had no way to see the password being typed

   Every selector starts with .egl-profile- , .egl-login- or .egl-form- . None
   of them exist in the compiled bundle, so none can repaint a frozen screen.
   ========================================================================= */

/* ------------------------------------------- header Profile link on mobile */
.egl-profile-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex: none;
}

/* The word "Profile" stays on every screen size.
   
   It was hidden below 480px to save room in a header that also holds a menu
   button, a title and Log Out. Testing on a real phone said the picture alone
   is not obvious enough - people did not know it was the way in. So the word
   comes back and the row gives up space elsewhere instead: the label shrinks
   a little and the gap tightens, which is enough on a 360px screen. */
.egl-profile-link {
    min-height: 36px;
    white-space: nowrap;
}

@media (max-width: 480px) {
    .egl-profile-link {
        gap: 6px;
        font-size: 12px;
    }

    .egl-profile-link .egl-profile-avatar-sm {
        width: 20px;
        height: 20px;
    }
}

/* ------------------------------------------------ Remember me on the login */
.egl-login-remember {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    row-gap: 10px;
}

.egl-login-remember__box {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    cursor: pointer;
    user-select: none;
}

.egl-login-remember__text {
    font-size: 13px;
    line-height: 1;
    color: var(--egl-login-dim);
}

/* Phase 51 - the one line that says what the tick actually does. It takes the
   whole width of the row, under the box and the Forgot-password link, and
   reads from the same login tokens as everything else in this panel, so light
   mood is already handled where those tokens are redefined. */
.egl-login-remember__note {
    flex-basis: 100%;
    margin: 0;
    font-size: 12px;
    line-height: 1.45;
    color: var(--egl-login-dim);
    opacity: .85;
}

/* The browser's own checkbox came out much bigger than the 13px label beside
   it. Drawing it here fixes the size at 16px and keeps the tick centred. */
/* The selector is deliberately heavier than it looks.
 *
 * The login card carries the Tailwind arbitrary variant [&_input]:egl-input,
 * which compiles to
 *
 *     .\[\&_input\]\:egl-input input { width:100%; padding:.5rem .75rem;
 *                                      display:block; border-radius:.5rem }
 *
 * inside the frozen bundle. That is one class plus one element - (0,1,1) - and
 * it beat a plain .egl-login-check at (0,1,0), so this checkbox was being drawn
 * as a full width text field. Three earlier attempts at this failed because
 * they changed what the rule said instead of finding out what was overriding
 * it. Rendering the real page and reading the computed style is what found it.
 *
 * .egl-login-remember input.egl-login-check is (0,2,1) and wins. padding and
 * display have to be reset explicitly too: the bundle's padding of 24px across
 * would otherwise hold the box open at 26px whatever width is asked for. */
.egl-login-remember input.egl-login-check {
    appearance: none;
    -webkit-appearance: none;
    display: inline-block;
    flex: none;
    width: 16px;
    height: 16px;
    min-width: 16px;
    padding: 0;
    margin: 0;
    border: 1px solid #475569;
    border-radius: 4px;
    background-color: #1e293b;
    cursor: pointer;
    position: relative;
    transition: background-color 0.12s ease, border-color 0.12s ease;
}

.egl-login-remember input.egl-login-check:hover {
    border-color: #64748b;
}

/* The tick.
 *
 * The compiled bundle already supplies one and it renders correctly in every
 * browser this app runs in - it was only ever drawn too large, because the
 * bundle sets "background-size: 100% 100%" and the mark then runs corner to
 * corner however small the box is.
 *
 * So the only thing changed here is the size. Deliberately NO background-image
 * of our own: an earlier attempt swapped in a hand-written SVG, which stopped
 * rendering at all and left a blue box with no tick in it. Replacing something
 * that already works in order to resize it was the wrong move; overriding one
 * property is enough.
 *
 * .egl-login-check:checked is (0,2,0). The bundle's
 * input:where([type=checkbox]):checked is (0,1,1) - :where() adds nothing - so
 * this wins on specificity and the image underneath is still the bundle's. */
.egl-login-remember input.egl-login-check:checked {
    background-color: #2563eb;
    border-color: #2563eb;
    background-size: 68% 68%;
    background-position: 50%;
    background-repeat: no-repeat;
}

.egl-login-remember input.egl-login-check:focus-visible {
    outline: 2px solid #60a5fa;
    outline-offset: 2px;
}

/* ------------------------------- show/hide password on any dark panel form */
.egl-form-pw {
    position: relative;
}

.egl-form-pw input {
    padding-right: 42px;
}

.egl-form-pw__eye {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    margin-top: 2px;
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: #94a3b8;
    cursor: pointer;
    transition: color 0.15s ease;
}

.egl-form-pw__eye:hover,
.egl-form-pw__eye.is-revealed {
    color: #60a5fa;
}

.egl-form-pw__eye:focus-visible {
    outline: 2px solid #60a5fa;
    outline-offset: 1px;
}

/* ---------------------------------------------------------- light mode ---- */
html[data-theme='light'] .egl-login-remember input.egl-login-check {
    border-color: #cbd5e1;
    background-color: #ffffff;
}

html[data-theme='light'] .egl-login-remember input.egl-login-check:checked {
    background-color: #2563eb;
    border-color: #2563eb;
}

html[data-theme='light'] .egl-form-pw__eye {
    color: #64748b;
}

html[data-theme='light'] .egl-form-pw__eye:hover,
html[data-theme='light'] .egl-form-pw__eye.is-revealed {
    color: #2563eb;
}


/* ==========================================================================
   Phase 09E - the environment badge
   --------------------------------------------------------------------------
   A small amber chip that names the environment. It never renders on
   production, so none of this paints anything on the live site.

   Amber, not red: red on every page all day reads as "something is wrong"
   and stops being noticed within a week. Amber reads as "pay attention to
   where you are", which is exactly the message.

   These rules cannot be Tailwind utilities. The compiled bundle is frozen at
   the 17 August build and a class that is not already inside it does nothing.
   ========================================================================== */

.egl-env-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border: 1px solid #b45309;
    border-radius: 999px;
    background-color: #78350f;
    color: #fde68a;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    white-space: nowrap;
    cursor: default;
    user-select: none;
}

.egl-env-badge__dot {
    display: block;
    width: 6px;
    height: 6px;
    flex: none;
    border-radius: 50%;
    background-color: #fbbf24;
    animation: egl-env-pulse 2.4s ease-in-out infinite;
}

@keyframes egl-env-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.35; }
}

/* Anyone who has asked their device to reduce motion gets a steady dot. The
   badge still does its job; only the pulse stops. */
@media (prefers-reduced-motion: reduce) {
    .egl-env-badge__dot {
        animation: none;
    }
}

/* On the login page the badge sits above the card in the form column. That
   column is a flex column, so without this the chip would stretch to the full
   width of the card and stop looking like a chip. */
.egl-login-col .egl-env-badge {
    align-self: flex-start;
    margin-bottom: 14px;
}

/* Light theme. The dark values above are already legible on the slate header,
   but on a white page they turn into a heavy brown block, so the chip is
   inverted here: pale fill, dark text. */
html[data-theme='light'] .egl-env-badge {
    border-color: #f59e0b;
    background-color: #fef3c7;
    color: #92400e;
}

html[data-theme='light'] .egl-env-badge__dot {
    background-color: #d97706;
}

/* ===================================================== dashboard cards ===
   Phase 10A — the first family written the new way.

   Not one colour is spelled out here: every value comes from a token, so a
   single set of rules paints the card correctly in BOTH appearances. That is
   the whole point of the phase. These classes do not exist in the frozen
   bundle, so they cannot repaint anything that already ships.

   Accent is chosen by a modifier and read through --dash-accent*, which keeps
   the painting rules to one copy instead of one per colour.
   ======================================================================== */
.egl-dash-card {
    --dash-accent: var(--egl-primary);
    --dash-accent-soft: var(--egl-primary-soft);
    --dash-accent-border: var(--egl-primary-border);

    position: relative;
    display: flex;
    flex-direction: column;
    gap: .625rem;
    padding: 1.0625rem 1.125rem;
    border-radius: .875rem;
    border: 1px solid var(--egl-border);
    background:
        linear-gradient(135deg, var(--dash-accent-soft) 0%, transparent 62%),
        var(--egl-surface);
    box-shadow: var(--egl-shadow);
    overflow: hidden;
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}

.egl-dash-card::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    background: var(--dash-accent);
    opacity: .85;
}

.egl-dash-card:hover {
    transform: translateY(-2px);
    border-color: var(--dash-accent-border);
    box-shadow: var(--egl-shadow-lg);
}

.egl-dash-card--ok {
    --dash-accent: var(--egl-ok);
    --dash-accent-soft: var(--egl-ok-soft);
    --dash-accent-border: var(--egl-ok-border);
}

.egl-dash-card--warn {
    --dash-accent: var(--egl-warn);
    --dash-accent-soft: var(--egl-warn-soft);
    --dash-accent-border: var(--egl-warn-border);
}

.egl-dash-card--danger {
    --dash-accent: var(--egl-danger);
    --dash-accent-soft: var(--egl-danger-soft);
    --dash-accent-border: var(--egl-danger-border);
}

.egl-dash-card__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

.egl-dash-card__label {
    /* Phase 10I-2 — Aomith asked for bigger type on the statistic cards, and
       he is right that the room is there: these cards carry three short lines
       in a box wide enough for far more. */
    font-size: .9375rem;
    /* Phase 10D — the card's name carries the card. At 600 it read as a
       caption beside its own number; at 700 it reads as a heading. */
    font-weight: 700;
    letter-spacing: .01em;
    color: var(--egl-text-2);
}

.egl-dash-card__desc {
    margin-top: .25rem;
    font-size: .875rem;
    line-height: 1.4;
    color: var(--egl-text-muted);
}

.egl-dash-card__value {
    font-size: 2.25rem;
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
    color: var(--dash-accent);
}

.egl-dash-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    flex: none;
    border-radius: .75rem;
    border: 1px solid var(--dash-accent-border);
    background: var(--dash-accent-soft);
    color: var(--dash-accent);
}

/* Phase 10B — a fifth tone for states that are neither good nor a warning.
   Idle machines are not a problem, they are simply not running. */
.egl-dash-card--muted {
    --dash-accent: var(--egl-muted-tone);
    --dash-accent-soft: var(--egl-muted-soft);
    --dash-accent-border: var(--egl-muted-border);
}

/* ---- the same card, carrying a short list instead of one big number ---- */
.egl-dash-card__list {
    display: flex;
    flex-direction: column;
    gap: .375rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Phase 10E — min-width:0 everywhere a long name meets a flex or grid box.
   Without it "SINGLE NEEDLE LOCK STITCH" refuses to shrink and pushes the
   row straight out of the card, which is exactly what Aomith spotted. */
.egl-dash-card__list > li {
    min-width: 0;
}

.egl-dash-card__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-width: 0;
    gap: .75rem;
    padding: .4375rem .625rem;
    border-radius: .5rem;
    border: 1px solid var(--egl-border);
    background: var(--egl-surface-2);
    text-decoration: none;
    transition: border-color .15s ease, background-color .15s ease;
}

.egl-dash-card__row:hover {
    border-color: var(--dash-accent-border);
    background: var(--dash-accent-soft);
}

.egl-dash-card__row-name {
    font-size: .8125rem;
    font-weight: 500;
    color: var(--egl-text-2);
    min-width: 0;
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.egl-dash-card__row-count {
    font-size: .8125rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--dash-accent);
    flex: none;
}

/* ================================================ tiles: counts by type ===
   Phase 10C — a wide card carrying one small box per machine type, in the
   same visual language as the block boxes below it, so nothing new has to be
   learned. Ten boxes are shown and the rest wait behind "Show all".

   The reveal is pure CSS: a hidden checkbox in front of the grid. No
   JavaScript, no library, nothing added to the frozen bundle, and it still
   works on an old handset on the factory floor.
   ======================================================================== */
.egl-dash-tilegrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
    gap: .5rem;
}

.egl-dash-tile {
    display: flex;
    flex-direction: column;
    gap: .375rem;
    padding: .625rem .75rem;
    border-radius: .625rem;
    border: 1px solid var(--egl-border);
    background: var(--egl-surface-2);
    text-decoration: none;
    transition: border-color .15s ease, background-color .15s ease, transform .15s ease;
}

.egl-dash-tile:hover {
    border-color: var(--egl-primary-border);
    background: var(--egl-primary-soft);
    transform: translateY(-1px);
}

.egl-dash-tile__name {
    font-size: .6875rem;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: .01em;
    color: var(--egl-text-3);
    min-height: 2.0625rem;
}

.egl-dash-tile__count {
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--egl-text);
}

.egl-dash-tile__share {
    font-size: .6875rem;
    color: var(--egl-text-muted);
    margin-left: .375rem;
    font-weight: 500;
}

/* A hairline that shows the share of the fleet, so 739 and 1 do not look
   like the same quantity just because the boxes are the same size. */
.egl-dash-tile__bar {
    height: 3px;
    border-radius: 999px;
    background: var(--egl-border);
    overflow: hidden;
}

.egl-dash-tile__bar-fill {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--egl-primary);
}

/* ---- the CSS-only "Show all" reveal (no JavaScript anywhere) ---------- */
.egl-dash-more {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    clip-path: inset(50%);
    overflow: hidden;
    white-space: nowrap;
}

.egl-dash-more__extra {
    display: none;
}

/* Phase 10E — any container, not only the tile grid. The condition summary
   reused the tile grid class purely to satisfy this selector, and a grid
   track let its rows push past the edge of the box. */
.egl-dash-more:checked ~ * .egl-dash-more__extra {
    display: flex;
}

.egl-dash-more:checked ~ .egl-dash-morebar .egl-dash-more__show {
    display: none;
}

.egl-dash-more__hide {
    display: none;
}

.egl-dash-more:checked ~ .egl-dash-morebar .egl-dash-more__hide {
    display: inline;
}

.egl-dash-morebar {
    display: flex;
    justify-content: center;
    margin-top: .75rem;
}

.egl-dash-morebar__btn {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    padding: .375rem .875rem;
    border-radius: 999px;
    border: 1px solid var(--egl-border-strong);
    background: var(--egl-surface-2);
    color: var(--egl-text-2);
    font-size: .75rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease, color .15s ease;
}

.egl-dash-morebar__btn:hover {
    border-color: var(--egl-primary-border);
    background: var(--egl-primary-soft);
    color: var(--egl-primary);
}

.egl-dash-more:focus-visible ~ .egl-dash-morebar .egl-dash-morebar__btn {
    outline: 2px solid var(--egl-primary);
    outline-offset: 2px;
}

/* Phase 10D — a footer strip for cards that carry a badge or a link. */
.egl-dash-card__footer {
    margin-top: auto;
    padding-top: .625rem;
    border-top: 1px solid var(--egl-border);
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: .8125rem;
}

.egl-dash-card__link {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    color: var(--egl-primary);
    font-weight: 600;
    text-decoration: none;
}

.egl-dash-card__link:hover {
    text-decoration: underline;
}

/* A group of counted rows inside a wide card, e.g. the condition summary.
   The same CSS-only reveal keeps a long list from stretching the card. */
.egl-dash-group {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    padding: .75rem;
    border-radius: .75rem;
    border: 1px solid var(--egl-border);
    background: var(--egl-surface-2);
}

.egl-dash-group__title {
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .01em;
    color: var(--dash-accent, var(--egl-text-2));
}

.egl-dash-group__empty {
    font-size: .75rem;
    color: var(--egl-text-muted);
}

/* Phase 10D — the last hard-coded colours on the dashboard: the page title,
   the section icons and the plain notes under the role panels. Each had its
   shade written into the markup, so none of them answered to the appearance. */
.egl-dash-pagetitle {
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--egl-text);
}

.egl-dash-pagelead {
    margin-top: .125rem;
    font-size: .8125rem;
    color: var(--egl-text-muted);
}

.egl-dash-sectionicon {
    color: var(--egl-primary);
}

.egl-dash-note {
    font-size: .8125rem;
    line-height: 1.45;
    color: var(--egl-text-muted);
}


/* ========================================================================
   Phase 10G - the photographs on the Machine Statistics cards.

   Five studio pictures were supplied. Four carried a light studio
   background and the fifth a pure black one, so neither set could be used
   as it came: a light rectangle sits badly on a dark card and a black one
   sits badly on a light card. Every picture was cut out to a transparent
   PNG instead, so only the object itself is drawn. One file is then right
   in both appearances and the appearance decides only how strongly it is
   drawn - never which file is fetched, so nothing is swapped in script.

   These rules paint no text, so no contrast can be lost. The pictures are
   decorative: they carry alt="" and aria-hidden, and a screen reader
   passes over them.
   ======================================================================== */
.egl-dash-card__badge {
    display: block;
    width: 2.5rem;
    height: 2.5rem;
    flex: none;
    object-fit: contain;
    filter: drop-shadow(0 1px 2px rgba(15, 23, 42, .18));
}

html[data-theme='dark'] .egl-dash-card__badge {
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .55));
}

/* Phase 10G-2 — Aomith asked for the WHOLE photograph on each card, not only
   the badge cut out of its corner, and for the light appearance to show it
   properly instead of hinting at it.

   The picture now fills the card's height and sits against its right edge.
   Its own edges are faded inside the PNG itself, so no rectangle can appear
   against the card in either appearance, and the fade on the left keeps the
   label and the number over plain surface. */
.egl-dash-card__art {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    height: 100%;
    width: auto;
    max-width: 56%;
    object-fit: contain;
    object-position: right center;
    opacity: .7;
    pointer-events: none;
    user-select: none;
    -webkit-user-drag: none;
    z-index: 0;
}

/* 10G-3 — the four studio-on-white photographs were replaced by pictures shot
   on black, which cut out cleanly. Every picture on these cards is now a real
   cut-out with no background of its own, so the dark appearance no longer has
   to be held back to hide a white panel. It stays a little quieter than the
   light one only because a bright object on a dark card carries further. */
html[data-theme='dark'] .egl-dash-card__art {
    opacity: .58;
}

/* The picture stays behind the card's own words, never over the number. */
.egl-dash-card__head,
.egl-dash-card__value,
.egl-dash-card__footer {
    position: relative;
    z-index: 1;
}

@media (max-width: 640px) {
    .egl-dash-card__art {
        max-width: 44%;
        opacity: .55;
    }

    html[data-theme='dark'] .egl-dash-card__art {
        opacity: .45;
    }
}


/* Phase 10H - the note above the machine import box that says what the import
   will do. It takes both its shades from tokens, so it is already right in
   either appearance even though the rest of that page has not been converted
   yet.

   It joins the existing egl-form- family rather than starting an egl-import-
   one, so the overlay's "every light rule must be scoped" guard keeps the
   short allow-list it has instead of being widened for a single note. */
.egl-form-note {
    margin: -.5rem 0 1rem;
    padding: .625rem .75rem;
    border-radius: .625rem;
    border: 1px solid var(--egl-primary-border);
    background: var(--egl-primary-soft);
    font-size: .8125rem;
    line-height: 1.5;
    color: var(--egl-text-2);
}

.egl-form-note strong {
    font-weight: 700;
    color: var(--egl-text);
}


/* ========================================================================
   Phase 10I - Fleet Utilisation: the dial and the ring.

   The Machine Statistics grid held seven cards in rows of three, which left
   two empty cells at the end. This card fills both. The span is written here
   rather than with a col-span utility because the Tailwind bundle is frozen:
   a utility that was never used before this phase does not exist in it, and
   nothing may rebuild it.

   Every colour comes from a token, and the two drawings are plain SVG with no
   script behind them, so the card is correct in both appearances and needs no
   JavaScript to be right.
   ======================================================================== */
@media (min-width: 640px) {
    .egl-dash-gauge {
        grid-column: span 2;
    }
}

.egl-dash-gauge__body {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.25rem 2rem;
    margin-top: .25rem;
}

.egl-dash-gauge__dial {
    flex: 1 1 12rem;
    min-width: 11rem;
    max-width: 15rem;
    text-align: center;
}

.egl-dash-gauge__svg {
    display: block;
    width: 100%;
    height: auto;
}

.egl-dash-gauge__track {
    fill: none;
    stroke: var(--egl-border-strong);
    stroke-width: 14;
    stroke-linecap: round;
    opacity: .55;
}

.egl-dash-gauge__value {
    fill: none;
    stroke: var(--egl-ok);
    stroke-width: 14;
    stroke-linecap: round;
}

.egl-dash-gauge__needle {
    stroke: var(--egl-text);
    stroke-width: 3;
    stroke-linecap: round;
}

.egl-dash-gauge__hub {
    fill: var(--egl-surface);
    stroke: var(--egl-text);
    stroke-width: 3;
}

.egl-dash-gauge__end {
    fill: var(--egl-text-muted);
    font-size: 11px;
    font-weight: 600;
}

.egl-dash-gauge__percent {
    margin-top: -.25rem;
    font-size: 2.25rem;
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
    color: var(--egl-ok);
}

.egl-dash-gauge__caption {
    margin-top: .1875rem;
    font-size: .875rem;
    color: var(--egl-text-muted);
}

/* Phase 10I-2 — the ring and its legend sat hard against the dial, which left
   a hole in the middle of the card and threw the numbers out to the far edge.
   The group is centred in the space it has instead, and the legend is capped
   so a count stays beside the name it belongs to. */
.egl-dash-gauge__split {
    flex: 1 1 16rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.75rem;
    min-width: 0;
}

.egl-dash-gauge__ring {
    flex: none;
    width: 10.5rem;
    height: 10.5rem;
}

.egl-dash-gauge__ringtrack {
    fill: none;
    stroke: var(--egl-border-strong);
    stroke-width: 14;
    opacity: .45;
}

/* Only the slices are turned, not the whole drawing - the number in the
   middle has to stay the right way up. */
.egl-dash-gauge__slice {
    fill: none;
    stroke-width: 14;
    transform: rotate(-90deg);
    transform-origin: 60px 60px;
}

.egl-dash-gauge__slice.is-active,
.egl-dash-gauge__dot.is-active {
    stroke: var(--egl-ok);
    background: var(--egl-ok);
}

.egl-dash-gauge__slice.is-idle,
.egl-dash-gauge__dot.is-idle {
    stroke: var(--egl-muted-tone);
    background: var(--egl-muted-tone);
}

.egl-dash-gauge__slice.is-maintenance,
.egl-dash-gauge__dot.is-maintenance {
    stroke: var(--egl-danger);
    background: var(--egl-danger);
}

.egl-dash-gauge__slice.is-unplaced,
.egl-dash-gauge__dot.is-unplaced {
    stroke: var(--egl-warn);
    background: var(--egl-warn);
}

.egl-dash-gauge__ringvalue {
    fill: var(--egl-text);
    font-size: 22px;
    font-weight: 700;
}

.egl-dash-gauge__ringlabel {
    fill: var(--egl-text-muted);
    font-size: 11px;
    font-weight: 600;
}

.egl-dash-gauge__legend {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 20rem;
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.egl-dash-gauge__legenditem {
    display: flex;
    align-items: center;
    gap: .625rem;
    font-size: .9375rem;
    color: var(--egl-text-2);
}

.egl-dash-gauge__dot {
    flex: none;
    width: .75rem;
    height: .75rem;
    border-radius: 999px;
}

.egl-dash-gauge__legendname {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.egl-dash-gauge__legendcount {
    font-size: 1.125rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--egl-text);
}

.egl-dash-gauge__legendshare {
    width: 3.75rem;
    text-align: right;
    font-size: .9375rem;
    font-variant-numeric: tabular-nums;
    color: var(--egl-text-muted);
}


/* ========================================================================
   Phase 10J - the sidebar icons, one colour each.

   Every entry drew the same slate glyph, and three glyphs were used twice:
   Dashboard and Rental Machine Dashboard shared one, Machine Status and
   Rental Machine Status shared another, and Mechanic Contact List and
   Mechanic Engagement shared a third. Nine identical grey marks are not a
   menu you read, they are a menu you count down.

   The family is egl-navicon-, which exists in neither the frozen bundle nor
   anywhere else in this overlay, so nothing that already ships can be
   repainted by these rules. The nav link itself - egl-nav-link-active and
   egl-nav-link-inactive - IS in the frozen bundle and is not touched here.

   The tinted background is drawn with color-mix so one declaration serves all
   nine colours. A browser too old for color-mix drops that line and keeps the
   plain surface underneath, which is why the plain colour is written first.

   ------------------------------------------------------------------------
   PHASE 71 - THE CHIP STOPS BEING THE PICTURE AND BECOMES THE FRAME.

   Aomith, 1 October: "amader menu bar a icon gula koto sundor ar side bar a
   icon gula kemon fakase, ata thik kore daw, main menu and side bar er icon
   er same kore daw". He is right, and 10J is why: a 1.125rem line glyph on a
   14%-tinted wash is a faint mark by design, and next to his own icon pack on
   the front door it looks like the unfinished half of the app.

   The sidebar now draws the SAME FILES the menu tiles draw. Three things
   follow, and all three are the reason it is written this way:

     THE WASH AND THE BORDER ARE GONE. Each picture is already a coloured
     rounded square; a tinted square behind it reads as a double border.

     THE PER-ENTRY COLOUR STILL DOES REAL WORK. It is no longer paint on a
     glyph - it is the halo the entry you are ON wears, so every
     .egl-navicon-box--<key> rule below is still load-bearing and
     SidebarIconsTest still has something true to check.

     THE PICTURE IS SIZED BY HEIGHT, width auto, exactly as the menu tile
     sizes it, INSIDE A BOX OF ONE FIXED WIDTH. Both halves of that matter and
     the first screenshot is what showed why. The pack's cells came out a hair
     wider than tall and not all the same width, so sizing by height alone let
     each row set its own width - and Settings, the widest at 195x160, pushed
     its label five pixels right of the other nineteen. A fixed SQUARE would
     have fixed the alignment and broken the other half, letterboxing the wide
     ones into looking smaller than their neighbours. So the box is as wide as
     the widest picture: every label starts at the same place and every
     picture is drawn at the same height, neither squashed nor shrunk. Every
     <img> carries its own width and height attributes, so nothing shifts
     while they load.
   ======================================================================== */
.egl-navicon-box {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.125rem;
    flex: none;
    padding: .125rem;
    border-radius: .625rem;
    border: 1px solid transparent;
    background: transparent;
    transition: background .18s ease, box-shadow .18s ease;
}

/* Phase 71 - his own icon pack, at the size the row can carry. */
.egl-navicon-img {
    display: block;
    height: 1.875rem;
    width: auto;
    max-width: 100%;
}

/* 10J-2, rewritten by 71 — the entry you are on wears its colour, and the
   state still comes from a class the layout adds rather than a selector
   reaching for .egl-nav-link-active: that class lives in the frozen bundle,
   and the overlay must not lead a rule with it.

   It is a halo now instead of a solid chip. A solid chip worked when the mark
   on it was a stroked glyph that could be repainted to the surface colour; a
   photograph cannot be repainted, so filling the chip would bury the picture
   instead of pointing at it. The ring and the glow are drawn in currentColor,
   which is the entry's own tone - so where you are is still said in colour. */
.egl-navicon-box--on {
    background: color-mix(in srgb, currentColor 14%, transparent);
    box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 38%, transparent),
                0 2px 10px color-mix(in srgb, currentColor 42%, transparent);
}

/* Phase 69 - the front door's own entry, first in the list. It shares the sky
   tone with Rental Machine Dashboard rather than inventing an eighteenth
   colour: every token in the palette is already spoken for, and a near-miss
   new one would read as a mistake next to the ones it nearly matches. The
   glyph is what tells them apart, and this is the only grid in the list. */
.egl-navicon-box--menu { color: var(--egl-nav-sky); }
.egl-navicon-box--dashboard { color: var(--egl-nav-blue); }
.egl-navicon-box--machines { color: var(--egl-nav-teal); }
.egl-navicon-box--contacts { color: var(--egl-nav-violet); }
.egl-navicon-box--alarms { color: var(--egl-nav-red); }
.egl-navicon-box--engagement { color: var(--egl-nav-amber); }
.egl-navicon-box--rental-dashboard { color: var(--egl-nav-sky); }
.egl-navicon-box--rental-status { color: var(--egl-nav-green); }
.egl-navicon-box--users { color: var(--egl-nav-rose); }
.egl-navicon-box--settings { color: var(--egl-nav-slate); }
/* Phase 13B — Machine Requirement Status. */
.egl-navicon-box--mreq { color: var(--egl-nav-indigo); }
/* Phase 14A — Schedule Maintenance. */
.egl-navicon-box--schedule { color: var(--egl-nav-orange); }
/* Phase 17A — QCO / Changeover Status. */
.egl-navicon-box--qco { color: var(--egl-nav-cyan); }
/* Phase 19A-1 — Loan from Group Factories. */
.egl-navicon-box--group-factory { color: var(--egl-nav-lime); }
.egl-navicon-box--skill { color: var(--egl-nav-emerald); }
/* Phase 26 - Style Layout Split. */
.egl-navicon-box--slx { color: var(--egl-nav-purple); }
/* Phase 48 - Machine Space. */
.egl-navicon-box--msp { color: var(--egl-nav-stone); }
/* Phase 60 - Monthly Planned Item Details. */
.egl-navicon-box--mpi { color: var(--egl-nav-fuchsia); }
/* Phase 80 - Contact Us. TEAL, which Machine Status already uses, and that
   is not an oversight: all seventeen nav tones were spoken for before this
   row existed (sky serves two rows already), so a new row has to share one.
   Teal was picked because the icon drawn for this row is teal, so the chip
   and the picture inside it agree instead of arguing. */
.egl-navicon-box--contact-us { color: var(--egl-nav-teal); }
.egl-navicon-box--about { color: var(--egl-nav-indigo); }

/* ==========================================================================
   Phase 13B-1 — the Machine Requirement module's own layout.
   --------------------------------------------------------------------------
   Written as real CSS rather than Tailwind utilities for a reason Aomith
   found on the screen: the compiled bundle is FROZEN (17 August) and is never
   rebuilt, so a utility class nobody had used before is simply absent. The
   entry grid had been built with `w-24`, which is not in that bundle. The Qty
   box therefore kept egl-input's width:100%, demanded the whole row, squeezed
   the machine-type dropdown down to its chevron, and pushed Remove off the
   page. Nothing errored. The markup looked perfect.

   Anything this module needs that the bundle might not have is written here
   instead, in its own egl-mreq- family - a family the bundle has never heard
   of, so these rules cannot repaint any frozen UI. Both appearances are served
   by the same declarations, using tokens that are defined for each.
   ========================================================================== */

/* One row of the "Machines Required" grid: dropdown, quantity, Remove.
   A grid rather than flex so the three widths are stated outright. The
   minmax(0, 1fr) is the part that matters - without the 0, the dropdown's
   min-content width would win again and the row would overflow exactly as it
   did before. */
.egl-mreq-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 6rem auto;
    gap: .5rem;
    align-items: center;
}

.egl-mreq-row > * {
    min-width: 0;
}

/* On a narrow screen the dropdown takes the whole width and the quantity and
   Remove sit under it. Three columns on a 360px phone would squeeze the
   machine name down to nothing, which is the fault this class exists to
   prevent - just at a different width. */
@media (max-width: 560px) {
    .egl-mreq-row {
        grid-template-columns: 5rem 1fr;
        grid-template-areas:
            'type type'
            'qty  remove';
        row-gap: .375rem;
    }

    .egl-mreq-row > [data-mreq-type] { grid-area: type; }
    .egl-mreq-row > [data-mreq-qty] { grid-area: qty; }
    .egl-mreq-row > [data-mreq-remove] { grid-area: remove; justify-self: start; }
}

/* The list page: ONE CARD PER SEWING LINE, one card per row.
   Aomith's choice, and the right one - his planning sheet is read down the
   page, line after line, and a grid of cards has to be read left to right and
   then wrapped, which is where you lose your place looking for K-07. The
   width that a side-by-side grid would have used goes to the styles instead. */
.egl-mreq-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: .75rem;
}

.egl-mreq-card {
    display: grid;
    grid-template-columns: 13rem minmax(0, 1fr);
    background: var(--egl-surface);
    border: 1px solid var(--egl-border);
    border-radius: .75rem;
    overflow: hidden;
}

/* The left rail: which line this is, and what it needs at its busiest. */
.egl-mreq-rail {
    padding: .875rem 1rem;
    background: var(--egl-surface-2);
    border-right: 1px solid var(--egl-border);
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.egl-mreq-stints {
    min-width: 0;
}

@media (max-width: 860px) {
    .egl-mreq-card {
        grid-template-columns: minmax(0, 1fr);
    }

    .egl-mreq-rail {
        border-right: 0;
        border-bottom: 1px solid var(--egl-border);
        flex-direction: row;
        align-items: baseline;
        justify-content: space-between;
        gap: .75rem;
    }
}

.egl-mreq-line {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--egl-text);
}

.egl-mreq-line-meta {
    font-size: .75rem;
    color: var(--egl-text-muted);
}

/* One style running on that line. Several may sit in one card - that is the
   whole point of the card, and why they are separated by a rule rather than
   run together. */
.egl-mreq-stint {
    padding: .75rem 1rem;
}

.egl-mreq-stint + .egl-mreq-stint {
    border-top: 1px dashed var(--egl-border);
}

.egl-mreq-stint-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
    flex-wrap: wrap;
}

/* The dates and the day count sit on their own line on a phone rather than
   being squeezed against the style name. */
.egl-mreq-when {
    font-size: .75rem;
    color: var(--egl-text-2);
    white-space: nowrap;
}

.egl-mreq-style {
    font-weight: 600;
    color: var(--egl-text);
}

.egl-mreq-sub {
    font-size: .75rem;
    color: var(--egl-text-muted);
    margin-top: .125rem;
}

.egl-mreq-total {
    font-weight: 700;
    color: var(--egl-ok);
    white-space: nowrap;
}

.egl-mreq-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
    margin-top: .5rem;
}

.egl-mreq-chip {
    display: inline-flex;
    align-items: baseline;
    gap: .3rem;
    padding: .15rem .45rem;
    border-radius: .375rem;
    background: var(--egl-muted-soft);
    border: 1px solid var(--egl-muted-border);
    font-size: .7rem;
    color: var(--egl-text-2);
}

.egl-mreq-chip b {
    color: var(--egl-ok);
    font-weight: 700;
}

.egl-mreq-actions {
    display: flex;
    gap: .375rem;
    margin-top: .625rem;
}

.egl-mreq-blockhead {
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--egl-text-muted);
    margin: 1.5rem 0 .625rem;
}

.egl-mreq-blockhead:first-child {
    margin-top: 0;
}

.egl-mreq-empty {
    padding: 2.5rem 1rem;
    text-align: center;
    color: var(--egl-text-muted);
}

.egl-mreq-note {
    font-size: .75rem;
    color: var(--egl-text-muted);
    margin-top: .25rem;
}

.egl-mreq-peak {
    text-align: right;
}

/* --------------------------------------------------------------------------
   Phase 13C - the availability dashboard.

   Same family, same reason. Everything the dashboard needs that the frozen
   bundle might not have is written here as real CSS under egl-mreq-, a name
   the compiled bundle has never heard of, so none of it can repaint a page
   that already works. FrozenBundleClassTest re-checks that every run, and
   from 13C it reads this module's whole view folder rather than plans/ alone.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Phase 13C-9 - the module's tabs, as a segmented control.

   Aomith on 9 September: "eigula ke button er moto design kore daw, sundor
   colourfull jeno professional lage". They were six words on a hairline, and
   with six of them the row read as a sentence rather than as a set of places
   to go.

   WHERE THE COLOUR COMES FROM, AND WHY IT IS NOT ON THE FILL. The sidebar has
   given every entry its own colour since 10J, and those ten --egl-nav- tokens
   are declared for BOTH appearances - so a tab carrying one of them is the
   same idea the sidebar already uses, and the eye reads the two as one system.

   The colour sits on the DOT and, when a tab is on, on its text and its
   underline - never as the pill's fill. That is deliberate: the light
   appearance sets these tokens saturated (#2563eb) and the dark one sets them
   pale (#60a5fa), so a solid fill would need white text in one appearance and
   dark text in the other, and the first person to add a tab would get it
   wrong. Against the surface both shades read correctly with no rule knowing
   which appearance is on - which is the rule this whole stylesheet is built
   around.

   His standing instruction is that a new module screen must look right in
   LIGHT first. This one was drawn that way and then checked dark.
   -------------------------------------------------------------------------- */
.egl-mreq-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
    margin-bottom: 1.25rem;
    padding: .375rem;
    background: var(--egl-surface-2);
    border: 1px solid var(--egl-border);
    border-radius: .75rem;
}

.egl-mreq-tab {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .5rem .875rem;
    font-size: .8125rem;
    font-weight: 600;
    line-height: 1.25;
    color: var(--egl-text-2);
    background: transparent;
    border: 1px solid transparent;
    border-radius: .5rem;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease, box-shadow .15s ease;
}

/* The dot. Small enough to be a mark rather than a decoration, and it is what
   carries the tab's colour when the tab is not the one you are on. */
.egl-mreq-tab::before {
    content: "";
    flex: none;
    width: .4375rem;
    height: .4375rem;
    border-radius: 9999px;
    background: var(--egl-text-muted);
}

.egl-mreq-tab:hover {
    color: var(--egl-text);
    background: var(--egl-surface-3);
}

/* The one you are on is lifted off the strip: it gets the surface colour, a
   real border and a shadow, so it reads as pressed rather than as underlined. */
.egl-mreq-tab--on {
    color: var(--egl-text);
    background: var(--egl-surface);
    border-color: var(--egl-border-strong);
    box-shadow: var(--egl-shadow);
    font-weight: 700;
}

/* One rule per tone. The dot always; the text and the underline only when the
   tab is the one you are on. */
.egl-mreq-tab--blue::before   { background: var(--egl-nav-blue); }
.egl-mreq-tab--teal::before   { background: var(--egl-nav-teal); }
.egl-mreq-tab--violet::before { background: var(--egl-nav-violet); }
.egl-mreq-tab--green::before  { background: var(--egl-nav-green); }
.egl-mreq-tab--amber::before  { background: var(--egl-nav-amber); }
.egl-mreq-tab--sky::before    { background: var(--egl-nav-sky); }
/* Phase 13C-11 - the seventh tab. Rose was free; reusing one of the six would
   undo exactly what giving them colours was for. */
.egl-mreq-tab--rose::before   { background: var(--egl-nav-rose); }

.egl-mreq-tab--blue.egl-mreq-tab--on   { color: var(--egl-nav-blue);   box-shadow: var(--egl-shadow), inset 0 -2px 0 0 var(--egl-nav-blue); }
.egl-mreq-tab--teal.egl-mreq-tab--on   { color: var(--egl-nav-teal);   box-shadow: var(--egl-shadow), inset 0 -2px 0 0 var(--egl-nav-teal); }
.egl-mreq-tab--violet.egl-mreq-tab--on { color: var(--egl-nav-violet); box-shadow: var(--egl-shadow), inset 0 -2px 0 0 var(--egl-nav-violet); }
.egl-mreq-tab--green.egl-mreq-tab--on  { color: var(--egl-nav-green);  box-shadow: var(--egl-shadow), inset 0 -2px 0 0 var(--egl-nav-green); }
.egl-mreq-tab--amber.egl-mreq-tab--on  { color: var(--egl-nav-amber);  box-shadow: var(--egl-shadow), inset 0 -2px 0 0 var(--egl-nav-amber); }
.egl-mreq-tab--sky.egl-mreq-tab--on    { color: var(--egl-nav-sky);    box-shadow: var(--egl-shadow), inset 0 -2px 0 0 var(--egl-nav-sky); }
.egl-mreq-tab--rose.egl-mreq-tab--on   { color: var(--egl-nav-rose);   box-shadow: var(--egl-shadow), inset 0 -2px 0 0 var(--egl-nav-rose); }

/* A phone gets one strip it can push sideways rather than four wrapped rows. */
@media (max-width: 640px) {
    .egl-mreq-tabs {
        flex-wrap: nowrap;
        overflow-x: auto;
    }
}

/* The three source cards. auto-fit rather than a fixed three, so a narrow
   window reflows to two and then to one instead of scrolling sideways - the
   numbers on these cards are the ones people read on a phone. */
.egl-mreq-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: .75rem;
    margin-bottom: .75rem;
}

.egl-mreq-stat {
    background: var(--egl-surface);
    border: 1px solid var(--egl-border);
    border-radius: .75rem;
    padding: .875rem 1rem;
}

.egl-mreq-stat-label {
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--egl-text-muted);
}

.egl-mreq-stat-value {
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1.15;
    color: var(--egl-text);
    font-variant-numeric: tabular-nums;
}

.egl-mreq-stat-meta {
    font-size: .75rem;
    color: var(--egl-text-muted);
}

.egl-mreq-stat-list {
    list-style: none;
    margin: .625rem 0 0;
    padding: .625rem 0 0;
    border-top: 1px dashed var(--egl-border);
    font-size: .75rem;
    color: var(--egl-text-2);
}

.egl-mreq-stat-list li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
}

.egl-mreq-stat-list li + li {
    margin-top: .25rem;
}

.egl-mreq-stat-list b {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* The one-line total under the cards. */
.egl-mreq-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .5rem .875rem;
    padding: .625rem 1rem;
    margin-bottom: .25rem;
    background: var(--egl-ok-soft);
    border: 1px solid var(--egl-ok-border);
    border-radius: .75rem;
}

.egl-mreq-strip-label {
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--egl-text-muted);
}

.egl-mreq-strip-value {
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--egl-ok);
    font-variant-numeric: tabular-nums;
}

.egl-mreq-strip-sum {
    font-size: .75rem;
    color: var(--egl-text-2);
}

/* A wide table on a narrow screen scrolls INSIDE its own box. Without this
   the page itself scrolls sideways and the sidebar goes with it, which is
   what nine columns on a 360px handset would otherwise do. */
.egl-mreq-tablewrap {
    overflow-x: auto;
}

.egl-mreq-table {
    width: 100%;
    border-collapse: collapse;
    font-size: .8125rem;
}

.egl-mreq-table th,
.egl-mreq-table td {
    padding: .5rem .75rem;
    text-align: left;
    border-bottom: 1px solid var(--egl-border);
}

/* A NUMBER never wraps - 1,278 broken across two lines is unreadable. */
.egl-mreq-table td {
    white-space: nowrap;
}

/* A HEADING does wrap. "Rent (External Supplier)" says exactly what the
   column is, and a column heading that says what it means is worth two lines
   - the alternative is a short heading that has to be explained every time
   somebody new opens the page. They sit on the bottom line so the headings
   and the first row still read as one band however tall the tallest gets. */
.egl-mreq-table th {
    white-space: normal;
    overflow-wrap: break-word;
    vertical-align: bottom;
}

.egl-mreq-table thead th.egl-mreq-num,
.egl-mreq-table tfoot th.egl-mreq-num {
    min-width: 5.5rem;
}

.egl-mreq-table thead th {
    position: sticky;
    top: 0;
    background: var(--egl-surface-2);
    font-size: .7rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--egl-text-muted);
}

.egl-mreq-table tbody tr:hover {
    background: var(--egl-muted-soft);
}

.egl-mreq-table tfoot th {
    background: var(--egl-surface-2);
    font-weight: 700;
    color: var(--egl-text);
    border-bottom: 0;
}

/* Aomith asked for the numbers in the middle of the column, the way a sheet
   is read. tabular-nums stays: it is what stops 1 being narrower than 8, so a
   column of figures still lines up under itself instead of shuffling. */
.egl-mreq-table .egl-mreq-num {
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.egl-mreq-typename {
    color: var(--egl-text);
    font-weight: 500;
}

/* Machines that exist but cannot be used - maintenance, or standing in
   another factory. Stated, never hidden: a shortage nobody can see is worse
   than a shortage. */
.egl-mreq-off {
    color: var(--egl-danger);
    font-weight: 700;
}

.egl-mreq-have {
    color: var(--egl-ok);
    font-weight: 700;
}

/* Nothing of this type anywhere. Amber rather than red - it is not a fault,
   it is the sentence "if you plan for this, you must buy it". */
.egl-mreq-none {
    color: var(--egl-warn);
    font-weight: 700;
}

.egl-mreq-tag {
    display: inline-block;
    margin-left: .375rem;
    padding: .05rem .35rem;
    border-radius: .3rem;
    background: var(--egl-warn-soft);
    border: 1px solid var(--egl-warn-border);
    font-size: .65rem;
    font-weight: 600;
    color: var(--egl-warn);
    white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Phase 13C-2a - the buffer page.

   Same family, same reason: written here as real CSS under egl-mreq-, a name
   the frozen bundle has never heard of, so none of it can repaint a page that
   already works. Both appearances are served by the same declarations through
   tokens that are defined for each, so this reads properly in LIGHT mode as
   well - Aomith asked for that before the theme pass, not after it.
   -------------------------------------------------------------------------- */

/* The percent box. A stated width, because egl-input is width:100% and in a
   table cell that makes a three-character number as wide as the column. This
   is the same fault w-24's absence caused on the entry grid in 13B-1 - the
   answer is to say the width here rather than reach for a utility the frozen
   bundle may not have. */
.egl-mreq-pct {
    width: 6.5rem;
    max-width: 100%;
    text-align: center;
    display: inline-block;
}

/* A table cell holding an input needs room to breathe, or the box touches the
   rule above it. */
.egl-mreq-table td .egl-mreq-pct {
    margin: -.125rem 0;
}

.egl-mreq-lead {
    color: var(--egl-text-2);
    font-size: .875rem;
    margin-bottom: .5rem;
}

/* The count of machine types nobody has set a buffer for. Amber, not red: it
   is not a fault, it is a sentence - "these will plan exactly what the sheet
   says, and somebody should mean that". */
.egl-mreq-warntext {
    color: var(--egl-warn);
    font-weight: 600;
}

/* --------------------------------------------------------------------------
   Phase 13C-2b - the period picker.

   Same family, same tokens, so it reads in light as well as dark before the
   theme pass ever happens.
   -------------------------------------------------------------------------- */

.egl-mreq-period {
    display: grid;
    /* Phase 13C-2e - 13rem, not 11. Aomith drew a box round "Monthly - whole
       month" running to the edge of its own field. The label is shorter now,
       but the week option ("Week 2 - 5 Sep - 10 Sep") is longer than either,
       and a dropdown whose text touches its border reads as broken however
       correct it is. */
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: .75rem;
    align-items: end;
    padding: .875rem 1rem;
    margin-bottom: 1rem;
    background: var(--egl-surface);
    border: 1px solid var(--egl-border);
    border-radius: .75rem;
}

.egl-mreq-period-field {
    min-width: 0;
}

/* And the belt to that brace: a select whose chosen option is longer than the
   box trims it with an ellipsis instead of pushing past the border. Room for
   the arrow on the right, so the text never sits under it. */
.egl-mreq-period-field .egl-input {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding-right: 2rem;
}

/* Phase 13C-2e - a two-column page header: the period picker on the left and
   a panel on the right.

   PHASE 13C-3b - NOT IN USE, AND KEPT ON PURPOSE. Aomith had the explanation
   panel removed from the Requirement + Buffer % page and said what is going
   there instead: "amra theme er kaj korar somoy akhane image add korbo". The
   rules are left standing for that day rather than deleted and written again
   from memory, which is how a layout comes back slightly different. */
.egl-mreq-headrow {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 1rem;
    align-items: stretch;
    margin-bottom: 1rem;
}

.egl-mreq-headrow > * {
    min-width: 0;
    margin-bottom: 0;
}

.egl-mreq-headnote {
    padding: .875rem 1rem;
    background: var(--egl-surface);
    border: 1px solid var(--egl-border);
    border-radius: .75rem;
}

@media (max-width: 1023px) {
    .egl-mreq-headrow {
        grid-template-columns: 1fr;
    }
}

/* One line of "how to fill this in", said in the units the boxes take. */
.egl-mreq-howto {
    margin-top: .35rem;
    font-size: .78rem;
    line-height: 1.45;
    color: var(--egl-text-muted);
}

.egl-mreq-howto b {
    color: var(--egl-text);
}

/* A figure that was not set for THIS period but carried in from an earlier
   one. Not a warning - it is normal - but worth being able to see. */
.egl-mreq-inherited {
    color: var(--egl-text-muted);
}

/* Phase 13C-3 - which day this machine type is heaviest on. Under the figure
   rather than beside it, because the figure is what the eye runs down and the
   date is what it stops for. */
/* --------------------------------------------------------------------------
   Phase 13C-3h - the coverage line under the two date boxes.

   It answers, before the question is asked, the one Aomith spent an evening
   on: which weeks does this run touch, and do I have to enter it again for
   the next one. Built only from tokens that already exist in BOTH theme
   blocks, so it needs no new colour and cannot drift between light and dark.
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Phase 13C-4a - a weekly revision, and the idle tick that goes with it.

   Only tokens that already exist in BOTH theme blocks, so nothing new has to
   be kept in step between light and dark.
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Phase 13C-6 - the Release Advisor.

   Three counts across the top and two tables under them. The rent card is the
   only red thing on the page: it is the one that costs money if it is missed.
   Every colour is a token that already exists in BOTH theme blocks.
   -------------------------------------------------------------------------- */
.egl-mreq-advicerow {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: .75rem;
    margin: 0 0 1rem;
}

.egl-mreq-advicecard {
    border-left: 3px solid var(--egl-border-strong);
}

.egl-mreq-advicecard--rent {
    border-left-color: var(--egl-danger);
}

.egl-mreq-advicecard--back {
    border-left-color: var(--egl-ok);
}

.egl-mreq-advicehead {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--egl-text-muted);
}

.egl-mreq-advicebig {
    margin-top: .15rem;
    font-size: 1.75rem;
    font-weight: 800;
    line-height: 1.1;
    color: var(--egl-text);
    font-variant-numeric: tabular-nums;
}

.egl-mreq-advicecard--rent .egl-mreq-advicebig {
    color: var(--egl-danger);
}

.egl-mreq-advicecard--back .egl-mreq-advicebig {
    color: var(--egl-ok);
}

.egl-mreq-advicetitle {
    margin: 1.25rem 0 .5rem;
    font-size: .95rem;
    font-weight: 700;
    color: var(--egl-text);
}

/* --------------------------------------------------------------------------
   Phase 13C-5 - the date-wise grid.

   Thirty narrow columns and one wide first column that has to stay readable
   while the rest scrolls sideways. Every colour is a token that already
   exists in BOTH theme blocks, so nothing new has to be kept in step.
   -------------------------------------------------------------------------- */
.egl-mreq-gridbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: .75rem;
    margin: 0 0 .75rem;
}

.egl-mreq-shapes {
    display: inline-flex;
    border: 1px solid var(--egl-border);
    border-radius: .45rem;
    overflow: hidden;
}

.egl-mreq-shape {
    padding: .35rem .8rem;
    font-size: .78rem;
    font-weight: 600;
    color: var(--egl-text-2);
    background: var(--egl-surface-2);
    text-decoration: none;
}

.egl-mreq-shape + .egl-mreq-shape {
    border-left: 1px solid var(--egl-border);
}

.egl-mreq-shape--on {
    background: var(--egl-primary-soft);
    color: var(--egl-primary);
}

.egl-mreq-gridfilter {
    display: flex;
    align-items: center;
    gap: .5rem;
}

.egl-mreq-gridfilter .egl-input {
    width: auto;
    min-width: 9rem;
}

/* The first column stays put while the dates scroll under it - a grid whose
   row labels slide off the screen is a grid nobody can read. */
/* Phase 13C-8 - these two were written as .egl-mreq-grid, which .egl-mreq-grid
   above already owns as "display: grid" for the plan card list. The date table
   carried both names, so the browser made a CSS grid out of a <table> and the
   header stopped lining up with the rows. The date grid has its own name now
   and the card list keeps the old one; nothing else on the page changes. */
.egl-mreq-dategrid .egl-mreq-gridhead {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--egl-surface);
    text-align: left;
    white-space: nowrap;
}

.egl-mreq-dategrid thead .egl-mreq-gridhead {
    z-index: 3;
    background: var(--egl-surface-2);
}

.egl-mreq-daycol {
    min-width: 2.4rem;
    padding-left: .3rem;
    padding-right: .3rem;
    font-variant-numeric: tabular-nums;
}

.egl-mreq-dow {
    display: block;
    font-size: .6rem;
    font-weight: 500;
    color: var(--egl-text-muted);
    text-transform: uppercase;
}

/* Friday belongs to no week. Greyed, never removed: a gap in the middle of a
   month is a fact about the plan. */
.egl-mreq-daycol--off {
    background: var(--egl-bg-2);
    color: var(--egl-text-muted);
}

.egl-mreq-cell {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.egl-mreq-cell--short {
    background: var(--egl-danger-soft);
    color: var(--egl-danger);
    font-weight: 700;
}

.egl-mreq-cellshort {
    display: block;
    font-size: .6rem;
    font-weight: 700;
    color: var(--egl-danger);
}

.egl-mreq-gridtotal td {
    border-top: 2px solid var(--egl-border-strong);
    background: var(--egl-surface-2);
    font-weight: 700;
}

/* --------------------------------------------------------------------------
   Phase 13C-4b - what a weekly plan did to the monthly figure.

   Up is amber, not red: needing more machines is a thing to act on, not a
   fault. Down is the ok colour, because machines freed is good news. Both
   tokens are already defined in BOTH theme blocks.
   -------------------------------------------------------------------------- */
.egl-mreq-change {
    display: inline-block;
    padding: .05rem .35rem;
    border-radius: .3rem;
    font-weight: 700;
    font-size: .72rem;
    white-space: nowrap;
}

.egl-mreq-change--up {
    border: 1px solid var(--egl-warn-border);
    background: var(--egl-warn-soft);
    color: var(--egl-warn);
}

.egl-mreq-change--down {
    border: 1px solid var(--egl-ok-border);
    background: var(--egl-ok-soft);
    color: var(--egl-ok);
}

.egl-mreq-revision {
    display: inline-block;
    margin-left: .35rem;
    padding: .05rem .4rem;
    border: 1px solid var(--egl-warn-border);
    border-radius: .3rem;
    background: var(--egl-warn-soft);
    color: var(--egl-warn);
    font-size: .65rem;
    font-weight: 700;
    letter-spacing: .01em;
    white-space: nowrap;
    vertical-align: .05rem;
}

.egl-mreq-idlebox {
    display: flex;
    align-items: center;
    gap: .45rem;
    margin-top: .6rem;
    padding: .4rem .6rem;
    border: 1px solid var(--egl-warn-border);
    border-radius: .4rem;
    background: var(--egl-warn-soft);
    color: var(--egl-text-2);
    font-size: .75rem;
    cursor: pointer;
}

.egl-mreq-idlebox input {
    width: .9rem;
    height: .9rem;
    accent-color: var(--egl-warn);
    cursor: pointer;
}

.egl-mreq-coverage {
    margin-top: .75rem;
    padding: .5rem .7rem;
    border: 1px solid var(--egl-info-border);
    border-left-width: 3px;
    border-radius: .4rem;
    background: var(--egl-info-soft);
    color: var(--egl-info);
    font-size: .75rem;
    font-weight: 600;
    line-height: 1.35;
}

.egl-mreq-coverage:empty {
    display: none;
}

.egl-mreq-peakday {
    display: block;
    margin-top: .1rem;
    font-size: .68rem;
    font-weight: 500;
    color: var(--egl-text-muted);
    white-space: nowrap;
}

/* Nothing planned for this type in this period. A quiet dash, not a zero in
   the same weight as a real figure - "no plan" and "a plan for none" read the
   same in a column of numbers and they are not the same fact. */
.egl-mreq-dash {
    color: var(--egl-text-muted);
    font-weight: 500;
}

/* Phase 13C-3d - Quantity and SMV on a line card.

   Aomith asked for them bold and coloured, orange or whatever suits. Orange
   suits because nothing else on this card is orange: the machine chips are
   green, the day count and the peak are green, and amber is the module's
   "something needs attention" all the way through. These two are neither -
   they are what the ORDER says, sitting beside what the MACHINES say - so
   they get a colour of their own and read as a different kind of fact.

   A chip rather than plain text: the card already speaks in chips, and a
   number with a word in front of it is easier to find when it has an edge. */
.egl-mreq-orderchip {
    display: inline-flex;
    align-items: baseline;
    gap: .3rem;
    margin: .25rem .35rem 0 0;
    padding: .1rem .45rem;
    border-radius: .35rem;
    background: var(--egl-order-soft);
    border: 1px solid var(--egl-order-border);
    font-size: .7rem;
    font-weight: 600;
    color: var(--egl-order);
    white-space: nowrap;
}

.egl-mreq-orderchip b {
    font-size: .8rem;
    font-weight: 800;
    color: var(--egl-order);
}

/* Never recorded. Kept grey and light on purpose - an absence should not
   shout louder than a figure. */
.egl-mreq-orderchip--none {
    background: transparent;
    border-color: var(--egl-border);
    color: var(--egl-text-muted);
    font-weight: 500;
}

/* The line that says which period is on screen. It spans the row on a wide
   window and sits under the dropdowns on a narrow one - it is the sentence
   that stops somebody reading August's figures as September's. */
.egl-mreq-period-showing {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    padding-top: .625rem;
    border-top: 1px dashed var(--egl-border);
}

.egl-mreq-period-label {
    font-weight: 700;
    color: var(--egl-text);
}

.egl-mreq-period-now {
    padding: .05rem .4rem;
    border-radius: .3rem;
    background: var(--egl-ok-soft);
    border: 1px solid var(--egl-ok-border);
    font-size: .7rem;
    font-weight: 600;
    color: var(--egl-ok);
}

/* The "fill dates from" box on the entry form. */
.egl-mreq-fillperiod {
    padding: .75rem 1rem;
    margin-bottom: 1rem;
    background: var(--egl-muted-soft);
    border: 1px solid var(--egl-muted-border);
    border-radius: .625rem;
}

.egl-mreq-fillperiod .egl-input {
    max-width: 26rem;
}

/* Phase 13C-3e - the entry form asks the period in three boxes now: the year,
   Monthly or Weekly, and then the week. One question per box.

   auto-fit rather than three fixed columns, because the third box is not
   always there - it opens only when Weekly is chosen, and the other two
   should not leave a hole waiting for it. */
.egl-mreq-periodrow {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: .75rem;
    align-items: end;
    max-width: 46rem;
}

.egl-mreq-periodrow .egl-input {
    max-width: 100%;
}

.egl-mreq-periodhead {
    display: block;
    margin-bottom: .5rem;
}

/* The year is shown, not asked. It follows the period the form was opened on,
   so it reads as a fact about the page rather than a box somebody forgot to
   fill in - flat, no focus ring, and the cursor says "not for typing". */
.egl-mreq-readonly {
    background: var(--egl-surface-2);
    color: var(--egl-text-2);
    font-weight: 700;
    cursor: default;
}

.egl-mreq-readonly:focus {
    outline: none;
    box-shadow: none;
}

/* Phase 13C-2c - the Admin's week date boxes. A stated width, because
   egl-input is width:100% and in a table cell that makes a date box as wide
   as the column. Same fault w-24's absence caused on the entry grid. */
.egl-mreq-date {
    width: 10.5rem;
    max-width: 100%;
    text-align: center;
    display: inline-block;
}

.egl-mreq-table td .egl-mreq-date {
    margin: -.125rem 0;
}

/* ==========================================================================
   Phase 74 - the bar that appears when the page did NOT reload.

   Named egl-dash- because it belongs to the shell, which is what carries it,
   and because that prefix is already one the overlay is allowed to style.

   It is only ever shown when somebody has unsaved typing on the page, so it
   has to be impossible to miss and impossible to be in the way: it sits at
   the bottom, clear of the content, and it holds its own button rather than
   asking anybody to find the browser's.
   ========================================================================== */
.egl-dash-refreshnote {
    position: fixed;
    left: 50%;
    bottom: 1.25rem;
    z-index: 60;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: .75rem;
    flex-wrap: wrap;
    max-width: calc(100vw - 2rem);
    padding: .75rem 1rem;
    border: 1px solid color-mix(in srgb, var(--egl-nav-amber) 45%, var(--egl-border));
    border-radius: .875rem;
    background: var(--egl-surface-2);
    color: var(--egl-text-2);
    font-size: .8125rem;
    line-height: 1.4;
    box-shadow: 0 10px 30px -12px color-mix(in srgb, #000 70%, transparent);
}
.egl-dash-refreshnote[hidden] {
    display: none;
}
.egl-dash-refreshnotetext {
    flex: 1 1 16rem;
    min-width: 0;
}
.egl-dash-refreshnotebtn {
    flex: none;
    padding: .375rem .75rem;
    border: 1px solid color-mix(in srgb, var(--egl-nav-amber) 55%, transparent);
    border-radius: .5rem;
    background: color-mix(in srgb, var(--egl-nav-amber) 16%, transparent);
    color: var(--egl-text);
    font-size: .75rem;
    font-weight: 600;
    cursor: pointer;
}
.egl-dash-refreshnotebtn:hover {
    border-color: var(--egl-nav-amber);
}

/* No hover rule here on purpose. The nav link's own hover and active states
   live in the frozen bundle, and reaching them from the overlay would need a
   selector led by .egl-nav-link- - a class the bundle already ships. The
   guard that keeps unscoped rules off frozen UI would refuse it, and rightly:
   the icon should answer to the link's state, not restate it. */

@media (prefers-reduced-motion: reduce) {
    .egl-navicon-box {
        transition: none;
    }
}


/* Phase 19B NOTE - the banner below is placed HERE, not at the end of the
   file, and that is deliberate. The gauge's phone block further down wins
   only by being the LAST rule of its specificity, and DashboardGaugeTest
   holds that by finding the last "flex-direction: column" in the whole
   file. The banner uses that same declaration, so appended at the end it
   quietly became the last one and the gauge's phone layout lost its
   guarantee. Anything new that uses flex-direction: column belongs above
   the gauge block, not below it. */

/* ─── Phase 20C - the Skill Update sheet's own grids ───────────────
   The frozen Tailwind bundle has no grid-cols-5 or grid-cols-6, so the
   sheet's three fixed grids are written here: five cycle-time boxes in
   one row, the six worked-out results, and the five summary boxes at the
   top. Layout only - no colour, so light and dark need nothing. Kept
   ABOVE the gauge block on purpose (see the note there). */
.egl-dash-skill-cycles {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0.5rem;
}
/* 22A - picking operators for one shared skill matrix: the tick in the
   list, the row it marks, and the chips of who is in the basket. */
.egl-sm-tick {
    width: 1.05rem;
    height: 1.05rem;
    accent-color: #2563eb;
    cursor: pointer;
}
.egl-sm-picked > td { background: rgba(37, 99, 235, 0.10); }
.egl-sm-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}
.egl-sm-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    border: 1px solid var(--egl-border);
    background: var(--egl-surface);
    font-size: 0.78rem;
    color: var(--egl-text);
}
.egl-sm-chip small { color: var(--egl-text-muted); }
.egl-sm-chip button {
    border: 0;
    background: none;
    color: var(--egl-text-muted);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}
.egl-sm-chip button:hover { color: #dc2626; }

/* 21A - the top bar on a phone. The row may wrap, the page's own header
   may shrink (min-width: 0), and Profile / Log Out keep their size and move
   to the right of their own line. Nothing changes on a wide screen, where
   everything already fits on one line. */
.egl-dash-shell-headrow { flex-wrap: wrap; }
.egl-dash-shell-headleft { min-width: 0; flex: 1 1 18rem; }
.egl-dash-shell-headleft > div { min-width: 0; }
.egl-dash-shell-headright { flex-shrink: 0; margin-left: auto; }

/* 20E-4 - the Skill Dashboard's donut cards: one per block, one per
   machine family. The ring is a conic gradient cut by a radial mask, so the
   middle is truly empty and the card behind shows in light and in dark. */
.egl-dash-skilldonuts {
    display: grid;
    gap: 0.75rem;
}
.egl-dash-skilldonuts--blocks { grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); }
.egl-dash-skilldonuts--machines { grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); }
.egl-dash-skilldonut {
    border: 1px solid var(--egl-border);
    border-radius: 0.75rem;
    padding: 0.75rem 0.7rem;
    background: var(--egl-surface);
}
.egl-dash-skilldonut__name {
    margin: 0 0 0.5rem;
    font-weight: 600;
    font-size: 0.875rem;
    color: var(--egl-text);
}
.egl-dash-skilldonut__body {
    display: grid;
    grid-template-columns: 4.6rem minmax(0, 1fr);
    align-items: center;
    gap: 0.6rem;
}
.egl-dash-skilldonut--machine {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 5.25rem 3.25rem;
    align-items: center;
    gap: 0.75rem;
}
.egl-dash-skilldonut--machine .egl-dash-skilldonut__name { margin: 0; align-self: start; }
.egl-dash-skilldonut__chart {
    position: relative;
    width: 5.25rem;
    height: 5.25rem;
}
.egl-dash-skilldonut__body .egl-dash-skilldonut__chart { width: 4.6rem; height: 4.6rem; }
.egl-dash-skilldonut__ring {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    -webkit-mask: radial-gradient(farthest-side, transparent 60%, #000 61%);
    mask: radial-gradient(farthest-side, transparent 60%, #000 61%);
}
.egl-dash-skilldonut__total {
    position: absolute;
    inset: 0;
    display: grid;
    place-content: center;
    text-align: center;
    font-weight: 700;
    font-size: 1rem;
    line-height: 1.1;
    color: var(--egl-text);
}
.egl-dash-skilldonut__total small {
    display: block;
    font-weight: 500;
    font-size: 0.65rem;
    color: var(--egl-text-muted);
}
.egl-dash-skilldonut__list {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 0.78rem;
    line-height: 1.55;
    color: var(--egl-text);
    white-space: nowrap;
}
.egl-dash-skill-legend i.egl-dash-skillbar__a, .egl-dash-skill-legend i.egl-dash-skillbar__b,
.egl-dash-skill-legend i.egl-dash-skillbar__c, .egl-dash-skill-legend i.egl-dash-skillbar__d,
.egl-dash-skill-legend i.egl-dash-skillbar__none { border-radius: 50%; }
.egl-dash-skilldonut__list i {
    display: inline-block;
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
    margin-right: 0.45rem;
}

/* 20E-2 - the dashboard's unit and block drop-downs: room for the arrow,
   and the two side by side (.egl-input's padding hides the select arrow) */
.egl-dash-skill-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}
.egl-dash-skill-filters .egl-dash-skill-filter {
    width: auto;
    min-width: 9.5rem;
    padding-right: 2.5rem;
}
/* 20A-4f - the operator's photo in a portrait (3:4) frame */
.egl-dash-skill-photo {
    width: 100%;
    max-width: 15rem;
    aspect-ratio: 3 / 4;
    margin: 1.25rem auto;
    border-radius: 0.75rem;
    overflow: hidden;
    border: 1px solid rgba(148, 163, 184, 0.35);
    background: rgba(148, 163, 184, 0.12);
}
.egl-dash-skill-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.egl-dash-skill-photo__empty {
    width: 100%;
    height: 100%;
    display: grid;
    place-content: center;
    justify-items: center;
    text-align: center;
    color: #64748b;
}
.egl-dash-skill-results {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.5rem;
}
.egl-dash-skill-summary {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
}
/* Phase 20E - the Skill Dashboard's grid bars. Colours are the meaning
   tokens, declared for both appearances, so nothing here needs a dark copy. */
.egl-dash-skillrow {
    display: grid;
    grid-template-columns: 9rem minmax(0, 1fr) 4.5rem;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.6rem;
}
.egl-dash-skillrow__name { font-weight: 600; font-size: 0.875rem; color: var(--egl-text); }
.egl-dash-skillrow__num { text-align: right; font-size: 0.8rem; color: var(--egl-text-muted); }
.egl-dash-skillrow__detail { margin: 0.15rem 0 0 9.75rem; font-size: 0.72rem; color: var(--egl-text-muted); }
.egl-dash-skillbar {
    display: flex;
    height: 0.95rem;
    border-radius: 0.4rem;
    overflow: hidden;
    background: var(--egl-muted-soft);
}
.egl-dash-skillbar > i { display: block; height: 100%; }
.egl-dash-skillbar__a { background: var(--egl-ok); }
.egl-dash-skillbar__b { background: var(--egl-info); }
.egl-dash-skillbar__c { background: var(--egl-warn); }
.egl-dash-skillbar__d { background: var(--egl-danger); }
.egl-dash-skillbar__none { background: var(--egl-muted-border); }
.egl-dash-skill-legend { display: flex; flex-wrap: wrap; gap: 1rem; font-size: 0.8rem; color: var(--egl-text-muted); }
.egl-dash-skill-legend i { display: inline-block; width: 0.7rem; height: 0.7rem; border-radius: 0.2rem; margin-right: 0.3rem; vertical-align: middle; }
@media (max-width: 640px) {
    .egl-dash-skillrow { grid-template-columns: 6.5rem minmax(0, 1fr) 3.5rem; }
    .egl-dash-skillrow__detail { margin-left: 7.25rem; }
}
@media (min-width: 1024px) {
    .egl-dash-skill-results { grid-template-columns: repeat(7, minmax(0, 1fr)); }
    .egl-dash-skill-summary { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* ==========================================================================
   Phase 19B — the Rental Machine Dashboard's opening banner.
   --------------------------------------------------------------------------
   Aomith sent a mock-up and asked for this page to look like it: a wide
   banner carrying the page's own name and one photograph, then the cards
   lined up underneath in even rows.

   Written as real CSS in the overlay, not as Tailwind utilities, for the
   reason this file exists at all: the compiled bundle is FROZEN, so a
   utility class nobody has used before is simply absent and does nothing,
   silently. Everything below is declared here and therefore actually runs.

   Every colour is a token that is declared for BOTH appearances, so the
   banner is correct in light and in dark without a second set of rules.
   ========================================================================== */
.egl-dash-hero {
    position: relative;
    display: grid;
    grid-template-columns: 1fr;
    gap: 0;
    margin-bottom: 1.5rem;
    border: 1px solid var(--egl-border);
    border-radius: 1.25rem;
    overflow: hidden;
    background: var(--egl-surface);
    box-shadow: var(--egl-shadow);
}

@media (min-width: 900px) {
    .egl-dash-hero {
        grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    }
}

.egl-dash-hero__text {
    padding: 1.75rem 1.75rem 1.5rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: .5rem;
    min-width: 0;
}

.egl-dash-hero__eyebrow {
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--egl-text-muted);
}

.egl-dash-hero__title {
    font-size: 1.75rem;
    line-height: 1.15;
    font-weight: 700;
    color: var(--egl-text);
    margin: 0;
}

@media (min-width: 900px) {
    .egl-dash-hero__title { font-size: 2.1rem; }
}

.egl-dash-hero__lead {
    font-size: .9rem;
    line-height: 1.5;
    color: var(--egl-text-2);
    margin: 0;
    max-width: 46ch;
}

/* The photograph. Its own background is dark, so it is given a frame of its
   own rather than being laid on the light banner, where it would read as a
   hole rather than a picture. */
.egl-dash-hero__art {
    position: relative;
    min-height: 190px;
    background: #0b1220;
}

.egl-dash-hero__art img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
}

/* A soft wash on the joining edge so the photograph meets the banner instead
   of being cut against it. Only on the wide layout - stacked on a phone the
   two sit one above the other and need no blend. */
@media (min-width: 900px) {
    .egl-dash-hero__art::after {
        content: '';
        position: absolute;
        inset: 0 auto 0 0;
        width: 22%;
        background: linear-gradient(to right, var(--egl-surface), transparent);
    }
}

/* A caption over the picture, the way the mock-up carries one. */
.egl-dash-hero__caption {
    position: absolute;
    right: 1rem;
    bottom: .9rem;
    z-index: 1;
    padding: .35rem .7rem;
    border-radius: 999px;
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .02em;
    color: #ffffff;
    background: rgba(15, 23, 42, .55);
    backdrop-filter: blur(4px);
}

/* ========================================================================
   Phase 10K - the Fleet Utilisation legend on a phone.

   On a handset the ring and the legend were fighting over about 330px: the
   ring took 168, the share column 60 and the count another 55, which left the
   NAME column almost nothing. "Active" disappeared entirely, "Idle" became
   "I..." and "Under Maintenance" became "U..." - the three words that say
   what the numbers mean.

   Aomith suggested smaller type. That would buy a few characters and cost
   legibility on a factory floor, and the names would still clip on a narrower
   handset - it treats the symptom. The room is the problem, so the ring moves
   ABOVE the legend on a phone and the legend gets the card's full width.
   Nothing shrinks to fit. The ring gives up 1.5rem only so the card does not
   end up taller than it was.

   WHY THIS BLOCK IS AT THE END OF THE FILE, which matters more than it looks:
   these selectors have the same specificity as the desktop ones above, so the
   LAST one in the file wins. Written any earlier - for instance inside the
   card-picture media query, where it was first drafted - the desktop
   width: 10.5rem and max-width: 20rem further down would have overridden it
   and the fix would have done nothing at any screen size.
   ======================================================================== */
@media (max-width: 640px) {
    .egl-dash-gauge__split {
        flex-direction: column;
        gap: 1rem;
    }

    .egl-dash-gauge__ring {
        width: 9rem;
        height: 9rem;
    }

    .egl-dash-gauge__legend {
        width: 100%;
        max-width: none;
    }
}

/* ============================================================================
   Phase 11A — the application shell, and the shared statistic card.

   layouts/dashboard.blade.php wraps EVERY page in the app, and it still spelled
   its colours out as Tailwind slate classes: text-white on the brand line,
   text-slate-400 on the sub-heading, border-slate-800/80 on the rules between
   sections, bg-slate-800/40 on the box holding the signed-in person. Those are
   correct on navy and wrong on white, so in light mode the furniture around the
   page kept the dark palette while the page itself turned pale.

   Everything below takes its colours from tokens declared for BOTH appearances,
   so one rule set is right in either and no rule needs a theme scope.

   Two constraints shaped the names:

     - the overlay guard requires every selector to be theme-scoped OR to start
       with .egl-(settings|theme|mech|login|profile|form|env|dash|navicon)- .
       The shell IS the dashboard layout, so egl-dash-shell- fits without
       widening that list;
     - a compound selector must START with an allowed class. That is why the
       brand's hover is written from .egl-dash-shell-brandlink and not from the
       Tailwind .group class the markup used to hang it on.

   Nothing here rebuilds Tailwind. Every length is spelled out in rem so it does
   not depend on a utility existing in the frozen bundle.
   ============================================================================ */

/* ---- rules between sections ---------------------------------------------- */
.egl-dash-shell-rule { border-bottom: 1px solid var(--egl-border); }
.egl-dash-shell-rule-top { border-top: 1px solid var(--egl-border); }

/* ---- the brand block at the top of the sidebar --------------------------- */
.egl-dash-shell-eyebrow {
    font-size: .625rem;
    line-height: 1rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    font-weight: 500;
    color: var(--egl-text-muted);
}

.egl-dash-shell-brand {
    margin-top: .5rem;
    font-size: 1rem;
    line-height: 1.5rem;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--egl-text);
    transition: color .15s ease;
}

.egl-dash-shell-brandlink:hover .egl-dash-shell-brand { color: var(--egl-primary); }

.egl-dash-shell-sub {
    margin-top: .25rem;
    font-size: .75rem;
    line-height: 1rem;
    color: var(--egl-text-3);
}

/* ---- the two icon-only buttons (open / close the sidebar on a phone) ------ */
.egl-dash-shell-iconbtn {
    padding: .5rem;
    border-radius: .5rem;
    color: var(--egl-text-3);
    transition: color .15s ease, background-color .15s ease;
}

.egl-dash-shell-iconbtn:hover {
    color: var(--egl-text);
    background-color: var(--egl-surface-3);
}

/* ---- the signed-in person, at the foot of the sidebar -------------------- */
.egl-dash-shell-userbox {
    padding: .75rem;
    border-radius: .75rem;
    background-color: var(--egl-surface-2);
    border: 1px solid var(--egl-border);
}

/* The placeholder shown until someone uploads a photograph. The gradient is
   built from tokens so it is a soft tint of the accent in either appearance,
   rather than the fixed navy it used to be. */
.egl-dash-shell-avatar {
    width: 2.25rem;
    height: 2.25rem;
    border-radius: .5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background-image: linear-gradient(to bottom right, var(--egl-primary-soft), var(--egl-surface-3));
    color: var(--egl-primary);
}

.egl-dash-shell-username {
    font-size: .875rem;
    line-height: 1.25rem;
    font-weight: 500;
    color: var(--egl-text);
}

.egl-dash-shell-useremail {
    font-size: .75rem;
    line-height: 1rem;
    color: var(--egl-text-muted);
}

.egl-dash-shell-rolechip {
    display: inline-block;
    margin-top: .625rem;
    padding: .125rem .5rem;
    font-size: .75rem;
    line-height: 1rem;
    font-weight: 500;
    border-radius: .375rem;
    background-color: var(--egl-surface-3);
    color: var(--egl-text-2);
    border: 1px solid var(--egl-border);
}

/* ---- the header strip ---------------------------------------------------- */
.egl-dash-shell-title {
    font-size: 1.25rem;
    line-height: 1.75rem;
    font-weight: 600;
    color: var(--egl-text);
}

.egl-dash-shell-profilelink {
    color: var(--egl-text-3);
    transition: color .15s ease;
}

.egl-dash-shell-profilelink:hover { color: var(--egl-text); }

/* ============================================================================
   Phase 11A — <x-stat-card>, the card used by the alarm history, the mechanic
   engagement page, the rental dashboard and the import preview.

   It could not simply be given tokens, because its colours arrive from the CALL
   SITES: every page passes strings like icon-bg="bg-teal-900/40 text-teal-400"
   and value-color="text-teal-400". Those are dark-mode colours written into
   four different pages.

   So the card now understands a TONE — a meaning, not a colour — exactly like
   the dashboard's own card does. A page that passes a tone gets the right shade
   in either appearance. A page that still passes icon-bg/value-color keeps
   working unchanged, which is what makes it safe to convert those four pages
   one at a time instead of all at once.
   ============================================================================ */

.egl-dash-statcard__label {
    font-size: .875rem;
    line-height: 1.25rem;
    font-weight: 500;
    color: var(--egl-text-3);
}

.egl-dash-statcard__desc {
    margin-top: .375rem;
    font-size: .875rem;
    line-height: 1.25rem;
    color: var(--egl-text-muted);
}

.egl-dash-statcard__footer {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--egl-border);
}

.egl-dash-statcard__value {
    margin-top: .5rem;
    font-size: 1.875rem;
    line-height: 2.25rem;
    font-weight: 700;
    letter-spacing: -.02em;
}

.egl-dash-statcard__value--info   { color: var(--egl-info); }
.egl-dash-statcard__value--ok     { color: var(--egl-ok); }
.egl-dash-statcard__value--warn   { color: var(--egl-warn); }
.egl-dash-statcard__value--danger { color: var(--egl-danger); }
.egl-dash-statcard__value--muted  { color: var(--egl-text); }

.egl-dash-statcard__icon--info   { background-color: var(--egl-info-soft);   color: var(--egl-info); }
.egl-dash-statcard__icon--ok     { background-color: var(--egl-ok-soft);     color: var(--egl-ok); }
.egl-dash-statcard__icon--warn   { background-color: var(--egl-warn-soft);   color: var(--egl-warn); }
.egl-dash-statcard__icon--danger { background-color: var(--egl-danger-soft); color: var(--egl-danger); }
.egl-dash-statcard__icon--muted  { background-color: var(--egl-muted-soft);  color: var(--egl-muted-tone); }

/* ============================================================================
   Phase 11B — the panels light mode was never told about.

   The overlay already carries 148 light-scoped rules. It remaps .text-slate-*,
   .bg-slate-*, .border-slate-*, the gradients, even the exceptions that keep
   white text white on a coloured button. That work was done properly.

   Three classes were simply missed, and they happen to be the ones that draw
   the big boxes on almost every page:

       .egl-filter-panel   the Import box AND the Filter Records box
       .egl-table-panel    the box the results table sits in
       .egl-main           the area the page is painted on

   The result is the worst of both: the TEXT inside them followed the light
   rules and went dark, while the BOX kept its navy from the frozen bundle. So
   the machine list read as dark grey on dark navy - present, but unreadable.
   Aomith's screenshot is exactly that.

   Every rule here is scoped to html[data-theme='light']. In dark mode they do
   not exist at all, so the appearance everyone uses today cannot move a pixel.
   ============================================================================ */

html[data-theme='light'] .egl-main {
    background-color: var(--egl-bg-2);
}

/* Only the colours are set, never the border WIDTH: the frozen bundle already
   draws these boxes, and adding a border here would nudge every page's layout
   by a pixel for no reason. */
html[data-theme='light'] .egl-filter-panel,
html[data-theme='light'] .egl-table-panel {
    background-color: var(--egl-surface);
    border-color: var(--egl-border);
    box-shadow: var(--egl-shadow);
}

html[data-theme='light'] .egl-card-body {
    color: var(--egl-text-2);
}

/* The file picker's own button is a ::file-selector-button, not an element the
   .bg-slate-800 rule can reach - a Tailwind file: variant compiles to a
   pseudo-element selector, so it needs saying separately. Without this the
   Choose File button stayed charcoal on white. */
html[data-theme='light'] .file\:bg-slate-800::file-selector-button {
    background-color: var(--egl-surface-3);
}

html[data-theme='light'] .file\:text-slate-300::file-selector-button,
html[data-theme='light'] .file\:text-slate-200::file-selector-button {
    color: var(--egl-text-2);
}

html[data-theme='light'] .hover\:file\:bg-slate-700:hover::file-selector-button {
    background-color: var(--egl-border-strong);
}

/* The small square behind a card's icon. Its fill is passed in by each page as
   a Tailwind string, so this only gives the shape an edge it can be seen by on
   white; the four pages that pass one are converted to a tone as each is
   reached. */
html[data-theme='light'] .egl-stat-icon {
    border: 1px solid var(--egl-border);
}

/* ============================================================================
   Phase 11C — the accent colours light mode was never told about.

   The pages pass their accents in as Tailwind strings, e.g.

       icon-bg="bg-teal-900/40 text-teal-400"

   On navy that reads well. On white it is a dark teal at 40% opacity — a pale
   smudge — carrying a text shade chosen for navy. Pale on pale. Aomith called
   it "fekase", which is exactly right.

   The overlay already remaps every slate shade for light mode; the accent hues
   were simply never covered. Each rule below was GENERATED from the classes the
   views actually use, so there is no dead CSS and nothing in use is missed:

     text-<hue>-300..500  ->  <hue>-600   dark enough to read on white
     bg-<hue>-700..950    ->  <hue>-50/100  a real tint instead of a smudge
     border-<hue>-600+    ->  <hue>-200

   Solid 500/600 fills are left alone: those are buttons and badges that are
   already correct, and the overlay's existing [class*='bg-blue-6'].text-white
   rules keep their labels white.

   Every selector is scoped to html[data-theme='light']. Dark mode is untouched.
   ============================================================================ */


/* ---- text ---- */
html[data-theme='light'] .text-amber-200\/90 { color: #d97706; }
html[data-theme='light'] .text-amber-300 { color: #d97706; }
html[data-theme='light'] .text-amber-400 { color: #d97706; }
html[data-theme='light'] .text-blue-300 { color: #2563eb; }
html[data-theme='light'] .text-blue-400 { color: #2563eb; }
html[data-theme='light'] .text-emerald-300 { color: #059669; }
html[data-theme='light'] .text-emerald-400 { color: #059669; }
html[data-theme='light'] .text-orange-300 { color: #ea580c; }
html[data-theme='light'] .text-orange-400 { color: #ea580c; }
html[data-theme='light'] .text-red-400 { color: #dc2626; }
html[data-theme='light'] .text-teal-400 { color: #0d9488; }
html[data-theme='light'] .text-teal-500 { color: #0d9488; }

/* ---- backgrounds ---- */
html[data-theme='light'] .bg-amber-900\/20 { background-color: #fffbeb; }
html[data-theme='light'] .bg-amber-900\/40 { background-color: #fef3c7; }
html[data-theme='light'] .bg-blue-900\/40 { background-color: #dbeafe; }
html[data-theme='light'] .bg-blue-950\/20 { background-color: #eff6ff; }
html[data-theme='light'] .bg-emerald-900\/40 { background-color: #d1fae5; }
html[data-theme='light'] .bg-emerald-950\/10 { background-color: #ecfdf5; }
html[data-theme='light'] .bg-orange-900\/40 { background-color: #ffedd5; }
html[data-theme='light'] .bg-orange-950\/10 { background-color: #fff7ed; }
html[data-theme='light'] .bg-red-700 { background-color: #fef2f2; }
html[data-theme='light'] .bg-red-900\/40 { background-color: #fee2e2; }
html[data-theme='light'] .bg-red-950\/20 { background-color: #fef2f2; }
html[data-theme='light'] .bg-red-950\/30 { background-color: #fef2f2; }
html[data-theme='light'] .bg-teal-900\/40 { background-color: #ccfbf1; }
html[data-theme='light'] .bg-teal-950\/20 { background-color: #f0fdfa; }

/* ---- borders ---- */
html[data-theme='light'] .border-amber-800\/50 { border-color: #fde68a; }
html[data-theme='light'] .border-blue-700 { border-color: #bfdbfe; }
html[data-theme='light'] .border-blue-700\/50 { border-color: #bfdbfe; }
html[data-theme='light'] .border-blue-800 { border-color: #bfdbfe; }
html[data-theme='light'] .border-blue-900\/30 { border-color: #bfdbfe; }
html[data-theme='light'] .border-emerald-900\/30 { border-color: #a7f3d0; }
html[data-theme='light'] .border-indigo-700 { border-color: #c7d2fe; }
html[data-theme='light'] .border-orange-900\/30 { border-color: #fed7aa; }
html[data-theme='light'] .border-red-900\/30 { border-color: #fecaca; }
html[data-theme='light'] .border-red-900\/40 { border-color: #fecaca; }
html[data-theme='light'] .border-teal-700\/50 { border-color: #99f6e4; }
html[data-theme='light'] .border-teal-900\/30 { border-color: #99f6e4; }

/* ============================================================================
   Phase 11D — the Machine Status page gets its picture.

   Aomith's note: the Import box and the filter box are spread very wide and
   take a lot of room, so narrowing the import box and putting the photograph
   in the space that frees up costs nothing and gives the page a subject.

   His demo mock-up also showed four statistic cards this page does not have.
   Those are NOT added: he said plainly that the mock-up was to explain the
   idea, not a layout to reproduce. The only change is where the import box
   ends and where the picture begins.

   The picture is a cut-out with a transparent background, so the card behind
   it is painted from tokens and is correct in both appearances. It is hidden
   below 1024px: on a phone the import box needs the whole width, and a
   decorative image would only push the real content further down.

   New family: egl-machine- . The overlay guard's allow-list is extended for
   it, and only after checking that the string appears nowhere in the frozen
   Tailwind bundle - the same test phase 10J applied to egl-navicon-.
   ============================================================================ */

.egl-machine-hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
    margin-bottom: 1.5rem;
}

@media (min-width: 1024px) {
    .egl-machine-hero {
        grid-template-columns: minmax(0, 1.85fr) minmax(0, 1fr);
        align-items: stretch;
    }
}

/* The panel already carries its own bottom margin from the frozen bundle.
   Inside a grid that would leave the two columns different heights. */
.egl-machine-hero__panel {
    margin-bottom: 0;
}

.egl-machine-hero__art {
    display: grid;
    place-items: center;
    padding: .75rem;
    border-radius: .75rem;
    border: 1px solid var(--egl-border);
    background-image: linear-gradient(135deg, var(--egl-primary-soft), var(--egl-surface-2));
    overflow: hidden;
}

/* Phase 11E — the picture is no longer hidden on a phone. Aomith asked for it
   to be visible there, just not in the way, so only its HEIGHT changes with
   the screen: a slim band on a phone, taller on a tablet, full size on a
   desktop. The Flutter app shows these same pages in a WebView, so this is
   the same fix for the app. It is still lazy-loaded and still aria-hidden -
   it is decoration, and a mechanic on mobile data should not pay for it
   before the page is usable. */
@media (min-width: 640px) {
    .egl-machine-hero__art { padding: 1rem; }
}

/* A Viewer never sees the import box. Without this the picture would sit in a
   narrow left column on its own, which looks like a mistake. */
.egl-machine-hero__art:only-child {
    grid-column: 1 / -1;
}

.egl-machine-hero__art img {
    display: block;
    width: 100%;
    height: auto;
    max-height: 6.5rem;
    object-fit: contain;
}

@media (min-width: 640px) {
    .egl-machine-hero__art img { max-height: 9rem; }
}

@media (min-width: 1024px) {
    .egl-machine-hero__art img { max-height: 14rem; }
}


/* ============================================================================
   Phase 11F — the login page's input fields, and a card edge that can be seen.

   Two things Aomith asked for.

   1  "light mood a login page dekhte khub baje lage"
      html[data-theme='light'] .egl-input already exists and works, so the login
      page's Email/Password boxes do not carry that class. These rules reach
      them by what they ARE, inside .egl-login-shell - which step 78 proved is
      on the page. It cannot miss, whatever class the inputs have.

   2  "card gular border cikon ujjol hoye jolbe" - he chose B+E from the
      samples. E: a faint blue in the border at rest, so the cards stand off
      the page ON A PHONE TOO, where there is no hover at all (the Flutter app
      shows these same pages in a WebView). B: on hover the border goes full
      accent with a soft 3px ring around it.

      No animation and no movement. He asked for the border to light up, not
      for the card to breathe or lift. No animation rule appears below.

      Colours are written out rather than built with color-mix(), because the
      mechanics' phones are not all new and color-mix() is only in recent
      browsers - an unsupported value would drop the whole declaration and the
      border would silently go back to invisible.
   ========================================================================== */

/* ---- 1. the login page's fields in light mode ---------------------------- */
html[data-theme='light'] .egl-login-shell input[type='email'],
html[data-theme='light'] .egl-login-shell input[type='password'],
html[data-theme='light'] .egl-login-shell input[type='text'],
html[data-theme='light'] .egl-guest-card input[type='email'],
html[data-theme='light'] .egl-guest-card input[type='password'],
html[data-theme='light'] .egl-guest-card input[type='text'] {
    background-color: var(--egl-surface);
    border-color: var(--egl-border-strong);
    color: var(--egl-text);
}

html[data-theme='light'] .egl-login-shell input[type='email']::placeholder,
html[data-theme='light'] .egl-login-shell input[type='password']::placeholder,
html[data-theme='light'] .egl-login-shell input[type='text']::placeholder,
html[data-theme='light'] .egl-guest-card input::placeholder {
    color: #94a3b8;
}

html[data-theme='light'] .egl-login-shell input[type='email']:focus,
html[data-theme='light'] .egl-login-shell input[type='password']:focus,
html[data-theme='light'] .egl-login-shell input[type='text']:focus,
html[data-theme='light'] .egl-guest-card input[type='email']:focus,
html[data-theme='light'] .egl-guest-card input[type='password']:focus,
html[data-theme='light'] .egl-guest-card input[type='text']:focus {
    background-color: var(--egl-surface);
    border-color: #1a63e0;
    color: var(--egl-text);
    box-shadow: 0 0 0 3px rgba(26, 99, 224, .18);
}

html[data-theme='light'] .egl-login-shell label {
    color: var(--egl-text);
}

/* ---- 2. the card edge at rest (E) ---------------------------------------- */
html[data-theme='light'] .egl-card,
html[data-theme='light'] .egl-card-hover,
html[data-theme='light'] .egl-filter-panel,
html[data-theme='light'] .egl-table-panel,
html[data-theme='light'] .egl-machine-hero__panel,
html[data-theme='light'] .egl-machine-hero__art {
    border-color: #b9cbea;
    box-shadow: 0 0 0 1px rgba(37, 99, 235, .08), 0 6px 18px rgba(15, 23, 42, .07);
    transition: border-color .18s ease, box-shadow .22s ease;
}

html[data-theme='dark'] .egl-card,
html[data-theme='dark'] .egl-card-hover,
html[data-theme='dark'] .egl-filter-panel,
html[data-theme='dark'] .egl-table-panel,
html[data-theme='dark'] .egl-machine-hero__panel,
html[data-theme='dark'] .egl-machine-hero__art {
    border-color: #415f87;
    box-shadow: 0 0 0 1px rgba(96, 165, 250, .09), 0 6px 18px rgba(0, 0, 0, .35);
    transition: border-color .18s ease, box-shadow .22s ease;
}

/* ---- 3. and the edge lighting up under the pointer (B) ------------------- */
html[data-theme='light'] .egl-card:hover,
html[data-theme='light'] .egl-card-hover:hover,
html[data-theme='light'] .egl-filter-panel:hover,
html[data-theme='light'] .egl-table-panel:hover,
html[data-theme='light'] .egl-machine-hero__panel:hover {
    border-color: #2563eb;
    box-shadow: 0 0 0 3px rgba(37, 99, 235, .26), 0 10px 26px rgba(15, 23, 42, .10);
}

html[data-theme='dark'] .egl-card:hover,
html[data-theme='dark'] .egl-card-hover:hover,
html[data-theme='dark'] .egl-filter-panel:hover,
html[data-theme='dark'] .egl-table-panel:hover,
html[data-theme='dark'] .egl-machine-hero__panel:hover {
    border-color: #60a5fa;
    box-shadow: 0 0 0 3px rgba(96, 165, 250, .30), 0 10px 26px rgba(0, 0, 0, .45);
}

/* ---- 4. a finger is not a mouse ------------------------------------------
   On a touch screen :hover can STICK after a tap - the card stays lit until
   something else is touched. So on pointer-coarse devices the resting edge is
   the only edge, which is exactly why E is in here. -------------------------*/
@media (hover: none) {
    html[data-theme='light'] .egl-card:hover,
    html[data-theme='light'] .egl-card-hover:hover,
    html[data-theme='light'] .egl-filter-panel:hover,
    html[data-theme='light'] .egl-table-panel:hover,
    html[data-theme='light'] .egl-machine-hero__panel:hover {
        border-color: #b9cbea;
        box-shadow: 0 0 0 1px rgba(37, 99, 235, .08), 0 6px 18px rgba(15, 23, 42, .07);
    }
    html[data-theme='dark'] .egl-card:hover,
    html[data-theme='dark'] .egl-card-hover:hover,
    html[data-theme='dark'] .egl-filter-panel:hover,
    html[data-theme='dark'] .egl-table-panel:hover,
    html[data-theme='dark'] .egl-machine-hero__panel:hover {
        border-color: #415f87;
        box-shadow: 0 0 0 1px rgba(96, 165, 250, .09), 0 6px 18px rgba(0, 0, 0, .35);
    }
}


/* ============================================================================
   Phase 11G — the Mechanic Contact List page.

   The card grid on this page was already themed in phase 08B; the overlay
   carries 56 .egl-mech-* rules including a full light-mode set. So this phase
   is small on purpose. It adds three things:

     1. the page heading, which still had text-white and text-slate-400 baked
        into the blade - white on a white page in light mode
     2. a hero row, so the filter panel gives up a third of its width and the
        photograph Aomith supplied sits beside it
     3. the same edge treatment the other cards got in 11F, for the new art
        card - resting accent border, brighter under a pointer, and nothing at
        all on a touch screen where :hover sticks after a tap

   No animation, no movement: same rule as 11F.
   ========================================================================== */

.egl-mech-head__title {
    color: var(--egl-text);
}

.egl-mech-head__lead {
    color: var(--egl-text-muted);
}

.egl-mech-hero {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
    align-items: stretch;
    margin-bottom: 1.5rem;
}

@media (min-width: 1024px) {
    .egl-mech-hero { grid-template-columns: minmax(0, 1.4fr) minmax(0, .6fr); }
}

.egl-mech-hero__panel {
    margin-bottom: 0;
}

.egl-mech-hero__art {
    display: grid;
    place-items: center;
    padding: .75rem;
    border-radius: .75rem;
    border: 1px solid var(--egl-border);
    background-color: var(--egl-surface);
    overflow: hidden;
}

@media (min-width: 640px) {
    .egl-mech-hero__art { padding: 1rem; }
}

/* The picture is visible at every width - a mechanic on a phone should see it
   too. Only its HEIGHT changes, so it never pushes the filters off the screen. */
.egl-mech-hero__art img {
    display: block;
    width: 100%;
    height: auto;
    max-height: 7rem;
    object-fit: contain;
}

@media (min-width: 640px) {
    .egl-mech-hero__art img { max-height: 10rem; }
}

@media (min-width: 1024px) {
    .egl-mech-hero__art img { max-height: 15rem; }
}

/* ---- the same edges the other cards got in 11F -------------------------- */
html[data-theme='light'] .egl-mech-hero__art {
    border-color: #b9cbea;
    box-shadow: 0 0 0 1px rgba(37, 99, 235, .08), 0 6px 18px rgba(15, 23, 42, .07);
    transition: border-color .18s ease, box-shadow .22s ease;
}

html[data-theme='dark'] .egl-mech-hero__art {
    border-color: #415f87;
    box-shadow: 0 0 0 1px rgba(96, 165, 250, .09), 0 6px 18px rgba(0, 0, 0, .35);
    transition: border-color .18s ease, box-shadow .22s ease;
}

html[data-theme='light'] .egl-mech-hero__art:hover {
    border-color: #2563eb;
    box-shadow: 0 0 0 3px rgba(37, 99, 235, .26), 0 10px 26px rgba(15, 23, 42, .10);
}

html[data-theme='dark'] .egl-mech-hero__art:hover {
    border-color: #60a5fa;
    box-shadow: 0 0 0 3px rgba(96, 165, 250, .30), 0 10px 26px rgba(0, 0, 0, .45);
}

@media (hover: none) {
    html[data-theme='light'] .egl-mech-hero__art:hover {
        border-color: #b9cbea;
        box-shadow: 0 0 0 1px rgba(37, 99, 235, .08), 0 6px 18px rgba(15, 23, 42, .07);
    }
    html[data-theme='dark'] .egl-mech-hero__art:hover {
        border-color: #415f87;
        box-shadow: 0 0 0 1px rgba(96, 165, 250, .09), 0 6px 18px rgba(0, 0, 0, .35);
    }
}


/* ============================================================================
   Phase 11H — the mechanic View and Add/Edit pages.

   These two blades never had a dark: class. They had the dark colours written
   straight in - bg-slate-800, text-white, border-slate-700 - so they render as
   black boxes on a white page in light mode. That is the fault being fixed.

   Most of the work is NOT new css. The form's inputs and labels are given the
   .egl-input and .egl-label classes that already exist and already work in
   both appearances; the block chips are given .egl-mech-chip, themed back in
   phase 08B. What is new here is only what had no class at all: the detail
   field boxes on the View page (the same markup repeated eight times), the
   empty-photo panel, and four small form pieces.

   No animation. Colours are written out rather than built with color-mix(),
   for the same reason as 11F: the mechanics' phones are not all new.
   ========================================================================== */

/* ---- the View page ------------------------------------------------------ */
.egl-mech-name  { color: var(--egl-text); }
.egl-mech-sub   { color: var(--egl-text-muted); }
.egl-mech-note  { color: var(--egl-text-muted); }

.egl-mech-field {
    border: 1px solid var(--egl-border);
}

html[data-theme='light'] .egl-mech-field { background-color: rgba(15, 23, 42, .035); }
html[data-theme='dark']  .egl-mech-field { background-color: rgba(255, 255, 255, .035); }

.egl-mech-field__label { color: var(--egl-text-muted); }
.egl-mech-field__value { color: var(--egl-text); }

.egl-mech-photo-empty { color: var(--egl-text-muted); }

html[data-theme='light'] .egl-mech-photo-empty { background: linear-gradient(160deg, #f1f5f9, #e2e8f0); }
html[data-theme='dark']  .egl-mech-photo-empty { background: linear-gradient(160deg, #1e293b, #0f172a); }

.egl-mech-photo-empty__ring { border: 1px solid var(--egl-border-strong); }

html[data-theme='light'] .egl-mech-photo-empty__ring { background-color: #e2e8f0; }
html[data-theme='dark']  .egl-mech-photo-empty__ring { background-color: rgba(255, 255, 255, .07); }

/* ---- the Add / Edit form ------------------------------------------------ */
.egl-form-error {
    margin-top: .25rem;
    font-size: .875rem;
    line-height: 1.25rem;
}

html[data-theme='light'] .egl-form-error { color: #dc2626; }
html[data-theme='dark']  .egl-form-error { color: #f87171; }

.egl-form-hint { color: var(--egl-text-muted); }

.egl-form-check {
    display: flex;
    align-items: center;
    gap: .5rem;
    border-radius: .5rem;
    border: 1px solid var(--egl-border);
    padding: .5rem .75rem;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}

html[data-theme='light'] .egl-form-check { background-color: #f8fafc; }
html[data-theme='dark']  .egl-form-check { background-color: rgba(255, 255, 255, .035); }

html[data-theme='light'] .egl-form-check:hover {
    background-color: #eef2f8;
    border-color: var(--egl-border-strong);
}

html[data-theme='dark'] .egl-form-check:hover {
    background-color: rgba(255, 255, 255, .07);
    border-color: var(--egl-border-strong);
}

.egl-form-check__text {
    font-size: .875rem;
    color: var(--egl-text);
}

.egl-form-checkbox {
    width: 1rem;
    height: 1rem;
    border-radius: .25rem;
    border: 1px solid var(--egl-border-strong);
    accent-color: var(--egl-primary);
}

.egl-form-rule { border-color: var(--egl-border); }


/* --------------------------------------------------------------------------
   Phase 13C-11 - the Dropdown Lists page.

   Three lists on one page, each row a name, what stands on it, and one
   button. No table: a table would promise columns that can be sorted and
   compared, and there is nothing here to compare - the row IS the unit.

   A hidden row stays in place rather than moving to a section of its own. The
   Admin who just hid something should see it exactly where it was, greyed and
   labelled, so "did that work" needs no scrolling to answer.

   Drawn light first, per Aomith's standing rule for a new screen, and then
   checked dark. Every colour is a token declared for both appearances, so no
   rule here has to know which appearance is on.
   -------------------------------------------------------------------------- */
.egl-mreq-listhead {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
    margin-bottom: .75rem;
}

.egl-mreq-listtitle {
    font-size: .9375rem;
    font-weight: 700;
    color: var(--egl-text);
}

.egl-mreq-listcount {
    font-size: .75rem;
    color: var(--egl-text-muted);
}

.egl-mreq-listbox {
    border: 1px solid var(--egl-border);
    border-radius: .625rem;
    overflow: hidden;
}

.egl-mreq-listrow {
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: center;
    gap: .75rem;
    padding: .625rem .875rem;
    background: var(--egl-surface);
}

.egl-mreq-listrow + .egl-mreq-listrow {
    border-top: 1px solid var(--egl-border);
}

/* Hidden reads as switched off, not as broken: the surface steps back and the
   name loses its weight, but it is still legible - it has to be, because
   unhiding it is done from this same row. */
.egl-mreq-listrow--off {
    background: var(--egl-surface-2);
}

.egl-mreq-listrow--off .egl-mreq-listname > span:first-child {
    color: var(--egl-text-muted);
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

.egl-mreq-listname {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    min-width: 0;
    font-size: .875rem;
    font-weight: 600;
    color: var(--egl-text);
    word-break: break-word;
}

.egl-mreq-listused {
    font-size: .75rem;
    color: var(--egl-text-2);
    white-space: nowrap;
}

.egl-mreq-listused b {
    font-weight: 700;
    color: var(--egl-text);
}

.egl-mreq-listact {
    margin: 0;
}

.egl-mreq-pill {
    display: inline-flex;
    align-items: center;
    padding: .0625rem .4375rem;
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .01em;
    border-radius: 9999px;
    border: 1px solid transparent;
    white-space: nowrap;
}

.egl-mreq-pill--off {
    color: var(--egl-muted-tone);
    background: var(--egl-muted-soft);
    border-color: var(--egl-muted-border);
}

.egl-mreq-pill--note {
    color: var(--egl-info);
    background: var(--egl-info-soft);
    border-color: var(--egl-info-border);
}

/* On a phone the count drops under the name and the button keeps the right
   edge, so a long machine type name never squeezes the one control on the
   row down to nothing. */
@media (max-width: 640px) {
    .egl-mreq-listrow {
        grid-template-columns: 1fr auto;
    }

    .egl-mreq-listused {
        grid-column: 1;
        grid-row: 2;
        white-space: normal;
    }

    .egl-mreq-listact {
        grid-column: 2;
        grid-row: 1 / span 2;
    }
}


/* Phase 13C-12 - the "used by N plans" count is a link to those plans.
   Underlined on hover only: a whole column of underlines would read as a
   list of links rather than as a column of facts, one of which you can
   follow. */
.egl-mreq-listlink {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px dotted var(--egl-border-strong);
}

.egl-mreq-listlink:hover {
    color: var(--egl-primary);
    border-bottom-color: var(--egl-primary);
}


/* ==========================================================================
   Phase 14A-1 — Schedule Maintenance.
   --------------------------------------------------------------------------
   Its own family, egl-sm-, for the same reason 13B-1 gave: the compiled
   Tailwind bundle is frozen and a utility nobody has used before is simply
   absent - no error, no warning, just a rule that never arrives.

   Written against the meaning tokens, which are declared for BOTH
   appearances, so one rule set is correct in light and in dark. It is built
   light-first: Aomith's standing rule is that a new module has to look right
   in light mode on the day it ships, and the theme pass comes last.
   ========================================================================== */

.egl-sm-lead {
    color: var(--egl-text-2);
    font-size: .9375rem;
    line-height: 1.7;
}

.egl-sm-note {
    color: var(--egl-text-muted);
    font-size: .8125rem;
    line-height: 1.7;
}

.egl-sm-empty {
    color: var(--egl-text-muted);
    font-size: .875rem;
    padding: .75rem 0;
}

.egl-sm-link {
    color: var(--egl-primary);
    text-decoration: none;
    border-bottom: 1px dotted var(--egl-primary);
}

.egl-sm-link:hover {
    border-bottom-style: solid;
}

/* A serial is read digit by digit off a sticker on a machine, so it is set in
   a mono face - the one place on the page where the shape of each character
   has to be unambiguous. */
.egl-sm-num {
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: .875rem;
    letter-spacing: .01em;
    color: var(--egl-text);
}

.egl-sm-dim {
    color: var(--egl-text-muted);
    font-size: .75rem;
    margin-top: .125rem;
}

.egl-sm-right {
    text-align: right;
}

/* ---------------------------------------------------------------- buckets */
/* The four groups, as one row of chips. They carry their counts, so the
   numbers stay on screen while one group is being read. */
.egl-sm-buckets {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.egl-sm-bucket {
    display: inline-flex;
    align-items: baseline;
    gap: .375rem;
    padding: .4375rem .75rem;
    border-radius: .625rem;
    border: 1px solid var(--egl-border);
    background: var(--egl-surface);
    color: var(--egl-text-3);
    font-size: .8125rem;
    text-decoration: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.egl-sm-bucket b {
    font-size: 1rem;
    font-weight: 700;
    color: var(--egl-text);
}

.egl-sm-bucket:hover {
    border-color: var(--egl-border-strong);
}

.egl-sm-bucket--on {
    border-color: var(--egl-primary);
    box-shadow: 0 0 0 1px var(--egl-primary);
}

.egl-sm-bucket--overdue {
    background: var(--egl-danger-soft);
    border-color: var(--egl-danger-border);
}

.egl-sm-bucket--overdue b {
    color: var(--egl-danger);
}

.egl-sm-bucket--due {
    background: var(--egl-warn-soft);
    border-color: var(--egl-warn-border);
}

.egl-sm-bucket--due b {
    color: var(--egl-warn);
}

.egl-sm-bucket--never {
    background: var(--egl-muted-soft);
    border-color: var(--egl-muted-border);
}

.egl-sm-bucket--never b {
    color: var(--egl-muted-tone);
}

/* ----------------------------------------------------------------- tables */
/* The wrapper scrolls, not the page. A seven-column table on a phone has to
   go somewhere, and sideways inside its own box beats a whole page that
   slides under the finger. */
.egl-sm-tablewrap {
    overflow-x: auto;
    margin-top: .75rem;
}

.egl-sm-table {
    width: 100%;
    border-collapse: collapse;
    font-size: .875rem;
}

.egl-sm-table th {
    text-align: left;
    padding: .5rem .75rem;
    font-size: .6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--egl-text-muted);
    border-bottom: 1px solid var(--egl-border);
    white-space: nowrap;
}

.egl-sm-table td {
    padding: .625rem .75rem;
    color: var(--egl-text-2);
    border-bottom: 1px solid var(--egl-border);
    vertical-align: top;
}

.egl-sm-table tbody tr:last-child td {
    border-bottom: 0;
}

.egl-sm-table--due td {
    white-space: nowrap;
}

/* The remark sits under the row it belongs to rather than in a column of its
   own: it is a sentence, and a sentence in a narrow column is a column of
   single words. */
.egl-sm-remarkrow td {
    padding-top: 0;
    border-bottom: 1px solid var(--egl-border);
    color: var(--egl-text-muted);
    font-size: .8125rem;
    white-space: normal;
}

.egl-sm-actions {
    white-space: nowrap;
}

/* The left edge of an overdue row is marked, so the eye finds the rows before
   it reads the status column. Colour is never the only signal - the pill
   beside it says the same thing in words. */
.egl-sm-row--overdue td:first-child {
    box-shadow: inset 3px 0 0 var(--egl-danger);
}

.egl-sm-row--due td:first-child {
    box-shadow: inset 3px 0 0 var(--egl-warn);
}

.egl-sm-row--never td:first-child {
    box-shadow: inset 3px 0 0 var(--egl-muted-border);
}

/* ------------------------------------------------------------ status pill */
.egl-sm-pill {
    display: inline-block;
    padding: .1875rem .5rem;
    border-radius: 9999px;
    border: 1px solid var(--egl-border);
    background: var(--egl-surface-2);
    color: var(--egl-text-3);
    font-size: .75rem;
    font-weight: 600;
    white-space: nowrap;
}

.egl-sm-pill--overdue {
    color: var(--egl-danger);
    background: var(--egl-danger-soft);
    border-color: var(--egl-danger-border);
}

.egl-sm-pill--due {
    color: var(--egl-warn);
    background: var(--egl-warn-soft);
    border-color: var(--egl-warn-border);
}

.egl-sm-pill--later {
    color: var(--egl-ok);
    background: var(--egl-ok-soft);
    border-color: var(--egl-ok-border);
}

.egl-sm-pill--never {
    color: var(--egl-muted-tone);
    background: var(--egl-muted-soft);
    border-color: var(--egl-muted-border);
}

/* ------------------------------------------- the badge on a machine's page */
/* Same four states as the pill, sized to stand beside the Active/Inactive
   badge that has always been there. It says nothing about the machine's
   status - only about its service record - and never moves that badge. */
.egl-sm-badge {
    display: inline-block;
    padding: .375rem .75rem;
    border-radius: .5rem;
    border: 1px solid var(--egl-border);
    background: var(--egl-surface-2);
    color: var(--egl-text-3);
    font-size: .875rem;
    font-weight: 600;
}

.egl-sm-badge--overdue {
    color: var(--egl-danger);
    background: var(--egl-danger-soft);
    border-color: var(--egl-danger-border);
}

.egl-sm-badge--due {
    color: var(--egl-warn);
    background: var(--egl-warn-soft);
    border-color: var(--egl-warn-border);
}

.egl-sm-badge--later {
    color: var(--egl-ok);
    background: var(--egl-ok-soft);
    border-color: var(--egl-ok-border);
}

.egl-sm-badge--never {
    color: var(--egl-muted-tone);
    background: var(--egl-muted-soft);
    border-color: var(--egl-muted-border);
}

/* ------------------------------------------ the box on a machine's page */
.egl-sm-box {
    border-top: 3px solid var(--egl-nav-orange);
}

.egl-sm-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
}

.egl-sm-meta {
    color: var(--egl-text-muted);
    font-size: .75rem;
}

.egl-sm-due {
    font-weight: 700;
    color: var(--egl-text);
}

.egl-sm-due--overdue { color: var(--egl-danger); }
.egl-sm-due--due { color: var(--egl-warn); }
.egl-sm-due--later { color: var(--egl-ok); }
.egl-sm-due--never { color: var(--egl-text-muted); }

/* ------------------------------------------------------------- the one box */
/* The interval page is one number and a sentence about what it does. It is
   drawn large on purpose: this single figure decides, for every machine at
   once, which of them the floor is told to service this week, so it should
   not look like one field among many. */
.egl-sm-bigset {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
}

.egl-sm-daybox {
    display: inline-flex;
    align-items: baseline;
    gap: .5rem;
    padding: .625rem .875rem;
    border-radius: .75rem;
    border: 1px solid var(--egl-border-strong);
    background: var(--egl-surface);
    color: var(--egl-text-muted);
    font-size: 1rem;
}

.egl-sm-dayinput {
    width: 5.5rem;
    border: 0;
    background: transparent;
    color: var(--egl-text);
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.1;
    text-align: center;
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

.egl-sm-dayinput:focus {
    outline: 2px solid var(--egl-primary);
    outline-offset: 3px;
    border-radius: .375rem;
}

.egl-sm-said {
    flex: 1 1 18rem;
    min-width: 0;
    color: var(--egl-text-2);
    font-size: .875rem;
    line-height: 1.7;
}

@media (max-width: 640px) {
    .egl-sm-bigset {
        align-items: stretch;
    }

    .egl-sm-said {
        flex-basis: 100%;
    }
}


/* ==========================================================================
   Phase 14A-2 — parts, and the warning that is the point of them.
   --------------------------------------------------------------------------
   Same family, same rules: meaning tokens only, declared for both
   appearances, light-first, and nothing here exists in the frozen bundle.
   ========================================================================== */

/* Why a part went in. Three states rather than four, and they mean something
   different from the due-list pills that share the shape: scheduled is the
   quiet one, broken and changed are the two that carry a photograph of what
   came out. */
.egl-sm-pill--scheduled {
    color: var(--egl-ok);
    background: var(--egl-ok-soft);
    border-color: var(--egl-ok-border);
}

.egl-sm-pill--broken {
    color: var(--egl-danger);
    background: var(--egl-danger-soft);
    border-color: var(--egl-danger-border);
}

.egl-sm-pill--changed {
    color: var(--egl-order);
    background: var(--egl-order-soft);
    border-color: var(--egl-order-border);
}

/* ------------------------------------------------------------- the warning */
/* Red, in the way, and it stays on screen while the form is filled in - but
   it never refuses the entry. Aomith's call and the right one: a part really
   can break twice, and a system that blocks the second one only teaches
   people to type a different part name. */
.egl-sm-warn {
    border: 1px solid var(--egl-danger-border);
    border-left: 4px solid var(--egl-danger);
    background: var(--egl-danger-soft);
    border-radius: .625rem;
    padding: .875rem 1rem;
}

.egl-sm-warn-head {
    color: var(--egl-danger);
    font-weight: 700;
    font-size: .9375rem;
}

.egl-sm-warn-body {
    color: var(--egl-text-2);
    font-size: .875rem;
    line-height: 1.7;
    margin-top: .25rem;
}

.egl-sm-warn-confirm {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    margin-top: .625rem;
    color: var(--egl-text);
    font-size: .875rem;
    font-weight: 600;
    cursor: pointer;
}

.egl-sm-warn-confirm input {
    margin-top: .1875rem;
    width: 1rem;
    height: 1rem;
    flex: none;
    accent-color: var(--egl-danger);
}

/* ------------------------------------------------------------- photographs */
/* The evidence. A thumbnail only says a picture exists, so each one opens the
   full photograph in its own tab - that is what somebody checking a claim
   actually needs to see. */
.egl-sm-thumbs {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
}

.egl-sm-thumb {
    position: relative;
    display: block;
    width: 3.25rem;
    height: 3.25rem;
    border-radius: .5rem;
    overflow: hidden;
    border: 1px solid var(--egl-ok-border);
    background: var(--egl-surface-2);
    text-decoration: none;
    flex: none;
}

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

/* The label is burnt onto the corner rather than set beside the picture: in a
   table cell two unlabelled squares are a guess, and "which one is the old
   part" is the only question being asked of them. */
.egl-sm-thumb span {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: .0625rem .25rem;
    background: var(--egl-ok);
    color: #ffffff;
    font-size: .5625rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    text-align: center;
}

.egl-sm-thumb--old {
    border-color: var(--egl-danger-border);
}

.egl-sm-thumb--old span {
    background: var(--egl-danger);
}

.egl-sm-thumb:hover {
    box-shadow: 0 0 0 2px var(--egl-primary);
}


/* ==========================================================================
   Phase 14A-2b — the two halves of the module.
   --------------------------------------------------------------------------
   The Due List is about MACHINES; the Parts Ledger is about PARTS. They are
   the same question asked from opposite ends, so they sit as two tabs rather
   than two entries in the sidebar - a sidebar that grows an entry for every
   view of the same data is a sidebar nobody reads.
   ========================================================================== */

.egl-sm-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
    border-bottom: 1px solid var(--egl-border);
    padding-bottom: .5rem;
}

.egl-sm-tab {
    display: inline-block;
    padding: .4375rem .875rem;
    border-radius: .5rem;
    border: 1px solid transparent;
    color: var(--egl-text-muted);
    font-size: .875rem;
    font-weight: 600;
    text-decoration: none;
    transition: color .15s ease, background .15s ease, border-color .15s ease;
}

.egl-sm-tab:hover {
    color: var(--egl-text);
    background: var(--egl-muted-soft);
}

/* The tab you are on is worn solid, the same way the sidebar marks where you
   are - the state is put on by the page, never by a selector reaching for a
   class the frozen bundle already ships. */
.egl-sm-tab--on {
    color: var(--egl-primary);
    background: var(--egl-primary-soft);
    border-color: var(--egl-primary-border);
}


/* ==========================================================================
   Phase 14A-2c — the photograph that was asked for and did not come.
   --------------------------------------------------------------------------
   14A-2a refused to save a broken or changed part without a picture of the
   old one. That rule is gone: the maintenance team's own register of every
   part ever fitted is being imported and none of it was photographed, and a
   rule the real history cannot satisfy makes the real history look like a
   violation.

   What replaces it is this mark. Amber, not red - nobody did anything wrong,
   something is simply missing - and it sits exactly where the thumbnails
   would have been, so the eye finds it in the same place either way.
   ========================================================================== */

.egl-sm-nophoto {
    display: inline-flex;
    align-items: center;
    height: 3.25rem;
    padding: 0 .5rem;
    border-radius: .5rem;
    border: 1px dashed var(--egl-warn-border);
    background: var(--egl-warn-soft);
    color: var(--egl-warn);
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    white-space: nowrap;
}

/* The ledger's way of asking for all of them at once. */
.egl-sm-nophoto-pick {
    display: inline-flex;
    align-items: center;
    gap: .4375rem;
    padding: .4375rem .75rem;
    border-radius: .625rem;
    border: 1px solid var(--egl-warn-border);
    background: var(--egl-warn-soft);
    color: var(--egl-warn);
    font-size: .8125rem;
    font-weight: 600;
    cursor: pointer;
}

.egl-sm-nophoto-pick input {
    width: 1rem;
    height: 1rem;
    flex: none;
    accent-color: var(--egl-warn);
}


/* ==========================================================================
   Phase 15A — the language picker.
   --------------------------------------------------------------------------
   Built like the theme picker beside it rather than as a dropdown: two
   choices, both visible, each naming itself. Somebody looking for Bengali is
   looking for the word বাংলা - if they could reliably read "Bengali" in
   English they would not be changing this setting, and a dropdown would hide
   the one word they can actually recognise behind a click.
   ========================================================================== */

.egl-settings-lang-option {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: 1rem 1.125rem;
    border-radius: .75rem;
    border: 1px solid var(--egl-border);
    background: var(--egl-surface);
    cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
}

.egl-settings-lang-option:hover {
    border-color: var(--egl-border-strong);
}

.egl-settings-lang-option input {
    width: 1.125rem;
    height: 1.125rem;
    flex: none;
    accent-color: var(--egl-primary);
}

/* The language's own name, set large enough to be picked out at arm's length
   on a phone held in a noisy room. */
.egl-settings-lang-name {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--egl-text);
    font-size: 1.0625rem;
    font-weight: 600;
}

.egl-settings-lang-check {
    flex: none;
    color: var(--egl-primary);
    font-size: 1rem;
    opacity: 0;
}

.egl-settings-lang-option.is-selected {
    border-color: var(--egl-primary);
    background: var(--egl-primary-soft);
    box-shadow: 0 0 0 1px var(--egl-primary);
}

.egl-settings-lang-option.is-selected .egl-settings-lang-check {
    opacity: 1;
}

/* ==========================================================================
   Phase 15D - the sidebar scrolls, and the way into it is obvious.

   Aomith, 12 September: "side bar ar schroll hoi na fix hoye ache amader to
   akhn onek option add hoce side bar to scroll kora lagbe".

   He is right, and it was only a matter of time. Every module adds an entry.
   The sidebar was laid out as a column that simply grew, so once the list was
   taller than the screen the last entries sat below the fold with nothing to
   scroll - on a short laptop screen, or a phone in landscape, they were
   unreachable.

   Two rules fix it, and the second one is the one that actually matters.
   ========================================================================== */

/* A flex child will not scroll while it is allowed to grow to fit its
   content, and by default it is: min-height resolves to auto, so the nav
   pushes the sidebar taller instead of scrolling inside it. Giving the
   sidebar ONE SCREEN of height is what makes "inside it" mean something.

   From lg up only. Below that the drawer is already pinned top to bottom by
   Tailwind's fixed inset-y-0, and position:sticky here would fight it - this
   file loads after the compiled bundle, so it would win, and the drawer would
   break. The narrow screen is the one he uses most, so it is left alone. */
@media (min-width: 1024px) {
    .egl-dash-sidebar {
        position: sticky;
        top: 0;
        height: 100vh;
        height: 100dvh;
    }
}

/* THE LINE THAT DOES THE WORK is min-height: 0. overflow-y: auto alone would
   do nothing here: the nav is a flex child, its automatic minimum size is its
   content, so it never becomes smaller than its content and therefore never
   overflows and never scrolls. Zeroing that minimum lets it be squeezed, and
   only then does overflow have anything to do. */
.egl-dash-navscroll {
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: var(--egl-border) transparent;
}

/* A slim bar drawn in the theme's own tokens, so it is quiet in both themes
   rather than the browser's default grey slab. */
.egl-dash-navscroll::-webkit-scrollbar {
    width: 8px;
}

.egl-dash-navscroll::-webkit-scrollbar-track {
    background: transparent;
}

.egl-dash-navscroll::-webkit-scrollbar-thumb {
    background-color: var(--egl-border);
    background-clip: content-box;
    border: 2px solid transparent;
    border-radius: 999px;
}

.egl-dash-navscroll::-webkit-scrollbar-thumb:hover {
    background-color: var(--egl-text-3);
}

/* ---- the button that opens it -------------------------------------------
   Three lines with nothing beside them is a convention, and a convention only
   reads to people who already know it. Aomith asked for something anyone
   would understand, so the icon keeps a word next to it. That also gives the
   button a real edge and a real background, which says "press me" in a way a
   bare glyph never does. */
.egl-dash-menubtn {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .5rem .75rem;
    border-radius: .625rem;
    border: 1px solid var(--egl-border);
    background: var(--egl-surface-2);
    color: var(--egl-text);
    font-size: .8125rem;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.egl-dash-menubtn:hover {
    background: var(--egl-surface-3);
    border-color: var(--egl-text-3);
    color: var(--egl-text);
}

/* --egl-primary, because that is what every other focus ring in this file
   uses. --egl-accent, which I reached for first, is defined nowhere: the
   outline would have resolved to nothing and drawn no ring at all, and
   nothing would have complained. */
.egl-dash-menubtn:focus-visible {
    outline: 2px solid var(--egl-primary);
    outline-offset: 2px;
}

/* On a very narrow phone the word is dropped and the button keeps its frame,
   so it still reads as a control rather than three loose lines. */
@media (max-width: 380px) {
    .egl-dash-menubtn span {
        display: none;
    }

    .egl-dash-menubtn {
        padding: .5rem;
    }
}

/* ==========================================================================
   Phase 15E - the phone, which 15D did not actually fix.

   Aomith, 12 September: "akhn o flutter a side bar scroll hoi na kintu
   browser a hoi". The browser was a wide window, where 15D's min-width rule
   applies. The handset is narrow, and there 15D deliberately left the drawer
   alone - on the belief that Tailwind's "fixed inset-y-0 left-0" already
   pinned it top to bottom.

   It does not. Checked against the frozen bundle rather than assumed:

       .fixed        present   ->  position: fixed
       .inset-y-0    MISSING
       .left-0       MISSING
       .z-40         MISSING
       .bg-black/60  MISSING

   So on a phone this drawer has been getting position:fixed and NOTHING
   else since the bundle was frozen on 17 August: no offsets, no height. A
   fixed box with no height is as tall as its content, and a nav with no
   height above it has nothing to scroll inside. The backdrop behind it has
   been painting no tint and taking no stacking order either - which is why
   the page behind the open drawer never dimmed.

   The Tailwind classes stay on the elements for the day the bundle is
   rebuilt. Until then these rules are what actually hold the drawer up.
   ========================================================================== */

@media (max-width: 1023.98px) {
    /* top and bottom are what give the fixed box its height. The two vh
       units are a convenience for anything that wants one value; if an older
       WebView understands neither, top:0 with bottom:0 still pins it, so the
       nav always has a real height to scroll against. */
    .egl-dash-sidebar {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        height: 100vh;
        height: 100dvh;
        z-index: 50;
    }

    /* Closed, the drawer carries Tailwind's .hidden, which is in the bundle
       and wins on display - so the rule above costs nothing until it opens. */

    .egl-dash-scrim {
        position: fixed;
        inset: 0;
        z-index: 40;
        background: rgba(2, 6, 23, .6);
    }
}


/* ============================================================================
   PHASE 15G - THE PHOTOGRAPH ON A PROFILE PAGE, PORTRAIT
   ============================================================================
   Aomith opened a contact's page and said the picture was cut: "picture kete
   geche, picture er size potrait kore daw".

   He is right, and it was never about this phase. The frame was h-64 - a
   fixed 16rem height across a column nearly twice that wide. A photograph of
   a person going into a letterbox loses the top of the head and the
   shoulders, whichever picture it is. The mechanic page has had the same
   frame since 08B, so this fixes both rather than leaving the two pages
   disagreeing about what a profile photo looks like.

   WHY THIS IS CSS AND NOT A TAILWIND CLASS: aspect-[3/4] is an arbitrary
   value, and arbitrary values only exist in the compiled bundle if they were
   in the source when it was built on 17 August. They were not. A class that
   is not in that bundle does nothing and says nothing about it - which is
   what 15D cost a round to learn.

   min-height is the floor, not the shape. Anything too old to understand
   aspect-ratio keeps exactly the 16rem it has now, so the worst case is
   today's behaviour rather than a collapsed box. Both names start with
   .egl-mech-, so neither can reach the frozen dark UI. No colour is set
   here at all, which is why there is no light-theme block below.
   ========================================================================= */
.egl-mech-portrait {
    display: block;
    width: 100%;
    aspect-ratio: 3 / 4;
    min-height: 16rem;
    object-fit: cover;
    /* Horizontal centre, and a little above vertical centre: when a tall
       picture has to lose something it should be the feet, not the face. */
    object-position: 50% 25%;
}

/* The same frame when there is no photograph, so the card does not change
   size depending on whether somebody has had their picture taken. */
.egl-mech-portrait-empty {
    width: 100%;
    aspect-ratio: 3 / 4;
    min-height: 16rem;
}

/* =========================================================================
   Phase 17A-2 - the QCO entry form, in the shape Aomith drew it.

   WHY THESE ARE .egl-form- AND NOT .egl-qco-: the overlay test only lets a
   handful of prefixes through, and `qco` is not one of them - deliberately,
   because the list is what stops a new module quietly restyling an old page.
   Everything here is a FORM control and nothing else on the site uses these
   names, so `form` is the honest prefix rather than a way round the rule.

   EVERY COLOUR IS A TOKEN. Both themes are then right by construction, which
   is the only way to keep his standing rule - new screens must look good in
   light mode - without writing the whole thing twice.

   The frozen Tailwind bundle cannot help here: a boxed panel, a chip and a
   tick-pill are not classes that were in the source on 17 August, and a
   class that is not in that bundle does nothing and says nothing about it.
   ========================================================================= */

/* A panel inside the form - his four drawn boxes. */
.egl-form-box {
    border: 1px solid var(--egl-border);
    border-radius: 0.75rem;
    background: var(--egl-surface-2);
    padding: 1rem;
}

.egl-form-box__title {
    margin: 0 0 0.75rem;
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    color: var(--egl-text-2);
}

/* The Upload Item Image corner, top right of the order box. */
.egl-form-upload {
    min-width: 14rem;
    max-width: 22rem;
    flex: 1 1 14rem;
}

/* ── who answers for the block ───────────────────────────────────────────
   Read-only on purpose. Nobody picks a name here: the block decides, and
   the server reads the same roster again when it saves. */
.egl-form-people {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    margin-top: 0.375rem;
    min-height: 2rem;
    align-items: center;
}

.egl-form-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 0.375rem;
    padding: 0.25rem 0.625rem;
    border: 1px solid var(--egl-border-strong);
    border-radius: 999px;
    background: var(--egl-surface-3);
    color: var(--egl-text);
    font-size: 0.8125rem;
    line-height: 1.25rem;
}

/* A person who is on the block's list but not at work today still belongs on
   the row - the sheet is about tomorrow. The status is said, not hidden. */
.egl-form-chip small {
    color: var(--egl-warn);
    font-size: 0.6875rem;
}

.egl-form-chip--empty {
    color: var(--egl-text-3);
    font-size: 0.8125rem;
}

/* ── the four check points, two boxes each ───────────────────────────── */
.egl-form-checks {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.5rem;
}

@media (min-width: 640px) {
    .egl-form-checks {
        grid-template-columns: 1fr 1fr;
        gap: 0.5rem 1.25rem;
    }
}

.egl-form-check {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.5rem 0.125rem;
    border-bottom: 1px solid var(--egl-border);
}

.egl-form-check__label {
    color: var(--egl-text);
    font-size: 0.875rem;
}

.egl-form-check__boxes {
    display: inline-flex;
    gap: 0.5rem;
    flex-shrink: 0;
}

/* The tick itself stays a real checkbox - his instruction was two check
   boxes, and a person who cannot see the styling must still be able to use
   the form. The pill beside it is what carries the colour. */
.egl-form-tick {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    cursor: pointer;
    user-select: none;
}

.egl-form-tick input {
    width: 1rem;
    height: 1rem;
    accent-color: var(--egl-ok);
    cursor: pointer;
}

.egl-form-tick--no input {
    accent-color: var(--egl-danger);
}

.egl-form-tick > span {
    padding: 0.125rem 0.5rem;
    border: 1px solid var(--egl-border-strong);
    border-radius: 999px;
    background: var(--egl-surface);
    color: var(--egl-text-3);
    font-size: 0.8125rem;
    line-height: 1.25rem;
    transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}

.egl-form-tick input:checked + span {
    background: var(--egl-ok-soft);
    border-color: var(--egl-ok-border);
    color: var(--egl-ok);
    font-weight: 600;
}

.egl-form-tick--no input:checked + span {
    background: var(--egl-danger-soft);
    border-color: var(--egl-danger-border);
    color: var(--egl-danger);
}

/* =========================================================================
   Phase 17B - one changeover line on its own page.

   A LABEL AND ITS VALUE, and nothing cleverer. A definition list is what
   this is; it is written as .egl-sm-fact rather than a <dl> because the
   value sometimes holds a badge or a row of chips, and a <dd> full of
   inline-flex children fights the browser's own idea of what a list is.

   .egl-sm- rather than a new family: that prefix is already this codebase's
   generic table-and-text set - .egl-sm-table, .egl-sm-note, .egl-sm-dim are
   used by the store, the schedule and the QCO pages alike - so a fact list
   belongs there rather than in a fourteenth prefix nobody would think to
   look under. Every colour is a token, so both themes are right by
   construction; his standing rule is that a new screen must look good in
   light mode, and writing it twice is how the two halves drift apart.
   ========================================================================= */

.egl-sm-facts {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.25rem 1.5rem;
}

@media (min-width: 768px) {
    .egl-sm-facts--two {
        grid-template-columns: 1fr 1fr;
    }
}

/* Label above value on a phone, side by side once there is room. The label
   column is fixed so the values line up down the page instead of stepping
   in and out with the length of each label. */
.egl-sm-fact {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.125rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--egl-border);
    min-width: 0;
}

@media (min-width: 480px) {
    .egl-sm-fact {
        grid-template-columns: 11rem 1fr;
        gap: 0.75rem;
        align-items: baseline;
    }
}

.egl-sm-fact__label {
    color: var(--egl-text-3);
    font-size: 0.8125rem;
    line-height: 1.25rem;
}

.egl-sm-fact__value {
    color: var(--egl-text);
    font-size: 0.9375rem;
    line-height: 1.5rem;
    /* A style number or a long remark must wrap rather than push the card
       sideways - the QCO table already scrolls horizontally and one page
       that does it is enough. */
    overflow-wrap: anywhere;
}

/* Chips inside a value sit on their own lines when there are several. */
.egl-sm-fact__value .egl-form-chip {
    margin: 0.125rem 0.25rem 0.125rem 0;
}

/* The picture frame when there is no picture. Same shape as
   .egl-mech-portrait-empty gives it, so the page does not change size
   depending on whether somebody remembered to take one. */
/*
   GRID, NOT A COLUMN FLEXBOX - AND THAT IS NOT A STYLE PREFERENCE.

   DashboardGaugeTest::test_the_phone_layout_comes_after_the_desktop_one_and_wins
   finds the LAST column-flex declaration in this file with strrpos and reads
   everything after it, expecting the phone gauge block. That block has the
   same specificity as the desktop one, so it only wins by coming later -
   which is a real rule worth guarding, from 10K.

   This rule sits at the END of the file, so writing it as a column flexbox
   moved that anchor onto itself and the test failed about a phone layout
   nobody had touched. STEP 289 was lost to exactly that. A grid whose items
   flow into one implicit column stacks the same way and leaves the anchor
   where it belongs.

   AND THE DECLARATION IS NOT SPELLED OUT ANYWHERE ABOVE, deliberately: the
   test matches plain text and does not care whether it found it in a rule or
   in a comment. The first draft of this very note put the words back in and
   took the anchor a second time.
*/
.egl-form-noshot {
    display: grid;
    align-content: center;
    justify-items: center;
    gap: 0.25rem;
    border: 1px dashed var(--egl-border-strong);
    border-radius: 0.75rem;
    background: var(--egl-surface-2);
    color: var(--egl-text-3);
}

.egl-form-noshot span {
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--egl-text-2);
}

.egl-form-noshot small {
    font-size: 0.75rem;
}

/* =========================================================================
   Phase 17C - the QCO entry form, laid out the way Aomith drew it.

   NOT ONE FIELD CHANGED. His brief was the layout and only the layout:
   "just layout ta thik koro tumi jeisob data entry option rakhco sob thik
   ache sudhu issue hocce dehte valo lagchilo na, data entry option onk
   chorano tai ami aktu sundor kore layout ta sajaite caccilam".

   WHAT WAS WRONG WITH THE OLD ONE, in one sentence: five panels stacked at
   full desktop width put a label and its box a foot apart, and the picture
   sat in a corner of the widest panel, where a 3:4 photograph either became
   a stamp or pushed a whole column of boxes down the page.

   SO: a main column of titled cards with the picture in a column of its
   own, the checklist and the remark across the whole width underneath, and
   a strip at the top repeating the four facts that identify the row.

   EVERY COLOUR IS A TOKEN. Both appearances are right by construction,
   which is his standing rule - a new screen has to look good in light mode,
   and writing it twice is how the two halves drift apart.

   AND NOTHING BELOW USES THE TWO DECLARATIONS DashboardGaugeTest FINDS BY
   POSITION. That test reads the LAST occurrence of a generic declaration in
   this file and expects the phone gauge block after it; STEP 289 was lost to
   a rule at the end of the file taking one of those anchors, and the second
   draft of its explanatory note took it again by spelling it out in prose.
   Stacking here is done with grid, and no fixed width in this block is one
   of the two the test measures. check_17a2.ps1 checks this on the machine.
   ========================================================================= */

/* ---- the strip at the top ---------------------------------------------
   The four facts a person wants without scrolling: date, block, line, plan.
   They are live - Alpine reads the same boxes below - and none of them is
   an input, so nothing here is submitted and nothing here can disagree with
   what is saved. */
.egl-form-head {
    display: grid;
    gap: 1rem;
    align-items: center;
    padding: 1rem 1.125rem;
    margin-bottom: 1rem;
    border: 1px solid var(--egl-border);
    border-radius: 0.875rem;
    background: var(--egl-surface);
    box-shadow: var(--egl-shadow);
}

@media (min-width: 1024px) {
    .egl-form-head {
        grid-template-columns: minmax(0, 1fr) auto;
    }
}

.egl-form-head__id {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    min-width: 0;
}

.egl-form-head__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    height: 3rem;
    inline-size: 3rem;
    border-radius: 0.75rem;
    background: var(--egl-primary-soft);
    border: 1px solid var(--egl-primary-border);
    color: var(--egl-primary);
}

.egl-form-head__title {
    margin: 0;
    font-size: 1.375rem;
    font-weight: 700;
    line-height: 1.75rem;
    color: var(--egl-text);
}

.egl-form-head__lead {
    margin: 0.125rem 0 0;
    font-size: 0.9375rem;
    color: var(--egl-text-2);
}

.egl-form-head__sub {
    margin: 0.0625rem 0 0;
    font-size: 0.8125rem;
    color: var(--egl-text-3);
}

/* Four of them, wrapping onto a second row on a phone rather than
   scrolling sideways - the QCO table already scrolls horizontally and one
   page that does it is enough. */
.egl-form-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 0.625rem;
}

.egl-form-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    min-width: 8.5rem;
    padding: 0.5rem 0.875rem;
    border: 1px solid var(--egl-border);
    border-radius: 0.75rem;
    background: var(--egl-surface-2);
}

.egl-form-pill__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    height: 2rem;
    inline-size: 2rem;
    border-radius: 0.5rem;
    background: var(--egl-info-soft);
    color: var(--egl-info);
}

.egl-form-pill__label {
    display: block;
    font-size: 0.6875rem;
    line-height: 1rem;
    color: var(--egl-text-3);
}

.egl-form-pill__value {
    display: block;
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.375rem;
    color: var(--egl-text);
    overflow-wrap: anywhere;
}

/* The plan pill is the one that carries a meaning rather than a fact, so it
   is the only one that takes a colour. Green for a changeover that was
   planned, amber for one that was not - the same two tones the sheet and
   the line page already use for the same word. */
.egl-form-pill--ok {
    background: var(--egl-ok-soft);
    border-color: var(--egl-ok-border);
}

.egl-form-pill--ok .egl-form-pill__icon {
    background: var(--egl-surface);
    color: var(--egl-ok);
}

.egl-form-pill--ok .egl-form-pill__value {
    color: var(--egl-ok);
}

.egl-form-pill--warn {
    background: var(--egl-warn-soft);
    border-color: var(--egl-warn-border);
}

.egl-form-pill--warn .egl-form-pill__icon {
    background: var(--egl-surface);
    color: var(--egl-warn);
}

.egl-form-pill--warn .egl-form-pill__value {
    color: var(--egl-warn);
}

/* ---- the body: a main column, and the picture beside it ---------------
   One column on a phone, two once there is room for the photograph to be a
   photograph. The aside is a fixed 20rem because a picture column that
   grows with the window is a picture that keeps changing size as you drag
   it; the main column takes whatever is left. */
.egl-form-page {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

@media (min-width: 1024px) {
    .egl-form-page {
        grid-template-columns: minmax(0, 1fr) 20rem;
    }
}

/* Grid rather than a stacking flexbox, and that is not a style preference -
   see the long note above .egl-form-noshot. Items with no explicit column
   fall into one implicit column and stack exactly the same way. */
.egl-form-main {
    display: grid;
    gap: 1rem;
    min-width: 0;
}

.egl-form-aside {
    display: grid;
    gap: 1rem;
    min-width: 0;
}

/* ---- a titled card ---------------------------------------------------- */
.egl-form-card {
    border: 1px solid var(--egl-border);
    border-radius: 0.875rem;
    background: var(--egl-surface);
    padding: 1.125rem;
    box-shadow: var(--egl-shadow);
    min-width: 0;
}

.egl-form-wide {
    margin-top: 1rem;
}

.egl-form-card__head {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

/* A coloured tile per card, so the four sections are told apart by shape
   and colour before a word is read. Each tone already means something in
   this codebase: info for the facts that identify the row, teal-ish muted
   for people, orange for the order, green for a check, slate for a note. */
.egl-form-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    height: 2.5rem;
    inline-size: 2.5rem;
    border-radius: 0.625rem;
    background: var(--egl-info-soft);
    border: 1px solid var(--egl-info-border);
    color: var(--egl-info);
}

/* Written out although it is the same as the base, because the base being
   info-toned is a default and not a decision: the day another tone becomes
   the default, Basic Info should not quietly follow it. */
.egl-form-card__icon--info {
    background: var(--egl-info-soft);
    border-color: var(--egl-info-border);
    color: var(--egl-info);
}

.egl-form-card__icon--team {
    background: var(--egl-primary-soft);
    border-color: var(--egl-primary-border);
    color: var(--egl-primary);
}

.egl-form-card__icon--order {
    background: var(--egl-order-soft);
    border-color: var(--egl-order-border);
    color: var(--egl-order);
}

.egl-form-card__icon--check {
    background: var(--egl-ok-soft);
    border-color: var(--egl-ok-border);
    color: var(--egl-ok);
}

.egl-form-card__icon--note,
.egl-form-card__icon--shot {
    background: var(--egl-muted-soft);
    border-color: var(--egl-muted-border);
    color: var(--egl-muted-tone);
}

.egl-form-card__title {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.5rem;
    color: var(--egl-text);
}

.egl-form-card__sub {
    margin: 0.0625rem 0 0;
    font-size: 0.8125rem;
    line-height: 1.125rem;
    color: var(--egl-text-3);
}

/* ---- the boxes inside a card -----------------------------------------
   Two and three across, and one across on a phone. The breakpoints are the
   ones the rest of this codebase uses, so a form does not start wrapping at
   a width no other page cares about. */
.egl-form-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
}

@media (min-width: 640px) {
    .egl-form-grid--2 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    .egl-form-grid--3 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1280px) {
    .egl-form-grid--3 {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* ---- the picture ------------------------------------------------------
   3:4, the same proportion the mechanic and contact cards use, so a
   photograph taken on a handset is not cropped into a letterbox. */
.egl-form-shot {
    display: block;
    aspect-ratio: 3 / 4;
    max-width: 100%;
    border: 1px solid var(--egl-border);
    border-radius: 0.75rem;
    background: var(--egl-surface-2);
    overflow: hidden;
}

.egl-form-shot img {
    height: 100%;
    inline-size: 100%;
    object-fit: cover;
    display: block;
}

/* Grid, for the reason written above .egl-form-noshot. */
.egl-form-shot--empty {
    display: grid;
    align-content: center;
    justify-items: center;
    gap: 0.375rem;
    border-style: dashed;
    border-color: var(--egl-border-strong);
    color: var(--egl-text-3);
}

.egl-form-shot--empty small {
    font-size: 0.75rem;
}

/* The file box stays a real file box - a person who cannot see the styling
   must still be able to hand in a picture. Only its button is dressed. */
.egl-form-file {
    display: block;
    inline-size: 100%;
    padding: 0.375rem;
    border: 1px solid var(--egl-border-strong);
    border-radius: 0.5rem;
    background: var(--egl-surface-2);
    color: var(--egl-text-3);
    font-size: 0.8125rem;
}

.egl-form-file::file-selector-button {
    margin-right: 0.625rem;
    padding: 0.375rem 0.875rem;
    border: 1px solid var(--egl-primary-border);
    border-radius: 0.5rem;
    background: var(--egl-primary-soft);
    color: var(--egl-primary);
    font-size: 0.8125rem;
    font-weight: 600;
    cursor: pointer;
}

/* ---- the four checks, as he drew them --------------------------------
   STILL TWO REAL CHECK BOXES. "check point 4 ta every check point er jonno
   check box 2 ta" was the instruction and it has not changed; what changed
   is that the pill grew around the box instead of sitting beside it, so the
   whole thing is one target on a handset. The box inside it is the same
   input the server reads, so the page works with the styling off. */
.egl-form-check {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.625rem;
    padding: 0.5rem 0.125rem;
    border-bottom: 0;
}

.egl-form-check__label {
    color: var(--egl-text);
    font-size: 0.9375rem;
}

.egl-form-check__boxes {
    display: inline-flex;
    gap: 0.5rem;
    flex-shrink: 0;
}

.egl-form-tick {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4375rem;
    min-width: 7rem;
    padding: 0.4375rem 0.875rem;
    border: 1px solid var(--egl-border-strong);
    border-radius: 0.625rem;
    background: var(--egl-surface);
    cursor: pointer;
    user-select: none;
    transition: background-color 120ms ease, border-color 120ms ease;
}

.egl-form-tick input {
    height: 0.9375rem;
    inline-size: 0.9375rem;
    accent-color: var(--egl-ok);
    cursor: pointer;
}

.egl-form-tick--no input {
    accent-color: var(--egl-danger);
}

/* The pill is the label now, so the span inside it goes back to being
   plain text. */
.egl-form-tick > span {
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--egl-text-2);
    font-size: 0.875rem;
    line-height: 1.25rem;
    font-weight: 500;
}

.egl-form-tick input:checked + span {
    background: transparent;
    border-color: transparent;
    color: var(--egl-ok);
    font-weight: 600;
}

.egl-form-tick--no input:checked + span {
    background: transparent;
    border-color: transparent;
    color: var(--egl-danger);
}

/* Colouring the whole pill needs :has, which not every browser on a floor
   has. It is written as its own rule on purpose: a browser that does not
   understand the selector drops THIS rule and keeps the two above, so the
   answer is still plainly readable - the word turns green or red either
   way. Nothing here is the only way to see what was ticked. */
.egl-form-tick:has(input:checked) {
    background: var(--egl-ok-soft);
    border-color: var(--egl-ok-border);
}

.egl-form-tick--no:has(input:checked) {
    background: var(--egl-danger-soft);
    border-color: var(--egl-danger-border);
}

/* ---- the remark ------------------------------------------------------ */
@media (min-width: 768px) {
    .egl-form-remark {
        display: grid;
        grid-template-columns: 15rem minmax(0, 1fr);
        gap: 1rem;
        align-items: start;
    }

    .egl-form-remark .egl-form-card__head {
        margin-bottom: 0;
    }
}

/* The card's own title already says Remarks out loud, so a second visible
   label would only repeat it - but the box still needs a label of its own
   or a screen reader is left with the placeholder. Moved out of sight
   rather than switched off, because display:none takes it out of the
   accessibility tree too and that is the one thing it is here for. */
.egl-form-remark__label {
    position: absolute;
    height: 1px;
    inline-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.egl-form-counter {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    margin-top: 0.375rem;
}

/* 2000 is what the rule in the controller says. A counter that promises a
   different number from the one the server enforces is worse than none. */
.egl-form-counter__n {
    flex: none;
    font-size: 0.75rem;
    color: var(--egl-text-3);
    font-variant-numeric: tabular-nums;
}

/* ---- the bar at the bottom -------------------------------------------
   Its own strip rather than two buttons loose under the last card, because
   with the checklist and the remark now running the full width there is no
   card edge left for them to belong to. */
.egl-form-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0.75rem;
    margin-top: 1rem;
    padding: 0.875rem 1.125rem;
    border: 1px solid var(--egl-border);
    border-radius: 0.875rem;
    background: var(--egl-surface);
    box-shadow: var(--egl-shadow);
}

/* =========================================================================
   Phase 17E - the QCO sheet, laid out the way Aomith drew it on the night
   of 14 September.

   THE SEVENTEEN-COLUMN TABLE IS GONE, and that is the whole change. It
   needed a horizontal scrollbar on a desktop and was unreadable on a
   handset, which is where most of the people who read this sheet read it.
   One card per line instead, and the six summary rows became six tiles -
   the same six numbers, still counted by DaySummary and never typed.

   .egl-sm- because that prefix is already this codebase's generic
   table-and-text family, and ThemeOverlayWiringTest allows it. There is no
   qco- prefix and adding one would mean touching that test.

   NOTHING BELOW USES THE DECLARATIONS DashboardGaugeTest FINDS BY POSITION
   (see the long note above .egl-form-noshot). Stacking is done with grid.
   ========================================================================= */

/* ---- the breadcrumb in the shared top bar ---------------------------- */
.egl-sm-crumb {
    color: var(--egl-text-3);
    font-size: 0.875rem;
    text-decoration: none;
}

.egl-sm-crumb:hover {
    color: var(--egl-primary);
}

.egl-sm-crumb-sep {
    color: var(--egl-text-muted);
    font-size: 0.875rem;
}

.egl-sm-crumb-on {
    color: var(--egl-text);
    font-size: 0.875rem;
    font-weight: 600;
}

/* ---- the title, and the line he put beside it ------------------------ */
.egl-sm-hero {
    display: grid;
    gap: 0.75rem;
    align-items: center;
    margin-bottom: 1rem;
}

@media (min-width: 900px) {
    .egl-sm-hero {
        grid-template-columns: minmax(0, 1fr) auto;
    }
}

.egl-sm-hero__title {
    margin: 0;
    font-size: 1.875rem;
    font-weight: 700;
    line-height: 2.25rem;
    letter-spacing: -0.01em;
    color: var(--egl-text);
}

.egl-sm-hero__sub {
    margin: 0.25rem 0 0;
    font-size: 0.9375rem;
    color: var(--egl-text-3);
}

.egl-sm-hero__tag {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    color: var(--egl-text-muted);
}

.egl-sm-hero__tagline {
    margin: 0;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--egl-text-2);
}

.egl-sm-hero__tagsub {
    margin: 0;
    font-size: 0.75rem;
    color: var(--egl-text-muted);
}

/* ---- the date strip -------------------------------------------------- */
.egl-sm-filter {
    border: 1px solid var(--egl-border);
    border-radius: 0.875rem;
    background: var(--egl-surface);
    box-shadow: var(--egl-shadow);
    padding: 1rem 1.125rem;
    margin-bottom: 1rem;
}

.egl-sm-filter__row {
    display: grid;
    gap: 0.75rem;
    align-items: end;
}

@media (min-width: 1024px) {
    .egl-sm-filter__row {
        grid-template-columns: minmax(0, 1fr) auto auto;
    }
}

.egl-sm-filter__field {
    min-width: 0;
}

.egl-sm-filter__btns {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.egl-sm-filter__add {
    display: flex;
    align-items: center;
}

/* ---- a titled block on this page ------------------------------------ */
.egl-sm-block {
    margin-bottom: 1rem;
}

/* The head grows a third column: the note beside the summary title, and
   the count-and-fold beside a unit's title. */
.egl-sm-block__head {
    flex-wrap: wrap;
    align-items: center;
}

.egl-sm-notebox {
    margin: 0 0 0 auto;
    max-width: 26rem;
    padding: 0.625rem 0.75rem;
    border: 1px solid var(--egl-info-border);
    border-radius: 0.625rem;
    background: var(--egl-info-soft);
    color: var(--egl-text-3);
    font-size: 0.75rem;
    line-height: 1.125rem;
}

.egl-sm-block__right {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

.egl-sm-count {
    padding: 0.25rem 0.625rem;
    border: 1px solid var(--egl-border-strong);
    border-radius: 999px;
    background: var(--egl-surface-3);
    color: var(--egl-text-2);
    font-size: 0.75rem;
}

.egl-sm-fold {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 2rem;
    inline-size: 2rem;
    border: 1px solid var(--egl-border);
    border-radius: 0.5rem;
    background: var(--egl-surface-2);
    color: var(--egl-text-3);
    cursor: pointer;
}

.egl-sm-fold:hover {
    border-color: var(--egl-border-strong);
    color: var(--egl-text);
}

/* ---- the six summary tiles ------------------------------------------
   Each tile keeps its own ALL / UNIT-01 / UNIT-02 columns, so the sheet
   still answers the two questions it always answered: how is the day, and
   how is my unit. */
.egl-sm-tiles {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 0.75rem;
}

@media (min-width: 640px) {
    .egl-sm-tiles {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1024px) {
    .egl-sm-tiles {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (min-width: 1536px) {
    .egl-sm-tiles {
        grid-template-columns: repeat(6, minmax(0, 1fr));
    }
}

.egl-sm-tile {
    border: 1px solid var(--egl-border);
    border-radius: 0.75rem;
    background: var(--egl-surface);
    padding: 0.75rem;
    min-width: 0;
}

.egl-sm-tile__head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--egl-border);
}

.egl-sm-tile__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    height: 1.75rem;
    inline-size: 1.75rem;
    border-radius: 0.5rem;
    background: var(--egl-info-soft);
    color: var(--egl-info);
}

.egl-sm-tile__label {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--egl-info);
    overflow-wrap: anywhere;
}

.egl-sm-tile__cols {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.25rem;
    margin-top: 0.5rem;
    text-align: center;
}

.egl-sm-tile__col {
    display: grid;
    gap: 0.125rem;
    min-width: 0;
}

.egl-sm-tile__colhead {
    font-size: 0.625rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--egl-text-muted);
}

.egl-sm-tile__n {
    font-size: 1.125rem;
    font-weight: 700;
    line-height: 1.5rem;
    color: var(--egl-text);
    font-variant-numeric: tabular-nums;
}

/* One tone per meaning, and every one of them a token - his standing rule
   is that a new screen has to look right in light mode too, and writing it
   twice is how the two halves drift apart. */
.egl-sm-tile--run .egl-sm-tile__icon { background: var(--egl-ok-soft); color: var(--egl-ok); }
.egl-sm-tile--run .egl-sm-tile__label { color: var(--egl-ok); }
.egl-sm-tile--prep .egl-sm-tile__icon { background: var(--egl-order-soft); color: var(--egl-order); }
.egl-sm-tile--prep .egl-sm-tile__label { color: var(--egl-order); }
.egl-sm-tile--eff .egl-sm-tile__icon { background: var(--egl-primary-soft); color: var(--egl-primary); }
.egl-sm-tile--eff .egl-sm-tile__label { color: var(--egl-primary); }
.egl-sm-tile--bad .egl-sm-tile__icon { background: var(--egl-danger-soft); color: var(--egl-danger); }
.egl-sm-tile--bad .egl-sm-tile__label { color: var(--egl-danger); }
.egl-sm-tile--unplan .egl-sm-tile__icon { background: var(--egl-muted-soft); color: var(--egl-muted-tone); }
.egl-sm-tile--unplan .egl-sm-tile__label { color: var(--egl-muted-tone); }

/* ---- one card per line ---------------------------------------------- */
.egl-sm-lines {
    display: grid;
    gap: 0.75rem;
}

.egl-sm-line {
    border: 1px solid var(--egl-border);
    border-radius: 0.75rem;
    background: var(--egl-surface-2);
    padding: 0.875rem;
    min-width: 0;
}

.egl-sm-line__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--egl-border);
}

.egl-sm-line__id {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.625rem;
    min-width: 0;
}

.egl-sm-line__block {
    font-size: 1rem;
    font-weight: 700;
    color: var(--egl-text);
}

.egl-sm-line__sep {
    color: var(--egl-border-strong);
}

.egl-sm-line__name {
    font-size: 1rem;
    font-weight: 700;
    color: var(--egl-text);
}

.egl-sm-line__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.375rem;
}

.egl-sm-line__metak {
    font-size: 0.75rem;
    color: var(--egl-text-3);
}

.egl-sm-stage {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 0.625rem;
    border-radius: 999px;
    font-size: 0.8125rem;
    font-weight: 600;
}

.egl-sm-stage--run {
    background: var(--egl-ok-soft);
    border: 1px solid var(--egl-ok-border);
    color: var(--egl-ok);
}

.egl-sm-stage--prep {
    background: var(--egl-order-soft);
    border: 1px solid var(--egl-order-border);
    color: var(--egl-order);
}

.egl-sm-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.1875rem 0.625rem;
    border-radius: 0.5rem;
    font-size: 0.8125rem;
    font-weight: 600;
}

.egl-sm-chip--plan {
    background: var(--egl-primary-soft);
    border: 1px solid var(--egl-primary-border);
    color: var(--egl-primary);
}

.egl-sm-chip--eff {
    background: var(--egl-ok-soft);
    border: 1px solid var(--egl-ok-border);
    color: var(--egl-ok);
    font-variant-numeric: tabular-nums;
}

/* The six things a line says, side by side once there is room and stacked
   on a handset. No horizontal scrollbar anywhere - that was the whole
   complaint about the table this replaces. */
.egl-sm-line__body {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 0.875rem;
    padding-top: 0.875rem;
}

@media (min-width: 768px) {
    .egl-sm-line__body {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1280px) {
    .egl-sm-line__body {
        grid-template-columns: minmax(0, 1.1fr) auto minmax(0, 0.8fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.1fr);
        gap: 1rem;
    }
}

.egl-sm-kv {
    display: grid;
    gap: 0.375rem;
    align-content: start;
    min-width: 0;
}

.egl-sm-kv__row {
    display: grid;
    /* Wider since 17F: the label now carries a glyph as well as a word. */
    grid-template-columns: 6.75rem minmax(0, 1fr);
    gap: 0.5rem;
    align-items: center;
}

/* 17F - the label carries the little picture from his icon sheet, so the
   row reads at a glance before a word of it is read. */
.egl-sm-kv__k {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.8125rem;
    color: var(--egl-text-3);
}

.egl-sm-kv__v {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--egl-text);
    overflow-wrap: anywhere;
}

/* The three measured things, as little tiles - he drew them boxed and
   apart from the plain label-and-value pairs beside them. */
.egl-sm-metrics {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.5rem;
    align-content: start;
}

.egl-sm-metric {
    display: grid;
    justify-items: center;
    gap: 0.125rem;
    padding: 0.5rem 0.375rem;
    border: 1px solid var(--egl-border);
    border-radius: 0.625rem;
    background: var(--egl-surface);
    text-align: center;
    min-width: 0;
}

.egl-sm-metric__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 1.75rem;
    inline-size: 1.75rem;
    border-radius: 0.5rem;
    background: var(--egl-primary-soft);
    color: var(--egl-primary);
}

/* Written out although it matches the base, for the reason given above
   .egl-form-card__icon--info: the base being primary-toned is a default,
   not a decision about Similarity. */
.egl-sm-metric--sim .egl-sm-metric__icon { background: var(--egl-primary-soft); color: var(--egl-primary); }
.egl-sm-metric--wip .egl-sm-metric__icon { background: var(--egl-info-soft); color: var(--egl-info); }
.egl-sm-metric--time .egl-sm-metric__icon { background: var(--egl-ok-soft); color: var(--egl-ok); }

.egl-sm-metric__label {
    font-size: 0.6875rem;
    color: var(--egl-text-3);
}

.egl-sm-metric__v {
    font-size: 0.9375rem;
    font-weight: 700;
    color: var(--egl-text);
    font-variant-numeric: tabular-nums;
}

/* ---- the four named columns: checks, technician, mechanic, remarks --- */
.egl-sm-col {
    display: grid;
    gap: 0.25rem;
    align-content: start;
    min-width: 0;
}

.egl-sm-col__head {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    margin: 0 0 0.25rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--egl-text-2);
}

.egl-sm-checkrow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.8125rem;
    color: var(--egl-text-3);
}

.egl-sm-person {
    margin: 0;
    padding: 0.1875rem 0.5rem;
    border-radius: 0.375rem;
    background: var(--egl-surface);
    font-size: 0.8125rem;
    color: var(--egl-text);
    overflow-wrap: anywhere;
}

.egl-sm-remark {
    margin: 0;
    padding: 0.4375rem 0.625rem;
    border: 1px solid var(--egl-warn-border);
    border-radius: 0.5rem;
    background: var(--egl-warn-soft);
    color: var(--egl-warn);
    font-size: 0.8125rem;
    overflow-wrap: anywhere;
}

/* The way into the line's own page. The one strong button on the card, so
   there is no question which thing to press. */
.egl-sm-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    margin-top: 0.5rem;
    padding: 0.5rem 0.875rem;
    border-radius: 0.625rem;
    background: linear-gradient(135deg, var(--egl-primary), var(--egl-nav-indigo));
    color: #ffffff;
    font-size: 0.875rem;
    font-weight: 600;
    text-decoration: none;
    box-shadow: var(--egl-shadow);
}

.egl-sm-cta:hover {
    filter: brightness(1.07);
    color: #ffffff;
}

/* ---- the line along the bottom -------------------------------------- */
.egl-sm-foot {
    display: grid;
    gap: 0.375rem;
    margin-top: 1.25rem;
    padding-top: 0.875rem;
    border-top: 1px solid var(--egl-border);
    color: var(--egl-text-muted);
    font-size: 0.75rem;
}

@media (min-width: 768px) {
    .egl-sm-foot {
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: center;
    }
}

.egl-sm-foot p {
    margin: 0;
}

.egl-sm-foot__right {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.egl-sm-foot__right span + span::before {
    content: '|';
    margin-right: 0.5rem;
    color: var(--egl-border-strong);
}

/* =========================================================================
   Phase 17D - handing the sheet to the floor.

   It sits inside the date strip rather than beside the lines, because it is
   about the WHOLE day, not about any one line. And it is quiet on purpose:
   this is the only control on the page that reaches somebody's phone, so it
   should read as a deliberate act, not as one more button to sweep past.
   ========================================================================= */
.egl-sm-send {
    display: grid;
    gap: 0.625rem;
    margin-top: 0.875rem;
    padding-top: 0.875rem;
    border-top: 1px solid var(--egl-border);
}

.egl-sm-send__row {
    display: grid;
    gap: 0.625rem;
    align-items: center;
}

@media (min-width: 768px) {
    .egl-sm-send__row {
        grid-template-columns: minmax(0, 1fr) auto;
    }
}

.egl-sm-send__title {
    margin: 0 0 0.125rem;
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--egl-text);
}

.egl-sm-send__act {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

/* The confirm step. Amber, because it is a pause rather than a danger - the
   sheet going out is the ordinary end of the meeting, it just cannot be
   taken back once it has. */
.egl-sm-send__confirm {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4375rem 0.625rem;
    border: 1px solid var(--egl-warn-border);
    border-radius: 0.625rem;
    background: var(--egl-warn-soft);
}

/* What went, and to how many phones. */
.egl-sm-sent {
    display: grid;
    gap: 0.25rem;
}

.egl-sm-sent__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-size: 0.8125rem;
    color: var(--egl-text-2);
}

/* ---------------------------------------------------------------------------
   Phase 17J - the navy envelope on Send everyone.
   The button stays the secondary button it was; only the glyph carries the
   colour, so the press still reads as the quiet action it is. Navy is dark
   enough to sit on the white card and would disappear on the dark one, so
   the dark theme gets the same hue lifted rather than a different colour.
   --------------------------------------------------------------------------- */
.egl-sm-send__icon {
    color: #1d3a6e;
}

html[data-theme='dark'] .egl-sm-send__icon {
    color: #9dbbe6;
}

/* Phase 17K - the spreadsheet glyph on Download Excel. Excel's own green,
   dark enough for the white card and lifted for the dark one, the same way
   the envelope beside Send everyone is handled. */
.egl-sm-xls__icon {
    color: #1d6f42;
}

html[data-theme='dark'] .egl-sm-xls__icon {
    color: #8fd3ad;
}

/* Phase 17M - the picture glyph on Download Image. A slate blue beside the
   spreadsheet green, so the two downloads read as a pair without either one
   shouting. Dark theme gets the same hue lifted, as everywhere else here. */
.egl-sm-png__icon {
    color: #2f5d8a;
}

html[data-theme='dark'] .egl-sm-png__icon {
    color: #9cc3ea;
}
/* Phase 17R - the Operation Breakdown sheet on a line's page.

   A PORTRAIT DOCUMENT, NOT A PORTRAIT OF A PERSON, so it does not take the
   egl-mech-portrait frame: that one crops to 3:4 and a cropped OB sheet has
   lost the rows at the bottom, which are the rows somebody came here to read.
   object-fit: contain keeps the whole page, whatever shape it was shot in.

   Capped at 420px tall because it sits in a column beside everything else
   that was entered. Nobody reads it at that size - they tap it, and the
   stored file opens full size in its own tab. The zoom-in cursor says so on a
   desktop; on a phone the note under it says so in words. */
.egl-sm-obsheet {
    display: block;
    width: 100%;
    max-height: 420px;
    object-fit: contain;
    object-position: top center;
    background: #f7f8f5;
    border: 1px solid #d8dfd6;
    border-radius: 6px;
    padding: 4px;
    cursor: zoom-in;
}

/* The letterboxed edges take the dark surface rather than staying near-white:
   a bright slab beside dark panels is the one thing that would make this page
   uncomfortable to read at night. The photograph's own paper stays white. */
html[data-theme='dark'] .egl-sm-obsheet {
    background: #232a25;
    border-color: #39423b;
}


/* ==========================================================================
   Phase 18A-1b - the "Order by" box on Store Parts was cutting its own text.
   --------------------------------------------------------------------------
   MEASURED, NOT GUESSED. The frozen bundle says, word for word:

       .egl-input { width:100%; padding:.5rem .75rem; border-width:1px;
                    display:block; font-size:.875rem }
       .w-auto    { width:auto }

   Both are one class - (0,1,0) - and .w-auto is in the utilities layer, which
   the bundle prints last, so `class="egl-input w-auto"` really did give the
   select width:auto. Rendered with exactly those two rules, the box came out
   241px, the content box 215px, and the longest option - "Furthest below its
   level first" - 194px. That leaves 21 pixels.

   Twenty-one pixels is also about what the browser wants for the dropdown
   arrow it draws itself, and the arrow is drawn INSIDE that same right-hand
   padding. So the text and the arrow were sharing one lane. On this Linux
   build the arrow is small enough to squeeze in; on Aomith's Windows Chrome
   the arrow is wider and the system font sets that sentence a few pixels
   longer, so the text ran under the arrow and the last letter was cut - and
   the arrow itself disappeared behind the words. His screenshot shows both.

   THE FIX IS ROOM, NOT A SMALLER FONT. 2.25rem of right padding gives the
   arrow a lane of its own; max-width keeps the box inside the panel on a
   phone, where the row wraps and there is no 241px to spare.

   Written here rather than as utilities because the bundle is frozen: a
   utility nobody has used before is simply absent, and would do nothing at
   all - silently, which is how this class of bug keeps happening. */
.egl-sm-sort {
    width: auto;
    max-width: 100%;
    padding-right: 2.25rem;
}


/* ==========================================================================
   Phase 18H - the Excel import says which step writes.
   --------------------------------------------------------------------------
   Every colour here is a token, so light and dark are one decision and not
   two. Written in the overlay because the compiled bundle is frozen: a
   utility class nobody has used before is simply absent from it and would do
   nothing at all, silently.

   THREE PIECES, in the order somebody meets them:
     .egl-sm-howto   on the list page, before a file is chosen - the two steps
     .egl-sm-gate    at the top of the check screen - nothing written yet
     .egl-sm-decide  at the bottom of it - what pressing the button costs
   ========================================================================== */

.egl-sm-howto {
    padding: 0.75rem 0.9375rem;
    border: 1px solid var(--egl-border);
    border-radius: 0.75rem;
    background: var(--egl-muted-soft);
}

.egl-sm-howto__title {
    margin: 0 0 0.25rem;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--egl-text);
}

/* Numbered, because the whole point is that there are two of them and they
   happen in an order. list-style-position keeps the number inside the padded
   box on a phone, where the text wraps under itself. */
.egl-sm-howto__steps {
    margin: 0;
    padding-left: 1.125rem;
    list-style: decimal;
    list-style-position: outside;
    font-size: 0.8125rem;
    line-height: 1.55;
    color: var(--egl-text-muted);
}

.egl-sm-howto__steps li + li {
    margin-top: 0.1875rem;
}

/* Blue rather than amber: this is a reassurance - you have not broken
   anything yet - and not a warning. The warning is further down, next to the
   button that can. */
.egl-sm-gate {
    padding: 0.8125rem 1rem;
    border: 1px solid var(--egl-info-border);
    border-radius: 0.75rem;
    background: var(--egl-info-soft);
}

.egl-sm-gate__title {
    margin: 0 0 0.1875rem;
    font-size: 0.9375rem;
    font-weight: 700;
    color: var(--egl-info);
}

.egl-sm-gate__text {
    margin: 0;
    font-size: 0.8125rem;
    line-height: 1.55;
    color: var(--egl-text-muted);
}

/* The decision. A stronger border than an ordinary card, because the eye has
   just come down a long table and this is not one more row of it. */
.egl-sm-decide {
    display: grid;
    gap: 0.5rem;
    padding: 1rem;
    border: 1px solid var(--egl-border-strong);
    border-radius: 0.875rem;
    background: var(--egl-surface);
    box-shadow: var(--egl-shadow);
}

.egl-sm-decide__title {
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
    color: var(--egl-text);
}

.egl-sm-decide__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.625rem;
    margin-top: 0.125rem;
}

/* The second half of the press. Amber and boxed, exactly like the confirm
   step on the QCO sheet in 17D - the same shape means the same thing, and
   somebody who has met one already knows what this one wants. */
.egl-sm-decide__confirm {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4375rem 0.625rem;
    border: 1px solid var(--egl-warn-border);
    border-radius: 0.625rem;
    background: var(--egl-warn-soft);
}


/* ==========================================================================
   Phase 16E - a blank box being filled in, on the import check screen.
   --------------------------------------------------------------------------
   Green, and only here. Every other line in that Detail column is stock
   moving; this one is a part's own description being completed, and the two
   should not read as the same kind of event. The token carries both themes.
   ========================================================================== */
.egl-sm-fill {
    color: var(--egl-ok);
    font-size: 0.8125rem;
    line-height: 1.5;
}

/* ------------------------------------------------------------------
   Phase 22C - the Machine Requirement header on a phone.

   Aomith, 23 Sep: this page was the last one that still slid sideways on
   a handset - 32px at 375px, measured. The cause was not the tab strip
   (that one is a strip you push sideways on purpose, and it is clipped);
   it was the Excel + Add Requirement pair in the page's own header. The
   heading beside them carries min-w-0, so it could shrink far enough for
   the flex row to call itself "fitted" and never wrap, while shrink-0
   held the two buttons at their full 285px - straight past the edge.

   A desktop keeps exactly what it had. Below 640px the pair takes a line
   of its own and the two buttons share it.
   ------------------------------------------------------------------ */
.egl-mreq-headright {
    flex-shrink: 0;
}

@media (max-width: 640px) {
    .egl-mreq-headright {
        flex-shrink: 1;
        flex-wrap: wrap;
        width: 100%;
        min-width: 0;
    }

    .egl-mreq-headright > a {
        flex: 1 1 8rem;
        justify-content: center;
    }
}

/* ------------------------------------------------------------------
   Phase 24B - the note under the process box for everyone who is not an
   Admin. Amber, because amber already means "somebody else decides this"
   all through the app - and it has to be read at a glance on a line.
   ------------------------------------------------------------------ */
.egl-sm-askadmin {
    color: #F59E0B;
    font-weight: 600;
}

/* ==================================================================
   Phase 26 - STYLE LAYOUT SPLIT
   ------------------------------------------------------------------
   A module of four pages, so its own prefix: egl-slx-. Light, quiet,
   and readable on a phone first - Aomith's rule for every new module,
   and his reason for wanting the dashboard's charts stacked one under
   another rather than side by side.

   Nothing here is forced over the bundle - every rule below is a class
   this module puts on its own markup, and none of them reaches for a
   class the frozen Tailwind bundle already ships.
   ================================================================== */

/* --- headings, notes and small print ----------------------------- */
.egl-slx-h {
    color: var(--egl-text);
    font-size: 1rem;
    font-weight: 700;
    margin-bottom: .5rem;
}

.egl-slx-p {
    color: var(--egl-text-3);
    font-size: .875rem;
    line-height: 1.55;
}

.egl-slx-hint {
    color: var(--egl-text-muted);
    font-size: .75rem;
    line-height: 1.5;
    margin-top: .25rem;
}

.egl-slx-label {
    display: block;
    color: var(--egl-text-muted);
    font-size: .75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .03em;
    margin-bottom: .25rem;
}

.egl-slx-askadmin {
    color: #F59E0B;
    font-weight: 600;
}

.egl-slx-note {
    border-radius: .625rem;
    border: 1px solid var(--egl-border);
    background: var(--egl-surface-2);
    color: var(--egl-text-2);
    padding: .75rem 1rem;
    font-size: .875rem;
}

.egl-slx-note--good {
    border-color: var(--egl-ok-border);
    background: var(--egl-ok-soft);
    color: var(--egl-ok);
}

.egl-slx-note--bad {
    border-color: var(--egl-danger-border);
    background: var(--egl-danger-soft);
    color: var(--egl-danger);
}

.egl-slx-check {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    color: var(--egl-text-2);
    font-size: .875rem;
    font-weight: 600;
    cursor: pointer;
}

/* --- the two-column page, one column on a phone ------------------ */
.egl-slx-split {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.25rem;
}

@media (min-width: 1024px) {
    .egl-slx-split {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    }
}

/* --- how far the data goes, month by month ----------------------- */
.egl-slx-months {
    display: grid;
    grid-template-columns: 1fr;
    gap: .625rem;
}

@media (min-width: 640px) {
    .egl-slx-months {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.egl-slx-month {
    border: 1px solid var(--egl-border);
    border-radius: .625rem;
    background: var(--egl-surface-2);
    padding: .75rem .875rem;
}

.egl-slx-month--now {
    border-color: var(--egl-primary-border);
    background: var(--egl-primary-soft);
}

.egl-slx-month-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    margin-bottom: .5rem;
}

.egl-slx-month-name {
    color: var(--egl-text);
    font-weight: 700;
    font-size: .9375rem;
}

.egl-slx-chip {
    border-radius: 999px;
    background: var(--egl-primary);
    color: #ffffff;
    font-size: .625rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    padding: .125rem .5rem;
}

.egl-slx-month-facts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .375rem .75rem;
    margin: 0;
}

.egl-slx-month-facts dt {
    color: var(--egl-text-muted);
    font-size: .6875rem;
    text-transform: uppercase;
    letter-spacing: .03em;
}

.egl-slx-month-facts dd {
    color: var(--egl-text);
    font-size: .875rem;
    font-weight: 600;
    margin: 0;
}

/* --- tables ------------------------------------------------------ */
.egl-slx-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.egl-slx-table {
    width: 100%;
    border-collapse: collapse;
    font-size: .8125rem;
}

.egl-slx-table th {
    text-align: left;
    color: var(--egl-text-muted);
    font-size: .6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    padding: .5rem .625rem;
    border-bottom: 1px solid var(--egl-border);
    white-space: nowrap;
}

.egl-slx-table td {
    color: var(--egl-text-2);
    padding: .5rem .625rem;
    border-bottom: 1px solid var(--egl-border);
    white-space: nowrap;
}

.egl-slx-table tbody tr:last-child td {
    border-bottom: 0;
}

.egl-slx-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.egl-slx-file {
    max-width: 14rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ------------------------------------------------------------------
   Phase 26C - the dashboard: five boxes, a summary line, and the bars.

   The bars grow into place rather than simply being there, and they
   arrive one after another. ALL OF IT IS CSS: the bar's own length is
   an inline --egl-slx-w and the growing is a keyframe from zero to it,
   so a page where the scripts have not loaded still draws every bar at
   its right length instead of showing a row of empty tracks. The
   stagger is a delay read from --egl-slx-i. Anyone who has asked their
   system to stop moving things gets the bars already in place, which
   the media query at the end settles.
   ------------------------------------------------------------------ */
.egl-slx-filters {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .75rem;
}

@media (min-width: 768px) {
    .egl-slx-filters {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (min-width: 1200px) {
    .egl-slx-filters {
        grid-template-columns: repeat(5, minmax(0, 1fr));
    }
}

.egl-slx-filter-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem;
    margin-top: .75rem;
}

.egl-slx-clear {
    color: var(--egl-primary);
    font-size: .8125rem;
    font-weight: 600;
    text-decoration: none;
}

.egl-slx-clear:hover {
    text-decoration: underline;
}

/* --- the summary line -------------------------------------------- */
.egl-slx-summary {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .625rem;
}

@media (min-width: 640px) {
    .egl-slx-summary {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

@media (min-width: 1200px) {
    .egl-slx-summary {
        grid-template-columns: repeat(7, minmax(0, 1fr));
    }
}

.egl-slx-stat {
    border: 1px solid var(--egl-border);
    border-left: 3px solid var(--egl-border-strong);
    border-radius: .625rem;
    background: var(--egl-surface);
    padding: .625rem .75rem;
    /* A grid rather than a column flex on purpose: the overlay's LAST
       flex-direction:column belongs to the dashboard gauge's phone block,
       and DashboardGaugeTest reads exactly that to prove the phone rules
       come after the desktop ones. Nothing this module adds may take that
       place. */
    display: grid;
    grid-template-columns: 1fr;
    gap: .125rem;
    min-width: 0;
}

.egl-slx-stat--good { border-left-color: var(--egl-ok); }
.egl-slx-stat--warn { border-left-color: var(--egl-warn); }
.egl-slx-stat--bad  { border-left-color: var(--egl-danger); }

.egl-slx-stat-n {
    color: var(--egl-text);
    font-size: 1.375rem;
    font-weight: 700;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.egl-slx-stat-l {
    color: var(--egl-text-muted);
    font-size: .6875rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    line-height: 1.3;
}

.egl-slx-stat-sub {
    display: block;
    text-transform: none;
    letter-spacing: 0;
    color: var(--egl-text-3);
    font-size: .6875rem;
}

/* --- the cards --------------------------------------------------- */
.egl-slx-card-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
}

.egl-slx-nudge {
    border-radius: 999px;
    border: 1px solid var(--egl-warn-border);
    background: var(--egl-warn-soft);
    color: var(--egl-warn);
    font-size: .75rem;
    font-weight: 700;
    padding: .25rem .75rem;
    text-decoration: none;
    white-space: nowrap;
}

/* --- the bars, one under another --------------------------------- */
.egl-slx-bars {
    display: grid;
    grid-template-columns: 1fr;
    gap: .25rem;
}

/* A row is banded rather than spaced: with 190 of them, a hairline and a
   hover tint read as a list you can follow, where white space just made
   it longer. */
.egl-slx-bars > .egl-slx-bar {
    padding: .5rem .5rem .4375rem;
    border-radius: .5rem;
    border-bottom: 1px solid var(--egl-border);
    transition: background .12s ease;
}

.egl-slx-bars > .egl-slx-bar:last-child {
    border-bottom: 0;
}

.egl-slx-bars > .egl-slx-bar:hover {
    background: var(--egl-surface-2);
}

.egl-slx-bar {
    min-width: 0;
    opacity: 0;
    transform: translateY(6px);
    animation: egl-slx-in .35s ease forwards;
    animation-delay: calc(var(--egl-slx-i, 0) * 45ms);
}

.egl-slx-bar--slim {
    animation-delay: calc(var(--egl-slx-i, 0) * 30ms);
}

@keyframes egl-slx-in {
    to { opacity: 1; transform: translateY(0); }
}

.egl-slx-bar-top {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .375rem .5rem;
    margin-bottom: .3125rem;
}

.egl-slx-bar-style {
    color: var(--egl-text);
    font-weight: 700;
    font-size: .875rem;
}

.egl-slx-bar-item {
    color: var(--egl-text-3);
    font-size: .8125rem;
}

.egl-slx-bar-buyer {
    color: var(--egl-text-muted);
    font-size: .75rem;
}

.egl-slx-tag {
    border-radius: 999px;
    border: 1px solid var(--egl-border);
    background: var(--egl-surface-3);
    color: var(--egl-text-3);
    font-size: .6875rem;
    font-weight: 600;
    padding: .0625rem .5rem;
    white-space: nowrap;
}

.egl-slx-tag--good {
    border-color: var(--egl-ok-border);
    background: var(--egl-ok-soft);
    color: var(--egl-ok);
}

.egl-slx-tag--warn {
    border-color: var(--egl-warn-border);
    background: var(--egl-warn-soft);
    color: var(--egl-warn);
}

.egl-slx-tag--bad {
    border-color: var(--egl-danger-border);
    background: var(--egl-danger-soft);
    color: var(--egl-danger);
}

.egl-slx-track {
    position: relative;
    height: 1.25rem;
    border-radius: .375rem;
    background: var(--egl-surface-3);
    overflow: hidden;
    display: flex;
    align-items: center;
}

.egl-slx-fill {
    position: absolute;
    inset: 0 auto 0 0;
    width: var(--egl-slx-w, 0%);
    border-radius: .375rem;
    animation: egl-slx-grow .9s cubic-bezier(.22, .61, .36, 1) both;
    animation-delay: calc(var(--egl-slx-i, 0) * 45ms);
}

@keyframes egl-slx-grow {
    from { width: 0; }
    to { width: var(--egl-slx-w, 0%); }
}

/* .28 was so faint the bars read as empty track. These are the width of
   the answer, so they are drawn at a strength you can see across a room -
   and the figure that sits on them is drawn over the track, not over the
   fill, so nothing has to fight it for contrast.

   On the dashboard the bar's colour answers one question and one only:
   did this style reach the efficiency it was costed at. Green yes, soft
   red no. The red is lighter than the green on purpose - there are more
   of them, and a wall of hard red says "everything is broken" rather
   than "these missed". Grey is for a style with no target to reach,
   which is not a pass and not a failure. */
.egl-slx-fill--good { background: var(--egl-ok); opacity: .5; }
.egl-slx-fill--warn { background: var(--egl-warn); opacity: .5; }
.egl-slx-fill--bad  { background: var(--egl-danger); opacity: .34; }
.egl-slx-fill--none { background: var(--egl-text-muted); opacity: .28; }

.egl-slx-bar-pcs {
    position: relative;
    color: var(--egl-text);
    font-size: .8125rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    padding-left: .625rem;
}

.egl-slx-bar-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .25rem .875rem;
    margin-top: .3125rem;
    color: var(--egl-text-muted);
    font-size: .75rem;
}

.egl-slx-bar-foot b {
    color: var(--egl-text-2);
    font-variant-numeric: tabular-nums;
}

.egl-slx-up { color: var(--egl-ok); font-weight: 700; }
.egl-slx-down { color: var(--egl-danger); font-weight: 700; }

/* --- card 2: one chart a reason ---------------------------------- */
.egl-slx-reasons {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
}

@media (min-width: 1024px) {
    .egl-slx-reasons {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.egl-slx-reason {
    border: 1px solid var(--egl-border);
    border-radius: .625rem;
    background: var(--egl-surface-2);
    padding: .875rem;
}

.egl-slx-reason-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
    margin-bottom: .625rem;
}

.egl-slx-reason-name {
    color: var(--egl-text);
    font-weight: 700;
    font-size: .875rem;
}

@media (prefers-reduced-motion: reduce) {
    .egl-slx-bar {
        opacity: 1;
        transform: none;
        animation: none;
    }

    .egl-slx-fill {
        animation: none;
        width: var(--egl-slx-w, 0%);
    }
}

/* ------------------------------------------------------------------
   Phase 26D and 26E - the Short quantity page and the reason list.
   ------------------------------------------------------------------ */
.egl-slx-shorts {
    display: grid;
    grid-template-columns: 1fr;
    gap: .75rem;
}

@media (min-width: 1024px) {
    .egl-slx-shorts {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.egl-slx-short {
    border: 1px solid var(--egl-border);
    border-radius: .625rem;
    background: var(--egl-surface-2);
    padding: .75rem .875rem;
    transition: opacity .4s ease, transform .4s ease;
}

/* A row that has just become a layout has left this page. It fades where
   it stands rather than the whole page reloading under the person. */
.egl-slx-short--gone {
    opacity: .35;
    transform: translateX(8px);
}

.egl-slx-short-facts {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .25rem .875rem;
    margin: .375rem 0 .625rem;
    color: var(--egl-text-muted);
    font-size: .75rem;
}

.egl-slx-short-facts b {
    color: var(--egl-text-2);
    font-variant-numeric: tabular-nums;
}

.egl-slx-short-pick {
    border-top: 1px dashed var(--egl-border);
    padding-top: .625rem;
}

/* --- the reason list --------------------------------------------- */
.egl-slx-addrow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .625rem;
}

.egl-slx-addrow > input[type="text"] {
    flex: 1 1 16rem;
    min-width: 0;
}

.egl-slx-reasonlist {
    display: grid;
    grid-template-columns: 1fr;
    gap: .625rem;
}

.egl-slx-reasonrow {
    border: 1px solid var(--egl-border);
    border-radius: .625rem;
    background: var(--egl-surface-2);
    padding: .75rem .875rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
}

/* Hidden means out of the dropdown, not gone. It is drawn quieter so the
   list says at a glance which ones an IE will actually be offered. */
.egl-slx-reasonrow--off {
    opacity: .6;
    border-style: dashed;
}

.egl-slx-reasonrow-main {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .625rem;
    flex: 1 1 22rem;
    min-width: 0;
}

.egl-slx-reasonrow-main > input[type="text"] {
    flex: 1 1 14rem;
    min-width: 0;
}

.egl-slx-reasonrow-side {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .625rem;
}

.egl-slx-remove {
    border: 0;
    background: none;
    color: var(--egl-danger);
    font-size: .8125rem;
    font-weight: 600;
    cursor: pointer;
    padding: .25rem .375rem;
}

.egl-slx-remove:hover {
    text-decoration: underline;
}

.egl-slx-confirm {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    color: var(--egl-text-2);
    font-size: .8125rem;
}

/* ------------------------------------------------------------------
   Phase 26H - the dashboard, designed for a real month.

   A month is around 190 styles. The first draft drew all of them, one
   under another, equally loud, with a summary of seven identical boxes
   above. Aomith shows this page to people above him, so what changed
   here is what the eye lands on first: one headline figure with the
   month beside it, a single bar splitting "closed in one go" from
   "split", and the rest as supporting numbers. The chart below gained
   an ordering, a search and a top-few view, so it is a chart again
   rather than a scroll.
   ------------------------------------------------------------------ */
.egl-slx-headline {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
}

@media (min-width: 900px) {
    .egl-slx-headline {
        grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
        align-items: stretch;
    }
}

.egl-slx-headline-main {
    border: 1px solid var(--egl-border);
    border-radius: .75rem;
    background: var(--egl-surface);
    padding: 1rem 1.125rem;
    box-shadow: var(--egl-shadow);
}

.egl-slx-headline-when {
    display: block;
    color: var(--egl-primary);
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

.egl-slx-headline-n {
    display: block;
    color: var(--egl-text);
    font-size: 2.75rem;
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
    margin-top: .25rem;
}

.egl-slx-headline-l {
    display: block;
    color: var(--egl-text-muted);
    font-size: .8125rem;
    font-weight: 600;
}

/* One bar for the month's whole answer: how much of it closed in one go
   and how much had to be laid out again. */
.egl-slx-split-bar {
    display: flex;
    height: .5rem;
    margin-top: .875rem;
    border-radius: 999px;
    overflow: hidden;
    background: var(--egl-surface-3);
}

.egl-slx-split-bar > span {
    width: var(--egl-slx-w, 0%);
    animation: egl-slx-grow .7s cubic-bezier(.22, .61, .36, 1) both;
}

.egl-slx-split-good { background: var(--egl-ok); }
.egl-slx-split-warn { background: var(--egl-warn); }

.egl-slx-split-key {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem .875rem;
    margin-top: .5rem;
    color: var(--egl-text-3);
    font-size: .75rem;
    font-weight: 600;
}

.egl-slx-dot {
    display: inline-block;
    width: .5rem;
    height: .5rem;
    border-radius: 999px;
    margin-right: .375rem;
}

.egl-slx-dot--good { background: var(--egl-ok); }
.egl-slx-dot--warn { background: var(--egl-warn); }

.egl-slx-headline-side {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .625rem;
}

/* Beside the headline these stretch to its height, so their contents are
   centred rather than left stranded at the top of a tall box. */
.egl-slx-headline-side .egl-slx-stat {
    align-content: center;
}

@media (min-width: 1200px) {
    .egl-slx-headline-side {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* --- the card's own controls ------------------------------------- */
.egl-slx-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}

.egl-slx-search {
    position: relative;
    display: block;
    flex: 1 1 11rem;
    min-width: 0;
}

.egl-slx-search > input {
    padding-left: 2.125rem;
}

.egl-slx-search-icon {
    position: absolute;
    left: .625rem;
    top: 50%;
    transform: translateY(-50%);
    width: 1rem;
    height: 1rem;
    color: var(--egl-text-muted);
    pointer-events: none;
}

.egl-slx-search-icon svg {
    width: 100%;
    height: 100%;
}

.egl-slx-sort {
    flex: 0 1 15rem;
    min-width: 0;
}

.egl-slx-count {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .375rem .75rem;
    margin-top: .875rem;
    padding-bottom: .625rem;
    border-bottom: 1px solid var(--egl-border);
    color: var(--egl-text-2);
    font-size: .8125rem;
    font-weight: 700;
}

.egl-slx-count .egl-slx-hint {
    margin-top: 0;
    font-weight: 500;
}

/* --- one style's row --------------------------------------------- */
.egl-slx-bar-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .25rem .5rem;
    margin-bottom: .375rem;
}

.egl-slx-rank {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.5rem;
    height: 1.25rem;
    padding: 0 .3125rem;
    border-radius: .3125rem;
    background: var(--egl-surface-3);
    color: var(--egl-text-muted);
    font-size: .6875rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* One row is a small table: the bar, then three columns that line up all
   the way down the card, so the eye runs down one column of percentages
   instead of hunting for each one at the end of a different bar. The
   pieces are OUTSIDE the bar - written on top of the fill they had to
   fight it for contrast, and lost. */
.egl-slx-bar-body {
    display: grid;
    align-items: center;
    /* On a phone the bar gets the whole width and the three figures sit on
       the line below it. Squeezed into a column beside them it was a
       sliver, which is no use as a bar. */
    grid-template-columns: auto auto minmax(0, 1fr);
    grid-template-areas:
        'track track track'
        'pcs   eff   delta';
    gap: .3125rem .625rem;
}

.egl-slx-track { grid-area: track; }
.egl-slx-pcs { grid-area: pcs; justify-content: flex-start; }
.egl-slx-fig { grid-area: eff; justify-content: flex-start; }
.egl-slx-delta { grid-area: delta; }

@media (min-width: 900px) {
    .egl-slx-bar-body {
        grid-template-columns: minmax(0, 1fr) 7.5rem 9.75rem 3.75rem;
        grid-template-areas: 'track pcs eff delta';
        gap: .875rem;
    }

    .egl-slx-pcs,
    .egl-slx-fig {
        justify-content: flex-end;
    }
}

.egl-slx-pcs {
    display: inline-flex;
    align-items: baseline;
    justify-content: flex-end;
    gap: .25rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.egl-slx-pcs b {
    color: var(--egl-text);
    font-size: .9375rem;
    font-weight: 700;
}

.egl-slx-pcs i {
    font-style: normal;
    color: var(--egl-text-muted);
    font-size: .6875rem;
    font-weight: 600;
}

.egl-slx-tags {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .3125rem;
}

.egl-slx-fig {
    display: inline-flex;
    align-items: baseline;
    justify-content: flex-end;
    gap: .3125rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.egl-slx-fig b {
    color: var(--egl-text);
    font-size: .875rem;
    font-weight: 700;
}

.egl-slx-fig i {
    font-style: normal;
    color: var(--egl-text-muted);
    font-size: .6875rem;
}

.egl-slx-delta {
    min-width: 3.25rem;
    text-align: right;
    font-size: .8125rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.egl-slx-bar-lines {
    margin-top: .25rem;
    color: var(--egl-text-muted);
    font-size: .6875rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A month has around 190 rows. At 45ms each the last one would arrive
   nine seconds in, which is not an animation, it is a wait - so the
   stagger stops after the first dozen. */
.egl-slx-bar {
    animation-delay: calc(min(var(--egl-slx-i, 0), 12) * 40ms);
}

.egl-slx-bar--slim {
    animation-delay: calc(min(var(--egl-slx-i, 0), 12) * 30ms);
}

@media (prefers-reduced-motion: reduce) {
    .egl-slx-split-bar > span {
        animation: none;
        width: var(--egl-slx-w, 0%);
    }
}

/* ------------------------------------------------------------------
   Phase 26H - the Short quantity page.

   The one thing every row is really about is how far under 20% it
   fell, and that was a number in a pill. It is now a small bar with
   the 20% mark notched into it, so a run that nearly made it and a run
   that made a hundred pieces look different at a glance rather than
   needing to be read.
   ------------------------------------------------------------------ */
.egl-slx-share {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin: .4375rem 0 .5rem;
}

.egl-slx-share-bar,
.egl-slx-legend-bar {
    position: relative;
    display: block;
    flex: 1 1 auto;
    height: .625rem;
    min-width: 4rem;
    border-radius: 999px;
    background: var(--egl-surface-3);
    overflow: hidden;
}

/* The notch: 20% of the line, drawn at 62% of the bar so that everything
   under the threshold has room to be told apart. */
.egl-slx-share-bar::after,
.egl-slx-legend-bar::after {
    content: '';
    position: absolute;
    left: 62%;
    top: -.125rem;
    bottom: -.125rem;
    width: 2px;
    background: var(--egl-text-muted);
    opacity: .8;
}

.egl-slx-share-fill,
.egl-slx-legend-bar > i {
    display: block;
    height: 100%;
    width: var(--egl-slx-w, 0%);
    border-radius: 999px;
    background: var(--egl-warn);
    opacity: .75;
    animation: egl-slx-grow .7s cubic-bezier(.22, .61, .36, 1) both;
}

.egl-slx-share-n {
    color: var(--egl-text-2);
    font-size: .75rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    min-width: 3rem;
    text-align: right;
}

.egl-slx-legend {
    display: flex;
    align-items: center;
    gap: .625rem;
    flex: 1 1 20rem;
    max-width: 26rem;
}

.egl-slx-legend .egl-slx-legend-bar {
    flex: 0 0 5rem;
}

.egl-slx-legend .egl-slx-hint {
    margin-top: 0;
}

/* The dropdown is what the page is for, so it sits on one line with its
   label rather than taking a third of the card. */
.egl-slx-short-pick {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    border-top: 1px dashed var(--egl-border);
    padding-top: .5rem;
    margin-top: .125rem;
}

.egl-slx-pick-label {
    margin-bottom: 0;
    flex: 0 0 auto;
}

.egl-slx-short-pick > select,
.egl-slx-short-pick > .egl-slx-p {
    flex: 1 1 10rem;
    min-width: 0;
}

@media (prefers-reduced-motion: reduce) {
    .egl-slx-share-fill,
    .egl-slx-legend-bar > i {
        animation: none;
        width: var(--egl-slx-w, 0%);
    }
}

/* ------------------------------------------------------------------
   Phase 26I - naming the two percentages.

   The row read "17.1% vs 65.0%" with nothing to say which was the one
   achieved and which the one costed. The rows are a table, so the
   columns are named once at the top of the card instead of on all 192
   rows - and below 900px, where the columns stop lining up, each row
   carries the words itself.
   ------------------------------------------------------------------ */
.egl-slx-colhead {
    display: none;
}

@media (min-width: 900px) {
    .egl-slx-colhead {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 7.5rem 9.75rem 3.75rem;
        gap: .875rem;
        align-items: baseline;
        margin-top: .875rem;
        padding: 0 .5rem .375rem;
        border-bottom: 1px solid var(--egl-border);
    }

    .egl-slx-colhead > span {
        color: var(--egl-text-muted);
        font-size: .625rem;
        font-weight: 700;
        letter-spacing: .06em;
        text-transform: uppercase;
        text-align: right;
    }

    .egl-slx-colhead > span:first-child {
        text-align: left;
    }
}

/* The words a row needs only when the header above it is not there. */
.egl-slx-onlysmall {
    order: -1;
}

@media (min-width: 900px) {
    .egl-slx-onlysmall {
        display: none;
    }
}

/* ------------------------------------------------------------------
   PHASE 29 - the process box on the Skill Update sheet.

   Aomith, 26 Sep: "IE ra process er box a process olpo aktu likhle e
   jeno oi related process gula niche suggestion a chole ase".

   With 549 processes the Single Needle list runs to 380 names. A plain
   dropdown that long is unusable on the floor, so the box is typed
   into and the machine's own processes come up underneath it.

   Light, like the rest: white card, soft border, the highlighted line
   in the same blue the sheet already uses. No animation - the list has
   to keep up with a man typing, not perform for him.
   ------------------------------------------------------------------ */

.egl-sm-combo {
    position: relative;
}

.egl-sm-combo-clear {
    position: absolute;
    top: 0;
    right: 0;
    height: 2.5rem;
    width: 2rem;
    line-height: 1;
    font-size: 1.15rem;
    color: var(--egl-text-muted);
    background: transparent;
    border: 0;
    cursor: pointer;
    border-radius: 0 .5rem .5rem 0;
}

.egl-sm-combo-clear:hover {
    color: var(--egl-danger);
}

.egl-sm-combo-list {
    position: absolute;
    z-index: 40;
    left: 0;
    right: 0;
    top: calc(100% + .25rem);
    margin: 0;
    padding: .25rem;
    list-style: none;
    max-height: 17rem;
    overflow-y: auto;
    background: var(--egl-surface);
    border: 1px solid var(--egl-border);
    border-radius: .6rem;
    box-shadow: 0 10px 24px -12px rgba(15, 23, 42, 0.28);
}

.egl-sm-combo-item {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: .5rem;
    padding: .4rem .55rem;
    border-radius: .4rem;
    font-size: .875rem;
    color: var(--egl-text);
    cursor: pointer;
}

.egl-sm-combo-item.is-on {
    background: rgba(37, 99, 235, 0.10);
    color: var(--egl-primary);
}

.egl-sm-combo-item small {
    font-size: .7rem;
    font-variant-numeric: tabular-nums;
    color: var(--egl-text-muted);
}

.egl-sm-combo-empty,
.egl-sm-combo-more {
    padding: .45rem .55rem;
    font-size: .75rem;
    color: var(--egl-text-muted);
}

.egl-sm-combo-more {
    border-top: 1px solid var(--egl-border);
    margin-top: .2rem;
}

/* ------------------------------------------------------------------
   PHASE 31 - the grade box answers back.

   Aomith, 26 Sep: "jodi kew vhul koreo bosai jemon designation Operator
   but grade 1 bosaice tahole jeno akta notes dekhai".

   Senior Operator is grade 1, Operator 2, Junior Operator 3 - that is
   the rule in every factory in the country, not a preference. The box
   stays open, but the moment it disagrees with the designation this
   line appears under it, and the save turns it back with the same
   words.
   ------------------------------------------------------------------ */

.egl-sm-graderule {
    margin-top: .35rem;
    padding: .35rem .55rem;
    border-radius: .4rem;
    font-size: .75rem;
    line-height: 1.35;
    color: var(--egl-danger);
    background: rgba(220, 38, 38, 0.08);
    border: 1px solid rgba(220, 38, 38, 0.25);
}

.egl-sm-graderule[hidden] {
    display: none;
}

/* ─── Phase 34B-1 · Add OB ────────────────────────────────────────────────
   Light and quiet, the way Aomith asked new modules to look.

   TWO RULES THIS BLOCK KEEPS, AND WHY. Nothing here forces a value with the
   override marker, because a test counts those and the count must stay at two.
   And the two-column split is a grid, not a flex stack, because another test
   reads the last stacking rule in this file and needs it to be the dashboard
   gauge's own. Writing either phrase even in a comment breaks those tests -
   which is exactly what happened the first time this block was written. */
.egl-sm-ob-split {
    display: grid;
    grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
    gap: 1.25rem;
    align-items: start;
}
@media (max-width: 900px) {
    .egl-sm-ob-split {
        grid-template-columns: minmax(0, 1fr);
    }
}
.egl-sm-ob-h {
    font-size: 0.95rem;
    font-weight: 600;
    color: #e2e8f0;
    margin-bottom: 0.5rem;
}
.egl-sm-ob-p {
    font-size: 0.85rem;
    line-height: 1.55;
    color: #b6c2d2;
}
.egl-sm-ob-hint {
    font-size: 0.76rem;
    line-height: 1.5;
    color: #8b97a8;
}
.egl-sm-ob-label {
    display: block;
    font-size: 0.8rem;
    font-weight: 500;
    color: #c4cedb;
    margin-bottom: 0.25rem;
}
.egl-sm-ob-note {
    border-radius: 0.55rem;
    padding: 0.7rem 0.9rem;
    font-size: 0.82rem;
    line-height: 1.55;
    border: 1px solid rgba(148, 163, 184, 0.28);
    background: rgba(148, 163, 184, 0.09);
    color: #c9d4e2;
}
.egl-sm-ob-note--wait {
    border-color: rgba(234, 179, 8, 0.4);
    background: rgba(234, 179, 8, 0.09);
    color: #f2dfa4;
}
.egl-sm-ob-note--bad {
    border-color: rgba(248, 113, 113, 0.42);
    background: rgba(248, 113, 113, 0.09);
    color: #f6bdbd;
}
.egl-sm-ob-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
    gap: 0.6rem;
    margin-top: 0.9rem;
}
.egl-sm-ob-tile {
    border-radius: 0.55rem;
    border: 1px solid rgba(148, 163, 184, 0.24);
    background: rgba(148, 163, 184, 0.07);
    padding: 0.6rem 0.7rem;
}
.egl-sm-ob-tile--good {
    border-color: rgba(52, 211, 153, 0.36);
    background: rgba(52, 211, 153, 0.08);
}
.egl-sm-ob-tile--wait {
    border-color: rgba(234, 179, 8, 0.38);
    background: rgba(234, 179, 8, 0.08);
}
.egl-sm-ob-tile-n {
    display: block;
    font-size: 1.35rem;
    font-weight: 600;
    line-height: 1.1;
    color: #eef3f9;
}
.egl-sm-ob-tile-l {
    display: block;
    font-size: 0.72rem;
    color: #93a0b1;
    margin-top: 0.15rem;
}
.egl-sm-ob-head {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
    gap: 0.6rem 1rem;
    margin-top: 0.4rem;
}
.egl-sm-ob-head dt {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #8b97a8;
}
.egl-sm-ob-head dd {
    font-size: 0.85rem;
    color: #dce4ee;
    margin: 0.1rem 0 0;
    word-break: break-word;
}
.egl-sm-ob-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.82rem;
}
.egl-sm-ob-table th {
    text-align: left;
    font-size: 0.71rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #8b97a8;
    font-weight: 600;
    padding: 0.4rem 0.5rem;
    border-bottom: 1px solid rgba(148, 163, 184, 0.28);
}
.egl-sm-ob-table td {
    padding: 0.4rem 0.5rem;
    color: #d3dce8;
    border-bottom: 1px solid rgba(148, 163, 184, 0.14);
    vertical-align: top;
}
.egl-sm-ob-table--lines td {
    font-size: 0.78rem;
}
.egl-sm-ob-num {
    text-align: right;
    white-space: nowrap;
}
.egl-sm-ob-strong {
    font-weight: 600;
    color: #eef3f9;
}
.egl-sm-ob-weak {
    color: #8b97a8;
}
.egl-sm-ob-wait {
    color: #e3c765;
}
.egl-sm-ob-mc {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.74rem;
    color: #a9b6c7;
    white-space: nowrap;
}
.egl-sm-ob-row--pending td,
.egl-sm-ob-row--unknown td {
    background: rgba(234, 179, 8, 0.06);
}
.egl-sm-ob-row--not_ours td {
    color: #8b97a8;
}

/* Phase 38 - the HR question under the grade box. Quiet until it matters. */
.egl-sm-hr {
    margin-top: 0.5rem;
    border-radius: 0.5rem;
    border: 1px solid rgba(234, 179, 8, 0.4);
    background: rgba(234, 179, 8, 0.09);
    padding: 0.55rem 0.7rem;
}
.egl-sm-hr-line {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: #f2dfa4;
    cursor: pointer;
}
.egl-sm-hr-note {
    font-size: 0.75rem;
    line-height: 1.5;
    color: #b9c4d2;
    margin-top: 0.3rem;
}

/* ── Add OB, the scanning moment ──────────────────────────────────────────
   Aomith, 28 Sep: "OB Upload dile OB je scan hocce sekhane akta Animation
   add korba Scanning er, dekhte sundor lagbe".

   Reading a bulletin takes a few seconds - the file is opened, the right tab
   and heading row are found, then every operation is put against the master.
   Until now the page only greyed the button, so those seconds looked like
   nothing happening. This draws what is actually happening: a page of
   operation lines with a light passing down it.

   THE SAME TWO RULES AS THE BLOCK ABOVE. No value is forced here, because a
   test counts those and the count must stay at two. And nothing here stacks a
   flex box downward, because another test reads the last such rule in this
   file and needs it to be the dashboard gauge's own.

   A man who has asked his system not to animate gets the still picture and
   the words, which say the same thing. */
.egl-sm-scan {
    display: grid;
    gap: 0.9rem;
    justify-items: center;
    padding: 0.4rem 0 0.2rem;
}
.egl-sm-scan-sheet {
    position: relative;
    width: 100%;
    max-width: 17rem;
    border-radius: 0.6rem;
    border: 1px solid rgba(148, 163, 184, 0.3);
    background: rgba(148, 163, 184, 0.07);
    padding: 0.75rem 0.8rem;
    overflow: hidden;
}
/* The operation lines. Uneven on purpose - a bulletin is not a block. */
.egl-sm-scan-row {
    height: 0.4rem;
    border-radius: 0.2rem;
    background: rgba(148, 163, 184, 0.26);
    margin-bottom: 0.42rem;
}
.egl-sm-scan-row:last-child {
    margin-bottom: 0;
}
.egl-sm-scan-row:nth-child(3n) {
    width: 62%;
}
.egl-sm-scan-row:nth-child(3n + 1) {
    width: 88%;
}
.egl-sm-scan-row:nth-child(3n + 2) {
    width: 74%;
}
/* The light. It is the whole idea, so it is the only thing that moves. */
.egl-sm-scan-beam {
    position: absolute;
    left: 0;
    right: 0;
    height: 2.4rem;
    top: -2.4rem;
    background: linear-gradient(
        to bottom,
        rgba(56, 189, 248, 0) 0%,
        rgba(56, 189, 248, 0.16) 45%,
        rgba(125, 211, 252, 0.62) 82%,
        rgba(125, 211, 252, 0.9) 100%
    );
    border-bottom: 1px solid rgba(186, 230, 253, 0.85);
    animation: egl-sm-scan-sweep 1.9s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}
@keyframes egl-sm-scan-sweep {
    0% {
        top: -2.4rem;
        opacity: 0;
    }
    12% {
        opacity: 1;
    }
    88% {
        opacity: 1;
    }
    100% {
        top: 100%;
        opacity: 0;
    }
}
.egl-sm-scan-say {
    font-size: 0.84rem;
    font-weight: 600;
    color: #cfe3f2;
    text-align: center;
}
.egl-sm-scan-steps {
    display: grid;
    gap: 0.3rem;
    justify-items: center;
    font-size: 0.75rem;
    line-height: 1.5;
    color: #8b97a8;
}
/* Each line brightens in turn, in the order the reader really works. */
.egl-sm-scan-step {
    animation: egl-sm-scan-say 5.7s linear infinite;
}
.egl-sm-scan-step:nth-child(2) {
    animation-delay: 1.9s;
}
.egl-sm-scan-step:nth-child(3) {
    animation-delay: 3.8s;
}
@keyframes egl-sm-scan-say {
    0%,
    33%,
    100% {
        color: #8b97a8;
    }
    6%,
    27% {
        color: #dbe8f4;
    }
}
@media (prefers-reduced-motion: reduce) {
    .egl-sm-scan-beam,
    .egl-sm-scan-step {
        animation: none;
    }
    .egl-sm-scan-beam {
        top: 45%;
    }
}

/* ── Add OB, 34B-2: the page writes now ───────────────────────────────────
   A good-news note, and the box where one wording is settled for good.

   THE SAME TWO RULES AS THE BLOCKS ABOVE. No value is forced here, because a
   test counts those and the count must stay at two. And nothing here stacks a
   flex box downward, because another test reads the last such rule in this
   file and needs it to be the dashboard gauge's own. */
.egl-sm-ob-note--good {
    border-color: rgba(34, 197, 94, 0.42);
    background: rgba(34, 197, 94, 0.1);
    color: #d3f0dc;
}
.egl-sm-ob-fix {
    display: grid;
    gap: 0.55rem;
    border-top: 1px solid rgba(148, 163, 184, 0.22);
    padding-top: 0.7rem;
    margin-top: 0.7rem;
}
.egl-sm-ob-fix:first-of-type {
    border-top: 0;
    padding-top: 0;
    margin-top: 0;
}
.egl-sm-ob-fix-said {
    font-size: 0.85rem;
    line-height: 1.5;
    color: #dbe5f0;
}
.egl-sm-ob-fix-said b {
    font-weight: 600;
    color: #ffffff;
}
.egl-sm-ob-fix-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    gap: 0.5rem;
    align-items: center;
}
@media (max-width: 720px) {
    .egl-sm-ob-fix-row {
        grid-template-columns: minmax(0, 1fr);
    }
}
.egl-sm-ob-fix-not {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.78rem;
    color: #a7b3c2;
    white-space: nowrap;
}
.egl-sm-ob-save {
    display: grid;
    gap: 0.6rem;
    border-radius: 0.6rem;
    border: 1px solid rgba(56, 189, 248, 0.32);
    background: rgba(56, 189, 248, 0.08);
    padding: 0.85rem 0.95rem;
}

/* ── Process list, Phase 41: Remove, and the warning above it ─────────────
   Aomith asked for the note in his own words and said why: "tahole ami chara
   onno admin o bujhbe". Remove is the one control on that page that reaches
   outside it, so it is the one that has to announce itself.

   THE SAME TWO RULES AS THE BLOCKS ABOVE. No value is forced here, because a
   test counts those and the count must stay at two. And nothing here stacks a
   flex box downward, because another test reads the last such rule in this
   file and needs it to be the dashboard gauge's own. */
.egl-sm-proc-warn {
    border-radius: 0.5rem;
    border: 1px solid rgba(248, 113, 113, 0.55);
    background: rgba(248, 113, 113, 0.12);
    padding: 0.6rem 0.8rem;
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.5;
    color: #fecaca;
}
.egl-sm-proc-remove {
    border-radius: 0.4rem;
    border: 1px solid rgba(248, 113, 113, 0.5);
    background: rgba(248, 113, 113, 0.1);
    padding: 0.28rem 0.7rem;
    font-size: 0.78rem;
    font-weight: 600;
    color: #fca5a5;
    cursor: pointer;
}
.egl-sm-proc-remove:hover {
    background: rgba(248, 113, 113, 0.2);
    color: #fee2e2;
}
.egl-sm-proc-remove:disabled {
    opacity: 0.55;
    cursor: default;
}
.egl-sm-proc-ask {
    display: grid;
    gap: 0.4rem;
    margin-top: 0.5rem;
    min-width: 19rem;
    max-width: 27rem;
    border-radius: 0.55rem;
    border: 1px solid rgba(248, 113, 113, 0.42);
    background: rgba(127, 29, 29, 0.22);
    padding: 0.7rem 0.85rem;
    white-space: normal;
}
.egl-sm-proc-ask-h {
    font-size: 0.85rem;
    font-weight: 600;
    color: #fee2e2;
}
.egl-sm-proc-ask-p {
    font-size: 0.8rem;
    line-height: 1.5;
    color: #e6d3d3;
}
.egl-sm-proc-ask-p--warn {
    font-weight: 600;
    color: #fca5a5;
}
.egl-sm-proc-moves {
    display: grid;
    gap: 0.15rem;
    font-size: 0.76rem;
    line-height: 1.45;
    color: #dcc9c9;
    max-height: 9rem;
    overflow-y: auto;
}
.egl-sm-proc-moves b {
    font-weight: 600;
    color: #fecaca;
}

/* ── Skill Matrix, light mood: Add OB, the scan, and the Process list ─────
   Aomith, on his own screen: "lekha gula onk faded, valo dekhacce na, lekha
   gula jeno light mood a properly sundor dekhai".

   HE WAS RIGHT, AND THE CAUSE IS MINE. The Skill Matrix's own colours were
   written in hex, for the dark appearance - #e2e8f0 text, #8b97a8 hints,
   rgba(127,29,29,.22) panels. Light grey on white is not a colour scheme, it
   is unreadable. The rest of this page was fine because it asks for
   var(--egl-text) and var(--egl-surface), which turn over with the theme.

   SO THIS BLOCK ASKS FOR MEANINGS, NOT SHADES. Every rule below points at a
   token - text, muted, ok, warn, danger - so a future theme pass moves them
   together and nothing is left behind again. Only the families I wrote in hex
   need it: the OB page, the scanning panel and the Process list's Remove.

   THE SAME TWO RULES AS EVERY BLOCK ABOVE. No value is forced here, because a
   test counts those and the count must stay at two. And nothing here stacks a
   flex box downward, because another test reads the last such rule in this
   file and needs it to be the dashboard gauge's own. */

/* ---- Add OB: the page's own words ---- */
html[data-theme='light'] .egl-sm-ob-h,
html[data-theme='light'] .egl-sm-ob-strong,
html[data-theme='light'] .egl-sm-ob-tile-n {
    color: var(--egl-text);
}
html[data-theme='light'] .egl-sm-ob-p,
html[data-theme='light'] .egl-sm-ob-label {
    color: var(--egl-text-2);
}
html[data-theme='light'] .egl-sm-ob-hint,
html[data-theme='light'] .egl-sm-ob-tile-l,
html[data-theme='light'] .egl-sm-ob-weak,
html[data-theme='light'] .egl-sm-ob-mc {
    color: var(--egl-text-muted);
}
html[data-theme='light'] .egl-sm-ob-wait {
    color: var(--egl-warn);
}
html[data-theme='light'] .egl-sm-ob-note {
    border-color: var(--egl-border-strong);
    background: var(--egl-surface-3);
    color: var(--egl-text-2);
}
html[data-theme='light'] .egl-sm-ob-note--good {
    border-color: var(--egl-ok-border);
    background: var(--egl-ok-soft);
    color: #065f46;
}
html[data-theme='light'] .egl-sm-ob-note--wait {
    border-color: var(--egl-warn-border);
    background: var(--egl-warn-soft);
    color: #92400e;
}
html[data-theme='light'] .egl-sm-ob-note--bad {
    border-color: var(--egl-danger-border);
    background: var(--egl-danger-soft);
    color: #991b1b;
}
html[data-theme='light'] .egl-sm-ob-tile {
    border-color: var(--egl-border);
    background: var(--egl-surface-2);
}
html[data-theme='light'] .egl-sm-ob-tile--good {
    border-color: var(--egl-ok-border);
    background: var(--egl-ok-soft);
}
html[data-theme='light'] .egl-sm-ob-tile--wait {
    border-color: var(--egl-warn-border);
    background: var(--egl-warn-soft);
}
html[data-theme='light'] .egl-sm-ob-fix {
    border-top-color: var(--egl-border);
}
html[data-theme='light'] .egl-sm-ob-fix-said {
    color: var(--egl-text-2);
}
html[data-theme='light'] .egl-sm-ob-fix-said b {
    color: var(--egl-text);
}
html[data-theme='light'] .egl-sm-ob-fix-not {
    color: var(--egl-text-muted);
}
html[data-theme='light'] .egl-sm-ob-save {
    border-color: var(--egl-primary-border);
    background: var(--egl-primary-soft);
}

/* ---- the scanning moment ---- */
html[data-theme='light'] .egl-sm-scan-sheet {
    border-color: var(--egl-border-strong);
    background: var(--egl-surface-2);
}
html[data-theme='light'] .egl-sm-scan-row {
    background: #cbd5e1;
}
html[data-theme='light'] .egl-sm-scan-beam {
    background: linear-gradient(
        to bottom,
        rgba(37, 99, 235, 0) 0%,
        rgba(37, 99, 235, 0.1) 45%,
        rgba(37, 99, 235, 0.3) 82%,
        rgba(37, 99, 235, 0.42) 100%
    );
    border-bottom-color: rgba(37, 99, 235, 0.75);
}
html[data-theme='light'] .egl-sm-scan-say {
    color: var(--egl-text);
}
html[data-theme='light'] .egl-sm-scan-steps {
    color: var(--egl-text-muted);
}
/* The step that is lit reads dark, the waiting ones read muted - the other
   way round from the dark appearance, because here dark IS the emphasis. */
@keyframes egl-sm-scan-say-light {
    0%,
    33%,
    100% {
        color: #94a3b8;
    }
    6%,
    27% {
        color: #0f172a;
    }
}
html[data-theme='light'] .egl-sm-scan-step {
    animation-name: egl-sm-scan-say-light;
}

/* ---- Process list: the warning, Remove, and what it would cost ---- */
html[data-theme='light'] .egl-sm-proc-warn {
    border-color: var(--egl-danger);
    background: var(--egl-danger-soft);
    color: #991b1b;
}
html[data-theme='light'] .egl-sm-proc-remove {
    border-color: var(--egl-danger-border);
    background: var(--egl-danger-soft);
    color: #b91c1c;
}
html[data-theme='light'] .egl-sm-proc-remove:hover {
    background: var(--egl-danger);
    border-color: var(--egl-danger);
    color: #ffffff;
}
html[data-theme='light'] .egl-sm-proc-ask {
    border-color: var(--egl-danger);
    background: #ffffff;
    box-shadow: 0 10px 28px rgba(15, 23, 42, 0.16);
}
html[data-theme='light'] .egl-sm-proc-ask-h {
    color: #991b1b;
}
html[data-theme='light'] .egl-sm-proc-ask-p {
    color: var(--egl-text-2);
}
html[data-theme='light'] .egl-sm-proc-ask-p--warn {
    color: #b91c1c;
}
html[data-theme='light'] .egl-sm-proc-moves {
    color: var(--egl-text-2);
}
html[data-theme='light'] .egl-sm-proc-moves b {
    color: #b91c1c;
}

/* ==========================================================================
   Phase 60 — Monthly Planned Item Details.
   --------------------------------------------------------------------------
   Written as real CSS rather than Tailwind utilities for the reason every
   module since 13B has been: the compiled bundle is FROZEN (17 August) and is
   never rebuilt, so a class that is not already in it does nothing at all.
   Everything here is new and the `egl-mpi-` family appears nowhere in that
   bundle, which is what makes it safe to style unscoped.

   COLOURS COME FROM MEANING TOKENS, never from a hex typed here, so the page
   is right in BOTH appearances. Aomith checks the light one on his own screen
   and has sent the screenshot back more than once when a module forgot.
   ========================================================================== */

/* ==========================================================================
   PHASE 77 — A DROP-DOWN THAT STOPS WRITING UNDER ITS OWN ARROW.
   --------------------------------------------------------------------------
   Aomith, 2 October: "dropdown a maintenance lekha ta card er bahire chole
   jai and arrow ta lekhar upore cole ase".

   MEASURED, NOT GUESSED, and the cause is one line. The frozen bundle styles
   every <select> itself:

       select { background-image: url(<chevron>);
                background-position: right .5rem center;
                background-size: 1.5em 1.5em;
                padding-right: 2.5rem }

   It draws the arrow AND leaves 2.5rem of room for it. But `select` is an
   element selector (0,0,1) and `.egl-input` is a class (0,1,0), and
   .egl-input says `padding: .5rem .75rem`. The shorthand wins and wipes the
   2.5rem down to 12px - so the arrow is still drawn in the same place, with
   the text now running underneath it. Rendered and measured: the box came
   out 112px, leaving 86px of content for a word that needs about 80, with
   the chevron sitting over the last of it.

   SO THIS RESTORES WHAT THE BUNDLE ALREADY INTENDED rather than inventing a
   new look. Same 2.5rem, same arrow, nothing repainted.

   WHY A NEW CLASS AND NOT A FIX TO .egl-input. .egl-input IS in the frozen
   bundle, and ThemeOverlayWiringTest refuses an unscoped rule on anything the
   bundle already ships - correctly, because such a rule can repaint frozen UI
   everywhere at once. egl-form- is the family that exists for exactly this:
   controls that appear on more than one page. "egl-form-" appears nowhere in
   the compiled bundle, and this is layout, not colour, so it is right in both
   appearances with no theme scope.

   It beats .egl-input by order, not by weight - both are one class, and
   egl-theme.css is served after the bundle. That is the same mechanism every
   other rule in this file relies on.

   THIS IS THE THIRD TIME this collision has been hit (Phase 18A-1b on Store
   Parts, 20E-2 on the dashboard filters, now here), and the first two each
   solved it for one box. Put this class on any select.egl-input that sits in
   a narrow cell and it is solved for good. */
.egl-form-select {
    padding-right: 2.5rem;
    /* A select is a flex/grid item often enough that this matters: without
       it the box refuses to shrink below its longest option and pushes its
       way out of the cell, which is the other half of what he saw. */
    min-width: 0;
    /* And when it genuinely cannot fit, it ends in an ellipsis instead of
       disappearing under the chevron. */
    text-overflow: ellipsis;
}

/* --------------------------------------------------------------- PHASE 76
   THE BLOCK CARD, AND THE LINES INSIDE IT.

   Aomith, 2 October: "Line gula block wise card a thakbe serial wise, jei
   Block er jei line seta sei block er card a thakbe".

   Three depths, and they have to read as three at a glance or the page is
   just a longer list: the BLOCK is a card with a border, a LINE is a labelled
   band inside it, and a STYLE is the card that already existed. The only
   thing carrying that hierarchy is surface tone and one accent rule down the
   left of each line - no shadows, no second border - because the page is
   mostly text and a boxed box inside a box turns it into a grid of cages.

   Every colour is a token, so this is right in LIGHT as well as dark. The
   block card deliberately uses --egl-surface (not surface-2): the style cards
   inside it are surface-2, so the card sits BEHIND them in both appearances
   rather than inverting when the theme flips.

   AND THE RAIL IS --egl-primary-border, NOT --egl-accent. I reached for
   --egl-accent first, exactly as I did once before at .egl-dash-menubtn - it
   is defined nowhere in this file, so the rail would have resolved to
   nothing, drawn no line at all, and not one thing would have complained.
   The only tokens that exist are the ones declared at the top. */
.egl-mpi-block {
    margin-bottom: 1rem;
    padding: .75rem;
    border: 1px solid var(--egl-border);
    border-radius: .875rem;
    background: var(--egl-surface);
}
.egl-mpi-blockhead {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: .625rem;
    padding-bottom: .5rem;
    border-bottom: 1px solid var(--egl-border);
}
.egl-mpi-blockname {
    margin: 0;
    color: var(--egl-text);
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: .01em;
}
.egl-mpi-blockcount {
    flex: none;
    color: var(--egl-text-3);
    font-size: .75rem;
}
.egl-mpi-line {
    /* The accent rail. It is what makes a line read as a line and not as a
       paragraph break, and it costs no vertical room - which matters on a
       page that can hold sixty of these. */
    padding-left: .625rem;
    border-left: 3px solid var(--egl-primary-border);
    margin-bottom: .75rem;
}
.egl-mpi-line:last-child {
    margin-bottom: 0;
}
.egl-mpi-linehead {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    margin-bottom: .375rem;
}
.egl-mpi-linename {
    color: var(--egl-text);
    font-size: .8125rem;
    font-weight: 700;
}
.egl-mpi-linecount {
    color: var(--egl-text-3);
    font-size: .6875rem;
}

/* A style standing under one line still shows every line it runs on. THIS is
   the chip for the line being listed, so a style appearing twice never reads
   as two different orders. */
.egl-mpi-chip--here {
    border-color: var(--egl-primary-border);
    background: var(--egl-primary-soft);
}

.egl-mpi-card {
    display: grid;
    grid-template-columns: 116px minmax(0, 1fr) auto;
    gap: 1rem;
    align-items: start;
    padding: .875rem;
    margin-bottom: .75rem;
    border: 1px solid var(--egl-border);
    border-radius: .75rem;
    background: var(--egl-surface-2);
}

/* The sample. A fixed box rather than a shrink-to-fit one, so forty cards
   down a page keep one left edge instead of stepping in and out. */
.egl-mpi-sample {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 116px;
    height: 116px;
    overflow: hidden;
    border: 1px dashed var(--egl-border-strong);
    border-radius: .625rem;
    background: var(--egl-surface-3);
}
.egl-mpi-sample img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.egl-mpi-sample--big {
    width: 100%;
    height: 320px;
}
.egl-mpi-sample--big img {
    object-fit: contain;
}
.egl-mpi-nosample {
    padding: .5rem;
    font-size: .7rem;
    line-height: 1.2;
    text-align: center;
    color: var(--egl-text-3);
}

.egl-mpi-body {
    min-width: 0;
}
.egl-mpi-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
}
.egl-mpi-style {
    font-size: 1.0625rem;
    font-weight: 700;
    color: var(--egl-text);
    overflow-wrap: anywhere;
}
.egl-mpi-sub {
    font-size: .8125rem;
    color: var(--egl-text-2);
}
.egl-mpi-when {
    font-size: .8125rem;
    font-weight: 600;
    color: var(--egl-text-2);
    white-space: nowrap;
}

.egl-mpi-facts {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem;
    margin-top: .5rem;
}
.egl-mpi-chip {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .125rem .45rem;
    border: 1px solid var(--egl-border);
    border-radius: .375rem;
    background: var(--egl-surface);
    font-size: .7rem;
    color: var(--egl-text-2);
}
.egl-mpi-chip b {
    color: var(--egl-text);
}
.egl-mpi-chip small {
    padding: 0 .25rem;
    border-radius: .25rem;
    background: var(--egl-warn-soft);
    color: var(--egl-warn);
    font-size: .625rem;
}

/* The three departments. One tone each, and the same three tones on the
   month page and on the style page, so a colour means one thing everywhere. */
.egl-mpi-prep {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
    margin-top: .625rem;
}
.egl-mpi-dept {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .15rem .5rem;
    border-radius: .375rem;
    border: 1px solid transparent;
    font-size: .7rem;
    font-weight: 600;
    white-space: nowrap;
}
.egl-mpi-dept b {
    font-weight: 700;
}
.egl-mpi-dept--maintenance {
    background: var(--egl-warn-soft);
    border-color: var(--egl-warn-border);
    color: var(--egl-warn);
}
.egl-mpi-dept--technical {
    background: var(--egl-surface-3);
    border-color: var(--egl-border-strong);
    color: var(--egl-nav-violet);
}
.egl-mpi-dept--ie {
    background: var(--egl-surface-3);
    border-color: var(--egl-border-strong);
    color: var(--egl-nav-sky);
}
/* Every note ticked. Said in colour as well as in the count, because the
   count is what somebody scans and the colour is what they see. */
.egl-mpi-dept--done {
    background: var(--egl-ok-soft);
    border-color: var(--egl-ok-border);
    color: var(--egl-ok);
}
/* Nothing written for this department at all - deliberately quiet, so the
   ones that DO have notes are the ones the eye lands on. */
.egl-mpi-dept--empty {
    background: transparent;
    border-color: var(--egl-border);
    color: var(--egl-text-3);
}

/* Laid out with grid rather than a flex column, and the reason is a guard
   test rather than taste: DashboardGaugeTest pins the LAST flex column
   direction in this file to the dashboard gauge's phone block, because that
   block only wins the cascade by coming last. One declared after it here
   would quietly take that position, and the gauge's legend would be squeezed
   to nothing on a phone again - which is the bug phase 10K fixed. */
.egl-mpi-go {
    display: grid;
    justify-items: end;
    align-content: start;
    gap: .5rem;
}

/* The style page: the sample beside what the plan says. */
.egl-mpi-split {
    display: grid;
    grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

/* Ticking a note off. A whole-row button rather than a checkbox, because
   this is pressed on a phone on a floor with a thumb. */
/* Grid here too, and for the same reason as .egl-mpi-go above. */
.egl-mpi-ticks {
    display: grid;
    gap: .375rem;
}
.egl-mpi-tick {
    display: flex;
    align-items: center;
    gap: .625rem;
    width: 100%;
    padding: .5rem .625rem;
    border: 1px solid var(--egl-border);
    border-radius: .5rem;
    background: var(--egl-surface);
    text-align: left;
    cursor: pointer;
}
.egl-mpi-tick:hover {
    border-color: var(--egl-border-strong);
}
.egl-mpi-tick-text {
    flex: 1 1 auto;
    min-width: 0;
    font-size: .8125rem;
    color: var(--egl-text);
    overflow-wrap: anywhere;
}
.egl-mpi-tick-state {
    flex: 0 0 auto;
    font-size: .7rem;
    font-weight: 600;
    color: var(--egl-text-3);
    white-space: nowrap;
}
.egl-mpi-tick--on {
    background: var(--egl-ok-soft);
    border-color: var(--egl-ok-border);
}
.egl-mpi-tick--on .egl-mpi-tick-text {
    color: var(--egl-text-2);
    text-decoration: line-through;
}
.egl-mpi-tick--on .egl-mpi-tick-state {
    color: var(--egl-ok);
}

/* A phone. The sample drops above the facts rather than squeezing the text
   into a column two words wide. */
@media (max-width: 767px) {
    .egl-mpi-card {
        grid-template-columns: 84px minmax(0, 1fr);
    }
    .egl-mpi-sample {
        width: 84px;
        height: 84px;
    }
    .egl-mpi-go {
        grid-column: 1 / -1;
        grid-auto-flow: column;
        justify-content: flex-end;
        align-items: center;
    }
    .egl-mpi-split {
        grid-template-columns: minmax(0, 1fr);
    }
    .egl-mpi-sample--big {
        height: 240px;
    }
}

/* --------------------------------------------------------------------------
   Phase 61 — the note about weeks that are not the plain Saturday-to-Thursday
   ones.

   Phase 55 drew this in the danger tone, because a month fixed under the old
   month-cut rule really did carry broken weeks. Phase 61 let the Admin type
   whatever the month runs on, so an eight-day week with a worked Friday in it
   is a decision rather than a fault — and a red box around a decision teaches
   people to ignore red boxes. A quiet card says the same thing without the
   accusation.
   -------------------------------------------------------------------------- */
.egl-mreq-oddweeks {
    padding: .75rem .875rem;
    border: 1px solid var(--egl-border);
    border-left: 3px solid var(--egl-nav-sky);
    border-radius: .5rem;
    background: var(--egl-surface-3);
    color: var(--egl-text-2);
    font-size: .8125rem;
}
.egl-mreq-oddweeks b {
    color: var(--egl-text);
}

/* ---------------------------------------------------------------------------
   PHASE 62 - A BUFFER LEFT ON A WEEK THAT NO LONGER EXISTS.

   The same quiet card as above, in the amber accent rather than the sky one,
   and for a reason worth keeping: this block is not describing a decision, it
   is describing a row nobody can reach any more. That deserves attention
   without an accusation — the row is still in force and still doing its job,
   it simply has no page that can open it. Amber says "look at this"; red would
   say "something is broken", and nothing is.

   One row per stray, laid out so the machine type and the period it is parked
   on read as a pair, with the Remove button on its own at the end.
   -------------------------------------------------------------------------- */
.egl-mreq-oddweeks--watch {
    border-left-color: var(--egl-nav-amber);
}
.egl-mreq-stray {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: .5rem .875rem;
    padding: .5rem 0;
    border-top: 1px solid var(--egl-border);
}
.egl-mreq-stray:first-of-type {
    border-top: 0;
    margin-top: .375rem;
}
.egl-mreq-stray-what {
    min-width: 0;
}
.egl-mreq-stray-who {
    display: block;
    color: var(--egl-text-3);
    font-size: .75rem;
}

/* ---------------------------------------------------------------------------
   PHASE 63-66 - THE FRONT DOOR.

   Four goes at this, and the fourth is his drawing rather than my reading of
   it. What 65 got wrong, in his words: "icon akpase ar card gula koto boro,
   ar niche oi option er name lekha, valo lagche na dekhte". The icon sat in
   one corner of a card twice the size it needed and the name was stranded
   underneath, so the eye had to cross a lot of empty colour between the
   picture and the words.

   66 is one ROW per page - icon left, name beside it, a small grey line under
   the name - in tiles sized to their content, wrapping across a panel per
   department. Picture and words in the same glance, and nothing stretched to
   fill a grid it did not need.

   The tones are still the sidebar's own, one line per entry at the bottom of
   this block, so a page is the same colour here as it is in the left-hand
   list. That is the only reason to colour them at all.
   -------------------------------------------------------------------------- */

/* ------------------------------------------------- the welcome band
   PHASE 73 - the band becomes the one piece of the app that is allowed to
   look like something. Three things Aomith asked for on 1 October, and the
   reasoning for each:

   HIS OWN PHOTO ACROSS THE MIDDLE, "dui pase faded majkhane a clear". Done
   with a mask rather than a gradient laid over the top, because a gradient
   would have to know the card's colour and would be wrong the moment the
   theme changed. A mask fades the picture itself to nothing, so whatever is
   behind it shows through - in light mode and dark, with no second rule.

   A RAISED CARD, "akta 3D Shape kore daw". Not a transform: a rotated panel
   reflows badly on a phone and blurs text on half the screens on the floor.
   It is done the way a real raised edge looks - a lit top, a dark bottom, a
   close contact shadow and one soft long one. The card does not move, it
   just stops being flat.

   THE MONITOR TRACE, "Hospital a CCU er vetore monitor a oirokom". The app
   is called FloorPulse; this is the name, drawn. A faint full trace sits
   there always and a bright head sweeps along it, which is what a monitor
   actually does - the line does not redraw, a beam passes over it.

   EVERYTHING HERE STOPS when the person has asked for less motion; see the
   reduced-motion block at the end of this file's menu section. A front door
   that twitches at somebody who has said no to movement is worse than a
   plain one.
   ------------------------------------------------------------------------ */
.egl-menu-hero {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem 1.25rem;
    flex-wrap: wrap;
    min-height: 9.5rem;
    margin-bottom: 1.25rem;
    /* The deep bottom padding is the trace's lane. Nothing is laid out into
       it, so the line never crosses a word - which is what the first render
       of this band did, straight through the factory's own name. */
    padding: 1.375rem 1.5rem 2.75rem;
    border: 1px solid var(--egl-border);
    border-top-color: color-mix(in srgb, #fff 20%, var(--egl-border));
    border-radius: 1rem;
    background: var(--egl-surface-2);
    background-image: linear-gradient(120deg,
        color-mix(in srgb, var(--egl-nav-sky) 16%, transparent),
        color-mix(in srgb, var(--egl-nav-indigo) 6%, transparent) 55%,
        transparent);
    /* The raised edge: lit along the top, shaded along the bottom, one tight
       contact shadow and one long soft one in the band's own blue. */
    box-shadow:
        inset 0 1px 0 color-mix(in srgb, #fff 18%, transparent),
        inset 0 -1px 0 color-mix(in srgb, #000 20%, transparent),
        0 1px 2px color-mix(in srgb, #000 16%, transparent),
        0 16px 34px -24px color-mix(in srgb, var(--egl-nav-sky) 60%, #000);
}

/* PHASE 73a - THE BAND BREATHES, the way the login box does.

   Aomith: "login page er login box er pechoner animation er moto jolbe
   nivbe". That is .egl-login-halo - one wide radial glow that swells and
   settles on a slow cycle. Borrowed rather than reinvented, so the front
   door and the door before it move the same way, and so there is one idea to
   change if it is ever wrong.

   It sits behind everything in the card, which already clips, so it can be
   wider than the band without spilling onto the page. */
.egl-menu-hero::after {
    content: "";
    position: absolute;
    left: 18%;
    top: 50%;
    width: 46rem;
    height: 46rem;
    max-width: 120%;
    z-index: -3;
    border-radius: 50%;
    pointer-events: none;
    background: radial-gradient(circle,
        color-mix(in srgb, var(--egl-nav-sky) 26%, transparent),
        transparent 62%);
    animation: egl-menu-breathe 7s ease-in-out infinite;
}

@keyframes egl-menu-breathe {
    0%, 100% {
        transform: translate(-50%, -50%) scale(.86);
        opacity: .45;
    }
    50% {
        transform: translate(-50%, -50%) scale(1.06);
        opacity: .95;
    }
}

/* The sheen across the top third, which is what tells the eye the surface is
   curved rather than printed. Behind the content, never in front of it. */
.egl-menu-hero::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 55%;
    z-index: -1;
    background: linear-gradient(180deg,
        color-mix(in srgb, #fff 7%, transparent),
        transparent);
    pointer-events: none;
}

.egl-menu-herotext {
    position: relative;
    z-index: 1;
    /* 0 grow, so the column is exactly as wide as the words. It used to grow
       with the band and left a hand's width of empty card between the text
       and the picture - the gap Aomith ringed in red. The picture takes that
       room now. */
    flex: 0 1 auto;
    min-width: 0;
}
/* "WELCOME TO" - small, spaced and in the band's blue, above the name rather
   than in front of it. His drawing: the greeting is the quiet part and the
   portal's name is the loud one, which is the right way round for a front
   door somebody opens twenty times a day. */
.egl-menu-hero .egl-menu-herokicker {
    margin: 0 0 .125rem;
    color: var(--egl-nav-sky);
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .2em;
    text-transform: uppercase;
}
.egl-menu-heroname {
    font-size: 2.125rem;
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: -.01em;
}
/* The first word in the page's own text colour and the rest in blue. NOT a
   hard white: on this dark band --egl-text IS white, and in light appearance
   it turns dark so the name is still readable. A literal #fff would have
   looked right on his screen tonight and vanished on a light one. */
.egl-menu-heroname span {
    color: var(--egl-text);
}
.egl-menu-heroname b {
    color: var(--egl-nav-sky);
    font-weight: 800;
    /* The name itself carries the beat - a glow that swells and settles, no
       movement at all. A word that moves is a word you cannot read. */
    animation: egl-menu-beat 2.6s ease-in-out infinite;
}
.egl-menu-hero p {
    margin-top: .25rem;
    color: var(--egl-text-3);
    font-size: .8125rem;
}
.egl-menu-hero .egl-menu-herofactory {
    margin-top: .1875rem;
    color: var(--egl-text-2);
    font-size: .9375rem;
    font-weight: 600;
}

/* ----------------------------- his own picture, AS THE CARD'S BACKGROUND

   THE THING I HAD WRONG FOR THREE GOES. I read "a cover photo in the band"
   as a picture sitting in the band beside the words, so it was a column
   between the text and the three marks. His drawing never said that, and he
   finally said it plainly: "demo image a background purota jure image ta
   ache... sudhu chobir majhkhane clear baki side gula faded but chobi kintu
   purotai ache background a".

   The picture IS the card. It fills it corner to corner, and the welcome, the
   factory's name and the three marks sit ON it. Clear through the middle,
   melting away at both ends so the words on the left and the marks on the
   right have quiet to be read against.

   No vertical fade: a background that stops short of the card's own top and
   bottom is a picture in a box again, which is the thing being fixed. */
.egl-menu-herocover {
    position: absolute;
    inset: 0;
    z-index: -2;
    margin: 0;
    overflow: hidden;
    /* Clear in the middle, gone at both ends. One layer, stops tracing an
       ease rather than a ramp - a ramp has two ends and the eye finds both. */
    -webkit-mask-image: linear-gradient(90deg,
        rgba(0,0,0,0) 0%, rgba(0,0,0,.06) 5%, rgba(0,0,0,.24) 11%,
        rgba(0,0,0,.56) 17%, rgba(0,0,0,.85) 23%, rgba(0,0,0,1) 30%,
        rgba(0,0,0,1) 70%, rgba(0,0,0,.85) 77%, rgba(0,0,0,.56) 83%,
        rgba(0,0,0,.24) 89%, rgba(0,0,0,.06) 95%, rgba(0,0,0,0) 100%);
    mask-image: linear-gradient(90deg,
        rgba(0,0,0,0) 0%, rgba(0,0,0,.06) 5%, rgba(0,0,0,.24) 11%,
        rgba(0,0,0,.56) 17%, rgba(0,0,0,.85) 23%, rgba(0,0,0,1) 30%,
        rgba(0,0,0,1) 70%, rgba(0,0,0,.85) 77%, rgba(0,0,0,.56) 83%,
        rgba(0,0,0,.24) 89%, rgba(0,0,0,.06) 95%, rgba(0,0,0,0) 100%);
}
.egl-menu-herocover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
}

/* The quiet the words need. Not a box behind them - a wash across the two
   ends of the whole card, in the card's own colour, so it reads as the
   picture sinking into the surface rather than as a panel laid on top.
   Inside the figure, so it darkens the picture and nothing else. */
.egl-menu-herocover::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(90deg,
        var(--egl-surface-2) 0%,
        color-mix(in srgb, var(--egl-surface-2) 82%, transparent) 16%,
        color-mix(in srgb, var(--egl-surface-2) 42%, transparent) 30%,
        transparent 46%,
        transparent 58%,
        color-mix(in srgb, var(--egl-surface-2) 38%, transparent) 72%,
        color-mix(in srgb, var(--egl-surface-2) 78%, transparent) 86%,
        var(--egl-surface-2) 100%);
}

/* ------------------------------------------------------- the three words */
.egl-menu-herotag {
    position: relative;
    z-index: 1;
    display: grid;
    flex: 0 1 auto;
    gap: .125rem;
    justify-items: end;
    text-align: right;
    color: var(--egl-text-3);
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .12em;
}
.egl-menu-heropoints {
    display: grid;
    grid-auto-flow: column;
    gap: 1.125rem;
    margin: .625rem 0 0;
    padding: 0;
    list-style: none;
}
.egl-menu-heropoints li {
    display: grid;
    justify-items: center;
    gap: .125rem;
    text-align: center;
}
.egl-menu-heropointmark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    margin-bottom: .125rem;
    border-radius: .5rem;
    border: 1px solid color-mix(in srgb, currentColor 28%, transparent);
    background: color-mix(in srgb, currentColor 14%, transparent);
}
.egl-menu-heropointmark svg {
    width: 1rem;
    height: 1rem;
}
.egl-menu-heropointmark--people  { color: var(--egl-nav-sky); }
.egl-menu-heropointmark--machine { color: var(--egl-nav-emerald); }
.egl-menu-heropointmark--output  { color: var(--egl-nav-amber); }
.egl-menu-heropoints b {
    color: var(--egl-text-2);
    font-size: .625rem;
    letter-spacing: .1em;
}
.egl-menu-heropoints small {
    color: var(--egl-text-3);
    font-size: .5625rem;
    letter-spacing: .1em;
}

/* ------------------------------------------------------ the monitor trace */
.egl-menu-pulse {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    /* ABOVE the picture (-2) and above the card's own background, but under
       the words, which carry z-index 1. With the photo filling the card the
       trace had nowhere to show from underneath it. */
    z-index: 0;
    width: 100%;
    height: 3rem;
    pointer-events: none;
}
.egl-menu-pulsehead {
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}
/* The beam, and nothing else. With no guide line under it the beat arrives
   out of an empty lane - his note, and he was right. The dash is longer than
   one beat so the whole shape lights up at once, the way it does on a
   monitor, rather than crawling through it point by point. */
.egl-menu-pulsehead {
    stroke: var(--egl-nav-sky);
    stroke-dasharray: 220 2600;
    stroke-dashoffset: 2820;
    filter: drop-shadow(0 0 5px color-mix(in srgb, var(--egl-nav-sky) 75%, transparent));
    /* 6s, and the number is not a guess. The path carries six beats, so one
       sweep at six seconds is one beat a second - sixty a minute, a calm
       resting pulse. At 4.5s it was eighty and read as hurried; much slower
       and a monitor looks like it is in trouble. Aomith: "beshi slow na
       beshi fast na". */
    animation: egl-menu-sweep 6s linear infinite;
}

@keyframes egl-menu-sweep {
    to { stroke-dashoffset: 0; }
}
@keyframes egl-menu-beat {
    0%, 62%, 100% { text-shadow: none; }
    70% { text-shadow: 0 0 14px color-mix(in srgb, var(--egl-nav-sky) 60%, transparent); }
    78% { text-shadow: none; }
    86% { text-shadow: 0 0 10px color-mix(in srgb, var(--egl-nav-sky) 45%, transparent); }
}

@media (prefers-reduced-motion: reduce) {
    .egl-menu-pulsehead {
        animation: none;
        stroke-dasharray: none;
        stroke-dashoffset: 0;
        opacity: .45;
    }
    .egl-menu-hero h1 b {
        animation: none;
    }
    .egl-menu-hero::after {
        animation: none;
        opacity: .5;
        transform: translate(-50%, -50%) scale(.96);
    }
}

/* ========================================================================
   PHASE 101 - THE BAND ON A PHONE.

   Aomith, with a photograph of his own screen: "phone er screen a lekha gula
   aktar upor arekta uthe geche". I measured it in a browser at 360, 390 and
   430 before touching anything, and no two boxes were on top of each other -
   the card stacks correctly at every width. What he was looking at was HIS
   OWN PICTURE, coming up through the words.

   Here is why, and it is the design above doing exactly what it was told.
   The picture is cleared through the MIDDLE and faded away at the LEFT and
   RIGHT ends, because on a laptop the band is a long strip with the words at
   one end, the marks at the other and the picture breathing in the gap. A
   phone has no gap. The same card is a tall stack, every line of it runs
   through the middle, and the middle is precisely where the picture is at
   full strength. The Meghna mark landed on "Executive Greentex Limited" and
   there was nothing wrong with the layout at all.

   So the picture is given back its own room, downwards instead of sideways:
   gone at the top where the welcome and the factory's name are, arriving
   through the lower half where only the three marks and the pulse sit, and
   dimmer than it is on a laptop because it has far less card to spread over.
   His photograph is still on the card - it is simply no longer standing in
   front of the writing.

   Nothing in this block exists above 40rem, so the laptop view he likes is
   untouched, down to the pixel.
   ===================================================================== */
@media (max-width: 40rem) {
    .egl-menu-hero {
        /* 1.5rem of side padding on a 358px card is a thumb's width of the
           screen spent on nothing. The bottom keeps its depth - that lane
           belongs to the trace. */
        padding: 1.25rem 1.125rem 2.5rem;
    }

    .egl-menu-herocover {
        /* Top-to-bottom now, not side-to-side. Nothing at all through the
           words, arriving by the time the marks begin. */
        -webkit-mask-image: linear-gradient(180deg,
            rgba(0,0,0,0) 0%, rgba(0,0,0,0) 34%, rgba(0,0,0,.18) 48%,
            rgba(0,0,0,.52) 64%, rgba(0,0,0,.85) 82%, rgba(0,0,0,1) 100%);
        mask-image: linear-gradient(180deg,
            rgba(0,0,0,0) 0%, rgba(0,0,0,0) 34%, rgba(0,0,0,.18) 48%,
            rgba(0,0,0,.52) 64%, rgba(0,0,0,.85) 82%, rgba(0,0,0,1) 100%);
        opacity: .5;
    }
    /* The wash follows the picture, so the three marks keep their quiet. */
    .egl-menu-herocover::after {
        background: linear-gradient(180deg,
            var(--egl-surface-2) 0%,
            color-mix(in srgb, var(--egl-surface-2) 72%, transparent) 55%,
            color-mix(in srgb, var(--egl-surface-2) 48%, transparent) 100%);
    }

    /* Right-aligned is right on a laptop, where this block sits at the far
       end of the strip. Stacked under the welcome it just looked adrift, so
       it lines up with the words above it and the three marks share the card
       evenly instead of huddling at one side. */
    .egl-menu-herotag {
        width: 100%;
        justify-items: start;
        text-align: left;
    }
    .egl-menu-heropoints {
        width: 100%;
        grid-auto-flow: row;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: .5rem;
    }
}

/* ------------------------------------- Phase 73: the Edit layout card
   It was a plain secondary button sitting beside a wide search box, and next
   to the new band it read as the one unfinished thing on the page. It is the
   Admin's own door, so it gets the sky tone the band uses - softly, as a wash
   rather than a filled button, because it is not the thing anybody came here
   to press. */
.egl-menu-editbtn {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    flex: none;
    padding: .625rem 1rem;
    border: 1px solid color-mix(in srgb, var(--egl-nav-sky) 32%, var(--egl-border));
    border-radius: .75rem;
    color: var(--egl-text-2);
    font-size: .8125rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    background: var(--egl-surface-2);
    background-image: linear-gradient(135deg,
        color-mix(in srgb, var(--egl-nav-sky) 20%, transparent),
        color-mix(in srgb, var(--egl-nav-indigo) 10%, transparent));
    box-shadow:
        inset 0 1px 0 color-mix(in srgb, #fff 14%, transparent),
        0 1px 2px color-mix(in srgb, #000 14%, transparent);
    transition: border-color .14s ease, transform .14s ease, box-shadow .14s ease;
}
.egl-menu-editbtn:hover {
    border-color: color-mix(in srgb, var(--egl-nav-sky) 60%, transparent);
    transform: translateY(-1px);
    box-shadow:
        inset 0 1px 0 color-mix(in srgb, #fff 18%, transparent),
        0 6px 16px -10px color-mix(in srgb, var(--egl-nav-sky) 70%, #000);
}
.egl-menu-editbtn svg {
    color: var(--egl-nav-sky);
}

/* ------------------------------------------- Phase 73: choosing the picture */
.egl-menu-coverbox {
    display: flex;
    align-items: center;
    gap: .75rem;
    flex-wrap: wrap;
    margin-bottom: .75rem;
    padding: .875rem 1rem;
    border: 1px solid var(--egl-border);
    border-radius: .875rem;
    background: var(--egl-surface-2);
}
.egl-menu-coverbox--off {
    background: var(--egl-surface-3);
}
.egl-menu-covertext {
    flex: 1 1 18rem;
    min-width: 0;
    color: var(--egl-text-3);
    font-size: .75rem;
    line-height: 1.45;
}
.egl-menu-covertext b {
    display: block;
    color: var(--egl-text);
    font-size: .8125rem;
}
.egl-menu-coverfile {
    flex: 0 1 20rem;
    min-width: 0;
    font-size: .75rem;
}

/* ------------------------------------------------- the search box */
.egl-menu-search {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-bottom: 1.25rem;
    padding: .625rem .875rem;
    /* Phase 73 - this box had surface-2 on surface-2 behind a hairline
       border, which is invisible in light appearance: Aomith opened it and
       the search box simply was not there. It states its own edge in the
       page's own ink now, so it is drawn from the same colour whatever is
       behind it, instead of hoping two near-identical greys stay apart. */
    border: 1px solid color-mix(in srgb, var(--egl-text) 20%, transparent);
    border-radius: .75rem;
    background: var(--egl-surface-2);
    box-shadow: inset 0 1px 2px color-mix(in srgb, var(--egl-text) 7%, transparent);
}
.egl-menu-search:focus-within {
    border-color: var(--egl-nav-sky);
}
.egl-menu-searchicon {
    display: inline-flex;
    color: var(--egl-text-3);
}
.egl-menu-searchinput {
    flex: 1;
    min-width: 0;
    border: 0;
    background: transparent;
    color: var(--egl-text);
    font-size: .875rem;
    outline: none;
}
.egl-menu-searchinput::placeholder {
    color: var(--egl-text-3);
}
.egl-menu-none {
    margin-bottom: 1rem;
    color: var(--egl-text-3);
    font-size: .8125rem;
}

/* ------------------------------------------------- one department, one panel */
.egl-menu-panel {
    margin-bottom: 1rem;
    padding: 1rem 1.125rem 1.125rem;
    border: 1px solid var(--egl-border);
    border-radius: 1rem;
    background: var(--egl-surface-2);
}
.egl-menu-panel--maintenance { --egl-menu-tone: var(--egl-nav-emerald); }
.egl-menu-panel--ie          { --egl-menu-tone: var(--egl-nav-sky); }
.egl-menu-panel--contacts    { --egl-menu-tone: var(--egl-nav-violet); }
.egl-menu-panel--admin       { --egl-menu-tone: var(--egl-nav-slate); }
.egl-menu-panel--cutting     { --egl-menu-tone: var(--egl-nav-amber); }
.egl-menu-panel--production  { --egl-menu-tone: var(--egl-nav-rose); }
.egl-menu-panel--finishing   { --egl-menu-tone: var(--egl-nav-orange); }
.egl-menu-panel--planning    { --egl-menu-tone: var(--egl-nav-fuchsia); }

.egl-menu-panelhead {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-bottom: .875rem;
}
.egl-menu-paneldot {
    display: inline-flex;
    color: var(--egl-menu-tone, var(--egl-nav-slate));
}
.egl-menu-paneltitle {
    color: var(--egl-text);
    font-size: 1rem;
    font-weight: 700;
}
.egl-menu-soon {
    padding: .125rem .5rem;
    border: 1px solid var(--egl-border);
    border-radius: 999px;
    color: var(--egl-text-3);
    font-size: .6875rem;
    white-space: nowrap;
}

/* ------------------------------------------------- the tiles
   THIS WAS WRAPPED FLEX UNTIL PHASE 75, and the note here used to argue for
   it: a tile should take the room its words need and no more. That reasoning
   is kept only so nobody re-discovers it as a fresh idea - he looked at the
   result on his own screen and asked for the opposite, and he was right.
   Read on.

   PHASE 75 - A GRID, NOT A WRAPPED ROW.

   Aomith, 2 October: "sob gula card jeno same size hoi... jodi 1st serial a
   5 ta hoi nicher serial a 3 ta bosle size thik thake na, ba alignment thik
   thake na".

   He is right and 66 is why. Wrapped flex items size themselves to their own
   words and then share out whatever is left on their row - so every tile was
   a slightly different width, and a short last row stretched its three tiles
   fat to fill the space. Five above, three below, nothing lining up.

   A grid of equal tracks fixes all of it at once, and AUTO-FILL is the whole
   trick. auto-FIT would collapse the empty tracks on a short row and stretch
   the tiles back out - exactly the bug. auto-FILL keeps the empty tracks
   standing, so the fourth tile of a short row sits under the fourth tile of
   the row above, at the same width, and the gap at the end is just a gap.

   Everything he asked for falls out of that one choice:
     - every tile the same width, because the tracks are equal
     - every tile the same height, from grid-auto-rows: 1fr
     - a new page dropped into a card re-balances the rows by itself, with
       no number anywhere to keep in step
     - zoom cannot shift it: the track size is in rem, so the whole grid is
       re-reckoned at the new size rather than overflowing
     - and on a phone, two to a row, flat. */
.egl-menu-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    grid-auto-rows: 1fr;
    gap: .625rem;
}
.egl-menu-tile {
    display: flex;
    align-items: center;
    gap: .75rem;
    min-width: 0;
    padding: .625rem .75rem;
    border-radius: .75rem;
    text-decoration: none;
    background: var(--egl-surface-3);
    border: 1px solid var(--egl-border);
    background-image: linear-gradient(120deg,
        color-mix(in srgb, currentColor 16%, transparent),
        color-mix(in srgb, currentColor 4%, transparent));
    border-color: color-mix(in srgb, currentColor 22%, transparent);
    transition: border-color .14s ease, transform .14s ease;
}
.egl-menu-tile:hover {
    transform: translateY(-1px);
    border-color: color-mix(in srgb, currentColor 55%, transparent);
}
.egl-menu-tileicon {
    flex: none;
    height: 2.5rem;
    width: auto;
    display: block;
}
.egl-menu-tiletext {
    flex: 1;
    min-width: 0;
}
.egl-menu-tiletext b {
    display: block;
    /* Explicit, because the tile's own colour is the tone and the name must
       not inherit it - a teal name on a teal wash is a name nobody reads. */
    color: var(--egl-text);
    font-size: .8125rem;
    font-weight: 600;
    line-height: 1.25;
    /* break-word, NOT anywhere. "anywhere" also makes the browser reckon the
       text's smallest possible width as one character, so on a phone the
       grid handed the name a sliver and it came out "Dashboar d". break-word
       keeps the longest word as the floor and only splits one when it truly
       cannot fit. */
    overflow-wrap: break-word;
}
.egl-menu-tiletext small {
    display: block;
    margin-top: .0625rem;
    color: var(--egl-text-3);
    font-size: .6875rem;
    line-height: 1.3;
    overflow-wrap: break-word;
}
.egl-menu-tilego {
    flex: none;
    display: inline-flex;
    color: var(--egl-text-3);
}
/* There is no chevron-right in the icon set and adding one for this would be
   a second glyph to keep in step with the first. A quarter turn is the same
   arrow. */
.egl-menu-tilego svg {
    transform: rotate(-90deg);
}

/* His words: "mobile screen a aksathe 2 ta kore card bosbe". Two fixed
   tracks rather than another auto-fill, because at that width auto-fill
   would drop to one and he has asked for two. minmax(0, 1fr) so a long name
   wraps inside its tile instead of pushing the track wider than the screen. */
@media (max-width: 40rem) {
    .egl-menu-tiles {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* PHASE 101 - WHY THE NAMES CAME OUT "Machin e Dashbo ard".

       Two tiles to a row on a 390px phone leaves each tile 155px. A row of
       icon, name and arrow then hands the name whatever is left after the
       other two have taken theirs - and that was FORTY-SIX PIXELS. At 360px
       it was thirty-one. Every name on the page was being folded into two
       and three letter pieces, which is exactly what Aomith photographed.
       Nothing was overlapping; the words had simply run out of room.
       (Measured in a browser at five widths, not guessed at.)

       The fix is not a smaller font - it is to stop the three of them
       sharing one line. The icon goes on top, the name underneath with the
       tile's whole width to itself, and the arrow moves to the corner it was
       already pointing from. 46px becomes 129px, and "Schedule Maintenance"
       fits in two honest lines.

       Only here. On a laptop the row reads better and nothing changes.

       THE TILE BECOMES A GRID TO DO IT, not a stacked flex box, and that is
       not a matter of taste. DashboardGaugeTest requires the LAST rule in
       this whole file that stacks a flex box to be the dashboard gauge's own
       phone block - those rules win only by coming last, and the guard finds
       them by searching the file from the end. A stack written here would
       quietly take that place and the gauge's phone fix would stop working at
       every width, with nothing on screen to say so. Phase 82 and Phase 92
       both met this and both answered it the same way: grid stacks by itself
       and needs no such declaration at all. This note is worded to avoid
       naming the property, because the guard would find the sentence. That is
       now the fifth time a guard in this file has caught its own
       explanation. */
    .egl-menu-tile {
        position: relative;
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        gap: .375rem;
        padding: .75rem;
    }
    .egl-menu-tileicon {
        height: 2rem;
    }
    /* Out of the flow, so it costs the name nothing, and in the corner the
       eye already goes to. Not removed: the arrow is what says the tile is a
       door rather than a label. */
    .egl-menu-tilego {
        position: absolute;
        top: .875rem;
        right: .75rem;
    }
}

/* A department that is not here yet is quiet, not broken. The dashed strip
   says "this space is taken" without asking for a tap. */
.egl-menu-waiting {
    padding: .875rem 1rem;
    border: 1px dashed var(--egl-border-strong);
    border-radius: .75rem;
    color: var(--egl-text-3);
    font-size: .8125rem;
}
.egl-menu-foot {
    margin-top: 1rem;
    color: var(--egl-text-3);
    font-size: .75rem;
}

/* ------------------------------------------------- one line per entry
   The SAME tone the sidebar gives that entry. Nothing invented here; if a
   colour changes in the list above, it changes on the tile too. */
.egl-menu-tile--dashboard        { color: var(--egl-nav-blue); }
.egl-menu-tile--machines         { color: var(--egl-nav-teal); }
.egl-menu-tile--alarms           { color: var(--egl-nav-red); }
.egl-menu-tile--schedule         { color: var(--egl-nav-orange); }
.egl-menu-tile--engagement       { color: var(--egl-nav-amber); }
.egl-menu-tile--contacts         { color: var(--egl-nav-violet); }
.egl-menu-tile--rental-dashboard { color: var(--egl-nav-sky); }
.egl-menu-tile--rental-status    { color: var(--egl-nav-green); }
.egl-menu-tile--group-factory    { color: var(--egl-nav-lime); }
.egl-menu-tile--mreq             { color: var(--egl-nav-indigo); }
.egl-menu-tile--mpi              { color: var(--egl-nav-fuchsia); }
.egl-menu-tile--slx              { color: var(--egl-nav-purple); }
.egl-menu-tile--skill            { color: var(--egl-nav-emerald); }
.egl-menu-tile--qco              { color: var(--egl-nav-cyan); }
.egl-menu-tile--msp              { color: var(--egl-nav-stone); }
.egl-menu-tile--users            { color: var(--egl-nav-rose); }
.egl-menu-tile--settings         { color: var(--egl-nav-slate); }
/* The two remaining contact lists sit in one panel now and would read as two
   copies of the same tile on one tone, so they are given neighbouring ones. */
.egl-menu-tile--ie-contacts      { color: var(--egl-nav-rose); }
.egl-menu-tile--tech-contacts    { color: var(--egl-nav-indigo); }
/* Phase 110D - the Production contact list. Emerald, which the contact
   family did not use; the tile picture is the same phone in the same green,
   so the word and the picture say one thing. Both themes get it, because
   --egl-nav-emerald is redefined in the light block above like every other
   nav colour - nothing here is a hard-coded hex. */
.egl-menu-tile--prod-contacts    { color: var(--egl-nav-emerald); }

/* ---------------------------------------------------------------------------
   PHASE 67 - ARRANGING THE MENU.

   Aomith: "kon option ta kon card a bosbe bar bar tomake diye code theke
   change kora lagbe na". Three phases running, every regrouping came back to
   me and became a deploy.

   The editor deliberately does NOT look like the menu. A row that can be
   dragged, nudged and hidden should not be mistaken for a tile you tap to go
   somewhere - so an edit row is wide, plain and full of controls, and the
   coloured tiles stay for the real thing.
   -------------------------------------------------------------------------- */
/* PHASE 101 - THE ROW THAT PUSHED THE WHOLE PAGE SIDEWAYS.

   Aomith's phone, measured at 390px: the page was 417px wide. Everything on
   the menu could be dragged left and right by 27px, which is what made the
   front door feel broken even where nothing was actually wrong.

   It was this one row, and only an Admin ever saw it - "Edit layout" is the
   only thing on the page that is not there for everybody. The search box and
   the button could not both fit, the row was told never to wrap, and so the
   button simply hung off the end of the screen and took the page with it.

   wrap, and a search box allowed to shrink. Two lines on a phone, one line
   everywhere else - the row decides for itself, with no width written down. */
.egl-menu-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .75rem;
    margin-bottom: 1.25rem;
}
.egl-menu-bar .egl-menu-search {
    flex: 1 1 12rem;
    /* Without this the box refuses to go below its own contents and the
       button is the one that gives way - off the edge of the screen. */
    min-width: 0;
    margin-bottom: 0;
}
.egl-menu-editbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .75rem;
    margin-bottom: 1rem;
    padding: .875rem 1rem;
    border: 1px solid var(--egl-border);
    border-left: 3px solid var(--egl-nav-sky);
    border-radius: .75rem;
    background: var(--egl-surface-3);
}
.egl-menu-editnote {
    color: var(--egl-text-2);
    font-size: .8125rem;
    max-width: 44rem;
}
.egl-menu-editnote b {
    color: var(--egl-text);
}
.egl-menu-editactions {
    display: flex;
    gap: .5rem;
}
.egl-menu-editpanel {
    border-style: dashed;
}
.egl-menu-editgrow {
    flex: 1;
}
.egl-menu-editrows {
    display: grid;
    gap: .5rem;
}
.egl-menu-editrow {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .625rem;
    padding: .5rem .625rem;
    border: 1px solid var(--egl-border);
    border-radius: .625rem;
    background: var(--egl-surface);
    border-left: 3px solid currentColor;
}
.egl-menu-editrow .egl-menu-tiletext {
    flex: 1 1 10rem;
}
.egl-menu-grip {
    color: var(--egl-text-3);
    cursor: grab;
    font-size: 1rem;
    line-height: 1;
}
.egl-menu-editcontrols {
    display: flex;
    align-items: center;
    gap: .375rem;
    flex-wrap: wrap;
}
.egl-menu-nudge {
    width: 1.75rem;
    height: 1.75rem;
    border: 1px solid var(--egl-border);
    border-radius: .375rem;
    background: var(--egl-surface-2);
    color: var(--egl-text-2);
    font-size: .8125rem;
    line-height: 1;
}
.egl-menu-nudge:disabled {
    opacity: .35;
}
.egl-menu-moveto {
    width: auto;
    min-width: 11rem;
    padding-top: .25rem;
    padding-bottom: .25rem;
    font-size: .75rem;
}
.egl-menu-hiddentray {
    border-style: dashed;
}
.egl-menu-resetrow {
    display: flex;
    align-items: center;
    gap: .625rem;
    flex-wrap: wrap;
    margin-top: .5rem;
    color: var(--egl-text-3);
    font-size: .75rem;
}

/* ---------------------------------------------------------------------------
   PHASE 68 - CARDS OF HIS OWN, AND THE EMPTY ONES GONE QUIET.
   -------------------------------------------------------------------------- */
.egl-menu-cardname {
    width: auto;
    min-width: 12rem;
    max-width: 20rem;
    padding-top: .25rem;
    padding-bottom: .25rem;
    font-size: .875rem;
    font-weight: 600;
}
.egl-menu-switch {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    color: var(--egl-text-3);
    font-size: .75rem;
    white-space: nowrap;
}
.egl-menu-addcard {
    border-style: dashed;
}
.egl-menu-addrow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}
.egl-menu-addrow .egl-input {
    width: auto;
    min-width: 10rem;
    flex: 0 1 14rem;
    padding-top: .375rem;
    padding-bottom: .375rem;
    font-size: .8125rem;
}

/* ==========================================================================
   PHASE 80 — CONTACT US.
   --------------------------------------------------------------------------
   Aomith, 3 October: a page shaped the way a professional application has
   one — who built this, who helps, and who to ring when something is wrong.

   A NEW FAMILY, egl-cu-, and it was checked the same way every family since
   13B has been: "egl-cu" appears NOWHERE in the compiled bundle, so none of
   these rules can repaint anything that already ships. That check is what
   earns a prefix its place in ThemeOverlayWiringTest's list, and the entry
   there carries the same note.

   Every colour is a meaning token, so the page is right in LIGHT as well as
   dark — he checks the light one on his own screen and has sent a screenshot
   back more than once when a module forgot.
   ========================================================================== */

.egl-cu-band {
    margin-bottom: 1rem;
    padding: .875rem;
    border: 1px solid var(--egl-border);
    border-radius: .875rem;
    background: var(--egl-surface);
}
.egl-cu-bandname {
    margin: 0 0 .75rem;
    padding-bottom: .5rem;
    border-bottom: 1px solid var(--egl-border);
    color: var(--egl-text);
    font-size: 1rem;
    font-weight: 700;
}

/* The emergency block is the one somebody opens this page in a hurry to
   find, so it is the one that is allowed to shout — a warm border and a
   tinted ground, nothing more. */
.egl-cu-band--urgent {
    border-color: var(--egl-danger-border);
    background: var(--egl-danger-soft);
}
.egl-cu-band--urgent .egl-cu-bandname {
    color: var(--egl-danger);
    border-bottom-color: var(--egl-danger-border);
}

/* Same grid lesson as Phase 75's menu tiles: auto-FILL, never auto-fit.
   auto-fit collapses the empty tracks of a short last row and stretches the
   cards back out, which is exactly what he objected to there. */
.egl-cu-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
    grid-auto-rows: 1fr;
    gap: .625rem;
}
.egl-cu-card {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    min-width: 0;
    padding: .75rem;
    border: 1px solid var(--egl-border);
    border-radius: .75rem;
    background: var(--egl-surface-2);
}
.egl-cu-card--founder {
    border-color: var(--egl-primary-border);
    background: var(--egl-primary-soft);
}

.egl-cu-face {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3.25rem;
    height: 3.25rem;
    overflow: hidden;
    border-radius: 999px;
    border: 1px solid var(--egl-border);
    background: var(--egl-surface-3);
}
.egl-cu-face img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.egl-cu-initials {
    color: var(--egl-text-3);
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: .02em;
}

.egl-cu-who {
    min-width: 0;
}
.egl-cu-name {
    margin: 0;
    color: var(--egl-text);
    font-size: .9375rem;
    font-weight: 700;
    /* break-word, not anywhere — Phase 75 paid for that lesson: "anywhere"
       makes the browser reckon the smallest width as one character, and a
       name comes out broken mid-syllable on a phone. */
    overflow-wrap: break-word;
}
.egl-cu-role {
    margin: .125rem 0 0;
    color: var(--egl-text-3);
    font-size: .75rem;
    overflow-wrap: break-word;
}
.egl-cu-note {
    margin: .375rem 0 0;
    color: var(--egl-text-2);
    font-size: .75rem;
    line-height: 1.4;
    overflow-wrap: break-word;
}

.egl-cu-reach {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
    margin-top: .5rem;
}
.egl-cu-reachbtn {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .25rem .5rem;
    border: 1px solid var(--egl-border);
    border-radius: .375rem;
    background: var(--egl-surface);
    color: var(--egl-text-2);
    font-size: .75rem;
    text-decoration: none;
    overflow-wrap: anywhere;
}
.egl-cu-reachbtn:hover {
    border-color: var(--egl-border-strong);
    color: var(--egl-text);
}

.egl-cu-empty {
    margin: 0;
    color: var(--egl-text-muted);
    font-size: .8125rem;
}
.egl-cu-locked {
    margin: 0;
    padding: 0;
    list-style: none;
}
.egl-cu-locked li {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .5rem;
    padding: .375rem 0;
    border-bottom: 1px solid var(--egl-border);
    font-size: .8125rem;
    color: var(--egl-text);
}
.egl-cu-locked li:last-child {
    border-bottom: 0;
}
.egl-cu-locked span {
    color: var(--egl-text-3);
    font-size: .75rem;
}
.egl-cu-preview {
    width: 4rem;
    height: 4rem;
    object-fit: cover;
    border-radius: .5rem;
    border: 1px solid var(--egl-border);
}

@media (max-width: 40rem) {
    .egl-cu-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* PHASE 81 - "Design and Developed By". One card, two kinds of fact: the name
   and the photograph come from code and cannot be changed by anybody, the
   designation and the workplace come from settings because they move with a
   career. The page shows no seam between them - only the manage page does. */
.egl-cu-band--built {
    border-color: var(--egl-primary-border);
    background: var(--egl-primary-soft);
}
.egl-cu-card--builder {
    align-items: center;
    gap: 1rem;
    background: var(--egl-surface);
}
.egl-cu-face--big {
    width: 5.5rem;
    height: 5.5rem;
}
.egl-cu-name--big {
    font-size: 1.0625rem;
}
.egl-cu-facts {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
    margin-top: .5rem;
}
.egl-cu-fact {
    padding: .125rem .5rem;
    border: 1px solid var(--egl-border);
    border-radius: 999px;
    background: var(--egl-surface-2);
    color: var(--egl-text-3);
    font-size: .6875rem;
}
.egl-cu-lockedrow {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .5rem 0;
}
.egl-cu-lockedrow b {
    display: block;
    color: var(--egl-text);
    font-size: .875rem;
}
.egl-cu-lockedrow span {
    display: block;
    margin-top: .125rem;
    color: var(--egl-text-3);
    font-size: .75rem;
}

/* PHASE 82 - ONE CARD SHAPE, AND THE SCREEN THAT ARRANGES THEM.

   Aomith: the cards below his were smaller than his own. "Inspiration and
   idea sharing er card ta jeno upore amar name e jei card ... er moto same
   length thake and profile picture ta jeno amr card jemon temon thake".

   So the grid is gone and every card is full width, one to a row, with the
   same big round photograph. His is no longer a special case of the shape -
   only of where its words come from. */
/* A one-column GRID rather than a flex column stack, and that is not a whim.
   DashboardGaugeTest requires the LAST rule in this file that stacks a flex
   box vertically to be the dashboard gauge's phone block, because those
   rules win by coming last; a stack appended here would silently take that
   place. Grid does the same job and leaves the invariant alone.

   AND THIS COMMENT IS WORDED TO AVOID THE PROPERTY NAME ITSELF. The guard
   greps the file, so writing it out here - even to explain it - makes the
   comment the last match and fails the test. That is the fourth time this
   session a guard has found its own explanation: step 501, Phase 75, Phase
   77's test, and now the note warning about it. */
.egl-cu-stack {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: .625rem;
}

/* The call button. A tel: href already hands the number to the dialler; what
   was missing was that it LOOKED like a line of text, so nobody on the floor
   knew it could be tapped. */
.egl-cu-callbtn {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    padding: .3rem .5rem .3rem .55rem;
    border: 1px solid var(--egl-ok-border);
    border-radius: .375rem;
    background: var(--egl-ok-soft);
    color: var(--egl-ok);
    font-size: .8125rem;
    font-weight: 600;
    text-decoration: none;
}
.egl-cu-callbtn:hover {
    border-color: var(--egl-ok);
}
.egl-cu-callnum {
    overflow-wrap: anywhere;
}
.egl-cu-calltag {
    padding: 0 .375rem;
    border-radius: 999px;
    background: var(--egl-ok);
    color: var(--egl-surface);
    font-size: .625rem;
    letter-spacing: .04em;
    text-transform: uppercase;
}

/* ---------------------------------------------- the arranging screen */
.egl-cu-arrange {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: .625rem;
}
.egl-cu-arrblock {
    border: 1px solid var(--egl-border);
    border-radius: .75rem;
    background: var(--egl-surface);
}
.egl-cu-arrhead {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    padding: .5rem .625rem;
    border-bottom: 1px solid var(--egl-border);
    background: var(--egl-surface-2);
    border-radius: .75rem .75rem 0 0;
}
.egl-cu-headinput {
    width: auto;
    flex: 1 1 12rem;
    min-width: 0;
    font-weight: 600;
}
.egl-cu-arrcount {
    flex: none;
    color: var(--egl-text-3);
    font-size: .6875rem;
}
/* The handle. Cursor: grab is the only thing on screen that says "this moves"
   before you try it - and on a phone, where there is no cursor at all, the
   arrows beside it are what actually get used. */
.egl-cu-grip {
    flex: none;
    color: var(--egl-text-muted);
    cursor: grab;
    user-select: none;
    font-size: .875rem;
}
.egl-cu-arrrows {
    padding: .5rem .625rem;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: .375rem;
}
.egl-cu-arrrow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    padding: .375rem .5rem;
    border: 1px solid var(--egl-border);
    border-radius: .5rem;
    background: var(--egl-surface-2);
}
.egl-cu-arrname {
    color: var(--egl-text);
    font-size: .8125rem;
    font-weight: 600;
    overflow-wrap: break-word;
}
.egl-cu-arrrole {
    flex: 1 1 8rem;
    min-width: 0;
    color: var(--egl-text-3);
    font-size: .6875rem;
    overflow-wrap: break-word;
}
.egl-cu-arrhidden {
    padding: 0 .375rem;
    border-radius: 999px;
    background: var(--egl-muted-soft);
    color: var(--egl-muted-tone);
    font-size: .625rem;
}
.egl-cu-arrbtns {
    display: flex;
    align-items: center;
    gap: .375rem;
    margin-left: auto;
}
.egl-cu-removerow {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
    margin-top: .5rem;
}

/* ============================================================================
   PHASE 92 - PEOPLE: THE DIRECTORY AND ONE PERSON'S PROFILE.

   Aomith, 5 October 2026: every user gets a profile "যা সবাই দেখতে পাবে", with
   phone and email visible to everyone who can sign in, and a cover picture
   each person uploads for themselves.

   EVERY SELECTOR HERE STARTS WITH .egl-profile- , which the overlay already
   allows and which appears nowhere in the frozen Tailwind bundle. Nothing new
   had to be added to the allowlist, and nothing in the bundle can be reached
   by accident.

   EVERY COLOUR IS A TOKEN, so the page is right in light mode without one
   extra rule. He asked for that in September and it has held since: "tumi
   akhn theke new module a jei theme e banabe seta jeno light mood a sundor
   lage".

   NOTHING HERE SETS A COLUMN FLEX DIRECTION, deliberately, and this sentence
   avoids writing the property out for the same reason. The dashboard gauge's
   phone fix depends on being the LAST such declaration in the file, the guard
   that protects it finds the last one by searching the text, and this block is
   appended after it - so a mention in a comment would have broken the guard
   exactly as a real rule would. Everything that stacks here uses grid, which
   stacks by default and needs no such declaration at all.
   ======================================================================== */

/* ─── the directory ─────────────────────────────────────────────────── */

.egl-profile-dirhead {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
}

.egl-profile-dirsearch {
    flex: 1 1 16rem;
    min-width: 0;
    max-width: 24rem;
    padding: .5rem .75rem;
    border: 1px solid var(--egl-border);
    border-radius: .625rem;
    background: var(--egl-surface-2);
    color: var(--egl-text);
    font-size: .8125rem;
}

.egl-profile-dirsearch::placeholder {
    color: var(--egl-text-muted);
}

.egl-profile-dirsearch:focus {
    outline: none;
    border-color: var(--egl-primary);
    box-shadow: 0 0 0 3px var(--egl-primary-soft);
}

.egl-profile-dirgrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: .625rem;
}

.egl-profile-dircard {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .625rem .75rem;
    border: 1px solid var(--egl-border);
    border-radius: .75rem;
    background: var(--egl-surface-2);
    text-decoration: none;
    transition: border-color .15s ease, background-color .15s ease;
}

.egl-profile-dircard:hover {
    border-color: var(--egl-nav-rose);
    background: var(--egl-surface-3);
}

.egl-profile-diravatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 999px;
    border: 1px solid var(--egl-border-strong);
    background: var(--egl-surface-3);
    overflow: hidden;
}

.egl-profile-diravatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.egl-profile-dirinitial {
    color: var(--egl-text-2);
    font-weight: 700;
    font-size: 1rem;
}

.egl-profile-dirtext {
    display: grid;
    gap: .0625rem;
    min-width: 0;
}

.egl-profile-dirname {
    color: var(--egl-text);
    font-size: .875rem;
    font-weight: 600;
    overflow-wrap: break-word;
}

.egl-profile-dirmeta {
    color: var(--egl-text-3);
    font-size: .75rem;
    overflow-wrap: break-word;
}

/* ─── one person's profile ──────────────────────────────────────────── */

.egl-profile-herocard {
    overflow: hidden;
}

.egl-profile-cover {
    height: 9rem;
    background: var(--egl-surface-3);
}

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

/* NOBODY HAS TO UPLOAD A COVER, and for a long time almost nobody will. The
   band a profile without one gets is a deliberate gradient in the app's own
   rose rather than an empty grey box, so a profile with no cover looks
   finished instead of looking like a picture that failed to load.

   TWO GRADIENTS RATHER THAN ONE AND AN opacity, and that is not a flourish.
   An opacity below 1 makes the band its own STACKING CONTEXT, and a stacking
   context paints above the ordinary in-flow content that follows it - so the
   name and designation underneath were being painted over by the band they
   sit below. The second gradient does the softening without changing how the
   page is painted. */
.egl-profile-cover--plain {
    background:
        linear-gradient(180deg, rgba(255, 255, 255, .16), rgba(15, 23, 42, .10)),
        linear-gradient(135deg, var(--egl-nav-rose), var(--egl-nav-violet));
}

/* THE PORTRAIT RIDES UP INTO THE BAND, THE WORDS DO NOT. Pulling the whole
   row up put the name, the designation and the role badge inside the band as
   soon as a person had all three - the taller the block, the further in it
   went. Only the portrait carries the negative margin now, so the overlap is
   the same at any name length. position: relative keeps the row above the
   band whatever the band is painted with. */
.egl-profile-hero {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 1rem;
    padding: .75rem 1.25rem 1.25rem;
}

.egl-profile-heroportrait {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 6rem;
    height: 6rem;
    border-radius: 999px;
    border: 3px solid var(--egl-surface);
    background: var(--egl-surface-3);
    overflow: hidden;
    margin-top: -3.25rem;
}

.egl-profile-heroportrait img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.egl-profile-heronames {
    display: grid;
    gap: .125rem;
    min-width: 0;
    padding: .25rem 0 .25rem;
}

.egl-profile-heroname {
    color: var(--egl-text);
    font-size: 1.125rem;
    font-weight: 700;
    overflow-wrap: break-word;
}

.egl-profile-mail {
    overflow-wrap: break-word;
}

.egl-profile-maillink {
    color: var(--egl-primary);
    font-size: .8125rem;
    text-decoration: none;
}

.egl-profile-maillink:hover {
    text-decoration: underline;
}

.egl-profile-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: .625rem;
}

.egl-profile-fact {
    display: grid;
    gap: .1875rem;
    padding: .625rem .75rem;
    border: 1px solid var(--egl-border);
    border-radius: .625rem;
    background: var(--egl-surface-2);
}

.egl-profile-factlabel {
    color: var(--egl-text-muted);
    font-size: .625rem;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.egl-profile-factvalue {
    color: var(--egl-text);
    font-size: .875rem;
    font-weight: 600;
    overflow-wrap: break-word;
}

/* ─── the cover picture field on the edit form ──────────────────────── */

.egl-profile-coverfield {
    display: grid;
    gap: .25rem;
}

.egl-profile-coverfield__preview {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 6.5rem;
    border: 1px dashed var(--egl-border-strong);
    border-radius: .75rem;
    background: var(--egl-surface-2);
    overflow: hidden;
}

.egl-profile-coverfield__preview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.egl-profile-coverfield__empty {
    color: var(--egl-text-muted);
    font-size: .75rem;
}

/* Phase 92 - the sidebar row. Rose, the same tone User Management wears:
   these two are the app's people pages, one open to everybody and one the
   Admin's, and an unrelated colour would say they are unrelated. */
.egl-navicon-box--people { color: var(--egl-nav-rose); }


/* ─── Phase 104 - the Machine Type list, in two sections ──────────────
   Sewing and Support are two different questions - "what does K-32 need"
   and "how many presses does the floor need" - so they are two blocks of
   rows inside the one card rather than two cards: they are still one list,
   governed by one set of buttons, and two cards would say otherwise.

   Written with GRID, not with a stacking flex row. The dashboard gauge's
   phone block has to be the LAST rule of its kind in this file and
   DashboardGaugeTest holds that by text, so anything appended here uses
   grid-auto-flow instead - the same answer Phases 82, 92 and 101 reached.
   Layout only, both appearances get it for free. */
.egl-mreq-listsub {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
    margin: 1.375rem 0 .5rem;
}

/* The first section starts straight under the card's own heading, which has
   already left a gap of its own. */
.egl-mreq-listsub:first-of-type {
    margin-top: .25rem;
}

.egl-mreq-listsubtitle {
    font-size: .8125rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--egl-text);
}

.egl-mreq-listsubcount {
    font-size: .75rem;
    color: var(--egl-text-muted);
}

/* Two controls on a row now - "Move to Support" and "Hide" - where there
   was one. Side by side while there is room; on a phone the act column is
   already a narrow strip holding both rows of the grid, so they stack. */
.egl-mreq-listact {
    display: grid;
    grid-auto-flow: column;
    align-items: center;
    justify-content: end;
    gap: .375rem;
}

.egl-mreq-listact form {
    margin: 0;
}

@media (max-width: 640px) {
    .egl-mreq-listact {
        grid-auto-flow: row;
        justify-items: stretch;
    }

    /* The button sits inside its own form, so stretching the form is not
       enough - the button has to fill it, or "Hide" ends up half the width
       of "Move to Support" sitting right above it and the pair reads as two
       unrelated controls. */
    .egl-mreq-listact form {
        display: grid;
    }
}

/* ============================================================================
   PHASE 109A-2 - SETTINGS > FACTORY SETUP: THREE BOXES, NOT ONE.

   Aomith, 26 October 2026, after using the page 109A shipped:

     "amader factory te jei duita unit ache akhn ami jodi add floor dei tahole
      ki new unit/floor je create hobe seta other place in factory te dhukbe
      naki existing unit er sathe show korbe seta bujha jacce na ... tai tumi
      aktu sundor kore agula guciye daw ... existing factory er running unit
      block line er box alada kore akta colour koro 3d akta vibe niye aso"

   He is right and the fault was mine. 109A printed the three kinds of thing
   in three sections and then put all three "add" forms together at the BOTTOM
   of one card. So the control that creates a floor sat below a heading about
   sister factories, and nothing on screen said where the new row would land.

   THE FIX IS LAYOUT, NOT COLOUR. Every add form now lives INSIDE the box it
   adds to: "add a block" sits inside the floor it will stand on, "add a line"
   inside the block it will belong to, and the three families are three
   separate cards rather than three headings in one. A control that is
   physically inside the thing it changes cannot be ambiguous about it.

   Colour then tells the three apart at a glance, which is what he asked for:
     own    the factory's own floors - primary, and RAISED (his "3d vibe")
     group  machines borrowed from the group's sister factories - order/orange
     place  this factory's non-sewing places - ok/green

   EVERY SELECTOR HERE STARTS WITH .egl-fs- , which appears NOWHERE in the
   compiled Tailwind bundle, so none of these rules can repaint any frozen UI.
   ThemeOverlayWiringTest's allowlist is extended by one word for it.

   EVERY COLOUR IS A MEANING TOKEN declared for BOTH appearances, so one rule
   set is correct in light and in dark and nothing needs a theme scope - the
   same arrangement dash, msp and cu already use. He has asked more than once
   that a new module look right in light mood, and this is how that is kept a
   fact rather than a promise.

   NOTHING HERE STACKS WITH A FLEX COLUMN, and this sentence avoids writing
   that property out for the same reason the profile family's comment does:
   the dashboard gauge's phone fix has to remain the LAST such declaration in
   this file and the guard that protects it finds the last one by searching
   the text, so a mention in a comment breaks it exactly as a real rule would.
   Everything that stacks here uses grid, which stacks by default.
   ======================================================================== */

/* ─── the three cards ───────────────────────────────────────────────── */

.egl-fs-card {
    display: grid;
    gap: .75rem;
    margin-top: 1.25rem;
    padding: 1rem;
    border: 1px solid var(--egl-border);
    border-radius: 1rem;
    background: var(--egl-surface);
}

/* THE FACTORY'S OWN FLOOR. Raised off the page - a thicker left edge, a
   gradient that lifts the top, and the large shadow. This is the box somebody
   setting up a new factory spends their time in, and it should be obvious
   before anything is read that it is not the same kind of thing as the two
   below it. */
.egl-fs-card--own {
    border-color: var(--egl-primary-border);
    border-left: 4px solid var(--egl-primary);
    background: linear-gradient(180deg, var(--egl-primary-soft) 0, var(--egl-surface) 5.5rem);
    box-shadow: var(--egl-shadow-lg);
}

.egl-fs-card--group {
    border-color: var(--egl-order-border);
    border-left: 4px solid var(--egl-order);
    background: var(--egl-surface);
    box-shadow: var(--egl-shadow);
}

.egl-fs-card--place {
    border-color: var(--egl-ok-border);
    border-left: 4px solid var(--egl-ok);
    background: var(--egl-surface);
    box-shadow: var(--egl-shadow);
}

.egl-fs-card--warn {
    border-color: var(--egl-danger-border);
    border-left: 4px solid var(--egl-danger);
    background: var(--egl-danger-soft);
}

.egl-fs-head {
    display: grid;
    gap: .25rem;
}

.egl-fs-head__title {
    color: var(--egl-text);
    font-size: 1rem;
    font-weight: 700;
}

/* The same heading in Bengali, directly under the English one. His reason:
   "koyek month por o je kew easily bujhte pare ba ami easily mone korte pari
   and onno der ke bujhai dite pari". Both at once, not one or the other -
   this page is read by whoever is standing up the next factory, and that
   person may be reading either. */
.egl-fs-head__bn {
    color: var(--egl-text-2);
    font-size: .8125rem;
    font-weight: 600;
}

.egl-fs-card--own .egl-fs-head__title {
    color: var(--egl-primary);
}

.egl-fs-card--group .egl-fs-head__title {
    color: var(--egl-order);
}

.egl-fs-card--place .egl-fs-head__title {
    color: var(--egl-ok);
}

.egl-fs-card--warn .egl-fs-head__title {
    color: var(--egl-danger);
}

/* ─── the note that says what this box does ─────────────────────────── */

.egl-fs-note {
    display: grid;
    gap: .25rem;
    padding: .625rem .75rem;
    border: 1px dashed var(--egl-border-strong);
    border-radius: .625rem;
    background: var(--egl-surface-2);
}

.egl-fs-note__en {
    color: var(--egl-text-3);
    font-size: .75rem;
    line-height: 1.45;
}

.egl-fs-note__bn {
    color: var(--egl-text-2);
    font-size: .8125rem;
    line-height: 1.6;
}

/* ─── a floor, a block, a row ───────────────────────────────────────── */

.egl-fs-floor,
.egl-fs-block {
    display: grid;
    gap: 0;
    border: 1px solid var(--egl-border);
    border-radius: .75rem;
    background: var(--egl-surface);
    overflow: hidden;
}

.egl-fs-floor {
    border-color: var(--egl-primary-border);
    box-shadow: var(--egl-shadow);
}

.egl-fs-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    padding: .5rem .625rem;
    border-bottom: 1px solid var(--egl-border);
    background: var(--egl-surface-2);
}

.egl-fs-floor > .egl-fs-bar {
    background: var(--egl-primary-soft);
}

.egl-fs-body {
    display: grid;
    gap: .375rem;
    padding: .5rem .625rem;
}

.egl-fs-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    padding: .375rem .5rem;
    border: 1px solid var(--egl-border);
    border-radius: .5rem;
    background: var(--egl-surface-2);
}

.egl-fs-name {
    color: var(--egl-text);
    font-size: .8125rem;
    font-weight: 600;
    overflow-wrap: break-word;
}

.egl-fs-meta {
    flex: 1 1 8rem;
    min-width: 0;
    color: var(--egl-text-3);
    font-size: .6875rem;
    overflow-wrap: break-word;
}

.egl-fs-off {
    padding: 0 .375rem;
    border-radius: 999px;
    background: var(--egl-muted-soft);
    color: var(--egl-muted-tone);
    font-size: .625rem;
}

/* ─── Phase 110C — who answers for a block ──────────────────────────────
   READ-ONLY, so it is deliberately quieter than the controls above it: no
   border of its own, a flat surface tint, and the names at the same size as
   the other meta text. It must not look like something you can press.
   Every colour is an existing token, so it reads correctly in light mood as
   well as dark - Aomith has raised faded text more than once. */

.egl-fs-who {
    display: grid;
    gap: .25rem;
    margin-top: .25rem;
    padding: .375rem .5rem;
    border-radius: .5rem;
    background: var(--egl-surface-2);
}

.egl-fs-who__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .375rem;
    color: var(--egl-text-2);
    font-size: .6875rem;
    font-weight: 600;
}

.egl-fs-who__link {
    margin-left: auto;
    color: var(--egl-info);
    font-weight: 500;
    text-decoration: underline;
}

.egl-fs-who__row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .375rem;
    font-size: .6875rem;
}

.egl-fs-who__side {
    flex: none;
    min-width: 6.5rem;
    color: var(--egl-text-3);
    font-weight: 600;
}

.egl-fs-who__name {
    padding: 0 .375rem;
    border-radius: .375rem;
    background: var(--egl-surface-3);
    color: var(--egl-text);
}

.egl-fs-who__desg {
    color: var(--egl-text-3);
}

.egl-fs-who__status {
    margin-left: .25rem;
    padding: 0 .25rem;
    border-radius: 999px;
    background: var(--egl-warn-soft);
    color: var(--egl-text-2);
    font-size: .625rem;
}

.egl-fs-who__none {
    color: var(--egl-text-muted);
    font-size: .6875rem;
}

/* Phase 110B — a line whose operators never move. Deliberately NOT the grey
   of .egl-fs-off above: switched off and fixed are two different facts and
   two greys side by side would read as one. Both tokens are declared for
   light and for dark, so the pill keeps its contrast in either mood. */
.egl-fs-fixed {
    padding: 0 .375rem;
    border-radius: 999px;
    background: var(--egl-info-soft);
    color: var(--egl-info);
    font-size: .625rem;
    font-weight: 600;
}

.egl-fs-btns {
    display: flex;
    align-items: center;
    gap: .375rem;
    margin-left: auto;
}

.egl-fs-empty {
    color: var(--egl-text-muted);
    font-size: .75rem;
}

/* ─── the add strip, which always sits INSIDE what it adds to ───────── */

.egl-fs-add {
    display: grid;
    gap: .375rem;
    margin-top: .25rem;
    padding: .5rem .625rem;
    border: 1px solid var(--egl-border-strong);
    border-radius: .625rem;
    background: var(--egl-surface-3);
}

.egl-fs-add__en {
    color: var(--egl-text-2);
    font-size: .75rem;
    font-weight: 600;
}

.egl-fs-add__bn {
    color: var(--egl-text-3);
    font-size: .75rem;
    line-height: 1.55;
}

.egl-fs-add__ctl {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .375rem;
}

.egl-fs-add__ctl input,
.egl-fs-add__ctl select {
    flex: 1 1 10rem;
    min-width: 0;
    max-width: 18rem;
}

/* A control inside a row sits BESIDE its label, not under it. .egl-input is
   full-width by default, which on a row of "label - box - button" pushed the
   button onto a third line and made eight identical rename rows three times
   taller than they needed to be. */
.egl-fs-row input,
.egl-fs-row select {
    flex: 1 1 10rem;
    min-width: 0;
    max-width: 20rem;
}

.egl-fs-sum {
    color: var(--egl-text-3);
    font-size: .75rem;
    cursor: pointer;
}

@media (max-width: 640px) {
    .egl-fs-add__ctl {
        display: grid;
    }

    .egl-fs-add__ctl input,
    .egl-fs-add__ctl select {
        max-width: none;
    }

    .egl-fs-btns {
        margin-left: 0;
    }

    .egl-fs-row input,
    .egl-fs-row select {
        max-width: none;
    }
}

/* ═══ PHASE 110A-1 — THE BUYER AND ITEM BOXES ════════════════════════════
   Boxes 1, 2 and 3 are the SHAPE of the factory: blue, orange, green. These
   two are about what the factory MAKES and who for, so they are a fourth
   family at a glance - nobody should read "add a buyer" as "add a line".

   Violet, because it is the one hue genuinely apart from the other three.
   --egl-info was the obvious candidate and is unusable here: it is #2563eb,
   the SAME value as --egl-primary, so box 4 would have looked like box 1.
   --egl-warn is amber, too close to box 2's orange and carrying a "something
   is wrong" meaning this box does not have.

   The colour is defined as three properties scoped TO THIS CARD rather than
   as new global tokens. A global token is a promise to the whole app; this is
   one family of boxes on one page. Light first, dark overridden under
   html[data-theme='dark'] the way every other rule in this file does. Checked
   on screen in BOTH - his standing rule is that a new module has to look good
   in light mood, not only dark. */
.egl-fs-card--name {
    --egl-fs-name: #7c3aed;
    --egl-fs-name-soft: #f5f3ff;
    --egl-fs-name-border: #ddd6fe;

    border-color: var(--egl-fs-name-border);
    border-left: 4px solid var(--egl-fs-name);
    background: var(--egl-surface);
    box-shadow: var(--egl-shadow);
}

html[data-theme='dark'] .egl-fs-card--name {
    --egl-fs-name: #a78bfa;
    --egl-fs-name-soft: rgba(124, 58, 237, .16);
    --egl-fs-name-border: rgba(167, 139, 250, .35);
}

.egl-fs-card--name .egl-fs-head__title {
    color: var(--egl-fs-name);
}

/* The heading that separates "the shape of the factory" from "what it makes".
   Not a card - a label above the next two cards, so the page reads as two
   groups rather than five boxes in a row. */
.egl-fs-sec {
    display: grid;
    gap: .15rem;
    margin: 1.75rem 0 .75rem;
    padding-left: .75rem;
    border-left: 4px solid var(--egl-border-strong);
}

.egl-fs-sec__en {
    color: var(--egl-text);
    font-size: .9375rem;
    font-weight: 700;
    letter-spacing: .01em;
}

.egl-fs-sec__bn {
    color: var(--egl-text-2);
    font-size: .8125rem;
    font-weight: 600;
}

/* "Where it is used", table by table, inside the row's own <details>. */
.egl-fs-use {
    margin: .4rem 0 0;
    padding-left: 1.1rem;
    display: grid;
    gap: .15rem;
    color: var(--egl-text-2);
    font-size: .8125rem;
}

.egl-fs-use li {
    line-height: 1.55;
}

/* The row's "Where it is used" opener. Without this it inherits the row's own
   size and reads larger than the name it belongs to, which puts the emphasis
   on the wrong thing - seen on screen in both themes before it was fixed. */
.egl-fs-row > .egl-fs-body > summary {
    color: var(--egl-text-2);
    font-size: .6875rem;
    font-weight: 600;
    cursor: pointer;
}

.egl-fs-row > .egl-fs-body > summary:hover {
    color: var(--egl-text);
}
