/*
    Threads production UI presentation family
    -----------------------------------------
    This stylesheet preserves the complete visual vocabulary reviewed in the
    local /up interface. It deliberately includes controls that Threads does
    not use yet, so future business pages inherit the same established look
    instead of inventing page-specific substitutes.

    The file is presentation-only. It does not copy /up business rules, API
    requests, database assumptions, or page-specific data behaviour.
*/

/* Package Ubuntu locally so this presentation family never depends on a
   network font request and remains portable between both development Macs. */
@font-face {
    font-family: Ubuntu;
    src: url("assets/fonts/Ubuntu-Regular.ttf") format("truetype");
    font-style: normal;
    font-weight: 400;
    font-display: swap;
}

/* --------------------------------------------------------------------------
   Reusable production additions adopted during the Threads consolidation
   -------------------------------------------------------------------------- */

/* Keep a live result count aligned with the native search control. */
.management-count {
    margin-left: auto;
    padding-bottom: 11px;
    color: var(--muted);
    font-size: 12px;
    white-space: nowrap;
}

/* Present a role picture and its authoritative text as one compact identity. */
.role-identity {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

/* Give either approved artwork or a text fallback the same dependable frame. */
.role-identity img,
.role-identity__fallback {
    width: 36px;
    height: 36px;
    flex: 0 0 36px;
    border: 1px solid rgb(255 255 255 / 12%);
    border-radius: 9px;
    background: rgb(var(--accent-rgb) / 12%);
    object-fit: contain;
}

/* Centre the initial shown when a role has no approved local picture. */
.role-identity__fallback {
    display: inline-grid;
    place-items: center;
    color: var(--accent-hover);
    font-weight: 700;
}

/* Express short record state without introducing another button treatment. */
.status-tag {
    display: inline-flex;
    align-items: center;
    min-height: 26px;
    padding: 4px 10px;
    border: 1px solid rgb(255 255 255 / 8%);
    border-radius: 999px;
    background: rgb(255 255 255 / 6%);
    color: var(--muted);
    font-size: 11px;
    font-weight: 700;
    white-space: nowrap;
}

/* Draw attention to a required next step while keeping the chip restrained. */
.status-tag--warning {
    border-color: rgb(var(--accent-rgb) / 28%);
    background: rgb(var(--accent-rgb) / 13%);
    color: var(--accent-hover);
}

/* Keep server-side validation messages inside the native authentication family. */
.auth-message {
    display: grid;
    gap: 3px;
    margin: 0 0 20px;
    padding: 12px 14px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: rgb(15 17 21 / 58%);
    color: var(--muted);
    font-size: 13px;
    line-height: 1.45;
}

.auth-message strong {
    color: var(--ink);
}

.auth-message--success { border-color: rgb(90 173 112 / 40%); }
.auth-message--danger { border-color: rgb(195 55 80 / 48%); }
.auth-message--info { border-color: rgb(var(--accent-rgb) / 38%); }

@media (max-width: 620px) {
    .management-count {
        width: 100%;
        margin-left: 0;
        padding-bottom: 0;
        text-align: right;
    }
}

@font-face {
    font-family: Ubuntu;
    src: url("assets/fonts/Ubuntu-Bold.ttf") format("truetype");
    font-style: normal;
    font-weight: 700;
    font-display: swap;
}

/*
    :root represents the whole document.
    We keep our reusable Threads colours here so they have one home.
*/
:root {
    /* Tell built-in browser controls that this is a dark interface. */
    color-scheme: dark;

    /* Always reserve the vertical scrollbar lane so page width never jumps. */
    overflow-y: scroll;

    /* Preserve the same scrollbar space even when the browser visually hides its thumb. */
    scrollbar-gutter: stable;

    /* Use Ubuntu first, followed by safe alternatives if it is unavailable. */
    font-family: Ubuntu, "Ubuntu Sans", Inter, system-ui, sans-serif;

    /* Our first small collection of Threads design colours. */
    --canvas: #191b20;
    --ink: #f2f4f7;
    --muted: #a6adb8;
    --line: #373c45;
    --line-strong: #4a505c;
    --surface-hover: #333842;
    --accent: #8c1d30;
    --accent-hover: #a52740;
    --accent-readable: #f2788e;
    --accent-soft: #43242b;
    --accent-focus: rgb(242 120 142 / 32%);
    --accent-ink: #ffffff;
    --accent-glow: rgb(140 29 48 / 14%);
    --accent-shadow: rgb(72 15 26 / 40%);
    --accent-rgb: 140 29 48;
    --accent-readable-rgb: 242 120 142;

    /* Use Burgundy's approved Threads artwork as the safe default emblem. */
    --threads-emblem-image: url("assets/glyphs/threads-emblem-burgundy.png");
    --info: #72a9e8;
    --success: #66c48c;
    --warning: #d8b35b;
    --error: #ef7184;
    /* Layer a quiet theme reflection behind the navigation's ordinary black depth. */
    --shadow-navigation: 0 14px 40px rgb(0 0 0 / 28%), 0 0 46px rgb(var(--accent-rgb) / 6%);

    /* Let management glass pick up slightly more ambient theme colour than the navigation. */
    --shadow-management: 0 24px 70px rgb(0 0 0 / 42%), 0 0 58px rgb(var(--accent-rgb) / 8%);

    /* Keep small floating surfaces crisp with the lightest theme-coloured reflection. */
    --shadow-menu: 0 4px 14px 3px rgb(0 0 0 / 50%), 0 1px 3px rgb(0 0 0 / 68%), 0 0 24px rgb(var(--accent-rgb) / 5%);
}

/* Apply the original creative purple Threads accent as one coordinated family. */
:root[data-accent="purple"] {
    /* Keep the shared navigation artwork synchronized with this palette. */
    --threads-emblem-image: url("assets/glyphs/threads-emblem-purple.png");
    --accent: #58388a;
    --accent-hover: #69469e;
    --accent-readable: #bda4e6;
    --accent-soft: #30283e;
    --accent-focus: rgb(189 164 230 / 30%);
    --accent-ink: #ffffff;
    --accent-glow: rgb(88 56 138 / 15%);
    --accent-shadow: rgb(38 24 61 / 46%);
    --accent-rgb: 88 56 138;
    --accent-readable-rgb: 189 164 230;
}

/* Apply the original calm green Threads accent as one coordinated family. */
:root[data-accent="green"] {
    /* Keep the shared navigation artwork synchronized with this palette. */
    --threads-emblem-image: url("assets/glyphs/threads-emblem-green.png");
    --accent: #405936;
    --accent-hover: #506b45;
    --accent-readable: #99bb8a;
    --accent-soft: #2a3327;
    --accent-focus: rgb(153 187 138 / 28%);
    --accent-ink: #ffffff;
    --accent-glow: rgb(64 89 54 / 15%);
    --accent-shadow: rgb(25 36 21 / 48%);
    --accent-rgb: 64 89 54;
    --accent-readable-rgb: 153 187 138;
}

/* Apply the original energetic orange Threads accent as one coordinated family. */
:root[data-accent="orange"] {
    /* Keep the shared navigation artwork synchronized with this palette. */
    --threads-emblem-image: url("assets/glyphs/threads-emblem-orange.png");
    --accent: #a94f0b;
    --accent-hover: #c35d0e;
    --accent-readable: #f3a15e;
    --accent-soft: #472f20;
    --accent-focus: rgb(243 161 94 / 30%);
    --accent-ink: #ffffff;
    --accent-glow: rgb(169 79 11 / 15%);
    --accent-shadow: rgb(82 38 6 / 44%);
    --accent-rgb: 169 79 11;
    --accent-readable-rgb: 243 161 94;
}

/* Apply the original clear blue Threads accent as one coordinated family. */
:root[data-accent="blue"] {
    /* Keep the shared navigation artwork synchronized with this palette. */
    --threads-emblem-image: url("assets/glyphs/threads-emblem-blue.png");
    --accent: #166ee1;
    --accent-hover: #2d7ff9;
    --accent-readable: #84b8ff;
    --accent-soft: #203752;
    --accent-focus: rgb(45 127 249 / 32%);
    --accent-ink: #ffffff;
    --accent-glow: rgb(22 110 225 / 16%);
    --accent-shadow: rgb(8 47 98 / 46%);
    --accent-rgb: 22 110 225;
    --accent-readable-rgb: 132 184 255;
}

/* Apply the original optimistic yellow Threads accent with dark readable action text. */
:root[data-accent="yellow"] {
    /* Keep the shared navigation artwork synchronized with this palette. */
    --threads-emblem-image: url("assets/glyphs/threads-emblem-yellow.png");
    --accent: #d9c75a;
    --accent-hover: #e6d56a;
    --accent-readable: #ebdc88;
    --accent-soft: #45412b;
    --accent-focus: rgb(235 220 136 / 32%);
    --accent-ink: #211c08;
    --accent-glow: rgb(217 199 90 / 15%);
    --accent-shadow: rgb(72 65 24 / 42%);
    --accent-rgb: 217 199 90;
    --accent-readable-rgb: 235 220 136;
}

/*
    Make width and height calculations easier for every HTML element.
    Padding will now stay inside an element's declared size.
*/
* {
    box-sizing: border-box;
}

/* The body represents everything visible inside the browser page. */
body {
    /* Remove the small outer gap that browsers add automatically. */
    margin: 0;

    /* Make the background cover the full height of the browser window. */
    min-height: 100vh;

    /* Add comfortable space between the content and the window edges. */
    padding: 32px;

    /*
        CSS reads multiple backgrounds from top to bottom:
        1. A dark transparent layer that keeps text readable.
        2. Threads's real repeating linen texture.
        3. The solid canvas colour as our final fallback.
    */
    background:
        linear-gradient(rgb(11 13 16 / 42%), rgb(11 13 16 / 42%)),
        url("assets/threads-dark-linen-web.jpg") 0 0 / 620px 620px repeat,
        var(--canvas);

    /* Use Threads's light text colour against the dark background. */
    color: var(--ink);

    /* Fade the complete Threads canvas in as one cohesive page-load movement.
       Release the finished animation layer so later menu repaints stay clean. */
    animation: threads-page-canvas-enter 720ms ease-out;
}

/* Let the shared navigation settle gently from above during a full page load. */
body > .site-header {
    /* Coordinate the navigation with the complete canvas entrance, then release
       its transform layer instead of retaining an identity transform forever. */
    animation: threads-page-header-enter 720ms ease-out;
}

/* Let the unique content settle gently from below during a full page load. */
body > main {
    /* Coordinate the page content with the canvas and navigation entrances,
       then release its transform layer so glass cards do not halo on menu open. */
    animation: threads-page-content-enter 720ms ease-out;
}

/* Fade the complete page away briefly before an ordinary Threads navigation. */
body.is-page-leaving {
    /* Prevent a second interaction while the selected destination is opening. */
    pointer-events: none;

    /* Use a shorter departure so navigation remains responsive rather than sluggish. */
    animation: threads-page-canvas-leave 360ms ease-in both;
}

/* Lift the shared navigation slightly as the current document departs. */
body.is-page-leaving > .site-header {
    /* Pair this restrained movement with the navigation's longer arrival. */
    animation: threads-page-header-leave 360ms ease-in both;
}

/* Lower the principal content slightly as the current document departs. */
body.is-page-leaving > main {
    /* Reverse the content's arrival direction without making navigation feel heavy. */
    animation: threads-page-content-leave 360ms ease-in both;
}

/* Fade the complete linen canvas into view without moving fixed-position layers. */
@keyframes threads-page-canvas-enter {
    /* Begin fully transparent so partially styled content never flashes first. */
    from {
        opacity: 0;
    }

    /* Finish at the ordinary fully readable page state. */
    to {
        opacity: 1;
    }
}

/* Lower the navigation gently into its ordinary page position. */
@keyframes threads-page-header-enter {
    /* Begin slightly above and subtly compressed. */
    from {
        transform: translateY(-10px) scale(0.995);
    }

    /* Finish at the navigation's natural position and scale. */
    to {
        transform: translateY(0) scale(1);
    }
}

/* Raise the principal page content gently into its ordinary position. */
@keyframes threads-page-content-enter {
    /* Begin slightly below and subtly compressed. */
    from {
        transform: translateY(14px) scale(0.995);
    }

    /* Finish at the content's natural position and scale. */
    to {
        transform: translateY(0) scale(1);
    }
}

/* Fade the current linen canvas away before the next document replaces it. */
@keyframes threads-page-canvas-leave {
    /* Preserve the complete visible page at the first departure frame. */
    from {
        opacity: 1;
    }

    /* Finish transparent so the next page can arrive cleanly. */
    to {
        opacity: 0;
    }
}

/* Return the navigation gently toward the direction from which it arrived. */
@keyframes threads-page-header-leave {
    /* Begin at the navigation's natural resting position. */
    from {
        transform: translateY(0) scale(1);
    }

    /* Finish slightly raised and subtly compressed. */
    to {
        transform: translateY(-8px) scale(0.997);
    }
}

/* Return the principal content gently toward the direction from which it arrived. */
@keyframes threads-page-content-leave {
    /* Begin at the content's natural resting position. */
    from {
        transform: translateY(0) scale(1);
    }

    /* Finish slightly lowered and subtly compressed. */
    to {
        transform: translateY(10px) scale(0.997);
    }
}

/* Reveal newly loaded structural content only inside its expanding boundary. */
.is-layout-height-expanding {
    /* Prevent rows or controls from appearing beyond the still-moving card edge. */
    overflow: hidden;
}

/* Respect visitors who request little or no interface motion. */
@media (prefers-reduced-motion: reduce) {
    /* Present complete page structure immediately without fading or movement. */
    body,
    body > .site-header,
    body > main,
    body.is-page-leaving,
    body.is-page-leaving > .site-header,
    body.is-page-leaving > main {
        animation: none;
    }
}

/* Keep the complete site header fixed to the visible top edge while the page scrolls. */
.site-header {
    /* Let the header follow the viewport after the page scroll reaches it. */
    position: sticky;

    /* Hold the sticky header against the very top of the browser window. */
    top: 0;

    /* Keep every navigation submenu above glass cards that create their own layers. */
    z-index: 40;

    /* Recover the 32-pixel body gutters so the menu can span the complete window. */
    width: calc(100% + 64px);

    /* Pull the shared header into both body gutters and up to the window's top edge. */
    margin: -32px -32px 0;
}

/* Present the main navigation as a restrained Threads glass surface. */
.main-navigation {
    /* Arrange the brand, menu, and account controls in one flexible row. */
    display: flex;

    /* Keep every navigation group vertically aligned. */
    align-items: center;

    /* Preserve space between neighbouring navigation groups. */
    gap: 20px;

    /* Allow groups to move to another row instead of overflowing. */
    flex-wrap: wrap;

    /* Align the full-width menu contents with the page's ordinary 32-pixel gutter. */
    padding: 12px 32px;

    /* Draw the faint highlighted edge used by Threads glass panels. */
    border: 1px solid rgb(255 255 255 / 12%);

    /* Keep friendly lower corners while the upper edge meets the browser window. */
    border-radius: 0 0 14px 14px;

    /* Keep scrolling page text quiet beneath the sticky bar while preserving dark glass depth. */
    background: rgb(18 20 24 / 96%);

    /* Lift the navigation slightly above the linen canvas. */
    box-shadow: var(--shadow-navigation);

    /* Soften the linen that remains visible through supporting browsers. */
    backdrop-filter: blur(16px) saturate(120%);

    /* Apply the same glass effect in Safari. */
    -webkit-backdrop-filter: blur(16px) saturate(120%);
}

/* Keep the Threads mark and name together as one home link. */
.navigation-brand {
    /* Place the compact mark and brand name beside one another. */
    display: inline-flex;

    /* Vertically centre the brand name against its mark. */
    align-items: center;

    /* Separate the mark from the Threads name. */
    gap: 9px;

    /* Use the main text colour for the application identity. */
    color: var(--ink);

    /* Remove the ordinary underline from the brand link. */
    text-decoration: none;

    /* Give the application name a confident visual weight. */
    font-weight: 700;
}

/* Give the compact Threads mark a predictable navigation size. */
.navigation-brand__logo {
    /* Display the emblem selected by the current trusted accent palette. */
    display: block;

    /* Set the visible width of the brand mark. */
    width: 34px;

    /* Match the height to the width so the mark remains square. */
    height: 34px;

    /* Prevent the flex layout from compressing the recognisable emblem. */
    flex: 0 0 34px;

    /* Paint the transparent theme-specific artwork without distorting it. */
    background: var(--threads-emblem-image) center / contain no-repeat;
}

/* Arrange the principal garment-production destinations as a clean list. */
.navigation-menu {
    /* Place the menu destinations beside one another. */
    display: flex;

    /* Allow menu choices to wrap cleanly on narrower screens. */
    flex-wrap: wrap;

    /* Add a small consistent gap between destinations. */
    gap: 4px;

    /* Remove the browser's default list indentation. */
    padding: 0;

    /* Remove the browser's default outer list spacing. */
    margin: 0;

    /* Remove the ordinary bullet from each menu item. */
    list-style: none;
}

/* Give every navigation destination the same compact shape. */
.navigation-link {
    /* Let padding and alignment behave consistently for links and placeholders. */
    display: inline-flex;

    /* Vertically centre each menu label. */
    align-items: center;

    /* Give every destination a comfortable compact click area. */
    min-height: 36px;

    /* Add horizontal breathing room around each destination label. */
    padding: 7px 10px;

    /* Round each destination like an Threads control. */
    border-radius: 7px;

    /* Use the quieter colour until a destination becomes active. */
    color: var(--muted);

    /* Remove the standard underline from navigation links. */
    text-decoration: none;

    /* Increase the principal menu labels by one point for easier reading. */
    font-size: 15px;
}

/* Identify the page that is currently open. */
.navigation-link.is-current {
    /* Create a positioning reference for the glowing light beneath the label. */
    position: relative;

    /* Brighten the active destination label. */
    color: var(--ink);
}

/* Draw the same soft status light beneath current main-menu and submenu links. */
.navigation-link.is-current::after,
.navigation-submenu__link.is-current .navigation-submenu__label::after {
    /* Create an empty decorative element that CSS can shape into a light. */
    content: "";

    /* Position the light independently beneath the current link's label. */
    position: absolute;

    /* Centre the light inside the element that owns the current-page label. */
    left: 50%;

    /* Hold the main-menu light close to its control's lower edge. */
    bottom: 2px;

    /* Give the light a short understated width. */
    width: 28px;

    /* Keep the light thin so it resembles a small status lamp. */
    height: 2px;

    /* Turn the thin rectangle into a softly rounded light. */
    border-radius: 999px;

    /* Use Threads's brighter burgundy red at the centre of the light. */
    background: var(--accent-hover);

    /* Spread the red colour outward to create the soft illuminated halo. */
    box-shadow: 0 0 7px rgb(var(--accent-rgb) / 90%), 0 0 16px rgb(var(--accent-rgb) / 65%);

    /* Keep the decorative light from intercepting mouse or touch interaction. */
    pointer-events: none;

    /* Make the light breathe gently without distracting from the page content. */
    animation: navigation-current-glow 2.8s ease-in-out infinite;
}

/* Define the slow brightening and dimming motion for the current-page light. */
@keyframes navigation-current-glow {
    /* Begin and finish with a quiet, slightly narrower glow. */
    0%,
    100% {
        /* Keep the light visible while it is in its dim state. */
        opacity: 0.45;

        /* Centre and gently compress the dim light. */
        transform: translateX(-50%) scaleX(0.72);
    }

    /* Reach a soft full glow halfway through each animation cycle. */
    50% {
        /* Brighten the light without making it completely harsh. */
        opacity: 0.95;

        /* Return the glowing light to its full intended width. */
        transform: translateX(-50%) scaleX(1);
    }
}

/* Identify a parent menu that contains the currently open page. */
.navigation-link.has-current-child {
    /* Create a positioning reference for the smaller parent glow. */
    position: relative;

    /* Brighten the parent label while one of its child pages is current. */
    color: var(--ink);
}

/* Draw a quieter red light beneath the parent of the current page. */
.navigation-link.has-current-child::before {
    /* Create an empty decorative element that CSS can shape into a light. */
    content: "";

    /* Position the parent light independently beneath its menu label. */
    position: absolute;

    /* Centre the parent light horizontally inside the menu control. */
    left: 50%;

    /* Hold the parent light close to the control's lower edge. */
    bottom: 2px;

    /* Keep the parent light shorter than the actual current-page light. */
    width: 20px;

    /* Match the thin lamp-like shape of the stronger child light. */
    height: 2px;

    /* Round the parent light into a soft narrow capsule. */
    border-radius: 999px;

    /* Use Threads's deeper burgundy for the quieter parent state. */
    background: var(--accent);

    /* Create a smaller, softer halo than the actual current-page glow. */
    box-shadow: 0 0 6px rgb(var(--accent-rgb) / 65%), 0 0 12px rgb(var(--accent-rgb) / 38%);

    /* Prevent the decorative parent light from intercepting interaction. */
    pointer-events: none;

    /* Let the parent light breathe gently in step with the current-page light. */
    animation: navigation-parent-glow 2.8s ease-in-out infinite;
}

/* Define the restrained breathing motion for a current page's parent menu. */
@keyframes navigation-parent-glow {
    /* Begin and finish with a faint, slightly narrower parent light. */
    0%,
    100% {
        /* Keep the parent indicator quieter in its dim state. */
        opacity: 0.25;

        /* Centre and gently compress the dim parent light. */
        transform: translateX(-50%) scaleX(0.72);
    }

    /* Reach the parent indicator's restrained peak halfway through the cycle. */
    50% {
        /* Brighten the parent without competing with the actual current page. */
        opacity: 0.62;

        /* Return the parent light to its full intended width. */
        transform: translateX(-50%) scaleX(1);
    }
}

/* Explain visually that planned destinations are not clickable yet. */
.navigation-link.is-disabled {
    /* Reduce emphasis while keeping the future structure understandable. */
    opacity: 0.52;

    /* Show that the unfinished destination cannot be selected. */
    cursor: not-allowed;
}

/* Anchor the administrator submenu panel to its own menu control. */
.navigation-submenu {
    /* Give the absolutely positioned panel a local positioning reference. */
    position: relative;
}

/* Make the native submenu summary match the other navigation choices. */
.navigation-submenu > summary {
    /* Remove the browser's ordinary disclosure-marker spacing. */
    list-style: none;

    /* Show that the administrator label opens an interactive menu. */
    cursor: pointer;
}

/* Remove Safari and Chromium's native disclosure triangle. */
.navigation-submenu > summary::-webkit-details-marker {
    /* Hide the native marker because we provide a styled indicator below. */
    display: none;
}

/* Add a compact dropdown indicator after the administrator label. */
.navigation-submenu > summary::after {
    /* Display a downward triangle that communicates expandable content. */
    content: "▾";

    /* Separate the triangle from the administrator label. */
    margin-left: 6px;

    /* Keep the indicator quieter than the menu text. */
    font-size: 10px;

    /* Animate the indicator smoothly when the menu opens. */
    transition: transform 130ms ease;
}

/* Rotate the indicator while the administrator submenu is open. */
.navigation-submenu[open] > summary::after {
    /* Turn the downward triangle upward to indicate the open state. */
    transform: rotate(180deg);
}

/* Highlight the administrator control while its submenu is open. */
.navigation-submenu[open] > summary {
    /* Place the open menu control on Threads's raised surface. */
    background: var(--surface-hover);

    /* Brighten the open menu label. */
    color: var(--ink);
}

/* Present administrator destinations inside a compact floating panel. */
.navigation-submenu__panel {
    /* Position the panel independently beneath the administrator control. */
    position: absolute;

    /* Keep the floating panel above the page content. */
    z-index: 20;

    /* Place the panel just beneath its summary control. */
    top: calc(100% + 6px);

    /* Align the left edge of the panel with the administrator control. */
    left: 0;

    /* Give short submenu labels a comfortable consistent width. */
    min-width: 160px;

    /* Add compact breathing room inside the floating menu. */
    padding: 6px;

    /* Remove the browser's ordinary outer list spacing. */
    margin: 0;

    /* Remove bullets from the nested administrator list. */
    list-style: none;

    /* Draw Threads's stronger floating-surface boundary. */
    border: 1px solid var(--line-strong);

    /* Give the floating panel compact rounded corners. */
    border-radius: 8px;

    /* Place the submenu on Threads's raised dark surface. */
    background: #292d35;

    /* Lift the submenu clearly above the linen background. */
    box-shadow: var(--shadow-menu);

    /* Let opening and closing motion grow naturally from the menu control. */
    transform-origin: top left;
}

/* Animate an opened submenu or nested submenu into view. */
.navigation-submenu[open]:not(.is-closing) > .navigation-submenu__panel {
    /* Play the short reusable opening motion once the native menu is open. */
    animation: navigation-submenu-open 160ms ease-out both;
}

/* Animate a submenu away before JavaScript removes its native open state. */
.navigation-submenu.is-closing > .navigation-submenu__panel {
    /* Play the reusable closing motion and retain its final hidden frame. */
    animation: navigation-submenu-close 150ms ease-in both;
}

/* Place a future sub-submenu beside its parent panel instead of over it. */
.navigation-submenu__panel .navigation-submenu__panel {
    /* Align the nested panel with the top of its own control. */
    top: 0;

    /* Place the nested panel just beyond the right edge of its parent menu. */
    left: calc(100% + 6px);
}

/* Style one clickable destination inside the administrator submenu. */
.navigation-submenu__link {
    /* Let the link fill the complete width of the submenu panel. */
    display: block;

    /* Add a comfortable compact click target around the link label. */
    padding: 9px 10px;

    /* Round the hover surface inside the outer floating panel. */
    border-radius: 6px;

    /* Use the main Threads text colour for available destinations. */
    color: var(--ink);

    /* Remove the browser's ordinary link underline. */
    text-decoration: none;

    /* Increase submenu labels by the same single point as the principal menu. */
    font-size: 14px;
}

/* Give each submenu's visible text its own compact positioning box. */
.navigation-submenu__label {
    /* Keep the positioning box only as wide as the visible submenu text. */
    display: inline-block;

    /* Let the current-page glow position itself relative to this text width. */
    position: relative;
}

/* Give pointer and keyboard users clear submenu-link feedback. */
.navigation-submenu__link:hover,
.navigation-submenu__link:focus-visible,
.navigation-submenu__link.is-current {
    /* Remove the browser's inconsistent default focus outline. */
    outline: 0;

    /* Keep hover and keyboard focus on Threads's raised surface. */
    background: var(--surface-hover);
}

/* Let the glowing light replace the solid current-page submenu background. */
.navigation-submenu__link.is-current {
    /* Remove the raised block so the animated light becomes the active signal. */
    background: transparent;
}

/* Place a submenu's current-page glow immediately beneath its visible text. */
.navigation-submenu__link.is-current .navigation-submenu__label::after {
    /* Move the light below the letters instead of beneath the full-width row. */
    bottom: -5px;
}

/* Define the gentle motion used when any navigation submenu appears. */
@keyframes navigation-submenu-open {
    /* Begin slightly raised, compressed, and transparent. */
    from {
        /* Hide the panel at the first animation frame. */
        opacity: 0;

        /* Lift and slightly compress the panel before it settles. */
        transform: translateY(-6px) scale(0.98);
    }

    /* Finish at the panel's ordinary visible position and size. */
    to {
        /* Reveal the panel completely. */
        opacity: 1;

        /* Return the panel to its natural position and size. */
        transform: translateY(0) scale(1);
    }
}

/* Define the gentle motion used before any navigation submenu closes. */
@keyframes navigation-submenu-close {
    /* Finish slightly raised, compressed, and transparent. */
    to {
        /* Hide the panel at the final animation frame. */
        opacity: 0;

        /* Lift and slightly compress the panel as it disappears. */
        transform: translateY(-6px) scale(0.98);
    }
}

/* Respect people who ask their operating system to reduce interface motion. */
@media (prefers-reduced-motion: reduce) {
    /* Remove submenu panel animation while preserving open and closed behaviour. */
    .navigation-submenu > .navigation-submenu__panel {
        /* Display submenu state changes without movement. */
        animation-duration: 1ms;
    }

    /* Keep the current-page light steady for people who prefer reduced motion. */
    .navigation-link.is-current::after,
    .navigation-submenu__link.is-current .navigation-submenu__label::after,
    .navigation-link.has-current-child::before {
        /* Stop the repeating glow while preserving the current-page indicator. */
        animation: none;

        /* Keep the non-moving light gently visible. */
        opacity: 0.7;

        /* Centre the stationary light at its ordinary full width. */
        transform: translateX(-50%) scaleX(1);
    }
}

/* Keep the signed-in identity and logout action together. */
.navigation-account {
    /* Push the account controls toward the far edge of the navigation bar. */
    margin-left: auto;

    /* Place the username and logout action beside one another. */
    display: flex;

    /* Vertically align the username with the logout button. */
    align-items: center;

    /* Separate the account identity from the logout action. */
    gap: 12px;
}

/* Turn the complete signed-in identity into the quiet My Preferences destination. */
.navigation-account-preferences {
    /* Keep optional role artwork beside the two-line account identity. */
    display: inline-flex;

    /* Vertically centre artwork against the username and role lines. */
    align-items: center;

    /* Separate configured artwork from the account copy. */
    gap: 9px;

    /* Preserve the surrounding navigation colours rather than using link blue. */
    color: inherit;

    /* Remove the browser's ordinary link underline. */
    text-decoration: none;

    /* Give the account destination a compact comfortable interaction surface. */
    padding: 5px 7px;

    /* Match the restrained rounding used throughout Threads controls. */
    border-radius: 8px;

    /* Animate the personal destination without moving neighbouring controls. */
    transition: background-color 130ms ease, box-shadow 130ms ease;
}

/* Highlight the personal destination during pointer and keyboard interaction. */
.navigation-account-preferences:hover,
.navigation-account-preferences:focus-visible,
.navigation-account-preferences[aria-current="page"] {
    /* Remove the browser's inconsistent default focus outline. */
    outline: 0;

    /* Add a restrained tint from the user's selected accent. */
    background: rgb(var(--accent-rgb) / 18%);

    /* Draw the shared accessible accent focus treatment. */
    box-shadow: 0 0 0 2px var(--accent-focus);
}

/* Display configured role artwork as a compact menu portrait. */
.navigation-role-picture {
    /* Give every supplied role picture one consistent width. */
    width: 32px;

    /* Match the height to produce a square picture frame. */
    height: 32px;

    /* Prevent the flexible navigation bar from shrinking the picture. */
    flex: 0 0 32px;

    /* Turn square artwork into a friendly circular menu portrait. */
    border-radius: 50%;

    /* Crop varying source proportions without stretching the artwork. */
    object-fit: cover;

    /* Add a quiet edge that works across every accent selection. */
    border: 1px solid rgb(255 255 255 / 18%);

    /* Give the role picture a restrained accent halo. */
    box-shadow: 0 0 0 2px rgb(var(--accent-rgb) / 20%);
}

/* Stack the authenticated username above its smaller role label. */
.navigation-user-identity {
    /* Place the username row and role label on separate lines. */
    display: inline-flex;

    /* Arrange the two identity lines vertically. */
    flex-direction: column;

    /* Align the role label with the username rather than the green light. */
    align-items: flex-start;

    /* Keep the two related lines visually close together. */
    gap: 2px;
}

/* Keep the active-session light beside the authenticated account name. */
.navigation-user-status {
    /* Keep the green session light and username on the same line. */
    display: inline-flex;

    /* Vertically centre the small light against the username. */
    align-items: center;

    /* Leave a compact gap between the light and username. */
    gap: 7px;
}

/* Draw the green traffic light that represents an active login session. */
.navigation-status-light {
    /* Give the light a compact traffic-signal width. */
    width: 9px;

    /* Match the height to the width so the light remains circular. */
    height: 9px;

    /* Prevent the flexible navigation row from shrinking the light. */
    flex: 0 0 9px;

    /* Turn the small status element into a circle. */
    border-radius: 50%;

    /* Fill the active-session light with Threads green. */
    background: var(--success);

    /* Add a soft ring and glow so the green light feels illuminated. */
    box-shadow: 0 0 0 3px rgb(102 196 140 / 16%), 0 0 10px rgb(102 196 140 / 72%);
}

/* Style the compact account identity in the navigation bar. */
.navigation-username {
    /* Use the secondary text colour so the menu remains dominant. */
    color: var(--muted);

    /* Keep the account label compact. */
    font-size: 13px;
}

/* Style the assigned role directly beneath the authenticated username. */
.navigation-role {
    /* Align the role text beneath the username after the green light and gap. */
    margin-left: 16px;

    /* Use Threads green to connect the role with the active-session indicator. */
    color: var(--success);

    /* Keep the supporting role label smaller than the username. */
    font-size: 10px;

    /* Add slight letter spacing so the compact label remains readable. */
    letter-spacing: 0.04em;
}

/* Keep the homepage comfortably narrow on large screens. */
.homepage {
    width: min(100%, 760px);
    margin: 7vh auto 0;
}

/* Centre the administrator feature foundation within the browser window. */
.management-page {
    /* Let each management surface size itself from its real heading, controls
       and table instead of imposing one width on every business dataset. */
    width: fit-content;

    /* Never let intrinsic content make the complete page wider than its
       available canvas; narrow screens retain the table scroller below. */
    max-width: 100%;

    /* Permit the outer surface to shrink below a table's intrinsic width; the
       shared table boundary owns any necessary horizontal scrolling. */
    min-width: 0;

    /* Centre the feature and separate it comfortably from the shared navigation. */
    margin: 7vh auto 0;
}

/* Adopt the approved workhorse width only on pages standardized one by one. */
.management-page--standard-table {
    width: 100%;
    min-width: min(840px, 100%);
    max-width: min(1600px, 100%);
}

/* Present the administrator-only feature on an Threads glass surface. */
.management-card {
    /* Include padding and border in every intrinsic width calculation so the
       table cannot unknowingly receive less space than the card advertises. */
    box-sizing: border-box;

    /* Fill the dynamically sized page rather than establishing a second,
       competing width boundary. */
    width: 100%;

    /* Respect the page's viewport cap even when a dataset has many columns. */
    max-width: 100%;

    /* Allow every table card to shrink inside the application canvas instead
       of inheriting the table's combined intrinsic column width. */
    min-width: 0;

    /* Add generous breathing room around the protected feature content. */
    padding: clamp(28px, 6vw, 48px);

    /* Draw a faint highlighted edge around the glass card. */
    border: 1px solid rgb(255 255 255 / 12%);

    /* Give the protected feature the same friendly Threads corners. */
    border-radius: 18px;

    /* Let the linen remain visible beneath a restrained dark tint. */
    background: rgb(25 27 32 / 38%);

    /* Lift the protected feature above the linen canvas. */
    box-shadow: var(--shadow-management);

    /* Soften the linen visible through supporting browsers. */
    backdrop-filter: blur(20px) saturate(125%);

    /* Apply the same glass effect in Safari. */
    -webkit-backdrop-filter: blur(20px) saturate(125%);
}

/* Label the protected administrative area above its main heading. */
.management-eyebrow {
    /* Remove the browser's ordinary paragraph spacing. */
    margin: 0 0 8px;

    /* Use Threads green to identify successful administrator access. */
    color: var(--success);

    /* Keep the administrative label compact. */
    font-size: 12px;

    /* Give the small label a confident visual weight. */
    font-weight: 700;

    /* Separate the compact letters slightly for readability. */
    letter-spacing: 0.08em;

    /* Present the protected-area label consistently in uppercase. */
    text-transform: uppercase;
}

/* Style the main user-management heading. */
.management-card h1 {
    /* Remove default side spacing while preserving a small lower gap. */
    margin: 0 0 12px;

    /* Let the heading respond smoothly to the available screen width. */
    font-size: clamp(30px, 6vw, 46px);
}

/* Style the explanatory text inside the protected feature card. */
.management-description {
    /* Remove the browser's default paragraph spacing. */
    margin: 0;

    /* Use the quieter Threads colour for supporting information. */
    color: var(--muted);

    /* Keep longer explanatory text comfortably readable. */
    line-height: 1.6;
}

/* Give the personal appearance card enough room for six clear colour choices. */
.preferences-page {
    /* Widen this focused page slightly while retaining the shared centred layout. */
    width: min(100%, 820px);
}

/* Place the signed-in role picture immediately before the personal page heading. */
.preferences-heading-row {
    /* Arrange optional artwork and heading copy on one clear row. */
    display: flex;

    /* Vertically centre the picture against the complete heading group. */
    align-items: center;

    /* Separate the character artwork from the heading without disconnecting them. */
    gap: 18px;
}

/* Present role artwork as a larger page identity than its compact menu version. */
.preferences-role-picture {
    /* Give the character enough width to remain recognisable. */
    width: 74px;

    /* Match the height so transparent artwork receives a predictable frame. */
    height: 74px;

    /* Prevent the flexible heading row from shrinking the role picture. */
    flex: 0 0 74px;

    /* Preserve the complete character without stretching or cropping it. */
    object-fit: contain;

    /* Place the transparent artwork on a quiet accent-tinted identity surface. */
    background: rgb(var(--accent-rgb) / 12%);

    /* Draw a restrained edge around the personal identity picture. */
    border: 1px solid rgb(255 255 255 / 14%);

    /* Match Threads's friendly card rounding without forcing a circular crop. */
    border-radius: 14px;

    /* Add a soft accent halo that follows the user's selected colour. */
    box-shadow: 0 8px 24px rgb(0 0 0 / 24%), 0 0 18px var(--accent-glow);
}

/* Separate the appearance form clearly from its introductory heading. */
.preferences-form {
    /* Use a simple vertical flow for the choice, status, and save action. */
    display: grid;

    /* Preserve comfortable space between each part of the decision. */
    gap: 22px;

    /* Separate the form from the page description above it. */
    margin-top: 34px;
}

/* Remove ordinary fieldset decoration while preserving its accessible grouping. */
.accent-picker {
    /* Remove the browser's default fieldset border. */
    border: 0;

    /* Remove the browser's default inner fieldset space. */
    padding: 0;

    /* Remove the browser's default outer fieldset space. */
    margin: 0;
}

/* Present the appearance group name as a confident form heading. */
.accent-picker legend {
    /* Keep the legend easy to find without competing with the page title. */
    font-size: 17px;

    /* Give the group name clear visual weight. */
    font-weight: 700;

    /* Use the primary Threads text colour. */
    color: var(--ink);
}

/* Explain the preview-and-save behaviour directly beneath the legend. */
.accent-picker__description {
    /* Keep the explanation close to the group heading. */
    margin: 8px 0 18px;

    /* Use the quieter text colour for supporting guidance. */
    color: var(--muted);

    /* Preserve comfortable reading for the short sentence. */
    line-height: 1.5;
}

/* Arrange the original six Threads accents in a responsive choice grid. */
.accent-picker__choices {
    /* Use a grid so every choice remains the same width. */
    display: grid;

    /* Create three columns on comfortable desktop widths. */
    grid-template-columns: repeat(3, minmax(0, 1fr));

    /* Separate neighbouring colour cards without crowding them. */
    gap: 12px;
}

/* Present one complete Threads accent as a selectable card. */
.accent-choice {
    /* Store this choice's swatch colour independently from the active page theme. */
    --choice-colour: #8c1d30;

    /* Arrange the swatch and label on one compact row. */
    display: flex;

    /* Vertically centre the label against its colour sample. */
    align-items: center;

    /* Separate the sample from its human-facing name. */
    gap: 12px;

    /* Create a comfortable click and touch target. */
    min-height: 70px;

    /* Add breathing room inside the selectable card. */
    padding: 12px;

    /* Draw the ordinary quiet Threads control edge. */
    border: 1px solid var(--line);

    /* Match the friendly rounding of other Threads controls. */
    border-radius: 10px;

    /* Keep the linen visible through a restrained raised surface. */
    background: rgb(20 22 27 / 68%);

    /* Communicate that the whole card makes a selection. */
    cursor: pointer;

    /* Prevent unexpected text selection during quick colour comparison. */
    user-select: none;

    /* Animate feedback without changing the card's geometry. */
    transition: border-color 130ms ease, background-color 130ms ease, box-shadow 130ms ease;
}

/* Hide the native radio visually while leaving it keyboard and screen-reader accessible. */
.accent-choice input {
    /* Remove the radio from visual layout without disabling focus or semantics. */
    position: absolute;

    /* Reduce the native control to an invisible single-pixel box. */
    width: 1px;
    height: 1px;

    /* Hide the visual radio without using display none. */
    opacity: 0;
}

/* Give each original Threads choice its own authentic sample colour. */
.accent-choice--purple {
    --choice-colour: #58388a;
}

/* Give the calm green card its original Threads sample. */
.accent-choice--green {
    --choice-colour: #405936;
}

/* Give the energetic orange card its original Threads sample. */
.accent-choice--orange {
    --choice-colour: #a94f0b;
}

/* Give the clear blue card its original Threads sample. */
.accent-choice--blue {
    --choice-colour: #166ee1;
}

/* Give the optimistic yellow card its original Threads sample. */
.accent-choice--yellow {
    --choice-colour: #d9c75a;
}

/* Draw the large colour sample displayed inside one choice card. */
.accent-choice__swatch {
    /* Give the sample a confident visible width. */
    width: 34px;

    /* Match the height to keep the sample circular. */
    height: 34px;

    /* Prevent the flexible label from shrinking the sample. */
    flex: 0 0 34px;

    /* Turn the square box into a circular colour light. */
    border-radius: 50%;

    /* Fill the sample with this card's authentic Threads colour. */
    background: var(--choice-colour);

    /* Add a restrained inner highlight and outer colour glow. */
    box-shadow: inset 0 0 0 1px rgb(255 255 255 / 16%), 0 0 14px color-mix(in srgb, var(--choice-colour) 55%, transparent);
}

/* Highlight the choice currently selected by mouse, touch, or keyboard. */
.accent-choice:has(input:checked) {
    /* Use the selected choice's own colour rather than the previous page accent. */
    border-color: var(--choice-colour);

    /* Place a faint sample-coloured tint behind the selected label. */
    background: color-mix(in srgb, var(--choice-colour) 20%, rgb(20 22 27 / 82%));

    /* Draw a clear selected ring without moving neighbouring cards. */
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--choice-colour) 30%, transparent);
}

/* Give keyboard users an unmistakable indicator around the focused choice. */
.accent-choice:has(input:focus-visible) {
    /* Draw a light outer line that remains visible across every sample colour. */
    outline: 2px solid var(--ink);

    /* Separate the keyboard outline from the card edge. */
    outline-offset: 3px;
}

/* Report whether the visible accent is saved or only being previewed. */
.accent-preview-status {
    /* Remove ordinary paragraph margins inside the form grid. */
    margin: 0;

    /* Use the current accent's brighter readable companion colour. */
    color: var(--accent-readable);

    /* Keep this supporting state compact. */
    font-size: 13px;
}

/* Keep the save control stable while its label changes to Saving. */
.preferences-save-button {
    /* Use a compact baseline without trapping larger browser font metrics
       inside a fixed box that can force the label onto two lines. */
    width: auto;
    min-width: 160px;

    /* Keep both the ready and saving labels on one line in Chrome, Safari and
       browsers using enlarged text or non-default display scaling. */
    white-space: nowrap;

    /* Keep the action aligned to the start of the form. */
    justify-self: start;
}

/* Centre either preference-button label inside the stable button. */
.preferences-save-button__label,
.preferences-save-button__loading {
    /* Let each label fill the complete fixed action width. */
    display: block;
}

/* Remove the inactive label completely while preserving button dimensions. */
.preferences-save-button [hidden] {
    /* Honour the HTML hidden state despite the shared display rule above. */
    display: none;
}

/* Keep the compact palette usable on narrow phones and small windows. */
@media (max-width: 640px) {
    /* Reduce the accent grid to one comfortable column. */
    .accent-picker__choices {
        /* Give each choice the complete available width. */
        grid-template-columns: 1fr;
    }
}

/* Arrange the Users heading and its principal creation action across one responsive row. */
.management-heading-row {
    /* Place heading copy on the left and the Add User action on the right. */
    display: flex;

    /* Keep the heading and action aligned along their upper edges. */
    align-items: flex-start;

    /* Send the two groups towards opposite sides of the management card. */
    justify-content: space-between;

    /* Preserve comfortable separation before responsive wrapping is needed. */
    gap: 24px;
}

/* Let the Users heading copy consume the flexible space beside its action. */
.management-heading-copy {
    /* Allow the text group to grow while protecting the action's natural width. */
    flex: 1 1 auto;

    /* Allow long content to shrink inside flexbox instead of forcing overflow. */
    min-width: 0;
}

/* Group secondary heading tools beside the principal creation action. */
.management-heading-actions {
    /* Keep related page-level actions together without merging their hierarchy. */
    display: flex;

    /* Let actions wrap cleanly when translated or enlarged labels need room. */
    flex-wrap: wrap;

    /* Align every action to the same visual baseline. */
    align-items: center;

    /* Preserve a compact but distinct gap between arrangement and creation. */
    gap: 10px;

    /* Keep the complete group against the heading row's right edge. */
    justify-content: flex-end;
}

/* Keep the principal Add User action compact and visually connected to the heading. */
.management-add-user-button {
    /* Keep the plus symbol and action label neatly aligned on one row. */
    display: inline-flex;

    /* Centre both button contents vertically. */
    align-items: center;

    /* Preserve a compact gap between the plus symbol and action label. */
    gap: 7px;

    /* Prevent the short action label from wrapping onto two lines. */
    white-space: nowrap;
}

/* Prevent the linen page beneath an open modal dialog from scrolling independently. */
body.has-open-dialog {
    /* Lock the background while the administrator completes the focused task. */
    overflow: hidden;
}

/* Replace the browser's ordinary native-dialog box with an unframed positioning layer. */
.user-dialog {
    /* Remove the native dialog border because the inner surface supplies the Threads edge. */
    border: 0;

    /* Remove native spacing so the glass surface owns all internal dimensions. */
    padding: 0;

    /* Keep the dialog transparent outside its dedicated glass surface. */
    background: transparent;

    /* Preserve a consistent compact form width after native selects are hidden. */
    width: min(390px, calc(100vw - 32px));

    /* Preserve useful space around the dialog on narrow screens. */
    max-width: min(390px, calc(100vw - 32px));

    /* Remove the browser's ordinary maximum-height restriction. */
    max-height: calc(100vh - 32px);

    /* Inherit Ubuntu and the page's ordinary text colour. */
    color: var(--ink);

    /* Let the dialog use the same typeface as the surrounding application. */
    font: inherit;

    /* Prevent the animated surface from producing a temporary native scrollbar. */
    overflow: visible;
}

/* Keep the deletion confirmation narrower than forms containing several fields. */
.user-dialog--compact {
    /* Preserve a focused readable warning instead of stretching to the full form width. */
    width: min(360px, calc(100vw - 32px));
    max-width: min(360px, calc(100vw - 32px));
}

/* Give the reusable ordering workspace room for named draggable rows. */
.user-dialog--order-editor {
    /* Remain deliberately compact while avoiding cramped business labels. */
    width: min(430px, calc(100vw - 32px));
    max-width: min(430px, calc(100vw - 32px));
}

/* Give the longer Shops master a broad workspace with three readable columns. */
.user-dialog--shop-order-editor,
.user-dialog--size-order-editor {
    /* Three shop cards remain comfortably readable without approaching the viewport edge. */
    width: min(1120px, calc(100vw - 32px));
    max-width: min(1120px, calc(100vw - 32px));
}

/* Keep Fabric mapping creation and the existing resolution list together in
   one broad workflow instead of sending users to a second management page. */
.user-dialog--fabric-mapping-manager {
    width: min(1180px, calc(100vw - 32px));
    max-width: min(1180px, calc(100vw - 32px));
}

.fabric-mapping-create-form {
    padding: 0 18px 14px;
    border-bottom: 1px solid var(--line);
}

.fabric-mapping-create-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(150px, 1fr)) auto;
    align-items: end;
    gap: 10px;
    padding: 0;
}

.fabric-mapping-create-action {
    min-height: 44px;
    margin-bottom: 1px;
    white-space: nowrap;
}

.fabric-mapping-manager-list {
    padding: 10px 18px;
}

.fabric-mapping-table-wrap {
    max-height: min(48vh, 520px);
    overflow: auto;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: rgb(15 17 21 / 48%);
    scrollbar-gutter: stable;
}

.fabric-mapping-table {
    width: 100%;
    min-width: 820px;
}

.fabric-mapping-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: #24272e;
}

.fabric-mapping-table__number {
    width: 1%;
    text-align: right !important;
    white-space: nowrap;
}

@media (max-width: 900px) {
    .fabric-mapping-create-grid {
        grid-template-columns: 1fr;
    }
}

/* Darken and soften the Users page while the focused Add User dialog is open. */
.user-dialog::backdrop {
    /* Reduce background distraction without completely hiding the linen and table context. */
    background: rgb(5 6 8 / 68%);

    /* Blur the underlying page gently so the focused form remains visually dominant. */
    backdrop-filter: blur(3px);

    /* Apply the same background blur in Safari. */
    -webkit-backdrop-filter: blur(3px);
}

/* Fade the page-darkening layer into place whenever a user dialog opens. */
.user-dialog[open]::backdrop {
    /* Play one clearly visible restrained entrance instead of making the backdrop appear abruptly. */
    animation: user-dialog-backdrop-open 600ms ease-out both;
}

/* Fade the page-darkening layer away while a dialog is deliberately closing. */
.user-dialog[open].is-closing::backdrop {
    /* Reverse the backdrop transition slowly enough for its fade to remain visible. */
    animation: user-dialog-backdrop-close 500ms ease-in both;
}

/* Create the visible Threads glass card inside the native dialog layer. */
.user-dialog-surface {
    /* Hide child surfaces cleanly behind the rounded dialog corners. */
    overflow: hidden;

    /* Draw the familiar fine glass edge around the focused form. */
    border: 1px solid rgb(255 255 255 / 14%);

    /* Give the focused form confident but friendly Threads corners. */
    border-radius: 18px;

    /* Keep the form readable while preserving a restrained glass quality. */
    background: rgb(25 27 32 / 96%);

    /* Lift the dialog clearly above its darkened management page. */
    box-shadow: 0 30px 90px rgb(0 0 0 / 62%), 0 0 42px var(--accent-glow);

    /* Soften the linen and page content visible through supporting browsers. */
    backdrop-filter: blur(22px) saturate(125%);

    /* Apply the same glass treatment in Safari. */
    -webkit-backdrop-filter: blur(22px) saturate(125%);
}

/* Animate the glass surface into its final position whenever its dialog opens. */
.user-dialog[open] .user-dialog-surface {
    /* Combine a small upward movement, gentle scale, and slow fade into one visible entrance. */
    animation: user-dialog-surface-open 700ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

/* Animate the glass surface away before JavaScript completes native closure. */
.user-dialog[open].is-closing .user-dialog-surface {
    /* Use a deliberate reverse movement so the closing transition can be appreciated. */
    animation: user-dialog-surface-close 550ms ease-in both;
}

/* Define the glass card's restrained opening movement. */
@keyframes user-dialog-surface-open {
    /* Begin slightly lower, smaller, and transparent. */
    from {
        /* Move the card down just enough for the entrance to be perceptible. */
        transform: translateY(12px) scale(0.975);

        /* Hide the card at the first animation frame. */
        opacity: 0;
    }

    /* Finish at the browser's natural centred modal position. */
    to {
        /* Restore the glass card's ordinary position and size. */
        transform: translateY(0) scale(1);

        /* Make the completed glass surface fully visible. */
        opacity: 1;
    }
}

/* Define the matching glass card closing movement. */
@keyframes user-dialog-surface-close {
    /* Begin from the fully visible resting position. */
    from {
        /* Preserve the ordinary position and size at the start. */
        transform: translateY(0) scale(1);

        /* Keep the first closing frame fully visible. */
        opacity: 1;
    }

    /* Finish slightly lower, smaller, and transparent. */
    to {
        /* Retreat gently instead of disappearing abruptly. */
        transform: translateY(8px) scale(0.985);

        /* Fade the complete glass surface out. */
        opacity: 0;
    }
}

/* Define the darkened page layer's opening fade. */
@keyframes user-dialog-backdrop-open {
    /* Begin with no visible darkening. */
    from {
        /* Hide the backdrop at the first frame. */
        opacity: 0;
    }

    /* Finish with the backdrop's designed darkness and blur. */
    to {
        /* Reveal the complete backdrop treatment. */
        opacity: 1;
    }
}

/* Define the darkened page layer's closing fade. */
@keyframes user-dialog-backdrop-close {
    /* Begin with the complete backdrop visible. */
    from {
        /* Preserve the designed darkness at the first frame. */
        opacity: 1;
    }

    /* Finish with no visible page darkening. */
    to {
        /* Fade the backdrop away before native dialog closure. */
        opacity: 0;
    }
}

/* Respect people who ask their operating system to reduce interface motion. */
@media (prefers-reduced-motion: reduce) {
    /* Remove movement from both opening and closing glass surfaces. */
    .user-dialog[open] .user-dialog-surface,
    .user-dialog[open].is-closing .user-dialog-surface {
        /* Let JavaScript use immediate native closure for reduced-motion users. */
        animation: none;
    }

    /* Remove fading from both opening and closing backdrop states. */
    .user-dialog[open]::backdrop,
    .user-dialog[open].is-closing::backdrop {
        /* Keep the modal layer steady instead of animated. */
        animation: none;
    }
}

/* Arrange the Add User heading and compact close control across one row. */
.user-dialog-header {
    /* Place heading copy and close control beside one another. */
    display: flex;

    /* Align both groups with the upper edge of the dialog header. */
    align-items: flex-start;

    /* Place the compact close action at the far right. */
    justify-content: space-between;

    /* Prevent the text and close action from touching. */
    gap: 16px;

    /* Create balanced space inside the dialog header. */
    padding: 18px 20px 15px;

    /* Separate the heading from the form fields beneath it. */
    border-bottom: 1px solid var(--line);
}

/* Allow the Add User heading copy to shrink safely beside the close action. */
.user-dialog-heading {
    /* Protect the flex layout from long translated or future heading text. */
    min-width: 0;
}

/* Style the Add User dialog's principal heading. */
.user-dialog-heading h2 {
    /* Remove native heading margins while preserving a small explanatory gap. */
    margin: 0 0 5px;

    /* Keep this focused task heading smaller than the page-level heading beneath it. */
    font-size: 22px;
}

/* Style the short explanation beneath the Add User heading. */
.user-dialog-heading p {
    /* Remove the browser's default paragraph margins. */
    margin: 0;

    /* Use the quieter Threads colour for supporting information. */
    color: var(--muted);

    /* Keep the supporting explanation compact and readable. */
    line-height: 1.45;

    /* Keep confirmation copy proportional to the denser modal heading. */
    font-size: 13px;
}

/* Style the compact close action in the Add User dialog header. */
.user-dialog-close {
    /* Prevent the fixed-size action from shrinking beside long heading text. */
    flex: 0 0 auto;

    /* Create a dependable square pointer and keyboard target. */
    width: 36px;

    /* Match the close action's width for a balanced square. */
    height: 36px;

    /* Draw the same quiet edge used by surrounding Threads controls. */
    border: 1px solid var(--line);

    /* Round the compact interactive surface. */
    border-radius: 9px;

    /* Place the close action on a subtle raised dark surface. */
    background: rgb(255 255 255 / 5%);

    /* Use the primary ink colour for the multiplication-style close symbol. */
    color: var(--ink);

    /* Inherit Ubuntu and preserve a clearly readable close symbol. */
    font: inherit;

    /* Make the close symbol visually legible without adding an icon dependency. */
    font-size: 20px;

    /* Show the hand cursor over the available close action. */
    cursor: pointer;
}

/* Highlight the dialog close action during pointer or keyboard interaction. */
.user-dialog-close:hover,
.user-dialog-close:focus-visible {
    /* Remove the browser's inconsistent default focus ring. */
    outline: 0;

    /* Use the brighter burgundy edge while the action is targeted. */
    border-color: var(--accent-hover);

    /* Add the shared burgundy focus halo. */
    box-shadow: 0 0 0 3px var(--accent-focus);
}

/* Stack Add User fields and actions in one clear learning-friendly sequence. */
.user-dialog-form {
    /* Use grid so each field group occupies one complete row. */
    display: grid;

    /* Preserve consistent vertical rhythm between form groups. */
    gap: 15px;

    /* Add balanced space around the complete form. */
    padding: 18px 20px 20px;
}

/* Keep labels in every production dialog one step below ordinary body text. */
.user-dialog .form-field > span {
    /* Preserve clear hierarchy while reducing the previously oversized label. */
    font-size: 14px;
    font-weight: 500;
}

/* Compact modal fields without changing the roomier login and page forms. */
.user-dialog .form-field input,
.user-dialog .form-field select {
    /* Retain a dependable target while making the dialog visibly denser. */
    min-height: 40px;
    padding: 8px 11px;
    font-size: 14px;
}

/* Place the password input and visibility button on one joined field surface. */
.user-dialog-password-control {
    /* Create a local positioning reference for the visibility button. */
    position: relative;
}

/* Reserve room inside the temporary-password field for its Show or Hide action. */
.user-dialog-form .user-dialog-password-control input {
    /* Preserve ordinary field spacing plus space for the neighbouring text action. */
    padding-right: 68px;
}

/* Place the password visibility action inside the field's right edge. */
.user-dialog-password-control button {
    /* Anchor the control against the right side of the password field. */
    position: absolute;

    /* Centre the control vertically inside the 44-pixel field. */
    top: 50%;

    /* Preserve a compact gap from the field's right border. */
    right: 8px;

    /* Correct vertical centring after positioning the control at 50 percent. */
    transform: translateY(-50%);

    /* Remove the ordinary button border so the control remains part of the field. */
    border: 0;

    /* Remove extra vertical space while preserving a modest click target. */
    padding: 5px 6px;

    /* Keep the visibility action visually integrated with the dark input. */
    background: transparent;

    /* Use Threads's brighter burgundy as the interactive cue. */
    color: var(--accent-hover);

    /* Inherit the page's Ubuntu typeface. */
    font: inherit;

    /* Keep the supporting action smaller than entered password text. */
    font-size: 12px;

    /* Give the compact action enough weight to remain discoverable. */
    font-weight: 700;

    /* Show that the password visibility may be changed. */
    cursor: pointer;
}

/* Give the password visibility action clear keyboard feedback. */
.user-dialog-password-control button:focus-visible {
    /* Draw a compact accessible outline around the text control. */
    outline: 2px solid var(--accent-hover);

    /* Separate the outline slightly from the control text. */
    outline-offset: 1px;
}

/* Arrange the mutually exclusive role choices inside one semantic field group. */
.user-dialog-roles {
    /* Place the two current role options beside one another. */
    display: grid;

    /* Give both role choices an equal share of the available width. */
    grid-template-columns: repeat(2, minmax(0, 1fr));

    /* Separate the legend and neighbouring role choices. */
    gap: 10px;

    /* Remove native fieldset spacing that would conflict with our deliberate layout. */
    margin: 0;

    /* Remove native fieldset padding because each choice owns its own click surface. */
    padding: 0;

    /* Remove the native outline because the individual choices are visibly bordered. */
    border: 0;
}

/* Style the shared label above the role choices. */
.user-dialog-roles legend {
    /* Let the legend span both role columns. */
    grid-column: 1 / -1;

    /* Add a small lower gap before the role choices. */
    margin-bottom: 2px;

    /* Keep form labels compact and easy to scan. */
    font-size: 13px;

    /* Give the role-group label the same confidence as ordinary field labels. */
    font-weight: 500;

    /* Use the main interface colour for strong contrast. */
    color: var(--ink);
}

/* Turn each role radio label into one generous selectable surface. */
.user-dialog-role-option {
    /* Keep the radio control and its friendly label on one row. */
    display: flex;

    /* Centre the radio control against its label text. */
    align-items: center;

    /* Separate the radio control and friendly role label. */
    gap: 10px;

    /* Provide a comfortable target height for pointer and touch input. */
    min-height: 40px;

    /* Add balanced horizontal space within the selectable role surface. */
    padding: 0 11px;

    /* Draw the standard Threads control boundary. */
    border: 1px solid var(--line);

    /* Match the compact rounding used by form inputs. */
    border-radius: 7px;

    /* Place each role on a quiet dark input-like surface. */
    background: rgb(20 22 27 / 72%);

    /* Use the primary interface colour for the friendly role label. */
    color: var(--ink);

    /* Show that the complete option may be selected. */
    cursor: pointer;
}

/* Give each role radio control a consistent burgundy selected state. */
.user-dialog-role-option input {
    /* Remove native margins that would disturb the controlled flex gap. */
    margin: 0;

    /* Give the radio control a dependable width. */
    width: 16px;

    /* Match the radio control width for a balanced target. */
    height: 16px;

    /* Use Threads burgundy when the role is selected. */
    accent-color: var(--accent);

    /* Show the hand cursor directly over the radio control as well as its label. */
    cursor: pointer;
}

/* Explain unavailable role choices without hiding their current assignment. */
.user-dialog-role-option:has(input:disabled) {
    /* Reduce visual emphasis while retaining readable role information. */
    opacity: 0.58;

    /* Remove the pointer cue because this account cannot change its own role. */
    cursor: not-allowed;
}

/* Remove the pointer cue directly from a disabled role radio. */
.user-dialog-role-option input:disabled {
    /* Match the unavailable complete role surface. */
    cursor: not-allowed;
}

/* Style short supporting text attached to a form-field label. */
.form-field-note {
    /* Use the quieter interface colour for optional-field guidance. */
    color: var(--muted);

    /* Let the main field name retain the stronger label weight. */
    font-weight: 400;
}

/* Explain an account-specific protection directly beneath its role choices. */
.user-dialog-help {
    /* Remove native paragraph margins so the form grid controls spacing. */
    margin: -8px 0 0;

    /* Use the muted colour because this is supporting guidance rather than an error. */
    color: var(--muted);

    /* Keep the compact explanation easy to scan. */
    font-size: 11.5px;

    /* Preserve comfortable readability over multiple lines. */
    line-height: 1.45;
}

/* Remove help text completely whenever its semantic hidden attribute is present. */
.user-dialog-help[hidden] {
    /* Ensure the grid does not reserve a row for hidden guidance. */
    display: none;
}

/* Highlight a complete role option while its radio control receives keyboard focus. */
.user-dialog-role-option:focus-within {
    /* Use the brighter burgundy edge around the active role surface. */
    border-color: var(--accent-hover);

    /* Add the shared focus halo outside the role surface. */
    box-shadow: 0 0 0 3px var(--accent-focus);
}

/* Align the Add User cancellation and creation actions at the dialog's lower right. */
.user-dialog-actions {
    /* Place both actions on one row. */
    display: flex;

    /* Move both actions to the dialog's right edge. */
    justify-content: flex-end;

    /* Preserve a readable gap between Cancel and Create User. */
    gap: 10px;

    /* Separate the actions slightly from the last form field. */
    padding-top: 4px;
}

/* Own the PHP dialog header/body/footer geometry inside the Threads family. */
.user-dialog-surface > .user-dialog-form {
    /* Keep the last field attached to the footer without collapsing the rhythm. */
    padding-bottom: 6px;
}

/* Give the batch-entry task room for its compact staging table. */
.user-dialog--requirement-batch {
    width: min(940px, calc(100vw - 32px));
    max-width: min(940px, calc(100vw - 32px));
}

/* Give Requirement revision a horizontal three-row business layout. */
.user-dialog--requirement-edit {
    width: min(1080px, calc(100vw - 32px));
    max-width: min(1080px, calc(100vw - 32px));
}

.requirement-edit-form {
    gap: 16px;
}

.requirement-edit-row {
    display: grid;
    gap: 14px;
    min-width: 0;
}

.requirement-edit-row--context {
    grid-template-columns: minmax(170px, 0.7fr) minmax(220px, 1fr) minmax(220px, 1fr);
}

.requirement-edit-row--details {
    grid-template-columns: minmax(260px, 1.7fr) repeat(3, minmax(130px, 0.85fr)) minmax(120px, 0.7fr);
}

.requirement-edit-row--status {
    grid-template-columns: minmax(180px, 220px);
}

.requirement-edit-row > .form-field {
    min-width: 0;
}

@media (max-width: 920px) {
    .requirement-edit-row--context,
    .requirement-edit-row--details {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .requirement-edit-row--context > :last-child,
    .requirement-edit-row--details > :first-child {
        grid-column: 1 / -1;
    }
}

@media (max-width: 620px) {
    .requirement-edit-row--context,
    .requirement-edit-row--details,
    .requirement-edit-row--status {
        grid-template-columns: minmax(0, 1fr);
    }

    .requirement-edit-row--context > :last-child,
    .requirement-edit-row--details > :first-child {
        grid-column: auto;
    }
}

.requirement-batch-form {
    gap: 14px;
}

/* The Card batch editor behaves like a focused spreadsheet: batch-wide values
   stay above a scrollable set of directly editable rows. */
.user-dialog--card-batch {
    width: min(1400px, calc(100vw - 32px));
    max-width: min(1400px, calc(100vw - 32px));
    transform: translateY(clamp(-28px, -3vh, -16px));
}

/* A Card's allocations: five short columns, so it needs far less room than the
   batch builder but more than a compact confirmation. Everything else follows
   the Add Cards dialog, which owns the shared batch appearance. */
.user-dialog--card-dispatches {
    width: min(860px, calc(100vw - 32px));
    max-width: min(860px, calc(100vw - 32px));
}

.user-dialog--card-dispatches .card-staging-table th,
.user-dialog--card-dispatches .card-staging-table td,
.user-dialog--jeans-dispatch .card-staging-table th,
.user-dialog--jeans-dispatch .card-staging-table td {
    white-space: nowrap;
}

/* An editing row swaps text for controls in the same cells. They sit outside a
   .form-field, so they take the same field surface explicitly rather than
   falling back to the browser's own input appearance.
   
   Every dialog that edits a saved record in place shares these, because the
   alternative is each product looking like a different application — which is
   exactly what happened to Jeans while these were scoped to Shirts. */
.user-dialog--card-dispatches .card-staging-table :is(input, .threads-select),
.user-dialog--jeans-dispatch .card-staging-table :is(input, .threads-select) {
    width: 100%;
    min-width: 0;
}

.user-dialog--card-dispatches .card-staging-table input,
.user-dialog--jeans-dispatch .card-staging-table input {
    min-height: 40px;
    padding: 8px 11px;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: rgb(20 22 27 / 72%);
    color: var(--ink);
    font: inherit;
    font-size: 14px;
    transition: border-color 130ms ease, box-shadow 130ms ease, background-color 130ms ease;
}

.user-dialog--card-dispatches .card-staging-table input:focus-visible,
.user-dialog--jeans-dispatch .card-staging-table input:focus-visible {
    border-color: var(--accent);
    outline: none;
    box-shadow: 0 0 0 3px rgb(var(--accent-rgb) / 22%);
}

.user-dialog--card-dispatches .card-staging-table td,
.user-dialog--jeans-dispatch .card-staging-table td {
    vertical-align: middle;
}

/* The batch builder's staging list is a running total that is expected to be
   scrolled; a Card's allocations are a finite set the user is working through,
   so ten fit before it scrolls. Capped against the viewport so a short window
   still shows the header, the add row and the footer. */
.user-dialog--card-dispatches .card-staging-wrap {
    max-height: min(560px, 52vh);
}

/* Ten again, but a Jeans allocation row is taller than a Shirt one — its Shop
   cell holds the enhanced select — so the same ten need more room. */
.user-dialog--jeans-dispatch .card-staging-wrap {
    max-height: min(620px, 60vh);
}

/* Two or three dates, so they sit on one line rather than in the create
   dialog's four-column Card summary grid. */
.card-dispatches-summary {
    grid-column: auto;
    grid-template-columns: repeat(auto-fit, minmax(0, max-content));
    gap: 24px;
    margin-bottom: 14px;
}

/* The Dispatch page's builder carries Shop and Pieces, with the date held in
   its Card context above. Here the date belongs to the line itself, so the
   same control gains a fourth column rather than wrapping the add button. */
.user-dialog--card-dispatches .dispatch-line-builder {
    grid-template-columns: minmax(150px, 0.7fr) minmax(180px, 1fr) minmax(110px, 0.45fr) auto;
}

@media (max-width: 760px) {
    .user-dialog--card-dispatches .dispatch-line-builder {
        grid-template-columns: 1fr;
    }
}

.user-dialog--card-edit {
    width: min(1180px, calc(100vw - 32px));
    max-width: min(1180px, calc(100vw - 32px));
}

.card-batch-header {
    padding-bottom: 18px;
}

.card-batch-title-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

.card-batch-count {
    padding: 4px 9px;
    border: 1px solid rgb(var(--accent-rgb) / 30%);
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent-readable);
    font-size: 11px;
    font-weight: 700;
}

.card-batch-form,
.card-edit-form {
    gap: 18px;
}

.card-batch-context {
    display: grid;
    grid-template-columns: minmax(220px, 1.2fr) repeat(3, minmax(170px, 1fr));
    align-items: end;
    gap: 16px;
    padding: 18px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: linear-gradient(135deg, rgb(var(--accent-rgb) / 8%), rgb(0 0 0 / 8%));
}

.card-batch-context__intro {
    display: flex;
    align-items: center;
    gap: 11px;
    min-width: 0;
}

.card-batch-context__intro h3,
.card-batch-context__intro p {
    margin: 0;
}

.card-batch-context__intro h3 {
    color: var(--ink);
    font-size: 15px;
}

.card-batch-context__intro p {
    margin-top: 3px;
    color: var(--muted);
    font-size: 11px;
    line-height: 1.35;
}

.card-batch-step {
    display: grid;
    width: 34px;
    height: 34px;
    flex: 0 0 34px;
    place-items: center;
    border: 1px solid rgb(var(--accent-rgb) / 36%);
    border-radius: 9px;
    background: var(--accent-soft);
    color: var(--accent-readable);
    font-size: 11px;
    font-weight: 700;
}

.card-batch-lines {
    display: grid;
    gap: 10px;
    min-width: 0;
    padding: 18px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: linear-gradient(135deg, rgb(var(--accent-rgb) / 6%), rgb(0 0 0 / 8%));
}

.card-batch-lines__heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

.card-batch-add {
    display: none;
}

.card-entry-list {
    display: grid;
    max-height: min(50vh, 520px);
    gap: 12px;
    padding: 1px;
    overflow: auto;
}

.card-entry-row {
    display: grid;
    gap: 12px;
    padding: 4px 0 14px;
    border: 0;
    background: transparent;
}

.card-entry-row + .card-entry-row {
    padding-top: 16px;
    border-top: 1px solid var(--line);
}

.card-entry-row__heading {
    display: flex;
    align-items: center;
    color: var(--muted);
    font-size: 10px;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.card-entry-row__heading strong {
    color: var(--accent-readable);
}

.card-entry-row__top,
.card-entry-row__bottom {
    display: grid;
    width: 100%;
    max-width: 1050px;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    align-items: end;
    gap: 12px;
    min-width: 0;
}

.card-entry-row__fabric {
    grid-column: span 4;
}

.card-entry-row__sleeve,
.card-entry-row__cut,
.card-entry-row__item,
.card-entry-row__suffix,
.card-entry-row__size,
.card-entry-row__colours,
.card-entry-row__pieces {
    grid-column: span 2;
}

.card-entry-row .form-field {
    min-width: 0;
}

.card-entry-row__actions {
    display: flex;
    align-items: center;
    align-self: end;
    gap: 7px;
    min-height: 40px;
    grid-column: span 1;
}

.card-entry-add,
.card-entry-row__actions .card-entry-remove {
    display: grid;
    width: 40px;
    height: 40px;
    flex: 0 0 40px;
    place-items: center;
    border-radius: 8px;
    font-family: inherit;
    font-size: 20px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}

.card-entry-add {
    border: 1px solid var(--accent-hover);
    background: var(--accent);
    color: var(--accent-ink);
}

.card-entry-add:hover,
.card-entry-add:focus-visible {
    outline: none;
    background: var(--accent-hover);
    box-shadow: 0 0 0 3px var(--accent-focus);
}

.card-entry-add[hidden],
.card-entry-row__actions .card-entry-remove:disabled {
    display: none;
}

.card-staging-wrap {
    max-height: 220px;
    overflow: auto;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: rgb(0 0 0 / 10%);
}

.card-staging-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
}

/*
 * A running total that sits above the lines it counts rather than beneath
 * them. Under the table it moved down the dialog with every line added, so it
 * was never in the same place twice — MPF, 27 August 2026. Above the table it
 * stays put, and it is the first thing read after the builder that feeds it.
 */
.staging-running-total {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    margin: 0;
    padding: 9px 12px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: rgb(var(--accent-rgb) / 10%);
    color: var(--muted);
    font-size: 13px;
    font-weight: 700;
}

.staging-running-total strong {
    color: var(--ink);
    font-size: 15px;
    white-space: nowrap;
}

/* Separates two figures that answer different questions in one row. */
.staging-running-total__divider {
    margin: 0 4px;
    color: var(--muted);
}

/* A staging table's running total, read the same way the data tables read
   theirs: the accent wash, the heavier rule above it, and no rule below.
   
   Held at the foot of the scrolling area rather than scrolling away with the
   lines — a running total that has to be scrolled to is not much of one. The
   background is opaque so the lines cannot show through it. */
.card-staging-total > th,
.card-staging-total > td {
    position: sticky;
    bottom: 0;
    z-index: 1;
    border-top: 1px solid var(--line-strong);
    border-bottom: 0;
    background: linear-gradient(rgb(var(--accent-rgb) / 10%), rgb(var(--accent-rgb) / 10%)), var(--canvas);
    color: var(--ink);
    font-weight: 700;
}

.card-staging-table th,
.card-staging-table td {
    padding: 9px 10px;
    border-right: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    color: var(--ink);
    text-align: left;
    white-space: nowrap;
}

.card-staging-table th:first-child,
.card-staging-table td:first-child {
    width: 76px;
    text-align: center;
}

.card-staging-table th:last-child,
.card-staging-table td:last-child {
    border-right: 0;
}

.card-staging-table th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: rgb(31 34 40 / 98%);
    color: var(--muted);
    font-size: 10px;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.card-staging-table tbody tr:last-child td {
    border-bottom: 0;
}

.card-staging-table tbody tr {
    transition: background-color 180ms ease, box-shadow 180ms ease;
}

.card-staging-table tbody tr.is-duplicate {
    background: rgb(var(--accent-rgb) / 18%);
    box-shadow: inset 3px 0 0 var(--accent-hover);
}

.card-staging-table [data-card-staged-empty] td {
    padding: 16px;
    color: var(--muted);
    text-align: center;
}

.card-staging-remove {
    display: inline-grid;
    width: 30px;
    height: 30px;
    place-items: center;
    border: 0;
    border-radius: 7px;
    background: rgb(195 55 80 / 88%);
    color: #fff;
    font-family: inherit;
    font-size: 17px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}

.card-staging-remove:hover,
.card-staging-remove:focus-visible {
    outline: none;
    background: rgb(218 68 92 / 100%);
    box-shadow: 0 0 0 3px rgb(195 55 80 / 18%);
}

.card-entry-table-wrap {
    max-height: min(42vh, 430px);
    overflow: auto;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: rgb(0 0 0 / 8%);
}

.card-entry-table {
    width: 100%;
    min-width: 1000px;
    border-collapse: separate;
    border-spacing: 0;
    table-layout: fixed;
}

.card-entry-table th {
    position: sticky;
    top: 0;
    z-index: 3;
    padding: 10px 8px;
    border-bottom: 1px solid var(--line);
    background: rgb(31 34 40 / 98%);
    color: var(--muted);
    font-size: 10px;
    letter-spacing: .04em;
    text-align: left;
    text-transform: uppercase;
}

.card-entry-table th small {
    display: block;
    margin-top: 2px;
    color: color-mix(in srgb, var(--muted) 68%, transparent);
    font-size: 8px;
    letter-spacing: 0;
    text-transform: none;
}

.card-entry-table th:nth-child(1) { width: 42px; }
.card-entry-table th:nth-child(2) { width: 120px; }
.card-entry-table th:nth-child(3) { width: 165px; }
.card-entry-table th:nth-child(4) { width: 280px; }
.card-entry-table th:nth-child(5) { width: 190px; }
.card-entry-table th:nth-child(6) { width: 110px; }
.card-entry-table th:nth-child(7) { width: 130px; }
.card-entry-table th:nth-child(8) { width: 48px; }

.card-entry-row td {
    padding: 8px;
    border-bottom: 1px solid var(--line);
    background: rgb(255 255 255 / 1.5%);
    vertical-align: middle;
}

.card-entry-row:last-child td {
    border-bottom: 0;
}

.card-entry-row:focus-within td {
    background: rgb(var(--accent-rgb) / 6%);
}

.card-entry-row__number {
    color: var(--muted);
    font-size: 11px;
    font-weight: 700;
    text-align: center;
}

.card-entry-control,
.card-entry-table .threads-select__trigger {
    width: 100%;
    min-height: 38px;
    padding: 7px 9px;
    border-radius: 7px;
    font-size: 11px;
}

.card-entry-control {
    border: 1px solid var(--line);
    background: rgb(20 22 27 / 92%);
    color: var(--ink);
    font-family: inherit;
}

.card-entry-control:hover,
.card-entry-control:focus {
    outline: none;
    border-color: var(--accent-hover);
    background: rgb(28 30 36 / 96%);
    box-shadow: 0 0 0 3px var(--accent-focus);
}

.card-entry-pieces {
    display: block;
    width: 100%;
    min-height: 38px;
    padding: 7px 9px;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: rgb(20 22 27 / 92%);
    color: var(--ink);
    font-family: inherit;
    font-size: 12px;
    font-weight: 700;
    text-align: right;
}

.card-entry-pieces:hover,
.card-entry-pieces:focus {
    outline: none;
    border-color: var(--accent-hover);
    background: rgb(28 30 36 / 96%);
    box-shadow: 0 0 0 3px var(--accent-focus);
}

.card-entry-pieces[readonly],
.card-entry-pieces[readonly]:hover,
.card-entry-pieces[readonly]:focus {
    border-color: var(--line);
    outline: none;
    background: rgb(var(--accent-rgb) / 12%);
    box-shadow: none;
    color: var(--accent-readable);
    cursor: default;
}

.card-entry-remove {
    display: grid;
    width: 30px;
    height: 30px;
    place-items: center;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: var(--muted);
    font-family: inherit;
    font-size: 18px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}

.card-entry-remove:hover,
.card-entry-remove:focus-visible {
    background: rgb(195 55 80 / 14%);
    color: #ef7184;
}

.card-entry-remove:disabled {
    opacity: .25;
    cursor: not-allowed;
}

.card-batch-add-inline {
    display: flex;
    min-height: 46px;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border: 1px dashed rgb(var(--accent-rgb) / 38%);
    border-radius: 10px;
    background: transparent;
    color: var(--accent-readable);
    cursor: pointer;
}

.card-batch-add-inline small {
    color: var(--muted);
}

.card-batch-add-inline:hover,
.card-batch-add-inline:focus-visible {
    border-style: solid;
    background: var(--accent-soft);
}

.card-batch-actions {
    align-items: center;
    justify-content: space-between;
}

.card-batch-actions > p {
    margin: 0;
    color: var(--muted);
    font-size: 12px;
}

.card-batch-actions > div {
    display: flex;
    gap: 10px;
}

.card-edit-context {
    display: grid;
    grid-template-columns: minmax(170px, 230px) minmax(170px, 230px);
    gap: 14px;
}

.card-edit-details {
    display: grid;
    grid-template-columns: repeat(5, minmax(130px, 1fr));
    align-items: end;
    gap: 12px;
    min-width: 0;
}

.card-edit-details > .form-field {
    min-width: 0;
}

.card-edit-details .card-line-builder__fabric {
    grid-column: span 2;
}

.card-pieces-preview {
    display: flex;
    min-height: 40px;
    align-items: center;
    padding: 8px 12px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: rgb(0 0 0 / 12%);
    color: var(--ink);
    font-weight: 700;
}

@media (max-width: 920px) {
    .card-batch-context,
    .card-edit-details {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .card-batch-context__intro {
        grid-column: 1 / -1;
    }

    .card-edit-details .card-line-builder__fabric {
        grid-column: 1 / -1;
    }

    .card-entry-row__top,
    .card-entry-row__bottom {
        grid-template-columns: repeat(8, minmax(0, 1fr));
    }

    .card-entry-row__actions {
        grid-column: span 2;
    }
}

@media (max-width: 700px) {
    .card-entry-row__top,
    .card-entry-row__bottom {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .card-entry-row__fabric {
        grid-column: 1 / -1;
    }

    .card-entry-row__sleeve,
    .card-entry-row__cut,
    .card-entry-row__item,
    .card-entry-row__suffix,
    .card-entry-row__size,
    .card-entry-row__colours,
    .card-entry-row__pieces,
    .card-entry-row__actions {
        grid-column: span 1;
    }
}

@media (max-width: 560px) {
    .card-batch-context,
    .card-edit-context,
    .card-edit-details {
        grid-template-columns: minmax(0, 1fr);
    }

    .card-batch-lines__heading,
    .card-batch-actions {
        align-items: stretch;
        flex-direction: column;
    }

    .card-batch-actions > div,
    .card-batch-actions .button {
        width: 100%;
    }

    .card-batch-add-inline small {
        display: none;
    }

    .card-entry-row__top,
    .card-entry-row__bottom {
        grid-template-columns: minmax(0, 1fr);
    }

    .card-entry-row__fabric,
    .card-entry-row__sleeve,
    .card-entry-row__cut,
    .card-entry-row__item,
    .card-entry-row__suffix,
    .card-entry-row__size,
    .card-entry-row__colours,
    .card-entry-row__pieces,
    .card-entry-row__actions {
        grid-column: auto;
    }

    .card-edit-details .card-line-builder__fabric {
        grid-column: auto;
    }
}

.requirement-batch-context {
    display: grid;
    grid-template-columns: minmax(150px, 0.38fr) minmax(180px, 0.5fr) minmax(240px, 1fr);
    gap: 14px;
}

.requirement-line-builder {
    display: grid;
    grid-template-columns: minmax(240px, 1.7fr) repeat(3, minmax(90px, 0.75fr)) minmax(82px, 0.65fr) auto;
    align-items: end;
    gap: 12px;
    margin: 0;
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: 12px;
}

.requirement-line-builder legend {
    padding: 0 6px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.requirement-line-add {
    min-height: 40px;
    white-space: nowrap;
}

.requirement-batch-error {
    margin: 0;
    color: var(--error);
    font-size: 13px;
    font-weight: 600;
}

.requirement-staging {
    max-height: 230px;
    overflow: auto;
    border: 1px solid var(--line);
    border-radius: 12px;
}

.requirement-staging-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.requirement-staging-table th,
.requirement-staging-table td {
    padding: 9px 10px;
    border-bottom: 1px solid var(--line);
    text-align: left;
    white-space: nowrap;
}

.requirement-staging-table th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: rgb(31 34 40 / 98%);
    color: var(--muted);
    font-size: 11px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.requirement-staging-table tbody tr:last-child td {
    border-bottom: 0;
}

.requirement-staging-table tbody tr {
    transition: background-color 180ms ease, box-shadow 180ms ease;
}

.requirement-staging-table tbody tr.is-duplicate {
    background: rgb(var(--accent-rgb) / 18%);
    box-shadow: inset 3px 0 0 var(--accent-hover);
}

@media (max-width: 880px) {
    .requirement-batch-context {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .requirement-batch-context__shop {
        grid-column: 1 / -1;
    }

    .requirement-line-builder {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .requirement-line-builder__fabric,
    .requirement-line-add {
        grid-column: 1 / -1;
    }
}

@media (max-width: 520px) {
    .requirement-batch-context,
    .requirement-line-builder {
        grid-template-columns: 1fr;
    }

    .requirement-line-builder__fabric,
    .requirement-line-add,
    .requirement-batch-context__shop {
        grid-column: auto;
    }
}

.user-dialog-surface > .user-dialog-actions {
    /* Match the newly compact header and body edges system-wide. */
    padding: 12px 20px 20px;
}

/* Reduce modal-only actions while ordinary page buttons retain their hierarchy. */
.user-dialog-actions .button {
    /* Make both primary and secondary footer actions share one compact geometry. */
    min-height: 40px;
    padding: 8px 13px;
    font-size: 14px;
}

/* Arrange the reset action and universal search above the user table. */
.user-table-toolbar {
    /* Separate the table controls from the page explanation above them. */
    margin-top: 28px;

    /* Place the reset action on the left and universal search on the right. */
    display: flex;

    /* Allow controls to move onto another line when horizontal space becomes limited. */
    flex-wrap: wrap;

    /* Align controls neatly along their lower edges. */
    align-items: flex-end;

    /* Preserve useful space between neighbouring toolbar groups. */
    gap: 14px;

    /* Keep toolbar controls inside the same responsive width as their table. */
    min-width: 0;
    max-width: 100%;
}

/* Keep the reset action on the toolbar's left side. */
.user-table-toolbar-actions {
    /* Keep the reset action inside a predictable flexible group. */
    display: flex;

    /* Allow the controls to wrap instead of becoming compressed. */
    flex-wrap: wrap;

    /* Align each compact control along the same lower edge. */
    align-items: flex-end;

    /* Preserve a small readable space between action groups. */
    gap: 10px;

    /* Preserve only the reset action's natural width; search receives every
       remaining pixel and wraps only when the complete row truly cannot fit. */
    flex: 0 0 auto;
}

/* Present lifecycle status as two calm table views while retaining one shared
   data-table controller and one authoritative row collection. */
.user-table-lifecycle-tabs {
    /* The travelling highlight is positioned against this strip. */
    position: relative;
    display: inline-flex;
    align-items: flex-end;
    gap: 4px;
    margin-top: 28px;
    padding: 4px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: rgb(15 17 21 / 48%);
}

.user-table-lifecycle-tabs + .user-table-toolbar {
    margin-top: 14px;
}

/* A secondary business view sits on its own compact row beneath lifecycle. */
.user-table-segment-tabs {
    display: flex;
    flex-wrap: wrap;
    width: max-content;
    max-width: 100%;
    margin-top: 8px;
}

.user-table-segment-tabs + .user-table-toolbar {
    margin-top: 14px;
}

.user-table-segment-label {
    align-self: center;
    padding: 0 9px 0 5px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 700;
    white-space: nowrap;
}

/* The highlight that travels between pills. It carries the colour the current
   pill used to draw for itself, so there is one rectangle to move rather than
   two to switch. Transform and size only — no layout is disturbed while it
   moves. */
.user-table-lifecycle-indicator {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 0;
    border: 1px solid var(--accent);
    border-radius: 7px;
    background: var(--accent-soft);
    pointer-events: none;
    transition: transform 420ms ease, width 420ms ease, height 420ms ease;
}

/* Lit on its way and back to its resting colour on arrival.
   
   Deliberately an animation rather than a class that is added and later taken
   away: an animation ends by itself and, with no fill mode, leaves the element
   on its ordinary styles. A class removed on a timer or a transitionend can be
   missed — and then the highlight simply glows for ever, which is what MPF saw
   the first time this was attempted. */
@keyframes tab-indicator-travel {
    0% {
        border-color: var(--accent);
        background-color: var(--accent-soft);
        box-shadow: 0 0 0 0 rgb(var(--accent-rgb) / 0%);
    }

    45% {
        border-color: var(--accent-readable);
        background-color: rgb(var(--accent-rgb) / 34%);
        box-shadow: 0 0 0 3px rgb(var(--accent-rgb) / 20%), 0 0 18px rgb(var(--accent-rgb) / 42%);
    }

    100% {
        border-color: var(--accent);
        background-color: var(--accent-soft);
        box-shadow: 0 0 0 0 rgb(var(--accent-rgb) / 0%);
    }
}

.user-table-lifecycle-indicator.is-travelling {
    animation: tab-indicator-travel 420ms ease;
}

/* While the travelling highlight is in play the pill stops drawing its own,
   otherwise both would be visible at once during the journey. The text colour
   still changes on the pill itself, which is what the fade covers. */
.user-table-lifecycle-tabs.has-travelling-indicator .user-table-lifecycle-tab.is-current {
    border-color: transparent;
    background: transparent;
}

.user-table-lifecycle-tabs:not(.has-travelling-indicator) .user-table-lifecycle-indicator {
    opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
    /* Move it without the journey, and without the glow that describes one. */
    .user-table-lifecycle-indicator {
        transition: none;
    }

    .user-table-lifecycle-indicator.is-travelling {
        animation: none;
    }
}

.user-table-lifecycle-tab {
    /* Sit above the travelling highlight so the label stays readable. */
    position: relative;
    z-index: 1;
    min-height: 38px;
    padding: 8px 13px;
    border: 1px solid transparent;
    border-radius: 7px;
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;

    /* Let the highlight arrive rather than appear. The pill keeps its own
       highlight — this is the cheap half of the sliding indicator MPF asked
       about on 26 August 2026, tried first to see whether it is enough. */
    transition: background-color 160ms ease,
                border-color 160ms ease,
                color 160ms ease;
}

@media (prefers-reduced-motion: reduce) {
    /* Change the highlight immediately, without the crossfade. */
    .user-table-lifecycle-tab {
        transition: none;
    }
}

.user-table-lifecycle-tab:hover,
.user-table-lifecycle-tab:focus-visible {
    color: var(--ink);
    border-color: var(--line-strong);
    background: var(--surface-hover);
}

.user-table-lifecycle-tab.is-current {
    color: var(--accent-readable);
    border-color: var(--accent);
    background: var(--accent-soft);
}

.user-table-lifecycle-count {
    display: inline-grid;
    min-width: 22px;
    min-height: 22px;
    margin-left: 5px;
    padding-inline: 5px;
    place-items: center;
    border-radius: 999px;
    background: rgb(255 255 255 / 8%);
    color: inherit;
    font-size: 11px;
}

/* Reserve a stable row for current-page selection actions so checking a record
   never moves the table vertically. Inactive actions remain visibly disabled. */
.user-table-bulk-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 7px;
    min-height: 42px;
    margin-top: 10px;
    padding: 7px 9px 7px 13px;
    border: 1px solid var(--accent);
    border-radius: 8px;
    background: rgb(var(--accent-rgb) / 13%);
    box-shadow: var(--shadow-sm);
}

.user-table-bulk-actions strong {
    margin-right: 4px;
    color: var(--accent-readable);
    font-size: 12px;
}

.user-table-bulk-actions__divider {
    width: 1px;
    height: 22px;
    margin: 0 2px;
    background: var(--line);
}

.user-table-bulk-action {
    min-height: 32px;
    padding: 6px 9px;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--ink);
    font: inherit;
    font-size: 12px;
    cursor: pointer;
}

.user-table-bulk-action:hover:not(:disabled),
.user-table-bulk-action:focus-visible {
    outline: 0;
    border-color: var(--line-strong);
    background: var(--surface-hover);
    box-shadow: 0 0 0 3px var(--accent-focus);
}

.user-table-bulk-action--danger {
    color: #ef7184;
}

.user-table-bulk-action:disabled {
    opacity: .4;
    cursor: default;
}

/* Arrange the current-view export label and its three actions together. */
.user-table-export-group {
    /* Place the label and export buttons on one compact row. */
    display: inline-flex;

    /* Vertically centre the label and button text. */
    align-items: center;

    /* Separate neighbouring export controls consistently. */
    gap: 5px;

    /* Let the compact actions wrap as a group on constrained cards instead of
       pushing the caption or table beyond their shared boundary. */
    flex-wrap: wrap;
    justify-content: flex-end;
}

/* Style the compact word that introduces the export choices. */
.user-table-export-label {
    /* Use the muted colour for this supporting label. */
    color: var(--muted);

    /* Keep the label smaller than its actionable neighbours. */
    font-size: 11px;

    /* Give the small label enough weight to remain readable. */
    font-weight: 700;
}

/* Style each current-view export action as a compact Threads button. */
.user-table-export-button {
    /* Match the neighbouring reset and search control height. */
    min-height: 38px;

    /* Draw a quiet boundary around each inactive action. */
    border: 1px solid var(--line);

    /* Add compact internal space around each short export label. */
    padding: 8px 10px;

    /* Match the restrained rounding used throughout the table controls. */
    border-radius: 8px;

    /* Place export actions on a translucent dark surface. */
    background: rgb(15 17 21 / 58%);

    /* Use the primary interface colour for actionable labels. */
    color: var(--ink);

    /* Reuse the surrounding Ubuntu interface font. */
    font: inherit;

    /* Keep the three short action labels compact. */
    font-size: 12px;

    /* Show that each control performs an export action. */
    cursor: pointer;
}

/* Highlight export actions during pointer and keyboard interaction. */
/* A toggle rather than an action: it changes what the next export contains,
   so it carries the same pressed treatment a current tab does. */
.user-table-export-toggle.is-current {
    color: var(--accent-readable);
    border-color: var(--accent);
    background: var(--accent-soft);
}

.user-table-export-button:hover,
.user-table-export-button:focus-visible {
    /* Remove the browser's inconsistent default focus outline. */
    outline: 0;

    /* Use the brighter burgundy boundary while an action is targeted. */
    border-color: var(--accent-hover);

    /* Add the restrained shared burgundy focus halo. */
    box-shadow: 0 0 0 3px var(--accent-focus);
}

/* Anchor each floating checkbox panel to its own filter control. */
.user-table-filter {
    /* Give the absolutely positioned panel a local positioning reference. */
    position: relative;

    /* Prevent a filter control from compressing its visible column name. */
    flex: 0 0 auto;
}

/* Separate the filter controls from the column-name row above them. */
.user-table-filter-row th {
    /* Add compact space around filters without inheriting the larger heading padding. */
    padding: 8px 10px 11px;

    /* Keep filter labels in their natural readable casing. */
    text-transform: none;

    /* Remove the extra letter spacing intended only for column names. */
    letter-spacing: normal;
}

/* A direct column filter keeps exact numeric entry visible without opening a menu. */
.user-table-column-text-filter {
    width: 88px;
    min-height: 34px;
    padding: 6px 8px;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: rgb(15 17 21 / 72%);
    color: var(--ink);
    font: inherit;
    font-size: 12px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.user-table-column-text-filter:focus {
    outline: 0;
    border-color: var(--accent-hover);
    box-shadow: 0 0 0 3px var(--accent-focus);
}

.user-table-column-text-filter::placeholder {
    color: var(--muted);
    opacity: 1;
}

/* Make the native details summary look like an Threads filter button. */
.user-table-filter > summary {
    /* Remove the browser's native disclosure-marker spacing. */
    list-style: none;

    /* Place the filter name and selection count on one row. */
    display: inline-flex;

    /* Vertically centre both parts of the filter control. */
    align-items: center;

    /* Separate the filter name from its compact status. */
    gap: 9px;

    /* Give every filter control a comfortable compact height. */
    min-height: 38px;

    /* Add balanced horizontal space around the control contents. */
    padding: 8px 11px;

    /* Draw a quiet boundary around the inactive filter. */
    border: 1px solid var(--line);

    /* Match the compact rounding used by other Threads controls. */
    border-radius: 8px;

    /* Place the control on a restrained translucent surface. */
    background: rgb(15 17 21 / 58%);

    /* Use the primary text colour for the column name. */
    color: var(--ink);

    /* Keep the filter label compact. */
    font-size: 13px;

    /* Keep column names and selection counts on one readable line. */
    white-space: nowrap;

    /* Show that the complete summary opens an interactive dropdown. */
    cursor: pointer;
}

/* Remove Safari and Chromium's native details triangle. */
.user-table-filter > summary::-webkit-details-marker {
    /* Hide the marker because the control already behaves like a labelled dropdown. */
    display: none;
}

/* Show a compact dropdown arrow after the filter status. */
.user-table-filter > summary::after {
    /* Display a small downward triangle. */
    content: "▾";

    /* Use a compact arrow that does not compete with the filter text. */
    font-size: 10px;

    /* Use the muted colour for the supporting dropdown indicator. */
    color: var(--muted);

    /* Animate the indicator when its checkbox panel opens. */
    transition: transform 150ms ease;
}

/* Rotate the dropdown indicator while its panel is open. */
.user-table-filter[open] > summary::after {
    /* Turn the arrow upward to represent the open state. */
    transform: rotate(180deg);
}

/* Highlight an open or actively filtering dropdown control. */
.user-table-filter[open] > summary,
.user-table-filter.has-selection > summary {
    /* Use the brighter accent boundary to indicate activity. */
    border-color: var(--accent-hover);

    /* Add a restrained burgundy focus-like halo. */
    box-shadow: 0 0 0 3px var(--accent-focus);
}

/* Style the compact All or selected-count text inside a filter control. */
.user-table-filter__status {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    max-width: 220px;
    overflow-x: auto;
    scrollbar-width: none;

    /* Use the muted colour while the filter includes every value. */
    color: var(--muted);

    /* Keep the supporting status smaller than the column label. */
    font-size: 11px;
}

.user-table-filter__status::-webkit-scrollbar {
    display: none;
}

/* Brighten a status count when its dropdown contains selections. */
.user-table-filter.has-selection .user-table-filter__status {
    /* Use the brighter burgundy to identify an active filter count. */
    color: var(--accent-hover);
}

/* Echo the selected dropdown value in the trigger using the same pill
   language as Dispatch Report while keeping compact table columns usable. */
.user-table-filter__pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex: 0 0 auto;
    max-width: 112px;
    padding: 3px 7px;
    overflow: hidden;
    border: 1px solid rgb(var(--accent-rgb) / 46%);
    border-radius: 999px;
    background: rgb(var(--accent-rgb) / 14%);
    color: var(--accent-hover);
    font: inherit;
    font-size: 11px;
    font-weight: 700;
    line-height: 1.2;
    text-overflow: ellipsis;
    vertical-align: middle;
    cursor: pointer;
}

.user-table-filter__pill:hover,
.user-table-filter__pill:focus-visible {
    outline: 0;
    border-color: var(--accent-hover);
    background: rgb(var(--accent-rgb) / 24%);
    box-shadow: 0 0 0 2px var(--accent-focus);
}

.user-table-filter__pill-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.user-table-filter__pill-remove {
    flex: 0 0 auto;
    font-size: 13px;
    line-height: 1;
}

/* Present checkbox options inside a floating Threads panel. */
.user-table-filter__panel {
    /* Position the panel independently beneath its summary control. */
    position: absolute;

    /* Keep the filter panel above the table and neighbouring content. */
    z-index: 30;

    /* Place the panel just beneath its filter control. */
    top: calc(100% + 7px);

    /* Align the panel's left edge with its filter control. */
    left: 0;

    /* Give checkbox labels enough room without becoming oversized. */
    width: 230px;

    /* Add compact internal spacing around options and the clear action. */
    padding: 8px;

    /* Draw Threads's stronger floating-surface boundary. */
    border: 1px solid var(--line-strong);

    /* Give the floating filter panel compact rounded corners. */
    border-radius: 9px;

    /* Place options on the raised dark surface used by floating menus. */
    background: #292d35;

    /* Lift the checkbox panel clearly above the table. */
    box-shadow: var(--shadow-menu);
}

/* Keep a right-edge column's floating filter inside its available panel. */
.user-table-filter--align-right .user-table-filter__panel {
    /* Release the ordinary left alignment used by earlier columns. */
    left: auto;

    /* Align the floating panel with the filter control's right edge. */
    right: 0;
}

/* Lift desktop filter panels out of a horizontally scrolling table's clipping
   area. The table controller supplies viewport-safe top and left coordinates. */
.user-table-filter.is-viewport-positioned .user-table-filter__panel {
    position: fixed;
    right: auto;
    max-width: calc(100vw - 16px);
    margin: 0;
    inset: auto;
    overflow-y: auto;
    z-index: 300;
}

/* Let people narrow a long checkbox list without applying a table filter yet. */
.user-table-filter__search {
    /* Use the complete floating-panel width. */
    width: 100%;

    /* Separate search from the checkbox choices beneath it. */
    margin-bottom: 7px;

    /* Draw the same quiet boundary used by other compact controls. */
    border: 1px solid var(--line);

    /* Match the filter panel's compact internal rounding. */
    border-radius: 7px;

    /* Add readable space around typed search text. */
    padding: 8px 9px;

    /* Place the input on a deeper inset surface. */
    background: rgb(15 17 21 / 72%);

    /* Reuse Threads typography and primary text colour. */
    color: var(--ink);
    font: inherit;
    font-size: 12px;
}

/* Give searchable filter inputs the standard accessible accent focus. */
.user-table-filter__search:focus {
    /* Remove inconsistent browser focus outlines. */
    outline: 0;

    /* Brighten the focused boundary using the current personal accent. */
    border-color: var(--accent-hover);

    /* Add the familiar restrained focus halo. */
    box-shadow: 0 0 0 3px var(--accent-focus);
}

/* Present one shared bulk action between a filter's option search and visible choices. */
.user-table-filter__select-visible {
    /* Fill the filter panel so the visible-results scope reads as one complete action. */
    width: 100%;

    /* Separate the action gently from both the search field and checkbox list. */
    margin: 0 0 7px;
    padding: 7px 8px;

    /* Use the current trusted accent without competing with primary page actions. */
    border: 1px solid rgb(var(--accent-rgb) / 48%);
    border-radius: 6px;
    background: rgb(var(--accent-rgb) / 10%);
    color: var(--accent-hover);

    /* Match compact filter typography and align with the checkbox labels beneath it. */
    font: inherit;
    font-size: 11px;
    font-weight: 700;
    text-align: left;
    cursor: pointer;
}

/* Make keyboard and pointer activation clear without native browser decoration. */
.user-table-filter__select-visible:hover,
.user-table-filter__select-visible:focus-visible {
    outline: 0;
    border-color: var(--accent-hover);
    background: rgb(var(--accent-rgb) / 17%);
    box-shadow: 0 0 0 3px var(--accent-focus);
}

/* Explain that no additional visible result can currently be selected. */
.user-table-filter__select-visible:disabled {
    color: var(--muted);
    border-color: var(--line);
    background: transparent;
    box-shadow: none;
    cursor: not-allowed;
    opacity: 0.66;
}

/* Keep long checkbox lists contained inside their dropdown panel. */
.user-table-filter__options {
    /* Limit the panel height before vertical scrolling begins. */
    max-height: 220px;

    /* Allow additional checkbox values to scroll vertically. */
    overflow-y: auto;
}

/* A standardized filter owns a wheel or touch gesture through either scroll
   boundary instead of leaking the remaining movement into the page. */
[data-production-table-standard] .user-table-filter__panel,
[data-production-table-standard] .user-table-filter__options {
    overscroll-behavior: contain;
}

/* Style one complete checkbox option as a comfortable clickable row. */
.user-table-filter__option {
    /* Place the checkbox beside its visible value. */
    display: flex;

    /* Vertically align the checkbox with its label. */
    align-items: center;

    /* Separate the checkbox from its visible text. */
    gap: 9px;

    /* Add a comfortable compact click target around each option. */
    padding: 8px;

    /* Round the option's hover surface inside the panel. */
    border-radius: 6px;

    /* Use the primary Threads text colour for available values. */
    color: var(--ink);

    /* Keep checkbox labels compact. */
    font-size: 13px;

    /* Show that the complete row changes a filter selection. */
    cursor: pointer;
}

/* Ensure local option search wins over the option row's explicit flex layout. */
.user-table-filter__option[hidden] {
    /* Author-level flex display otherwise overrides the browser's native hidden rule. */
    display: none;
}

/* Highlight a checkbox row when the pointer passes over it. */
.user-table-filter__option:hover {
    /* Place the hovered option on Threads's raised surface. */
    background: var(--surface-hover);
}

/* Give a selected option the same clear raised treatment as the shared
   searchable business dropdowns. */
.user-table-filter__option:has(input:checked) {
    background: rgb(var(--accent-rgb) / 14%);
    color: var(--accent-hover);
}

/* Apply the Threads accent colour to native filter checkboxes. */
.user-table-filter__option input {
    /* Use Threads burgundy when the checkbox is selected. */
    accent-color: var(--accent-hover);
}

.user-table-filter__option-text {
    min-width: 0;
    flex: 1 1 auto;
}

.user-table-filter__selected-marker {
    margin-left: auto;
    color: var(--accent-hover);
    font-size: 12px;
    font-weight: 800;
    opacity: 0;
}

.user-table-filter__option input:checked ~ .user-table-filter__selected-marker {
    opacity: 1;
}

/* Style loading or empty text displayed inside a filter panel. */
.user-table-filter__message {
    /* Remove the browser's ordinary paragraph spacing. */
    margin: 0;

    /* Add the same internal space used by checkbox options. */
    padding: 8px;

    /* Use the muted colour for supporting filter information. */
    color: var(--muted);

    /* Keep the supporting panel message compact. */
    font-size: 12px;
}

/* Keep empty-search feedback absent while one or more matching choices remain. */
.user-table-filter__message[hidden] {
    /* Match the explicit option-row hidden rule for dependable cross-browser behaviour. */
    display: none;
}

/* Present the one-filter clear action beneath its checkbox options. */
.user-table-filter__clear {
    /* Let the clear action fill the available panel width. */
    width: 100%;

    /* Separate the action from checkbox options with a quiet line. */
    margin-top: 6px;

    /* Add compact internal space around the action text. */
    padding: 8px;

    /* Draw only a top boundary between options and the action. */
    border: 0;

    /* Add the separating line using an inset shadow. */
    box-shadow: inset 0 1px 0 var(--line);

    /* Keep the clear action on the panel's existing background. */
    background: transparent;

    /* Use the muted colour until the action is hovered or focused. */
    color: var(--muted);

    /* Keep the supporting action compact. */
    font: inherit;

    /* Align the action text with checkbox labels above it. */
    text-align: left;

    /* Show that this label performs an action. */
    cursor: pointer;
}

/* Brighten the one-filter clear action during pointer or keyboard use. */
.user-table-filter__clear:hover,
.user-table-filter__clear:focus-visible {
    /* Remove the browser's inconsistent default focus outline. */
    outline: 0;

    /* Use the primary text colour while the action is active. */
    color: var(--ink);
}

/* Style the toolbar action that resets every active filter group. */
.user-table-clear-all {
    /* Keep the reset action aligned with neighbouring filter controls. */
    min-height: 38px;

    /* Draw a restrained boundary so the persistent action reads as a button. */
    border: 1px solid var(--accent-hover);

    /* Place the action on a faint burgundy-tinted surface. */
    background: rgb(var(--accent-rgb) / 14%);

    /* Add comfortable horizontal space around the compact label. */
    padding: 8px 12px;

    /* Match the compact rounding used by the other table controls. */
    border-radius: 8px;

    /* Use Threads burgundy to identify the reversible clearing action. */
    color: var(--accent-hover);

    /* Reuse the surrounding Ubuntu interface font. */
    font: inherit;

    /* Keep the reset label compact. */
    font-size: 12px;

    /* Prevent the short reset label from wrapping or compressing. */
    white-space: nowrap;

    /* Show that the reset label performs an action. */
    cursor: pointer;
}

/* Soften the clear-all button when no filters currently need clearing. */
.user-table-clear-all:disabled {
    /* Use the quiet table boundary instead of the active burgundy edge. */
    border-color: var(--line);

    /* Return the inactive action to a restrained transparent surface. */
    background: rgb(15 17 21 / 38%);

    /* Use the muted colour to communicate that the action is unavailable. */
    color: var(--muted);

    /* Remove the pointer cue because clicking currently performs no work. */
    cursor: default;

    /* Reduce emphasis while keeping the label comfortably readable. */
    opacity: 0.7;
}

/* Keep the universal search control on the right side of wide toolbars. */
.user-table-search {
    /* Push universal search toward the toolbar's far edge. */
    margin-left: auto;

    /* Consume the toolbar's actual remaining space. This replaces the old
       input-specific desktop width with one container-driven measurement. */
    flex: 1 1 auto;
    min-width: 0;
    max-width: 100%;

    /* Stack its visible label above the text field. */
    display: flex;

    /* Place the label and input on separate vertical lines. */
    flex-direction: column;

    /* Keep the related label and input visually close. */
    gap: 5px;
}

/* Style the visible universal-search label. */
.user-table-search label {
    /* Use the muted colour for the supporting field label. */
    color: var(--muted);

    /* Keep the compact label readable. */
    font-size: 11px;

    /* Give the small field label confident visual weight. */
    font-weight: 700;
}

/* Style the universal search field as an Threads input. */
.user-table-search input {
    /* Follow the dynamically allocated search group instead of carrying a
       fixed desktop width that truncates differently on every table. */
    width: 100%;

    /* Keep the search field aligned with filter-button heights. */
    min-height: 38px;

    /* Add comfortable internal space around entered text. */
    padding: 8px 11px;

    /* Draw a quiet boundary around the inactive search field. */
    border: 1px solid var(--line);

    /* Match the compact rounding used by table filters. */
    border-radius: 8px;

    /* Place entered text on a restrained translucent dark surface. */
    background: rgb(15 17 21 / 58%);

    /* Use the primary text colour for entered search terms. */
    color: var(--ink);

    /* Reuse the surrounding Ubuntu interface font. */
    font: inherit;

    /* Keep entered search terms compact. */
    font-size: 13px;
}

/* Highlight universal search during keyboard or pointer entry. */
.user-table-search input:focus {
    /* Remove the browser's inconsistent default focus outline. */
    outline: 0;

    /* Use the brighter accent boundary while the field is active. */
    border-color: var(--accent-hover);

    /* Add the shared restrained burgundy focus halo. */
    box-shadow: 0 0 0 3px var(--accent-focus);
}

/* Arrange record and page information beneath opposite sides of the table. */
.user-table-footer {
    /* Place the record count on the left and page count on the right. */
    display: flex;

    /* Send the two pieces of information to opposite horizontal edges. */
    justify-content: space-between;

    /* Align both compact labels along the same vertical centre. */
    align-items: center;

    /* Preserve space if the labels wrap on a very narrow display. */
    gap: 12px;

    /* Separate the footer gently from the table above it. */
    margin-top: 10px;

    /* Keep result and pagination controls aligned to the visible card width. */
    min-width: 0;
    max-width: 100%;
}

/* Report matching and total record counts on the footer's left side. */
.user-table-result-count {
    /* Remove ordinary paragraph margins so footer alignment remains exact. */
    margin: 0;

    /* Use the muted colour for supporting result information. */
    color: var(--muted);

    /* Keep the result count compact. */
    font-size: 12px;
}

/* Report current and total pages on the footer's right side. */
.user-table-page-count {
    /* Remove ordinary paragraph margins so footer alignment remains exact. */
    margin: 0;

    /* Use the muted colour for supporting pagination information. */
    color: var(--muted);

    /* Match the record counter's compact type size. */
    font-size: 12px;
}

/* Keep page-size choice, navigation and page position together on the right. */
.user-table-pagination {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    gap: 10px;
}

.user-table-pagination[hidden] {
    display: none;
}

/* Pair the compact native selector with one explicit label. */
.user-table-page-size {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    color: var(--muted);
    font-size: 12px;
}

.user-table-page-size select {
    min-width: 64px;
    min-height: 32px;
    padding: 5px 25px 5px 9px;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: rgb(15 17 21 / 72%);
    color: var(--ink);
    font: inherit;
    cursor: pointer;
}

.user-table-page-size select:focus {
    outline: 0;
    border-color: var(--accent-hover);
    box-shadow: 0 0 0 3px var(--accent-focus);
}

.user-table-pagination-navigation,
.user-table-pagination-pages {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.user-table-pagination-button {
    display: inline-grid;
    min-width: 32px;
    height: 32px;
    padding: 0 8px;
    place-items: center;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: rgb(15 17 21 / 58%);
    color: var(--ink);
    font: inherit;
    font-size: 12px;
    cursor: pointer;
}

.user-table-pagination-button:hover:not(:disabled) {
    border-color: var(--accent-hover);
    background: var(--surface-hover);
}

.user-table-pagination-button:focus-visible {
    outline: 0;
    border-color: var(--accent-hover);
    box-shadow: 0 0 0 3px var(--accent-focus);
}

.user-table-pagination-button:disabled {
    opacity: .4;
    cursor: default;
}

.user-table-pagination-button.is-current {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--ink);
    opacity: 1;
}

.user-table-pagination-ellipsis {
    min-width: 16px;
    color: var(--muted);
    text-align: center;
}

.user-table-pagination .user-table-page-count {
    min-width: 72px;
    text-align: right;
}

/* Hold the first user table inside a contained Threads surface. */
.user-table-wrapper {
    /* Separate the account table from its result count above it. */
    margin-top: 10px;

    /* Fill the measured management surface and remain its one table boundary. */
    width: 100%;
    max-width: 100%;

    /* Contain wide datasets here rather than widening the complete document.
       Open desktop filters are lifted to the viewport by the table controller. */
    overflow-x: auto;

    /* Prevent a sideways gesture from unexpectedly moving the complete page. */
    overscroll-behavior-inline: contain;

    /* Let the attached caption size itself from this visible table surface. */
    container-type: inline-size;

    /* Permit this boundary to shrink inside intrinsically sized cards. */
    min-width: 0;

    /* Draw a quiet boundary around the complete table. */
    border: 1px solid var(--line);

    /* Match the compact rounding used by other Threads controls. */
    border-radius: 10px;

    /* Place a restrained dark surface beneath the table rows. */
    background: rgb(15 17 21 / 48%);
}

/* Give the simple user table a stable full-width layout. */
.user-table {
    /* Use the columns' natural combined width, while still filling a card when
       its surrounding heading or toolbar needs more room than the table. */
    width: max-content;
    min-width: 100%;

    /* Join neighbouring cell borders into clean uninterrupted lines. */
    border-collapse: collapse;
}

/* Preserve the approved comfortable workhorse footprint inside a responsive
   card; narrow screens scroll this table boundary rather than the document. */
[data-production-table-standard] .user-table {
    min-width: max(840px, 100%);
}

[data-production-table-standard] .user-table-selection-cell input:disabled {
    cursor: not-allowed;
    opacity: 0.45;
}

/* Describe the user table above its column headings. */
.user-table caption {
    /* Add balanced space around the table description. */
    padding: 14px 16px;

    /* Align the description with the table's text columns. */
    text-align: left;

    /* Separate the description from the column headings beneath it. */
    border-bottom: 1px solid var(--line);

    /* Use the quieter Threads colour for supporting table information. */
    color: var(--muted);

    /* Keep the supporting description compact. */
    font-size: 13px;
}

/* Arrange the table description and export actions across one attached header bar. */
.user-table-caption-content {
    /* Use flexbox so the description and actions can occupy opposite sides. */
    display: flex;

    /* Send the table description left and the export group right. */
    justify-content: space-between;

    /* Keep the description and compact buttons vertically centred. */
    align-items: center;

    /* Preserve comfortable space when the caption becomes narrow. */
    gap: 14px;

    /* Wrap only when the real caption and export controls cannot share a row;
       no report-specific width or breakpoint is required. */
    flex-wrap: wrap;

    /* Keep the title and exports inside the visible table surface while only
       the data columns move horizontally beneath them. */
    position: sticky;
    left: 0;
    width: calc(100cqw - 32px);
}

/* Keep the table description visually separate from its attached actions. */
.user-table-caption-title {
    /* Give the description enough weight to anchor the table header bar. */
    font-weight: 500;

    /* Permit long business titles to yield space to exports without creating
       page-level overflow. */
    min-width: 0;
    overflow-wrap: anywhere;
}

/* Give table headings and account values consistent spacing. */
.user-table th,
.user-table td {
    /* Add a comfortable click-feature-ready area around every value. */
    padding: 13px 10px;

    /* Align every value consistently from the left edge. */
    text-align: left;

    /* Separate neighbouring rows with a subtle Threads line. */
    border-bottom: 1px solid var(--line);
}

/* Reserve one compact, consistently aligned column for current-page selection. */
.user-table .user-table-selection-cell {
    width: 44px;
    min-width: 44px;
    padding-inline: 14px;
    text-align: center;
}

/*
 * Threads draws its own checkbox rather than accepting the platform's.
 * `accent-color` can recolour a native box but cannot round it, and MPF asked
 * for slightly rounded and slightly larger ones throughout on 27 August 2026 —
 * so the control is rebuilt: same square, softer corners, and a tick drawn
 * with a border rather than a glyph so it scales with the box.
 */
input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    flex: none;
    width: 20px;
    height: 20px;
    margin: 0;
    border: 1px solid var(--line-strong);
    border-radius: 6px;
    background: rgb(20 22 27 / 72%);
    cursor: pointer;
    transition: border-color 130ms ease, background-color 130ms ease, box-shadow 130ms ease;
}

input[type="checkbox"]:hover:not(:disabled) {
    border-color: var(--accent);
}

input[type="checkbox"]:checked {
    border-color: var(--accent);
    background: var(--accent);
}

/* The tick: two borders of an empty box, rotated. It stays centred and keeps
   its weight at any size, which a text glyph does not. */
input[type="checkbox"]:checked::after {
    content: "";
    display: block;
    width: 5px;
    height: 10px;
    margin: 1px auto 0;
    border: solid var(--accent-ink, #fff);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

input[type="checkbox"]:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgb(var(--accent-rgb) / 30%);
}

input[type="checkbox"]:disabled {
    opacity: .5;
    cursor: default;
}

.user-table-selection-cell input[type="checkbox"] {
    display: block;
    margin: auto;
}

/* A responsive disclosure column exists only while the complete Requirements
   row cannot fit inside its table surface. */
.user-table-responsive-heading,
.user-table-responsive-filter,
.user-table-responsive-cell,
.user-table-responsive-detail-row {
    display: none;
}

.has-responsive-row-details .user-table-responsive-heading,
.has-responsive-row-details .user-table-responsive-filter,
.has-responsive-row-details .user-table-responsive-cell {
    display: table-cell;
    width: 44px;
    min-width: 44px;
    padding-inline: 8px;
    text-align: center;
}

.has-responsive-row-details #shirt-cards-table {
    width: 100%;
}

/* Keep the two compact classification axes from consuming the same width as
   longer business values elsewhere in the Requirement row. */
#shirt-requirements-table > thead > tr > :is(:nth-child(4), :nth-child(5)),
#shirt-requirements-table > tbody > .user-table__data-row > :is(:nth-child(4), :nth-child(5)),
#shirt-requirements-table > tfoot > tr > :is(:nth-child(4), :nth-child(5)) {
    width: 118px;
    max-width: 118px;
    padding-inline: 7px;
}

/* The shared filter normally reserves 128px. Let these deliberately compact
   columns own that width so their triggers ellipsize instead of overlapping. */
#shirt-requirements-table > thead > .user-table-filter-row > :is(:nth-child(4), :nth-child(5)) .user-table-filter {
    min-width: 0;
    max-width: 100%;
}

#shirt-requirements-table > thead > tr:first-child > :is(:nth-child(4), :nth-child(5)) .user-table-sort-button {
    gap: 4px;
}

#shirt-requirements-table > thead > tr:first-child > :is(:nth-child(4), :nth-child(5)) .user-table-sort-indicator {
    min-width: 0;
}

/* Give Shop codes a little more breathing room between the category pair and Sleeve. */
#shirt-requirements-table > thead > tr > :nth-child(6),
#shirt-requirements-table > tbody > .user-table__data-row > :nth-child(6),
#shirt-requirements-table > tfoot > tr > :nth-child(6) {
    width: 100px;
    min-width: 100px;
}

/* Pieces is quantitative: align its heading, values and current-view total on
   the shared numeric edge so magnitudes scan cleanly down the column. */
/* Quantitative columns align heading, values and current-view total on the
   shared numeric edge so magnitudes scan cleanly down the column. Which
   columns those are is declared once per heading as `type="number"`, and the
   table controller marks the matching body and total cells, so this holds for
   every table without each one restating its column numbers here. */
.user-table .user-table__numeric-cell {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* A new set of rows arrives the way a new page of content does, borrowing the
   page transition's own movement so a tab, a sort and a page turn all read the
   same. Only the arrival moves: there is nothing to wait for between one set of
   rows and the next, so withholding the new ones would only add delay. The body
   animates as one element rather than each row separately. */
.user-table > tbody.is-rows-entering {
    animation:
        threads-page-content-enter 220ms ease-out both,
        user-table-rows-enter 220ms ease-out both;
}

/* An empty result is a bigger change than one page of rows replacing another:
   everything the eye was reading has gone. It arrives a little more slowly, and
   without the upward travel, so it reads as a settled state rather than as rows
   that failed to appear. */
.user-table > tbody.is-rows-entering > tr:has(> .user-table__empty) {
    animation: user-table-empty-enter 320ms ease-out both;
}

@keyframes user-table-empty-enter {
    /* Begin transparent and very slightly small. */
    from {
        opacity: 0;
        transform: scale(0.985);
    }

    /* Finish at the ordinary readable message. */
    to {
        opacity: 1;
        transform: scale(1);
    }
}

@keyframes user-table-rows-enter {
    /* Begin transparent so a half-measured column never flashes first. */
    from {
        opacity: 0;
    }

    /* Finish at the ordinary fully readable rows. */
    to {
        opacity: 1;
    }
}

/* Respect visitors who request little or no interface motion. */
@media (prefers-reduced-motion: reduce) {
    /* Present each new set of rows immediately, without movement or fading. */
    .user-table > tbody.is-rows-entering,
    .user-table > tbody.is-rows-entering > tr:has(> .user-table__empty) {
        animation: none;
    }
}

/* A quantitative column declares its alignment once, on the heading, and the
   body cells follow by position. The heading and its filter were left behind,
   so a right-aligned column read as though its label belonged to the column
   beside it. */
.user-table > thead > tr > th[data-report-alignment="right"],
.user-table > thead > tr > th.user-table-numeric-filter {
    text-align: right;
}

/* The indicator reserves 24px so an arriving arrow cannot shift the heading.
   On a right-aligned column that reserved space would sit between the label and
   the column edge, leaving the label short of the digits it names, so the
   indicator moves to the label's other side. */
.user-table > thead > tr > th[data-report-alignment="right"] .user-table-sort-indicator {
    order: -1;
}

/* A two-word heading that wraps must align both its lines with the digits, not
   just the box holding them. */
.user-table > thead > tr > th[data-report-alignment="right"] .user-table-sort-button > span {
    text-align: right;
}

/* Cards carries Item Number, Colours and Status in addition to the comparable
   Requirement axes. Recover that extra width from table chrome—not data—so the
   complete desktop table fits the same standard management surface. */
#shirt-cards-table {
    width: 100%;
}

#shirt-cards-table th,
#shirt-cards-table td {
    padding-inline: 6px;
}

#shirt-cards-table .user-table-selection-cell {
    width: 38px;
    min-width: 38px;
    padding-inline: 10px;
}

#shirt-cards-table .user-table-filter-row th {
    padding: 8px 4px 11px;
}

#shirt-cards-table .user-table-filter > summary {
    gap: 5px;
    min-height: 36px;
    padding: 7px 6px;
    font-size: 12px;
}

#shirt-cards-table .user-table-filter__status {
    font-size: 10px;
}

#shirt-cards-table .user-table-sort-button {
    gap: 4px;
}

#shirt-cards-table .user-table-sort-indicator {
    min-width: 12px;
}

#shirt-cards-table .user-table-column-text-filter {
    min-width: 0;
    padding-inline: 6px;
}

/* Keep Date, Item, Fabric and Pieces scannable; disclose all supporting Card axes. */
.has-responsive-row-details #shirt-cards-table > thead > tr > :is(:nth-child(5), :nth-child(8), :nth-child(9), :nth-child(10), :nth-child(11), :nth-child(12), :nth-child(13), :nth-child(14), :nth-child(15), :nth-child(17)),
.has-responsive-row-details #shirt-cards-table > tbody > .user-table__data-row > :is(:nth-child(5), :nth-child(8), :nth-child(9), :nth-child(10), :nth-child(11), :nth-child(12), :nth-child(13), :nth-child(14), :nth-child(15), :nth-child(17)) {
    display: none;
}

.user-table-responsive-toggle {
    display: inline-grid;
    place-items: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 1px solid var(--line-strong);
    border-radius: 7px;
    background: rgb(var(--accent-rgb) / 12%);
    color: var(--accent-readable);
    font: inherit;
    font-size: 18px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    transition: border-color 160ms ease, background-color 160ms ease;
}

.user-table-responsive-toggle:hover,
.user-table-responsive-toggle:focus-visible,
.user-table-responsive-toggle[aria-expanded="true"] {
    border-color: var(--accent-readable);
    background: rgb(var(--accent-rgb) / 26%);
}

.has-responsive-row-details .user-table-responsive-detail-row {
    display: table-row;
    animation: responsive-table-detail-enter 180ms ease both;
}

.user-table-responsive-detail-row > td {
    padding: 0;
    background: rgb(var(--accent-rgb) / 7%);
}

.user-table-responsive-detail-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: 1px;
    margin: 0;
    padding: 1px;
    background: var(--line);
}

.user-table-responsive-detail-item {
    display: grid;
    gap: 4px;
    min-width: 0;
    padding: 11px 13px;
    background: rgb(18 21 26 / 96%);
}

.user-table-responsive-detail-item dt {
    color: var(--muted);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.user-table-responsive-detail-item dd {
    margin: 0;
    color: var(--ink);
    overflow-wrap: anywhere;
}

.user-table-responsive-detail-item[data-responsive-detail-key="date"] {
    display: none;
}

/* Categories, Sleeve, Cut and Size remain primary desktop columns, so do not
   duplicate them in the disclosure until the viewport becomes compact. */
.user-table-responsive-detail-item:is(
    [data-responsive-detail-key="category-one"],
    [data-responsive-detail-key="category-two"],
    [data-responsive-detail-key="sleeve"],
    [data-responsive-detail-key="cut"],
    [data-responsive-detail-key="size"]
) {
    display: none;
}

@media (max-width: 1100px) {
    .user-table-responsive-detail-item:is(
        [data-responsive-detail-key="category-one"],
        [data-responsive-detail-key="category-two"],
        [data-responsive-detail-key="sleeve"],
        [data-responsive-detail-key="cut"],
        [data-responsive-detail-key="size"]
    ) {
        display: grid;
    }
}

@keyframes responsive-table-detail-enter {
    from {
        opacity: 0;
        transform: translateY(-5px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@media (prefers-reduced-motion: reduce) {
    .has-responsive-row-details .user-table-responsive-detail-row {
        animation: none;
    }
}

.user-table__data-row.is-selected > td {
    background: rgb(var(--accent-rgb) / 10%);
}

/* Keep current-view totals attached to the table and visually distinct from
   ordinary records without competing with the main column headings. */
.user-table-total-row > th,
.user-table-total-row > td {
    border-top: 1px solid var(--line-strong);
    border-bottom: 0;
    background: rgb(var(--accent-rgb) / 10%);
    color: var(--ink);
    font-weight: 700;
}


/* Keep every first-column action heading and control aligned from the left edge. */
.user-table .user-table-actions-heading,
.user-table .user-table-actions-filter,
.user-table .user-table-actions-cell {
    /* Match the table's reading direction now that Actions is always first. */
    text-align: left;
}

/* Keep the action column compact while retaining comfortable button targets. */
.user-table-actions-heading,
.user-table-actions-filter,
.user-table-actions-cell {
    /* Reserve only the width required by the two short actions. */
    width: 1%;

    /* Prevent Edit and Delete from wrapping onto separate lines. */
    white-space: nowrap;
}

/* Arrange Edit and Delete neatly inside one table cell. */
.user-table-row-actions {
    /* Keep both actions on one row. */
    display: inline-flex;

    /* Preserve a compact gap between the related account actions. */
    gap: 7px;
}

/* Style one compact account action without competing with the table data. */
.user-table-row-action {
    /* Keep each emoji action at a consistent compact square size. */
    display: inline-grid;

    /* Centre the emoji perfectly inside its action surface. */
    place-items: center;

    /* Create a dependable compact pointer and keyboard target. */
    width: 34px;

    /* Match the width so the emoji action remains square. */
    height: 34px;

    /* Draw the familiar quiet Threads control boundary. */
    border: 1px solid var(--line-strong);

    /* Remove text-button spacing because the emoji is centred by the grid. */
    padding: 0;

    /* Match the table's small rounded control language. */
    border-radius: 7px;

    /* Place the action on a subtle translucent surface. */
    background: rgb(255 255 255 / 4%);

    /* Use the primary text colour for the ordinary Edit action. */
    color: var(--ink);

    /* Reuse the table's Ubuntu typography. */
    font: inherit;

    /* Give each emoji enough visual presence without overpowering the row. */
    font-size: 16px;

    /* Preserve the emoji's natural colour artwork. */
    line-height: 1;

    /* Show that this available control performs an action. */
    cursor: pointer;

    /* Smooth colour and glow feedback during interaction. */
    transition: border-color 130ms ease, background-color 130ms ease, box-shadow 130ms ease;

    /* Keep linked actions such as the PPC calculator visually identical to buttons. */
    text-decoration: none;
}

/* Keep code-drawn row-action artwork crisp and theme-coloured at compact table size. */
.user-table-row-action__icon {
    /* Give the Production Setup wrench the same presence as neighbouring action glyphs. */
    width: 17px;
    height: 17px;

    /* Prevent the inline SVG baseline from nudging the icon away from true centre. */
    display: block;
}

/* Float one shared Threads tooltip above compact table actions without table-cell clipping. */
.table-action-tooltip {
    /* Follow the action in viewport coordinates while remaining outside every table overflow area. */
    position: fixed;

    /* Keep the tooltip above menus, cards, and modal-dialog contents. */
    z-index: 120;

    /* Constrain long disabled-state explanations to a readable compact surface. */
    max-width: min(280px, calc(100vw - 20px));

    /* Give short action names comfortable breathing room. */
    padding: 7px 10px;

    /* Use the same compact rounded geometry as Threads controls. */
    border: 1px solid var(--line-strong);
    border-radius: 7px;

    /* Preserve the dark Threads depth while reflecting the user's chosen accent softly. */
    background: #25282f;
    box-shadow: var(--shadow-menu);

    /* Make the action meaning readable without overpowering the data table. */
    color: var(--ink);
    font-size: 13px;
    font-weight: 600;
    line-height: 1.3;
    text-align: center;

    /* Never let the tooltip intercept the pointer and cause hover flicker. */
    pointer-events: none;
}

/* The allocation the user arrived to edit, so it is findable among the Chart's
   other Shops rather than being one indistinguishable row among them. */
.card-staging-table tr.is-focused-allocation > td {
    background: var(--accent-soft);
}

/* A multi-line breakdown reads as a list, so keep its line breaks and align it
   left. Single-line tooltips keep the centred wording they have always had. */
.table-action-tooltip[data-multiline] {
    max-width: min(340px, calc(100vw - 20px));
    text-align: left;
    white-space: pre-line;
}

/* An inspectable table value is not a button, but it explains itself the same
   way, so it takes the same focus affordance. */
.jeans-chart-shops-value {
    cursor: help;
}

/* Draw the small Threads speech-point beneath a tooltip placed above its action. */
.table-action-tooltip[data-placement="above"]::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -5px;
    width: 8px;
    height: 8px;
    border-right: 1px solid var(--line-strong);
    border-bottom: 1px solid var(--line-strong);
    background: #25282f;
    transform: translateX(-50%) rotate(45deg);
}

/* Turn the speech-point upward when limited viewport room places the tooltip below. */
.table-action-tooltip[data-placement="below"]::after {
    content: "";
    position: absolute;
    left: 50%;
    top: -5px;
    width: 8px;
    height: 8px;
    border-top: 1px solid var(--line-strong);
    border-left: 1px solid var(--line-strong);
    background: #25282f;
    transform: translateX(-50%) rotate(45deg);
}

/* Honour the HTML hidden state even if later shared display rules become more specific. */
.table-action-tooltip[hidden] {
    display: none;
}

/* Give the dedicated Fabric PPC view enough room for four business-data columns. */
.fabric-ppc-page {
    /* Widen only this rule-management page while preserving centred responsive margins. */
    width: min(100%, 1040px);
}

/* Return from one Fabric's focused calculator rules to the parent master. */
.fabric-ppc-back-link {
    /* Keep the parent doorway compact above the page hierarchy label. */
    display: inline-flex;

    /* Separate it from the following eyebrow without adding page-wide padding. */
    margin-bottom: 18px;

    /* Use the active accent so the navigation relationship is clear. */
    color: var(--accent-hover);

    /* Preserve Ubuntu and remove a distracting default underline. */
    font-weight: 500;
    text-decoration: none;
}

/* Emphasize the back doorway for pointer and keyboard visitors. */
.fabric-ppc-back-link:hover,
.fabric-ppc-back-link:focus-visible {
    /* Restore a simple underline rather than changing layout dimensions. */
    text-decoration: underline;
}

/* Place the selected Fabric identity opposite its contextual creation action. */
.fabric-ppc-heading-row {
    /* Align heading copy and action in one adaptable row. */
    display: flex;
    align-items: flex-start;
    justify-content: space-between;

    /* Preserve comfortable breathing room between unlike elements. */
    gap: 24px;
}

/* Prevent a long Fabric title from pushing the action outside the card. */
.fabric-ppc-heading-row .management-heading-copy {
    /* Allow the heading group to shrink normally inside the flex row. */
    min-width: 0;
}

/* Keep copy and creation as two clearly related Fabric actions. */
.fabric-ppc-heading-actions {
    /* Place both actions together without allowing their labels to wrap. */
    display: flex;
    gap: 10px;
    flex-shrink: 0;
}

/* Separate each Fabric Production Setup concern without fragmenting the management card. */
.fabric-production-section {
    /* Begin each section on a clear rhythm beneath the Fabric identity. */
    margin-top: 34px;
}

/* Align one setup section's explanation with only the actions that affect it. */
.fabric-production-section-heading {
    /* Place supporting copy and contextual actions on one adaptable row. */
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 24px;

    /* Keep the heading visually attached to its following table. */
    margin-bottom: 14px;
}

/* Keep section headings subordinate to the selected Fabric's page title. */
.fabric-production-section-heading h2 {
    /* Remove browser spacing and use the same compact setup-heading scale as rounding. */
    margin: 0 0 4px;
    font-size: 18px;
}

/* Explain one section's business purpose without competing with its data. */
.fabric-production-section-heading p {
    /* Remove browser spacing and reuse supporting Threads text. */
    margin: 0;
    color: var(--muted);
    font-size: 13px;
}

/* Keep Category mapping actions compact without forcing its table columns wider. */
.fabric-category-table__actions {
    /* Reserve only the space required by Edit and Delete. */
    width: 1%;
    white-space: nowrap;
}

/* Use the shared table boundary without adding another unrelated top margin. */
.fabric-category-table-wrapper {
    /* Attach the table directly to its section heading. */
    margin-top: 0;
}

/* Arrange the two Category choices as one readable relationship. */
.fabric-category-form-grid {
    /* Keep both sides of the mapping equally prominent on comfortable dialog widths. */
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
}

/* Explain how the saved mapping changes production entry without adding another field. */
.fabric-category-form-note {
    /* Keep the relationship explanation quiet and close to its controls. */
    margin: 0;
    color: var(--muted);
    font-size: 13px;
    line-height: 1.45;
}

/* Present a PPC rounding setting as a quiet secondary panel. */
.fabric-ppc-rounding-form {
    /* Arrange explanation, label, input, and stable action on one readable row. */
    display: grid;
    grid-template-columns: minmax(220px, 1fr) auto 110px auto;
    align-items: end;

    /* Keep related controls close without crowding their text. */
    gap: 12px;

    /* Separate Product settings from both heading and rule table. */
    margin: 34px 0 28px;
    padding: 18px;

    /* Use the familiar inset Threads panel treatment. */
    border: 1px solid var(--line);
    border-radius: 12px;
    background: rgb(15 17 21 / 45%);
}

/* Keep a rounding-setting heading subordinate to its surrounding Product or Fabric name. */
.fabric-ppc-rounding-copy h2,
.fabric-ppc-rounding-copy h3 {
    /* Remove browser spacing and use a compact readable size. */
    margin: 0 0 4px;
    font-size: 18px;
}

/* Explain the rounding scope without dominating the control. */
.fabric-ppc-rounding-copy p {
    /* Remove browser spacing and use the supporting text colour. */
    margin: 0;
    color: var(--muted);
    font-size: 13px;
}

/* Style the rounding label consistently with ordinary form fields. */
.fabric-ppc-rounding-form label {
    /* Keep the short label visible directly above its number input. */
    align-self: center;
    color: var(--muted);
    font-size: 13px;
    font-weight: 500;
}

/* Give the standalone rounding number the shared Threads field treatment. */
.fabric-ppc-rounding-form input {
    /* Fill its dedicated grid column and remain a useful pointer target. */
    width: 100%;
    min-height: 44px;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: rgb(20 22 27 / 72%);
    color: var(--ink);
    font: inherit;
}

/* Join the selected Product's new-Fabric template directly to its contextual table. */
.fabric-default-rounding-form {
    /* Replace the standalone-card spacing with one integrated column section. */
    margin: 0;

    /* Let the column boundary provide the outer sides while retaining a clear lower divider. */
    border-width: 0 0 1px;
    border-radius: 0;

    /* Use a restrained accent wash to distinguish configuration from Fabric records. */
    background: rgb(var(--accent-rgb) / 7%);
}

/* Display the rule table inside the same clipped rounded wrapper as other masters. */
.fabric-ppc-table-wrapper {
    /* Separate the table from the Product setting panel above it. */
    margin-top: 0;
}

/* Reserve only the space required by Edit and Delete actions. */
.fabric-ppc-table__actions {
    /* Keep actions compact and together on one line. */
    width: 1%;
    white-space: nowrap;
}

/* Align whole-number PPC values consistently. */
.fabric-ppc-table__number {
    /* Keep numeric comparison easy down the column. */
    text-align: right;
}

/* Arrange four Add/Edit inputs as a compact responsive grid. */
.fabric-ppc-form-grid {
    /* Use two columns on comfortable dialog widths. */
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
}

/* Let PPC option panels extend beyond the glass card instead of being clipped at its edge. */
#ppc-rule-form-dialog .user-dialog-surface,
#copy-ppc-rules-dialog .user-dialog-surface,
#category-mapping-form-dialog .user-dialog-surface {
    /* Preserve the native dialog boundary while allowing the custom floating lists to remain visible. */
    overflow: visible;
}

/* Keep the native select only as a quiet data source after JavaScript builds the Threads control. */
.threads-select__source {
    /* Remove the operating-system control from sight and pointer interaction without deleting its value. */
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    border: 0;
    clip-path: inset(50%);
    overflow: hidden;
    white-space: nowrap;
    pointer-events: none;
}

/* Establish one positioning boundary for the visible trigger and its floating option list. */
.threads-select {
    /* Anchor the panel directly beneath its matching trigger. */
    position: relative;
    display: block;
    width: 100%;
}

/* Let a dialog listbox extend beyond the glass edge without being cropped. */
.user-dialog-surface:has(.threads-select) {
    /* The visible surface retains its own rounded border while options float. */
    overflow: visible;
}

/* Lift the active component above neighbouring dialog fields and preview panels. */
.threads-select.is-open {
    /* Keep the open list visually dominant without entering the modal's global layering system. */
    z-index: 30;
}

/* Present the selected value as a complete Threads-native form control. */
.threads-select__trigger {
    /* Align the readable value and chevron at opposite edges. */
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;

    /* Match the dimensions and internal rhythm of existing Threads inputs. */
    width: 100%;
    min-height: 44px;
    padding: 10px 13px;

    /* Reuse the dark inset field edge and surface. */
    border: 1px solid var(--line);
    border-radius: 7px;
    background: rgb(20 22 27 / 92%);
    color: var(--ink);

    /* Preserve Ubuntu and make the complete surface feel interactive. */
    font: inherit;
    text-align: left;
    cursor: pointer;

    /* Coordinate focus and opening feedback without moving surrounding fields. */
    transition: border-color 130ms ease, box-shadow 130ms ease, background-color 130ms ease;
}

/* Match enhanced dialog selects to the reduced modal field geometry. */
.user-dialog .threads-select__trigger {
    /* Keep the native value contract but use the compact modal silhouette. */
    min-height: 40px;
    padding: 8px 11px;
    font-size: 14px;
}

/* Keep placeholder text quieter until a genuine value has been selected. */
/* A locked control still shows its value — that is the point of locking it
   rather than hiding it — but stops inviting a click. Threads had no shared
   disabled state for the enhanced select or for a form field until a Jeans
   Chart needed to lock five of them on 27 August 2026. */
.threads-select__trigger:disabled,
.form-field input:disabled,
.form-field select:disabled {
    opacity: .55;
    cursor: default;
}

.threads-select__trigger:disabled:hover,
.form-field input:disabled:hover {
    border-color: var(--line);
    background: rgb(20 22 27 / 72%);
    box-shadow: none;
}

.threads-select__trigger.is-placeholder {
    /* Match the supporting colour used by ordinary empty inputs. */
    color: var(--muted);
}

/* Give keyboard focus, pointer focus, and the open state the same personal accent. */
.threads-select__trigger:hover,
.threads-select__trigger:focus,
.threads-select__trigger:focus-visible,
.threads-select.is-open .threads-select__trigger {
    /* Replace the browser outline with the established Threads field glow. */
    outline: none;
    border-color: var(--accent-hover);
    box-shadow: 0 0 0 3px var(--accent-focus);
    background-color: rgb(28 30 36 / 96%);
}

/* Mark an incomplete custom field clearly after attempted submission. */
.threads-select__trigger[aria-invalid="true"] {
    /* Use the semantic danger family without replacing the user's personal accent elsewhere. */
    border-color: var(--error);
    box-shadow: 0 0 0 3px rgb(214 91 91 / 18%);
}

/* Draw the familiar down chevron without relying on operating-system artwork. */
.threads-select__chevron {
    /* Create two short borders that meet as a downward arrow. */
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
    transition: transform 160ms ease;
}

/* Turn the chevron upward while its list is open. */
.threads-select.is-open .threads-select__chevron {
    /* Rotate in place so the trigger dimensions remain perfectly stable. */
    transform: translateY(3px) rotate(225deg);
}

/* Open the list above controls near a modal footer so actions remain visible. */
.threads-select.is-open-up .threads-select__panel {
    /* Replace the ordinary lower anchor with an upper-edge attachment. */
    top: auto;
    bottom: calc(100% + 7px);
}

/* Float a complete Threads surface beneath the trigger instead of opening a macOS menu. */
.threads-select__panel {
    /* Cover the same horizontal area as its trigger. */
    position: absolute;
    top: calc(100% + 7px);
    left: 0;
    right: 0;
    z-index: 40;

    /* Keep future longer lists usable inside the current viewport. */
    display: grid;
    max-height: 292px;
    padding: 6px;
    overflow-y: auto;

    /* Reuse the Threads floating-menu edge, depth, and personal accent reflection. */
    border: 1px solid rgb(255 255 255 / 16%);
    border-radius: 9px;
    background: rgb(17 19 24 / 99%);
    box-shadow: 0 18px 48px rgb(0 0 0 / 62%), 0 0 28px rgb(var(--accent-rgb) / 12%);
    backdrop-filter: blur(18px) saturate(120%);
    -webkit-backdrop-filter: blur(18px) saturate(120%);
}

/* Popovers enter the browser's top layer, escaping scrollable tables while the
   select controller keeps them visually anchored to their trigger. */
.threads-select__panel--top-layer {
    position: fixed;
    inset: auto;
    margin: 0;
}

.threads-select__panel--top-layer:popover-open {
    display: grid;
}

/* Guarantee that the floating surface disappears completely when JavaScript closes it. */
.threads-select__panel[hidden] {
    /* Override the component's grid layout while the semantic hidden state is active. */
    display: none;
}

/* Keep the native ISO date value authoritative while presenting one familiar
   calendar throughout production dialogs. */
.threads-date {
    position: relative;
    display: block;
    width: 100%;
    min-width: 0;
}

.threads-date__source {
    position: absolute;
    width: 1px !important;
    height: 1px;
    min-height: 0 !important;
    padding: 0 !important;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    border: 0 !important;
    white-space: nowrap;
}

.threads-date__trigger {
    display: grid;
    width: 100%;
    min-height: 44px;
    grid-template-columns: 17px minmax(0, 1fr) 12px;
    align-items: center;
    gap: 9px;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: rgb(20 22 27 / 72%);
    color: var(--ink);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color 130ms ease, box-shadow 130ms ease, background-color 130ms ease;
}

.user-dialog .threads-date__trigger {
    min-height: 40px;
    padding: 8px 11px;
    font-size: 14px;
}

.threads-date__trigger.is-placeholder {
    color: var(--muted);
}

.threads-date__trigger:hover,
.threads-date__trigger:focus-visible,
.threads-date.is-open .threads-date__trigger {
    outline: 0;
    border-color: var(--accent-hover);
    background: rgb(28 30 36 / 82%);
    box-shadow: 0 0 0 3px var(--accent-focus);
}

.threads-date__trigger[aria-invalid="true"] {
    border-color: var(--error);
    box-shadow: 0 0 0 3px rgb(214 91 91 / 18%);
}

.threads-date__icon {
    position: relative;
    width: 15px;
    height: 14px;
    border: 1.5px solid currentColor;
    border-radius: 3px;
    color: var(--muted);
}

.threads-date__icon::before {
    position: absolute;
    top: 3px;
    right: 1px;
    left: 1px;
    border-top: 1.5px solid currentColor;
    content: "";
}

.threads-date__value {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.threads-date__chevron {
    width: 9px;
    height: 9px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    color: var(--muted);
    transform: translateY(-2px) rotate(45deg);
    transition: transform 160ms ease;
}

.threads-date.is-open .threads-date__chevron {
    transform: translateY(3px) rotate(225deg);
}

.threads-date__panel {
    position: absolute;
    z-index: 50;
    top: calc(100% + 7px);
    left: 0;
    display: grid;
    width: 292px;
    padding: 9px;
    border: 1px solid rgb(255 255 255 / 16%);
    border-radius: 9px;
    background: rgb(17 19 24 / 99%);
    box-shadow: 0 18px 48px rgb(0 0 0 / 62%), 0 0 28px rgb(var(--accent-rgb) / 12%);
    color: var(--ink);
    backdrop-filter: blur(18px) saturate(120%);
    -webkit-backdrop-filter: blur(18px) saturate(120%);
}

.threads-date__panel--top-layer {
    position: fixed;
    inset: auto;
    margin: 0;
}

.threads-date__panel--top-layer:popover-open {
    display: grid;
}

.threads-date__panel[hidden] {
    display: none;
}

.threads-date__header,
.threads-date__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.threads-date__header {
    min-height: 36px;
    padding: 1px 2px 8px;
}

.threads-date__header strong {
    font-size: 13px;
    font-weight: 600;
}

.threads-date__step,
.threads-date__footer button {
    min-width: 30px;
    height: 30px;
    padding: 0 8px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--muted);
    font: inherit;
    cursor: pointer;
}

.threads-date__step {
    font-size: 22px;
    line-height: 1;
}

.threads-date__step:hover,
.threads-date__step:focus-visible,
.threads-date__footer button:hover,
.threads-date__footer button:focus-visible {
    outline: 0;
    background: var(--surface-hover);
    color: var(--ink);
}

.threads-date__weekdays,
.threads-date__grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 3px;
}

.threads-date__weekdays {
    padding: 4px 0 6px;
    color: var(--muted);
    font-size: 10px;
    text-align: center;
}

.threads-date__grid button {
    display: grid;
    aspect-ratio: 1;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: 6px;
    outline: 0;
    background: transparent;
    color: var(--ink);
    font: inherit;
    font-size: 12px;
    cursor: pointer;
}

.threads-date__grid button:hover {
    background: var(--surface-hover);
}

.threads-date__grid button:focus-visible {
    box-shadow: inset 0 0 0 2px var(--accent-hover);
}

.threads-date__grid button[data-outside="true"] {
    color: rgb(174 178 189 / 48%);
}

.threads-date__grid button[data-today="true"] {
    box-shadow: inset 0 0 0 1px var(--accent-readable);
}

.threads-date__grid button[aria-selected="true"] {
    background: var(--accent);
    color: var(--accent-ink);
    font-weight: 700;
}

.threads-date__footer {
    justify-content: flex-end;
    margin-top: 7px;
    padding-top: 7px;
    border-top: 1px solid var(--line);
}

.threads-date__footer button {
    color: var(--accent-readable);
    font-size: 12px;
    font-weight: 600;
}

/* Let searchable selectors accept text without changing the native value. */
.threads-select__search {
    position: sticky;
    top: 0;
    z-index: 1;
    width: 100%;
    min-height: 36px;
    margin-bottom: 5px;
    padding: 7px 9px;
    border: 1px solid var(--line);
    border-radius: 6px;
    /* Stay fully opaque while option rows scroll underneath this sticky field. */
    background: rgb(26 28 34);
    color: var(--ink);
    font: inherit;
    font-size: 13px;
}

/* Form-field input rules are declared later and intentionally use translucent
   surfaces. The floating search must instead remain opaque because option rows
   continue scrolling underneath its sticky position. */
.form-field .threads-select__search,
.form-field .threads-select__search:focus {
    background: rgb(26 28 34);
}

.threads-select__search:focus-visible {
    outline: 0;
    border-color: var(--accent-hover);
    box-shadow: 0 0 0 2px var(--accent-focus);
}

.threads-select__options {
    display: grid;
}

.threads-select__no-results {
    padding: 10px;
    color: var(--muted);
    font-size: 13px;
    text-align: center;
}

/* Make each choice a generous full-width Threads row. */
.threads-select__option {
    /* Keep the label flexible while reserving a stable selected marker. */
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;

    /* Provide one comfortable pointer and keyboard target. */
    width: 100%;
    min-height: 36px;
    padding: 7px 10px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--ink);
    font: inherit;
    font-size: 14px;
    text-align: left;
    cursor: pointer;
}

.threads-select__option[hidden],
.threads-select__no-results[hidden] {
    display: none;
}

/* Highlight the option currently under pointer or keyboard consideration. */
.threads-select__option:hover,
.threads-select__option:focus-visible {
    /* Use the personal accent as a restrained selection wash. */
    outline: none;
    background: rgb(var(--accent-rgb) / 14%);
}

/* Keep programmatic Arrow-key focus unmistakable even when the browser does
   not apply :focus-visible to an option focused from a search field. */
.threads-select__option.is-keyboard-active,
.user-table-filter__option.is-keyboard-active {
    outline: none;
    background: rgb(var(--accent-rgb) / 30%);
    box-shadow: inset 0 0 0 2px var(--accent-hover);
    color: var(--ink);
}

/* Keep the stored choice visible when the list is reopened. */
.threads-select__option[aria-selected="true"] {
    /* Keep the stored value readable on every accent theme. The accent remains
       in the background and marker instead of tinting the label itself. */
    background: rgb(var(--accent-rgb) / 20%);
    color: var(--ink);
    font-weight: 600;
}

/* Reserve the checkmark's width even when an option is not selected. */
.threads-select__selected-marker {
    /* Prevent option labels from shifting when their selected state changes. */
    flex: 0 0 auto;
    color: var(--ink);
    font-weight: 700;
    opacity: 0;
}

/* Reveal the marker only for the one selected option. */
.threads-select__option[aria-selected="true"] .threads-select__selected-marker {
    /* Keep selected state visible without depending on colour alone. */
    opacity: 1;
}

/* Operational table filters use the same closed field, searchable list and
   selected-marker language as Dispatch Report instead of the older Filter/All
   disclosure button. The native checkboxes remain authoritative underneath. */
.user-table-filter.threads-select {
    /* No percentage width here. A block already fills its cell, and a
       percentage inside a table sized by its content is exactly the construct
       Blink and WebKit resolve differently — it inflated every filtered column
       in Safari and Orion and pushed the table past its card. */
    display: block;
    /* This floor is what a filtered column can never shrink below, so on a wide
       table it decides whether the whole thing fits its card. Seven filtered
       columns on Dispatches multiply it sevenfold, and Sleeve, Cut and Size
       hold values like FS, AP and 36-40 that need nothing like this much.

       It is set low deliberately. Earlier values were tuned until the table
       just fitted in Blink, which left nothing spare and still scrolled in
       WebKit — Safari and Orion measure the nowrap actions column and these
       controls a little wider. At 96px the table's hard minimum is 1,397px
       against a 1,500px card: roughly 100px of slack, far more than any
       engine disagreement, rather than a fit tuned to one browser. */
    min-width: 96px;
}

.user-table-filter > .threads-select__trigger {
    display: flex;
    min-height: 38px;
    padding: 7px 10px;
    gap: 9px;
    border-radius: 7px;
    background: rgb(20 22 27 / 92%);
    font-size: 13px;
    font-weight: 400;
    text-transform: none;
}

.user-table-filter > .threads-select__trigger::after {
    content: none;
}

.user-table-filter[open] .threads-select__chevron {
    transform: translateY(3px) rotate(225deg);
}

.user-table-filter__status.threads-select__value {
    min-width: 0;
    overflow: hidden;
    color: var(--muted);
    font-size: 12px;
    line-height: 1.2;
    text-overflow: ellipsis;
}

.user-table-filter.has-selection .user-table-filter__status.threads-select__value {
    color: var(--ink);
}

.user-table-filter__panel.threads-select__panel {
    right: auto;
    width: 250px;
    max-width: calc(100vw - 16px);
    padding: 6px;
    background: rgb(17 19 24 / 99%);
    text-transform: none;
}

/* The Dispatch-style panel owns the complete vertical scroll. Letting its
   option list scroll independently creates two adjacent scrollbars on long
   filters such as Fabric. */
.user-table-filter__panel.threads-select__panel .user-table-filter__options {
    max-height: none;
    overflow-y: visible;
}

.user-table-filter__panel.threads-select__panel {
    scrollbar-width: thin;
    scrollbar-color: rgb(255 255 255 / 34%) transparent;
}

.user-table-filter__panel.threads-select__panel::-webkit-scrollbar {
    width: 8px;
}

.user-table-filter__panel.threads-select__panel::-webkit-scrollbar-track {
    background: transparent;
}

.user-table-filter__panel.threads-select__panel::-webkit-scrollbar-thumb {
    border: 2px solid transparent;
    border-radius: 999px;
    background: rgb(255 255 255 / 34%);
    background-clip: padding-box;
}

.user-table-filter__panel.threads-select__panel .user-table-filter__clear {
    position: sticky;
    top: 41px;
    z-index: 2;
    width: 100%;
    margin: 0 0 5px;
    padding: 7px 9px;
    border: 1px solid rgb(var(--accent-rgb) / 48%);
    border-radius: 6px;
    background: #111318;
    box-shadow: none;
    color: var(--accent-hover);
    font-size: 11px;
    font-weight: 700;
}

.user-table-filter__panel.threads-select__panel .user-table-filter__clear:disabled {
    border-color: var(--line);
    background: #111318;
    color: var(--muted);
    cursor: not-allowed;
    opacity: 1;
}

.user-table-filter__option input[data-production-table-filter-option] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    border: 0;
    white-space: nowrap;
}

.user-table-filter__option:has(input:focus-visible) {
    outline: 0;
    background: rgb(var(--accent-rgb) / 14%);
    box-shadow: inset 0 0 0 2px var(--accent-hover);
}

.user-table-filter__option:has(input:checked) {
    background: rgb(var(--accent-rgb) / 20%);
    color: var(--ink);
    font-weight: 600;
}

/* Show the future production calculation without storing it in the rule table. */
.fabric-ppc-preview {
    /* Stack the quiet label above the calculated suggestion. */
    display: grid;
    gap: 5px;

    /* Distinguish the preview from editable fields. */
    padding: 14px 16px;
    border: 1px solid var(--line);
    border-radius: 9px;
    background: rgb(var(--accent-rgb) / 8%);
}

/* Keep the preview label deliberately secondary. */
.fabric-ppc-preview span {
    /* Use muted compact text for explanation. */
    color: var(--muted);
    font-size: 12px;
}

/* Let the resulting Pieces suggestion remain easy to scan. */
.fabric-ppc-preview strong {
    /* Use the ordinary ink and a slightly larger number treatment. */
    color: var(--ink);
    font-size: 16px;
}

/* Give the selectable copy workflow enough width for readable combinations. */
.fabric-ppc-copy-dialog {
    /* Remain comfortably inside the viewport while supporting detailed rule rows. */
    max-width: min(640px, calc(100vw - 32px));
}

/* Group the selectable source rules without browser-default fieldset styling. */
.fabric-ppc-copy-rules {
    /* Remove default spacing before applying the shared inset-panel treatment. */
    margin: 0;
    padding: 0;
    border: 0;
}

/* Label the copy checklist consistently with form-field labels. */
.fabric-ppc-copy-rules legend {
    /* Separate the label slightly from its selection controls. */
    margin-bottom: 8px;
    color: var(--ink);
    font-size: 13px;
    font-weight: 500;
}

/* Present Select All as a quiet checklist toolbar. */
.fabric-ppc-copy-select-all {
    /* Align its native checkbox beside the readable action label. */
    display: flex;
    align-items: center;
    gap: 9px;

    /* Separate the bulk action from the individual rules beneath it. */
    padding: 11px 13px;
    border: 1px solid var(--line);
    border-radius: 8px 8px 0 0;
    background: rgb(255 255 255 / 4%);
    cursor: pointer;
}

/* Contain longer source-rule sets within the focused dialog. */
.fabric-ppc-copy-rule-options {
    /* Stack each selectable combination as one complete row. */
    display: grid;

    /* Keep many rules scrollable without making the dialog leave the viewport. */
    max-height: 260px;
    overflow-y: auto;

    /* Complete the inset checklist surface beneath Select All. */
    border: 1px solid var(--line);
    border-top: 0;
    border-radius: 0 0 8px 8px;
    background: rgb(15 17 21 / 45%);
}

/* Display one copyable source rule as a complete comfortable checkbox row. */
.fabric-ppc-copy-rule-option {
    /* Keep choice, combination, PPC, and status aligned predictably. */
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 10px;

    /* Give each rule a useful pointer target and quiet separator. */
    min-height: 46px;
    padding: 9px 13px;
    border-bottom: 1px solid rgb(255 255 255 / 7%);
    cursor: pointer;
}

/* Remove the final separator at the rounded bottom of the checklist. */
.fabric-ppc-copy-rule-option:last-child {
    /* Let the parent boundary complete the final row. */
    border-bottom: 0;
}

/* Highlight one rule row during pointer or keyboard-checkbox interaction. */
.fabric-ppc-copy-rule-option:hover,
.fabric-ppc-copy-rule-option:focus-within {
    /* Use a restrained accent wash without changing layout dimensions. */
    background: rgb(var(--accent-rgb) / 10%);
}

/* Apply the selected accent consistently to every copy-dialog checkbox. */
.fabric-ppc-copy-dialog input[type="checkbox"] {
    /* Keep native accessibility while coordinating its selected colour. */
    width: 17px;
    height: 17px;
    accent-color: var(--accent);
    cursor: pointer;
}

/* Keep the human-readable combination from overflowing its grid column. */
.fabric-ppc-copy-rule-combination {
    /* Allow long future Field Values to wrap inside the row. */
    min-width: 0;
    line-height: 1.4;
}

/* Mark combinations whose destination already has a current rule. */
.fabric-ppc-copy-existing {
    /* Use a compact warning-coloured badge rather than disabling the useful choice. */
    padding: 3px 6px;
    border-radius: 999px;
    background: rgb(225 164 72 / 14%);
    color: var(--warning);
    font-size: 10px;
    font-weight: 700;
    white-space: nowrap;
}

/* Explain an unselected source or source with no rules inside the checklist. */
.fabric-ppc-copy-message {
    /* Replace browser paragraph spacing with one deliberate empty-state area. */
    margin: 0;
    padding: 20px 14px;
    color: var(--muted);
    text-align: center;
}

/* Make replacement an explicit opt-in separate from ordinary rule selection. */
.fabric-ppc-copy-replace {
    /* Align the checkbox with its two-line consequence description. */
    display: flex;
    align-items: flex-start;
    gap: 10px;

    /* Use a soft warning surface for the more consequential option. */
    padding: 13px;
    border: 1px solid rgb(225 164 72 / 28%);
    border-radius: 8px;
    background: rgb(225 164 72 / 7%);
    cursor: pointer;
}

/* Stack the replacement title and explanation compactly. */
.fabric-ppc-copy-replace span {
    /* Keep both pieces of copy inside one readable column. */
    display: grid;
    gap: 3px;
}

/* Keep the replacement explanation visibly secondary. */
.fabric-ppc-copy-replace small {
    /* Use the supporting colour and readable line height. */
    color: var(--muted);
    line-height: 1.4;
}

/* Summarize how many rules the next copy action will affect. */
.fabric-ppc-copy-summary {
    /* Remove browser spacing and keep status near the submit actions. */
    margin: 0;
    color: var(--muted);
    font-size: 13px;
}

/* Adapt the PPC controls cleanly to narrow browser widths. */
@media (max-width: 760px) {
    .fabric-ppc-heading-row {
        /* Stack the contextual action beneath heading copy on small screens. */
        flex-direction: column;
    }

    .fabric-ppc-heading-actions {
        /* Stack both contextual actions across the narrow card width. */
        width: 100%;
        flex-direction: column;
    }

    .fabric-ppc-heading-actions .button {
        /* Make both actions equally easy to tap on narrow screens. */
        width: 100%;
    }

    .fabric-production-section-heading {
        /* Stack a section's action beneath its explanation on narrow screens. */
        flex-direction: column;
    }

    .fabric-production-section-heading > .button {
        /* Make the single Category action a comfortable full-width target. */
        width: 100%;
    }

    .fabric-ppc-rounding-form {
        /* Give every setting element the full available width. */
        grid-template-columns: 1fr;
        align-items: stretch;
    }

    .fabric-ppc-form-grid {
        /* Keep dialog fields readable without squeezing two narrow columns. */
        grid-template-columns: 1fr;
    }

    .fabric-category-form-grid {
        /* Stack both Category choices without squeezing their custom option lists. */
        grid-template-columns: 1fr;
    }

    .fabric-ppc-copy-rule-option {
        /* Let the status badge wrap beneath the readable combination. */
        grid-template-columns: auto minmax(0, 1fr) auto;
    }

    .fabric-ppc-copy-existing {
        /* Align the existing-status badge beneath the combination on narrow screens. */
        grid-column: 2 / -1;
        justify-self: start;
    }
}

/* Highlight an ordinary table action during pointer or keyboard interaction. */
.user-table-row-action:hover,
.user-table-row-action:focus-visible {
    /* Remove the browser's inconsistent default keyboard outline. */
    outline: 0;

    /* Use the brighter Threads burgundy edge around the active control. */
    border-color: var(--accent-hover);

    /* Add a faint accent surface behind the action label. */
    background: rgb(var(--accent-rgb) / 20%);

    /* Draw a restrained accessible glow around the active control. */
    box-shadow: 0 0 0 3px var(--accent-focus);
}

/* Identify Delete as the destructive member of the action pair. */
.user-table-row-action--danger {
    /* Add a faint burgundy surface behind the destructive wastebasket. */
    background: rgb(var(--accent-rgb) / 10%);
}

/* Remove ordinary form-field spacing from the dedicated order-editor body. */
.order-editor-body {
    /* The guidance and list supply their own compact vertical rhythm. */
    gap: 10px;
}

/* Explain the editor's draft and save boundary before the draggable list. */
.order-editor-guidance {
    /* Remove the browser paragraph margin inside the controlled grid. */
    margin: 0;

    /* Use supporting colour because the category names remain primary. */
    color: var(--muted);

    /* Keep the compact instruction readable without dominating the dialog. */
    font-size: 12px;
    line-height: 1.45;
}

/* Create the reusable, independently scrolling business-order list. */
.order-editor-list {
    /* Stack movable records with a small visible separation. */
    display: grid;
    gap: 7px;

    /* Remove native ordered-list geometry; explicit position labels replace it. */
    margin: 0;
    padding: 3px;
    list-style: none;

    /* Keep lengthy masters inside the viewport instead of growing the dialog. */
    max-height: min(50vh, 420px);
    overflow-y: auto;

    /* Reserve scrollbar room so the list does not shift as it grows. */
    scrollbar-gutter: stable;
}

/* Read Shop positions vertically before continuing in the neighbouring column. */
.order-editor-list--shop-columns,
.order-editor-list--size-columns {
    /* CSS column flow preserves DOM order: 1–10, 11–20 and 21–30. */
    grid-template-rows: repeat(10, minmax(44px, auto));
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);

    /* Ten compact rows fit in the taller modal without an internal vertical scrollbar. */
    max-height: none;
    overflow: visible;
    scrollbar-gutter: auto;
}

/* Return the Shop order workspace to one scrollable column on compact screens. */
@media (max-width: 760px) {
    .order-editor-list--shop-columns,
    .order-editor-list--size-columns {
        grid-template-rows: none;
        grid-template-columns: minmax(0, 1fr);
        grid-auto-flow: row;
        max-height: min(50vh, 420px);
        overflow-y: auto;
        scrollbar-gutter: stable;
    }
}

/* Present each draft position as one calm draggable row. */
.order-editor-item {
    /* Align the position, business name and grip in a predictable row. */
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr) 38px;
    align-items: center;
    gap: 9px;

    /* Preserve a compact but dependable row target. */
    min-height: 44px;
    padding: 4px 5px 4px 10px;

    /* Separate neighbouring draft positions without making them table cells. */
    border: 1px solid var(--line);
    border-radius: 8px;
    background: rgb(22 24 29 / 76%);

    /* Animate only restrained state feedback, never the row's position. */
    transition: border-color 180ms ease, background-color 180ms ease, opacity 180ms ease;
}

/* Make the saved/draft position scannable without competing with the name. */
.order-editor-position {
    /* Align one- and two-digit positions consistently. */
    font-variant-numeric: tabular-nums;

    /* Use a restrained weight and colour for structural numbering. */
    color: var(--muted);
    font-size: 12px;
    font-weight: 700;
    text-align: center;
}

/* Protect long category names inside the flexible centre column. */
.order-editor-name {
    /* Allow the name to contract instead of widening the modal. */
    min-width: 0;

    /* Keep ordinary category names concise and readable. */
    overflow-wrap: anywhere;
    font-size: 14px;
    font-weight: 500;
}

/* Draw a focused grip that is available only inside the ordering workspace. */
.order-editor-handle {
    /* Remove browser defaults before applying the compact Threads control. */
    appearance: none;
    display: inline-grid;
    place-items: center;
    width: 36px;
    min-height: 36px;
    padding: 0;

    /* Give keyboard and pointer users a quiet but visible control boundary. */
    border: 1px solid var(--line);
    border-radius: 7px;
    background: transparent;
    color: var(--muted-strong);

    /* Make the double grip compact and recognisable. */
    font: inherit;
    font-size: 17px;
    letter-spacing: -3px;
    cursor: grab;
    touch-action: none;
    user-select: none;
}

/* Expose the grip clearly during hover, keyboard focus or keyboard pickup. */
.order-editor-handle:hover,
.order-editor-handle:focus-visible,
.order-editor-handle[aria-pressed="true"] {
    /* Coordinate every interaction state with the user's current accent. */
    outline: 0;
    border-color: var(--accent-hover);
    background: rgb(var(--accent-rgb) / 18%);
    color: var(--ink);
    box-shadow: 0 0 0 3px var(--accent-focus);
}

/* Use the expected physical cursor while an item is held. */
.order-editor-handle:active,
.order-editor-handle[aria-pressed="true"] {
    /* Reinforce that the draft row is currently being moved. */
    cursor: grabbing;
}

/* Dim the carried row without removing its spatial reference. */
.order-editor-item.is-dragging {
    /* Keep enough contrast for the category name to remain identifiable. */
    opacity: 0.55;
}

/* Highlight the exact business row whose position will be replaced on drop. */
.order-editor-item.is-drag-over {
    /* Illuminate the complete target row rather than an ambiguous gap. */
    border-color: var(--accent-hover);
    background: rgb(var(--accent-rgb) / 24%);
    box-shadow: inset 0 0 0 1px rgb(var(--accent-rgb) / 42%), 0 0 14px rgb(var(--accent-rgb) / 24%);
}

/* Keep Reset, A-Z and Save in their requested left-to-right workflow order. */
.order-editor-actions {
    /* Let the short controls wrap safely under enlarged text. */
    flex-wrap: wrap;
}

/* Give the Product Fields hierarchy enough room for its three connected columns. */
.product-fields-page {
    /* Expand only this relationship browser beyond the ordinary single-table page width. */
    width: min(100%, 1240px);
}

/* Give the two-level Fabric browser a comfortable but focused desktop width. */
.fabrics-page {
    /* Accommodate both live setup-count columns without compressing Fabric names. */
    width: min(100%, 1200px);
}

/* Give the Product-scoped Size browser room for actions, state, and live history. */
.sizes-page {
    /* Give the five connected mapping panels room while retaining comfortable outer margins. */
    width: min(100%, 1480px);
}

/* Keep the universal Job Worker search on the toolbar's right edge. */
.job-worker-table-search {
    /* Consume remaining toolbar room while retaining the standard search-field cap. */
    margin-left: auto;
}

/* Reserve exactly enough room for Edit, Active state, and Delete actions. */
.job-worker-table__actions {
    /* Keep all three compact Threads actions on one predictable row. */
    width: 132px;
    white-space: nowrap;
}

/* Keep Job Worker state badges in one compact comparable column. */
.job-worker-table__status {
    /* Reserve enough room for both Active and Inactive labels. */
    width: 116px;
}

/* Align derived Card counts for quick historical comparison. */
.job-worker-table__item-count {
    /* Keep the complete heading readable without competing with the worker name. */
    width: 150px;
    text-align: right;
}

/* Balance a compact Product selector against the detailed Size table. */
.product-field-browser.size-browser {
    /* Keep Products predictable and give all remaining room to reusable Sizes. */
    grid-template-columns: 300px minmax(0, 1fr);

    /* Let each panel follow its own content height naturally. */
    align-items: start;
}

/* Allow Size filter panels and immediate action tooltips to escape the inset panel. */
.size-browser #sizes-column,
.size-browser #sizes-column .product-field-column__table-wrapper {
    /* Avoid clipping floating table controls at the contextual panel boundary. */
    overflow: visible;
}

/* Let the complete desktop Size list participate in the panel's natural height. */
.size-browser #sizes-column .product-field-column__table-wrapper {
    /* Remove the shared hierarchy cap that otherwise lets later rows paint outside the border. */
    max-height: none;
}

/* Keep the Size search and global reset action together above the table. */
.size-table-toolbar {
    /* Put the compact reset action before the flexible search field. */
    display: grid;

    /* Let search take the remaining width while keeping its action readable. */
    grid-template-columns: auto minmax(180px, 1fr);

    /* Align the button with the bottom edge of the labelled search input. */
    align-items: end;
    gap: 10px;

    /* Separate contextual controls from the panel header and table. */
    padding: 12px;

    /* Draw one quiet boundary before the table headings begin. */
    border-bottom: 1px solid var(--line);

    /* Keep the toolbar on the same inset surface as the Size table. */
    background: rgb(15 17 21 / 36%);
}

/* Adapt the shared Threads universal search to this contextual Size toolbar. */
.size-table-search {
    /* Keep this grid child in its assigned column instead of using report-toolbar alignment. */
    margin-left: 0;

    /* Use every remaining pixel without forcing the contextual panel wider. */
    width: 100%;
    min-width: 0;
}

/* Let the standard Threads search field fill its contextual toolbar column. */
.size-table-search input {
    /* Remove the wider report table's desktop cap inside this two-panel browser. */
    width: 100%;
}

/* Reserve exactly enough room for Edit, Active state, and Delete actions. */
.size-table__actions {
    /* Keep all three standard square controls on one row. */
    width: 132px;
    white-space: nowrap;
}

/* Keep Size status badges in a compact comparable column. */
.size-table__status {
    /* Reserve enough room for both Active and Inactive labels. */
    width: 116px;
}

/* Align live Card counts for quick comparison. */
.size-table__item-count {
    /* Keep the complete heading readable without dominating the Size name. */
    width: 150px;
    text-align: right;
}

/* Present Size availability as a restrained reusable status badge. */
.size-status-badge,
.job-worker-status-badge {
    /* Keep the short state label on one balanced line. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 64px;

    /* Use compact capsule spacing consistent with setup-count badges. */
    padding: 4px 8px;
    border-radius: 999px;

    /* Make available Sizes positive without overpowering their names. */
    background: rgb(91 207 141 / 13%);
    color: var(--success);
    font-size: 11px;
    font-weight: 700;
}

/* Show an intentionally retired Size as quiet history rather than an error. */
.size-status-badge.is-inactive,
.job-worker-status-badge.is-inactive {
    /* Use a neutral surface and supporting text for retained history. */
    background: rgb(255 255 255 / 6%);
    color: var(--muted);
}

/* Keep combination-specific ordering visually separate from reusable Size maintenance. */
.size-sort-section {
    position: relative;
    margin-top: 18px;
    padding: 18px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: rgb(15 17 21 / 56%);
    overflow: visible;
}

/* Quiet the workspace until a Product owns every required production Field. */
.size-sort-section.is-awaiting-selection {
    opacity: 0.7;
}

/* Balance the explanation against the three deliberate draft actions. */
.size-sort-section__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 18px;
}

.size-sort-section__header h2 {
    margin: 0;
    font-size: 18px;
}

.size-sort-section__header p,
.size-sort-guidance {
    margin: 5px 0 0;
    color: var(--muted);
    font-size: 13px;
}

/* Keep A-Z, Revert, and Save together so their draft lifecycle reads naturally. */
.size-sort-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 8px;
}

.size-sort-actions .button {
    min-height: 38px;
    padding: 8px 13px;
}

/* Give CG, Sleeve, and Cut equal weight on the complete combination line. */
.size-sort-dimensions {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
    margin-top: 18px;
}

.size-sort-dimension {
    min-width: 0;
}

.size-sort-dimension__label {
    display: block;
    margin-bottom: 6px;
    color: var(--ink);
    font-size: 12px;
    font-weight: 700;
}

/* Explain the mapping before exposing its ordered rows. */
.size-sort-order-panel {
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--line);
}

.size-sort-guidance {
    margin-top: 0;
}

/* Use a numbered, two-column flow that remains quick to scan for long Size sets. */
.size-sort-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    margin: 12px 0 0;
    padding: 0;
    list-style: none;
    counter-reset: size-sort-position;
}

.size-sort-list__item {
    counter-increment: size-sort-position;
    display: grid;
    grid-template-columns: 28px 28px minmax(0, 1fr);
    align-items: center;
    min-height: 44px;
    padding: 6px 10px;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: rgb(23 25 30 / 82%);
    cursor: grab;
    transition: border-color 120ms ease, background-color 120ms ease, opacity 120ms ease;
}

.size-sort-list__item::before {
    content: counter(size-sort-position) ".";
    color: var(--muted);
    font-size: 11px;
    font-weight: 700;
}

.size-sort-list__item.is-dragging {
    opacity: 0.45;
}

.size-sort-list__item.is-drag-over {
    border-color: var(--accent-hover);
    background: rgb(var(--accent-rgb) / 14%);
}

.size-sort-list__grip {
    color: var(--muted);
    font-size: 18px;
    user-select: none;
}

.size-sort-list__label {
    min-width: 0;
    overflow-wrap: anywhere;
    font-weight: 500;
}

/* Make an unavailable custom selector read like the rest of Threads' disabled controls. */
.size-sort-select .threads-select__trigger:disabled {
    color: var(--muted);
    cursor: not-allowed;
    opacity: 0.62;
}

/* Arrange the complete CG → Sleeve → Cut → All Sizes → Sort order workflow in one line. */
.size-mapping-panels {
    display: grid;
    grid-template-columns: repeat(3, minmax(130px, 0.78fr)) repeat(2, minmax(190px, 1.35fr));
    gap: 10px;
    margin-top: 16px;
}

/* Give each stage a clear independent Threads surface without breaking the connected workflow. */
.size-mapping-panel {
    min-width: 0;
    min-height: 330px;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: rgb(12 14 18 / 58%);
}

.size-mapping-panel > header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8px;
    min-height: 58px;
    padding: 12px;
    border-bottom: 1px solid var(--line);
    background: rgb(255 255 255 / 2%);
}

.size-mapping-panel > header h3 {
    margin: 0;
    color: var(--ink);
    font-size: 14px;
}

.size-mapping-panel > header span {
    color: var(--muted);
    font-size: 10px;
    text-align: right;
}

/* Stack permanent Field Values as direct single-choice rows instead of dropdown menus. */
.size-mapping-choice-list {
    display: grid;
    align-content: start;
    gap: 6px;
    padding: 9px;
}

.size-mapping-choice {
    width: 100%;
    min-height: 40px;
    padding: 8px 10px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: rgb(24 26 31 / 78%);
    color: var(--ink);
    font: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
    transition: border-color 120ms ease, background-color 120ms ease, box-shadow 120ms ease;
}

.size-mapping-choice:hover,
.size-mapping-choice:focus-visible {
    outline: none;
    border-color: var(--accent-hover);
    background: rgb(var(--accent-rgb) / 12%);
}

.size-mapping-choice[aria-selected="true"] {
    border-color: var(--accent-hover);
    background: rgb(var(--accent-rgb) / 20%);
    color: var(--ink);
    font-weight: 700;
    box-shadow: inset 3px 0 0 var(--accent);
}

/* Contain long Size sets inside their own two drag destinations. */
.size-mapping-size-list {
    display: grid;
    grid-template-columns: 1fr;
    align-content: start;
    gap: 6px;
    min-height: 270px;
    max-height: 420px;
    margin: 0;
    padding: 9px;
    overflow-y: auto;
    list-style: none;
}

.size-mapping-size-list .size-sort-list__item {
    grid-template-columns: 24px minmax(0, 1fr);
    min-height: 40px;
    margin: 0;
}

/* Match Size names to the compact CG, Sleeve, and Cut choice typography. */
.size-mapping-size-list .size-sort-list__label {
    /* Change only the business label, leaving grips, positions, and the red return action distinct. */
    font-size: 13px;
}

.size-mapping-size-list .size-sort-list__item::before {
    display: none;
}

/* Keep visible one-based positions only in the included Sort order panel. */
.size-mapping-panel--order .size-sort-list {
    /* Fill the fifth panel so no blank-looking lower area sits outside the drop surface. */
    flex: 1;

    /* Preserve the ordinary complete panel width while the flexible height grows. */
    width: 100%;

    counter-reset: size-sort-position;
}

/* Make the Sort order panel one full-height destination beneath its fixed heading. */
.size-mapping-panel--order {
    /* Stack the heading and list while allowing the list to occupy every remaining pixel. */
    display: flex;
    flex-direction: column;
}

.size-mapping-panel--order .size-sort-list__item {
    counter-increment: size-sort-position;
    /* Reserve one final compact column for the direct red return action. */
    grid-template-columns: 26px 24px minmax(0, 1fr) 26px;
}

.size-mapping-panel--order .size-sort-list__item::before {
    content: counter(size-sort-position) ".";
    display: block;
    color: var(--muted);
    font-size: 10px;
    font-weight: 700;
}

/* Give every included Size an immediate Threads-styled route back to All Sizes. */
.size-sort-list__remove {
    /* Keep the action compact so the Size name retains the useful row width. */
    display: inline-grid;
    place-items: center;
    width: 24px;
    height: 24px;
    padding: 0;

    /* Use semantic danger red because this action removes the Size from the allowed subset. */
    border: 1px solid rgb(244 98 98 / 48%);
    border-radius: 6px;
    background: rgb(122 31 36 / 20%);
    color: #ff777d;

    /* Match the deliberate compact action language used throughout Threads. */
    font: inherit;
    font-size: 18px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    transition: border-color 120ms ease, background-color 120ms ease, color 120ms ease, box-shadow 120ms ease;
}

/* Make the removal action respond immediately to both pointer and keyboard attention. */
.size-sort-list__remove:hover,
.size-sort-list__remove:focus-visible {
    outline: none;
    border-color: #ff777d;
    background: rgb(159 40 47 / 34%);
    color: #fff;
    box-shadow: 0 0 0 3px rgb(244 98 98 / 14%);
}

.size-mapping-panel__empty {
    margin: 0;
    padding: 14px 10px;
    color: var(--muted);
    font-size: 12px;
    line-height: 1.45;
    list-style: none;
}

/* Balance a compact Product selector against a Fabric panel using all remaining room. */
.product-field-browser.fabric-browser {
    /* Keep Products predictably compact and give every remaining pixel to Fabrics. */
    grid-template-columns: 300px minmax(0, 1fr);

    /* Let each panel use its own content height so Fabric height changes remain visible. */
    align-items: start;

    /* Smooth any genuine column-size change instead of snapping between layouts. */
    transition: grid-template-columns 720ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Let the contextual Fabric panel settle gently between unavailable and ready states. */
.fabric-browser #fabrics-column {
    /* Expand from the Product-side edge so the relationship remains visually clear. */
    transform-origin: left center;

    /* Smooth opacity, surface, boundary, and subtle expansion together. */
    transition: border-color 720ms ease, opacity 720ms ease, background-color 720ms ease, transform 720ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Give the awaiting-selection Fabric panel a restrained contracted resting state. */
.fabric-browser #fabrics-column.is-awaiting-selection {
    /* Contract only visually so the grid still reserves the complete remaining width. */
    transform: scaleX(0.985);
}

/* Keep the three Fabric controls together inside a predictable action column. */
.fabric-table__actions {
    /* Fit only the standard Edit and Delete controls without wasted drag space. */
    width: 94px;
    white-space: nowrap;
}

/* Keep comparable default colour counts aligned neatly. */
.fabric-table__colours {
    /* Reserve a compact column and align its numeric values. */
    width: 118px;
    text-align: right;
}

/* Keep live PPC coverage compact and easy to compare beside Default colours. */
.fabric-table__ppc-count {
    /* Reserve enough room for the readable zero-rule pending badge. */
    width: 122px;

    /* Align numeric counts and their heading consistently at the right edge. */
    text-align: right;
}

/* Keep live Category-mapping coverage aligned beside PPC coverage. */
.fabric-table__mapping-count {
    /* Match the readable Pending badge width used by the PPC-rule column. */
    width: 122px;

    /* Align numeric counts and their heading consistently at the right edge. */
    text-align: right;
}

/* Present either live Fabric-setup count as a quiet compact status badge. */
.fabric-setup-count-badge {
    /* Keep the count on one line without stretching the complete table cell. */
    display: inline-flex;

    /* Centre the count text inside its small rounded surface. */
    align-items: center;

    /* Keep short positive counts visually balanced. */
    justify-content: center;

    /* Give positive counts a stable minimum width for quick vertical scanning. */
    min-width: 28px;

    /* Add restrained breathing room around the live count. */
    padding: 4px 7px;

    /* Match the soft capsule geometry used by other compact Threads statuses. */
    border-radius: 999px;

    /* Separate configured counts gently from the table surface. */
    background: rgb(255 255 255 / 6%);

    /* Keep configured counts readable without competing with Fabric names. */
    color: var(--muted);

    /* Use a compact weight that remains legible at table density. */
    font-size: 11px;

    /* Give both numeric and Pending states a clear status-label weight. */
    font-weight: 700;

    /* Prevent the readable Pending label from wrapping within its column. */
    white-space: nowrap;
}

/* Make a zero-count Fabric setup area visibly pending without treating it as an error. */
.fabric-setup-count-badge.is-pending {
    /* Use warning colour because setup is incomplete rather than broken. */
    color: var(--warning);

    /* Add a restrained warning surface that remains compatible with every accent. */
    background: rgb(216 179 91 / 13%);
}

/* Let Fabric filter dropdowns escape the contextual table instead of being clipped. */
.fabric-browser #fabrics-column .product-field-column__table-wrapper {
    /* Allow both checkbox panels to float above later rows and the card boundary. */
    overflow: visible;

    /* Let the page's stable scrollbar handle long Fabric lists naturally. */
    max-height: none;
}

/* Let open Fabric filter panels extend beyond the contextual column boundary. */
.fabric-browser #fabrics-column {
    /* Preserve the floating dropdowns instead of clipping them at rounded panel edges. */
    overflow: visible;
}

/* Retain synchronized reveal clipping while the Fabric column itself expands. */
.fabric-browser #fabrics-column.is-layout-height-expanding {
    /* Keep newly arriving structural content inside the moving panel boundary. */
    overflow: hidden;
}

/* Reserve temporary invisible page space while any structural contraction settles scrolling. */
.layout-scroll-cushion {
    /* Keep the spacer out of every visual and pointer interaction. */
    visibility: hidden;
    pointer-events: none;

    /* Prevent an empty block from introducing accidental horizontal space. */
    width: 1px;

    /* Remove margins so JavaScript's measured dynamic height remains exact. */
    margin: 0;
}

/* Separate the Fabric ordering explanation from its connected browser. */
.fabric-order-hint {
    /* Match the rhythm used beneath Product Fields. */
    margin-top: 18px;
}

/* Arrange Product, Field, and Field Value as one left-to-right column browser. */
.product-field-browser {
    /* Use three equal columns so each hierarchy level receives predictable space. */
    display: grid;

    /* Keep all three hierarchy levels balanced on wide screens. */
    grid-template-columns: repeat(3, minmax(0, 1fr));

    /* Separate the columns without breaking their visible relationship. */
    gap: 16px;

    /* Give the hierarchy comfortable distance from its page introduction. */
    margin-top: 34px;
}

/* Present each hierarchy level as a contained Threads inset panel. */
.product-field-column {
    /* Allow table content to shrink without forcing the complete grid wider. */
    min-width: 0;

    /* Clip table corners cleanly inside the panel boundary. */
    overflow: hidden;

    /* Draw a restrained relationship-panel edge. */
    border: 1px solid var(--line);

    /* Use friendly corners that remain slightly tighter than the outer card. */
    border-radius: 12px;

    /* Place the hierarchy level on a deeper glass inset. */
    background: rgb(15 17 21 / 58%);

    /* Animate selection availability gently. */
    transition: border-color 150ms ease, opacity 150ms ease, background-color 150ms ease;
}

/* Quiet a child column until its required parent row is selected. */
.product-field-column.is-awaiting-selection {
    /* Reduce emphasis while keeping the hierarchy's shape understandable. */
    opacity: 0.62;
}

/* Hold each hierarchy title above its matching compact table. */
.product-field-column__header {
    /* Keep a consistent header height across all three columns. */
    min-height: 92px;

    /* Add compact but comfortable space around title and context. */
    padding: 18px;

    /* Draw a quiet boundary before the table rows begin. */
    border-bottom: 1px solid var(--line);

    /* Separate the header slightly from the deeper table surface. */
    background: rgb(31 33 39 / 52%);
}

/* Keep a contextual heading and its compact Add action on one row. */
.product-field-column__header--with-action {
    /* Place context at the left and creation at the right. */
    display: flex;

    /* Align short and wrapped content along their upper edge. */
    align-items: flex-start;

    /* Preserve useful distance between title context and its action. */
    justify-content: space-between;

    /* Keep the two groups from touching on narrower columns. */
    gap: 12px;
}

/* Style each hierarchy-level heading independently from the page heading. */
.product-field-column__header h2 {
    /* Remove browser heading margins. */
    margin: 0;

    /* Keep the compact column title distinct without competing with the page title. */
    font-size: 18px;
}

/* Style the current parent context beneath each hierarchy title. */
.product-field-column__header p {
    /* Add a small relationship gap beneath the column title. */
    margin: 6px 0 0;

    /* Use Threads's supporting text colour. */
    color: var(--muted);

    /* Keep changing Product and Field names compact. */
    font-size: 12px;

    /* Allow long future names to wrap naturally. */
    line-height: 1.35;
}

/* Keep contextual hierarchy creation actions compact. */
.product-field-add-button {
    /* Use a smaller target than the page's principal management action. */
    min-height: 34px;

    /* Add balanced compact button spacing. */
    padding: 7px 10px;

    /* Preserve a readable but secondary action label. */
    font-size: 12px;

    /* Prevent the short action from wrapping inside its narrow column. */
    white-space: nowrap;
}

/* Keep contextual alphabetical reset and creation actions together. */
.product-field-column__header-actions {
    /* Present both related actions on one compact row when space permits. */
    display: flex;

    /* Let narrow columns move one action beneath the other without overflow. */
    flex-wrap: wrap;

    /* Keep both controls anchored to the heading's right edge. */
    justify-content: flex-end;

    /* Preserve a small readable space between the ordering and creation actions. */
    gap: 7px;
}

/* Match the compact hierarchy action scale for alphabetical resets. */
.product-field-reset-order-button {
    /* Use the same dependable height as the neighbouring Add action. */
    min-height: 34px;

    /* Keep the secondary action compact inside a contextual column heading. */
    padding: 7px 10px;

    /* Preserve the same readable scale as other hierarchy actions. */
    font-size: 12px;

    /* Keep the short reset label together. */
    white-space: nowrap;
}

/* Keep both Product Fields header actions compact enough to remain on one row. */
.product-field-column__header-actions .button {
    /* Override the later general button height only inside these narrow column headers. */
    min-height: 34px;

    /* Preserve comfortable click space without forcing the action group to wrap. */
    padding: 7px 9px;

    /* Use the established compact hierarchy-control scale. */
    font-size: 12px;
}

/* Prevent Product Fields dialog actions from shifting when their progress text appears. */
.product-field-dialog-submit {
    /* Reserve enough room for Create, Creating, Save, and Saving labels from the outset. */
    min-width: 160px;

    /* Keep each short status label on one stable line. */
    white-space: nowrap;
}

/* Keep permanent-delete buttons completely still while their longer labels change. */
.product-field-dialog-delete-submit {
    /* Reserve one fixed footprint for both Delete permanently and Deleting status text. */
    width: 190px;

    /* Prevent the dialog action row from shrinking this destructive control. */
    flex: 0 0 190px;
}

/* Distinguish a relationship-blocked deletion from an in-flight request. */
.product-field-dialog-delete-submit.is-blocked:disabled {
    /* Communicate that child Values must be removed before this action becomes available. */
    cursor: not-allowed;
}

/* Keep a tall hierarchy independently usable without lengthening the entire page. */
.product-field-column__table-wrapper {
    /* Reserve a practical desktop height for garment configuration lists. */
    max-height: 520px;

    /* Scroll only the current hierarchy level when it has many rows. */
    overflow: auto;
}

/* Remove wide report-table assumptions from the compact hierarchy tables. */
.product-field-table {
    /* Fill the complete inset panel width. */
    width: 100%;

    /* Keep short names and counts naturally compact. */
    min-width: 0;

    /* Keep headings visible while a long hierarchy column scrolls. */
    position: relative;
}

/*
 * Let compact hierarchy headings and their filter controls leave together.
 *
 * The shared site navigation is deliberately sticky, but table controls must
 * remain attached to their own records. Pinning this complete table head made
 * its first row disappear behind the navigation during page scrolling while
 * the lower filter row appeared to float independently above the data rows.
 */
.product-field-table thead {
    /* Preserve the browser's ordinary table flow across every hierarchy page. */
    position: static;
}

/* Tighten hierarchy table cells without making them difficult to select. */
.product-field-table th,
.product-field-table td {
    /* Use compact column-view spacing. */
    padding: 12px 10px;
}

/* Give the compact drag, edit, and delete Actions column only the room it needs. */
.product-field-table__actions-heading,
.product-field-table__actions {
    /* Keep all three square controls on one predictable row. */
    width: 132px;

    /* Centre the paired actions inside their compact cell. */
    text-align: center;

    /* Prevent the three controls from wrapping onto separate lines. */
    white-space: nowrap;
}

/* Keep Product Field drag, Edit, and Delete actions aligned as one compact control group. */
.product-field-table__action-group {
    /* Centre the complete trio within the Actions column. */
    justify-content: center;

    /* Preserve comfortable separation without making the hierarchy columns too wide. */
    gap: 5px;
}

/* Keep compact child totals aligned along the right edge. */
.product-field-table__count-heading,
.product-field-table__count {
    /* Reserve just enough room for a short count and heading. */
    width: 64px;

    /* Align comparable totals cleanly down the column. */
    text-align: right;
}

/* Show that Product and Field rows select the next hierarchy level. */
.product-field-selectable-row {
    /* Communicate the row's navigation-like selection action. */
    cursor: pointer;
}

/* Preserve one unmistakable current selection independently from hover. */
.product-field-selectable-row.is-selected td {
    /* Use a restrained burgundy surface behind the selected relationship. */
    background: rgb(var(--accent-rgb) / 24%);
}

/* Mark only the selected row's outer left edge instead of repeating inside every cell. */
.product-field-selectable-row.is-selected td:first-child {
    /* Draw one inset accent marker without changing table geometry. */
    box-shadow: inset 3px 0 0 var(--accent-hover);
}

/* Give keyboard-selected hierarchy rows the same accessible focus language as form fields. */
.product-field-selectable-row:focus-visible {
    /* Remove the browser's inconsistent default row outline. */
    outline: 0;

    /* Draw the focus treatment inside the row so it is never clipped by the panel. */
    box-shadow: inset 0 0 0 3px var(--accent-focus);
}

/* Keep the hierarchy-wide drag explanation comfortably separated beneath the columns. */
.product-fields-page .product-order-hint {
    /* Add breathing room below the three connected panels. */
    margin-top: 18px;
}

/* Stack the hierarchy columns when a tablet cannot keep all three readable. */
@media (max-width: 980px) {
    .product-field-browser {
        /* Turn the horizontal explorer into the same logical top-to-bottom sequence. */
        grid-template-columns: 1fr;
    }

    /* Stack the two Fabric levels in the same natural selection order. */
    .product-field-browser.fabric-browser {
        /* Let each contextual table use the full narrow-screen width. */
        grid-template-columns: 1fr;
    }

    /* Stack Products and Sizes in the same natural contextual order. */
    .product-field-browser.size-browser {
        /* Give both tables the complete narrow-screen width. */
        grid-template-columns: 1fr;
    }

    /* Stack the Size toolbar when a narrow screen cannot fit both controls comfortably. */
    .size-table-toolbar {
        /* Preserve a readable full-width search field beneath the reset action. */
        grid-template-columns: 1fr;
    }

    .size-sort-section__header {
        flex-direction: column;
    }

    .size-sort-actions {
        justify-content: flex-start;
    }

    .size-sort-dimensions,
    .size-sort-list {
        grid-template-columns: 1fr;
    }

    .size-mapping-panels {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .size-mapping-panel--sizes {
        grid-column: span 3;
        min-height: 240px;
    }

    .size-mapping-size-list {
        min-height: 180px;
        max-height: 320px;
    }

    .product-field-column__table-wrapper {
        /* Avoid an unnecessarily tall repeated scroll region on narrow screens. */
        max-height: 420px;
    }

    /* Restore the deliberate contained Size-table scroller at the stacked breakpoint. */
    .size-browser #sizes-column .product-field-column__table-wrapper {
        /* Override the more specific desktop natural-height rule only on narrow screens. */
        max-height: 420px;

        /* Keep every later Size row inside the bordered table rather than painting beyond it. */
        overflow: auto;
    }
}

/* Explain protected destructive actions through a conventional disabled state. */
.user-table-row-action:disabled {
    /* Remove active colour from an unavailable action. */
    color: var(--muted);

    /* Use the quietest available boundary. */
    border-color: var(--line);

    /* Remove the raised action surface. */
    background: transparent;

    /* Communicate that the protected action cannot be activated. */
    cursor: not-allowed;

    /* Keep the label readable while reducing its emphasis. */
    opacity: 0.5;
}

/* Hide explanatory text visually while keeping it available to assistive technology. */
.visually-hidden {
    /* Remove the text from ordinary layout without using display none. */
    position: absolute;

    /* Reduce the hidden box to one pixel. */
    width: 1px;

    /* Match the hidden box height to its width. */
    height: 1px;

    /* Remove internal spacing that could affect layout. */
    padding: 0;

    /* Pull the tiny box outside ordinary visible flow. */
    margin: -1px;

    /* Hide any portion extending beyond the one-pixel box. */
    overflow: hidden;

    /* Clip the box for older browser accessibility patterns. */
    clip: rect(0, 0, 0, 0);

    /* Use the modern clipping method for current browsers. */
    clip-path: inset(50%);

    /* Remove any visual border. */
    border: 0;

    /* Prevent hidden words from wrapping into a larger box. */
    white-space: nowrap;
}

/* Stripe the visible sequence only. Lifecycle tabs, filtering and pagination
   keep non-current records in the DOM with `hidden`, so those rows must not
   consume an odd/even position. */
.user-table__data-row:nth-child(even of .user-table__data-row:not([hidden])) {
    /* Use a quiet translucent shade so neighbouring records are easier to track. */
    background: rgb(255 255 255 / 3.5%);
}

/* Define one soft breathing light around the complete hovered data row. */
@keyframes user-table-row-glow {
    /* Begin and finish with a restrained light around the row's combined outline. */
    0%,
    100% {
        /* Paint one shallow accent reflection around the row instead of every cell edge. */
        filter: drop-shadow(0 0 4px rgb(var(--accent-readable-rgb) / 10%));
    }

    /* Brighten the same complete outline gently at the middle of each cycle. */
    50% {
        /* Expand one soft reflection without creating bright internal column seams. */
        filter: drop-shadow(0 0 10px rgb(var(--accent-readable-rgb) / 24%));
    }
}

/* Define the continuous colour breathing beneath one complete hovered row. */
@keyframes user-table-row-surface {
    /* Keep the resting hover colour recognisably Threads. */
    0%,
    100% {
        background-color: rgb(var(--accent-rgb) / 25%);
    }

    /* Increase the shared tint without overwhelming the row text. */
    50% {
        background-color: rgb(var(--accent-rgb) / 40%);
    }
}

/* Treat the hovered table row as one composited shape for its surrounding light. */
.user-table__data-row:hover {
    /* Make one row-wide glow breathe slowly instead of repeating it in every cell. */
    animation: user-table-row-glow 2.4s ease-in-out infinite;
}

/* Give adjoining cells one identical tint so their shared boundaries disappear visually. */
.user-table__data-row:hover td {
    /* Animate colour only; cell-level inset shadows caused the unwanted bright seams. */
    animation: user-table-row-surface 2.4s ease-in-out infinite;
}

/* Respect people who ask their operating system to reduce interface motion. */
@media (prefers-reduced-motion: reduce) {
    /* Replace the breathing outer light with one steady row-wide treatment. */
    .user-table__data-row:hover {
        /* Stop the repeating row animation while retaining one continuous glow. */
        animation: none;

        /* Keep a restrained light around the complete row outline. */
        filter: drop-shadow(0 0 6px rgb(var(--accent-readable-rgb) / 16%));
    }

    /* Replace the breathing row animation with one steady hover treatment. */
    .user-table__data-row:hover td {
        /* Stop the repeating animation while retaining clear hover feedback. */
        animation: none;

        /* Keep a steady restrained burgundy highlight on the hovered record. */
        background-color: rgb(var(--accent-rgb) / 32%);

        /* No cell shadow is added, so internal boundaries and selected-row markers remain intact. */
    }
}

/* Give column headings a quiet administrative label treatment. */
.user-table th {
    /* Use the muted colour so account values remain visually dominant. */
    color: var(--muted);

    /* Keep the compact heading labels readable. */
    font-size: 12px;

    /* Give the headings enough weight to define the columns. */
    font-weight: 700;

    /* Separate compact uppercase letters slightly. */
    letter-spacing: 0.06em;

    /* Present both column headings consistently in uppercase. */
    text-transform: uppercase;
}

/* Turn a column heading into a clean full-width sorting control. */
.user-table-sort-button {
    /* Place the heading label beside its priority and direction indicator. */
    display: inline-flex;

    /* Vertically centre both parts of the sortable heading. */
    align-items: center;

    /* Preserve a compact gap before an active sort indicator. */
    gap: 7px;

    /* Remove ordinary button borders from the table heading. */
    border: 0;

    /* Remove ordinary button padding because the table cell already provides it. */
    padding: 0;

    /* Keep the sorting control on the existing heading surface. */
    background: transparent;

    /* Inherit the heading's muted inactive colour. */
    color: inherit;

    /* Reuse the heading's uppercase Ubuntu typography. */
    font: inherit;

    /* Preserve the heading's uppercase presentation. */
    text-transform: inherit;

    /* Preserve the heading's compact letter spacing. */
    letter-spacing: inherit;

    /* Show that the heading can change row order. */
    cursor: pointer;
}

/* Brighten sortable headings during pointer or keyboard interaction. */
.user-table-sort-button:hover,
.user-table-sort-button:focus-visible,
.user-table-sort-button.is-sorted {
    /* Remove the browser's inconsistent focus outline. */
    outline: 0;

    /* Use Threads's brighter burgundy for active sorting controls. */
    color: var(--accent-hover);
}

/* Style the compact priority number and direction arrow. */
.user-table-sort-indicator {
    /* Keep the indicator wide enough to avoid shifting the heading when it appears. */
    min-width: 24px;

    /* Preserve priority and arrow characters on one line. */
    white-space: nowrap;

    /* Make the active sort state slightly easier to scan. */
    font-weight: 700;
}

/* Keep ordinary table values clear against the dark surface. */
.user-table td {
    /* Use the primary Threads text colour for account information. */
    color: var(--ink);

    /* Keep account information comfortably readable. */
    font-size: 14px;
}

/* Keep one product glyph and its matching name together inside the name cell. */
.product-table-name {
    /* Align the artwork and text on one readable horizontal line. */
    display: inline-flex;

    /* Centre differently shaped glyphs against the product-name text. */
    align-items: center;

    /* Preserve a small breathing space between artwork and text. */
    gap: 10px;
}

/* Display each garment illustration as a compact consistent table glyph. */
.product-table-glyph {
    /* Give every glyph the same visible width. */
    width: 42px;

    /* Give every glyph the same visible height. */
    height: 42px;

    /* Preserve the complete garment without stretching or cropping it. */
    object-fit: contain;

    /* Prevent the glyph from shrinking when the product name needs space. */
    flex: 0 0 42px;

    /* Add restrained depth that matches the dimensional glyph artwork. */
    filter: drop-shadow(0 4px 7px rgb(0 0 0 / 24%));
}

/* Keep the custom-order instruction quiet beside the product-master title. */
.product-table-order-hint {
    /* Separate the instruction from the table title without creating a new row. */
    margin-left: 10px;

    /* Use the supporting Threads colour for this interaction hint. */
    color: var(--muted);

    /* Keep the instruction smaller than the table title. */
    font-size: 12px;

    /* Keep the hint from competing with the title's weight. */
    font-weight: 400;
}

/* Remove the unnecessary line beneath the final account row. */
.user-table tbody tr:last-child td {
    /* Let the final row meet the rounded table boundary cleanly. */
    border-bottom: 0;
}

/* Style the fallback message shown when the user list is empty. */
.user-table__empty {
    /* Centre the empty-state explanation across both columns. */
    text-align: center;

    /* Use the muted colour for the supporting empty-state message. */
    color: var(--muted);

}

/* Give the message room to read as a deliberate empty state rather than a single
   thin line left behind where the rows were. It also gives the arrival something
   to actually move, which a 43px sliver did not. The table's own cell padding is
   the more specific rule, so this has to name the cell to win. */
.user-table td.user-table__empty {
    padding-block: 46px;
}

/* Distinguish an AJAX loading failure from an ordinary no-results state. */
.user-table__empty--error {
    /* Use the brighter burgundy to identify the failed loading state. */
    color: var(--accent-hover);
}

/* Highlight letters matched by universal search inside visible table values. */
.user-table-search-highlight {
    /* Place the matching letters on Threads's warm burgundy highlight. */
    background: rgb(181 54 76 / 34%);

    /* Keep highlighted text bright and readable against the dark table. */
    color: var(--ink);

    /* Add a little horizontal breathing room around the matching letters. */
    padding: 1px 2px;

    /* Soften the highlight edges to match the rest of the interface. */
    border-radius: 3px;

    /* Add a restrained glow that makes the match easy to locate. */
    box-shadow: 0 0 8px rgb(181 54 76 / 28%);
}

/* Centre the contents of the homepage introduction. */
.hero {
    text-align: center;
}

/*
    Create a glass panel for the logo:
    - a translucent background lets the linen show through;
    - backdrop-filter blurs the linen behind the panel;
    - the light border catches the glass edge;
    - the shadow separates the panel from the page.
*/
.logo-panel {
    /* Create comfortable space between the logo and the glass edges. */
    padding: clamp(24px, 5vw, 48px);

    /* Draw a faint highlight around the edge of the glass. */
    border: 1px solid rgb(255 255 255 / 12%);

    /* Round the glass corners to match Threads's friendly geometry. */
    border-radius: 18px;

    /*
        Use a faint top sheen and a 28%-opaque dark tint.
        The lower opacity allows substantially more linen to show through.
    */
    background:
        linear-gradient(135deg, rgb(255 255 255 / 7%), rgb(255 255 255 / 1%)),
        rgb(25 27 32 / 28%);

    /* Add an inner glint and a soft outer shadow to create depth. */
    box-shadow:
        inset 0 1px 0 rgb(255 255 255 / 10%),
        0 22px 60px rgb(0 0 0 / 34%);

    /* Blur and enrich the linen visible through supporting browsers. */
    backdrop-filter: blur(18px) saturate(125%);

    /* Apply the same blur in Safari, which uses a prefixed property. */
    -webkit-backdrop-filter: blur(18px) saturate(125%);
}

/* Rebuild the shared Threads wordmark around the emblem chosen by the current theme. */
.threads-wordmark {
    /* Keep the emblem, Threads name, and descriptor on one horizontal line. */
    display: flex;

    /* Centre the two halves vertically as the complete wordmark changes size. */
    align-items: center;

    /* Match the designed maximum width of the original horizontal logo. */
    width: min(100%, 500px);

    /* Centre the complete composed wordmark inside its glass panel. */
    margin: 0 auto;

    /* Separate the emblem from the wordmark without losing their visual connection. */
    gap: clamp(18px, 4vw, 26px);

    /* Keep the wordmark's internal text aligned from its left edge. */
    text-align: left;
}

/* Display the approved emblem that belongs to the active accent theme. */
.threads-wordmark__emblem {
    /* Keep the emblem close to the original logo's one-quarter-width proportion. */
    width: 24%;

    /* Preserve the source artwork's square shape at every responsive width. */
    aspect-ratio: 1;

    /* Prevent the emblem from growing beyond the original 120-pixel artwork area. */
    max-width: 120px;

    /* Prevent the wordmark text from squeezing the recognisable emblem. */
    flex: 0 0 24%;

    /* Paint the same trusted theme-specific artwork used by the navigation. */
    background: var(--threads-emblem-image) center / contain no-repeat;
}

/* Stack the application name and its Kumar UP descriptor beside the emblem. */
.threads-wordmark__copy {
    /* Arrange the two text lines vertically without introducing extra HTML layout. */
    display: flex;

    /* Place the descriptor directly beneath the Threads name. */
    flex-direction: column;

    /* Keep the wordmark readable when the surrounding panel becomes narrow. */
    min-width: 0;
}

/* Match the strong white Threads lettering from the original horizontal logo. */
.threads-wordmark__name {
    /* Use the principal interface colour for the recognisable product name. */
    color: var(--ink);

    /* Scale the name fluidly while preserving the original 52-pixel maximum. */
    font-size: clamp(32px, 10vw, 52px);

    /* Give the application name the same confident weight as the original artwork. */
    font-weight: 700;

    /* Tighten the large letters slightly to reproduce the designed wordmark. */
    letter-spacing: -0.035em;

    /* Keep the name's line box close to the visible letters. */
    line-height: 1;
}

/* Preserve the quiet spaced descriptor beneath the main Threads name. */
.threads-wordmark__descriptor {
    /* Separate the descriptor slightly from the large word above it. */
    margin-top: 12px;

    /* Use the shared supporting colour so the descriptor remains secondary. */
    color: var(--muted);

    /* Scale the compact descriptor gently on smaller Dashboard panels. */
    font-size: clamp(9px, 2.4vw, 12px);

    /* Preserve the original wordmark's widely spaced uppercase treatment. */
    letter-spacing: 0.28em;

    /* Keep the descriptor visibly substantial despite its small size. */
    font-weight: 700;

    /* Prevent the short descriptor from wrapping onto another line. */
    white-space: nowrap;
}

/* Give the welcome heading breathing room beneath the logo panel. */
.hero h1 {
    margin: 32px 0 8px;
    font-size: clamp(28px, 5vw, 44px);
}

/* Give the supporting sentence Threads's quieter secondary colour. */
.hero p {
    margin: 0;
    color: var(--muted);
}

/* Remove the browser's default form margin inside the navigation bar. */
.logout-form {
    /* Let the form fit closely around its logout button. */
    margin: 0;
}

/* Keep the navigation logout action compact beside the username. */
.navigation-logout {
    /* Reduce the shared button height slightly inside the compact menu. */
    min-height: 36px;

    /* Use tighter spacing than a primary page action requires. */
    padding: 7px 11px;

    /* Match the compact size of the other navigation labels. */
    font-size: 13px;
}

/* Adapt the navigation groups when a tablet or phone has less horizontal room. */
@media (max-width: 820px) {
    .has-responsive-row-details #shirt-cards-table > thead > tr > :nth-child(4),
    .has-responsive-row-details #shirt-cards-table > tbody > .user-table__data-row > :nth-child(4) {
        display: none;
    }

    .user-table-responsive-detail-item[data-responsive-detail-key="date"] {
        display: grid;
    }

    /* Stack the page heading and Add User action on narrow screens. */
    .management-heading-row {
        /* Move the principal action beneath the heading copy. */
        flex-direction: column;

        /* Align the action naturally with the heading's left edge. */
        align-items: flex-start;
    }

    /* Let the principal Add User action remain easy to activate on narrow screens. */
    .management-add-user-button {
        /* Allow the button to fill the available management-card width. */
        width: 100%;

        /* Centre the short button label inside its full-width surface. */
        justify-content: center;
    }

    /* Let the complete heading-action group share the narrow card width. */
    .management-heading-actions {
        /* Match the stacked heading row rather than retaining desktop width. */
        width: 100%;

        /* Start secondary and primary actions from the heading's left edge. */
        justify-content: flex-start;
    }

    /* Stack role choices when two columns would feel cramped. */
    .user-dialog-roles {
        /* Give each role option its own complete row. */
        grid-template-columns: 1fr;
    }

    /* Reduce dialog edge spacing slightly on narrow screens. */
    .user-dialog-header,
    .user-dialog-form {
        /* Preserve useful content width without crowding the screen edges. */
        padding-left: 18px;

        /* Match the reduced left spacing on the right edge. */
        padding-right: 18px;
    }

    /* Move the principal destinations onto their own full-width row. */
    .navigation-menu {
        /* Place the menu row after the brand and account controls. */
        order: 3;

        /* Let the destination row use all available navigation width. */
        width: 100%;
    }

    /* Let universal search use the available narrow width. */
    .user-table-search {
        /* Allow universal search to fill its toolbar row. */
        width: 100%;
    }

    /* Stop universal search from pushing itself sideways on narrow screens. */
    .user-table-search {
        /* Align search naturally beneath the column-filter group. */
        margin-left: 0;
    }

    /* Let universal search fill the available phone or tablet width. */
    .user-table-search input {
        /* Replace the desktop limit with the complete narrow toolbar width. */
        width: 100%;
    }

    /* Let the reset control use the complete narrow toolbar width. */
    .user-table-toolbar-actions {
        /* Prevent the left action group from being squeezed beside search. */
        width: 100%;
    }

    /* Stack the table description above its export actions on narrow screens. */
    .user-table-caption-content {
        /* Place the two caption groups on separate lines. */
        flex-direction: column;

        /* Align both groups with the table's left text edge. */
        align-items: flex-start;
    }

    /* Restore horizontal table scrolling when a narrow screen cannot fit both columns. */
    .user-table-wrapper {
        /* Contain the table without forcing the complete page to become wider. */
        overflow-x: auto;
    }

    /* Keep an open filter panel inside the scrolling table on narrow screens. */
    .user-table-filter__panel {
        /* Let the panel participate in the header layout instead of floating outside it. */
        position: static;

        /* Separate the expanded panel from its compact summary control. */
        margin-top: 7px;
    }

    /* Give record count and pagination their own full-width rows on phones. */
    .user-table-footer,
    .user-table-pagination {
        flex-direction: column;
        align-items: stretch;
    }

    .user-table-pagination {
        justify-content: flex-start;
    }

    .user-table-pagination-navigation {
        flex-wrap: wrap;
    }

    .user-table-pagination .user-table-page-count {
        text-align: left;
    }
}

/* Prepare the current filtered and sorted table for paper or PDF output. */
@media print {
    /* Replace the dark application canvas with ordinary printable paper. */
    body {
        /* Use a white page background for economical printing and PDF viewing. */
        background: #ffffff;

        /* Use black as the default printable text colour. */
        color: #000000;

        /* Remove screen-only page spacing from the printed sheet. */
        padding: 0;
    }

    /* Hide navigation, interactive controls, filter rows, and notifications from exports. */
    .site-header,
    .user-table-toolbar,
    .user-table-bulk-actions,
    .user-table-pagination,
    .user-table-export-group,
    .user-table-filter-row,
    .toast-region {
        /* Remove screen-only interface elements from the printed layout. */
        display: none;
    }

    /* Selection is an on-screen operation and never belongs in reports. */
    .user-table-selection-cell {
        display: none;
    }

    /* Reports always retain the complete configured column set and never print
       the screen-only disclosure control or its duplicate detail surface. */
    .user-table-responsive-heading,
    .user-table-responsive-filter,
    .user-table-responsive-cell,
    .user-table-responsive-detail-row {
        display: none !important;
    }

    .has-responsive-row-details #shirt-cards-table > thead > tr > :is(:nth-child(4), :nth-child(5), :nth-child(8), :nth-child(9), :nth-child(10), :nth-child(11), :nth-child(12), :nth-child(13), :nth-child(14), :nth-child(15), :nth-child(17)),
    .has-responsive-row-details #shirt-cards-table > tbody > .user-table__data-row > :is(:nth-child(4), :nth-child(5), :nth-child(8), :nth-child(9), :nth-child(10), :nth-child(11), :nth-child(12), :nth-child(13), :nth-child(14), :nth-child(15), :nth-child(17)) {
        display: table-cell;
    }

    /* Let the management content occupy the printable page naturally. */
    .management-page {
        /* Replace the centred screen grid with ordinary print layout. */
        display: block;

        /* Remove screen-only outer spacing. */
        padding: 0;
    }

    /* Turn the Threads glass card into a clean printable report surface. */
    .management-card {
        /* Let the report use the complete printable width. */
        width: 100%;

        /* Remove screen-only card spacing. */
        padding: 0;

        /* Remove the glass-card boundary from paper output. */
        border: 0;

        /* Replace translucent glass with plain paper. */
        background: #ffffff;

        /* Remove screen depth from the flat printed report. */
        box-shadow: none;

        /* Disable the screen-only glass blur effect. */
        backdrop-filter: none;
    }

    /* Use dark readable text for the printed heading and supporting information. */
    .management-card h1,
    .management-description,
    .management-eyebrow,
    .user-table caption,
    .user-table th,
    .user-table td,
    .user-table-result-count,
    .user-table-page-count,
    .user-table-sort-button {
        /* Ensure every important report label prints clearly. */
        color: #000000;
    }

    /* Separate the printable table from its report heading. */
    .user-table-wrapper {
        /* Add clear space above the report table. */
        margin-top: 20px;

        /* Use a simple printable boundary around the table. */
        border-color: #888888;

        /* Avoid clipping any printable table content. */
        overflow: visible;

        /* Replace the screen surface with ordinary paper. */
        background: #ffffff;
    }

    /* Use economical grey striping for alternate printed records. */
    .user-table__data-row:nth-child(even of .user-table__data-row:not([hidden])) {
        /* Keep neighbouring printed records easy to follow. */
        background: #eeeeee;
    }

    /* Remove search highlighting decoration from the exported PDF. */
    .user-table-search-highlight {
        /* Keep matched text on the surrounding paper background. */
        background: transparent;

        /* Use ordinary printable text colour. */
        color: #000000;

        /* Remove screen-only highlight spacing. */
        padding: 0;

        /* Remove the screen-only highlight glow. */
        box-shadow: none;
    }
}

/* Centre authentication pages vertically and horizontally in the browser window. */
.auth-page {
    /* Use grid so the login shell can be centred with one alignment rule. */
    display: grid;

    /* Place the login shell in the middle of the available page area. */
    place-items: center;

    /* Use slightly smaller outer spacing on narrow screens than the homepage uses. */
    padding: 24px;
}

/* Limit the login experience to a comfortable form width. */
.auth-shell {
    /* Allow the shell to fill a phone while stopping it from becoming too wide. */
    width: min(100%, 440px);
}

/* Present the complete login form as an Threads glass panel. */
.login-card {
    /* Add generous space between the card edge and its contents. */
    padding: clamp(28px, 7vw, 42px);

    /* Draw a faint highlight around the edge of the glass. */
    border: 1px solid rgb(255 255 255 / 12%);

    /* Give the glass card soft Threads corners. */
    border-radius: 18px;

    /* Let the linen remain visible through a restrained dark tint. */
    background:
        linear-gradient(135deg, rgb(255 255 255 / 8%), rgb(255 255 255 / 2%)),
        rgb(25 27 32 / 38%);

    /* Add an inner glint and a deep shadow so the glass has physical depth. */
    box-shadow:
        inset 0 1px 0 rgb(255 255 255 / 10%),
        0 24px 70px rgb(0 0 0 / 42%);

    /* Blur and enrich the linen visible through browsers that support this property. */
    backdrop-filter: blur(20px) saturate(125%);

    /* Apply the same glass blur in Safari using its prefixed property. */
    -webkit-backdrop-filter: blur(20px) saturate(125%);
}

/* Give the brand a clear visual area above the form heading. */
.login-brand {
    /* Add space below the logo before the heading begins. */
    margin-bottom: 28px;
}

/* Keep the live-themed Threads wordmark sharp and responsive inside the login card. */
.login-logo {
    /* Preserve the shared flex row so the emblem retains its visible square size. */
    display: flex;

    /* Let the logo fill the card while respecting its designed maximum width. */
    width: min(100%, 320px);

    /* Centre the logo horizontally inside the card. */
    margin: 0 auto;
}

/* Separate the login introduction from the form controls beneath it. */
.login-heading {
    /* Add breathing room between the heading group and the first input. */
    margin-bottom: 28px;

    /* Centre the short welcome message under the logo. */
    text-align: center;
}

/* Style the login page's primary heading. */
.login-heading h1 {
    /* Remove the browser's default heading margin. */
    margin: 0;

    /* Make the heading prominent without overwhelming the compact card. */
    font-size: 28px;

    /* Use a compact line height that suits a single-line heading. */
    line-height: 1.2;
}

/* Style the supporting instruction below the login heading. */
.login-heading p {
    /* Add a small gap below the heading while removing unwanted side margins. */
    margin: 8px 0 0;

    /* Use Threads's quieter text colour for secondary information. */
    color: var(--muted);

    /* Keep the instruction compact and easy to scan. */
    font-size: 14px;
}

/* Stack the form fields and button with consistent spacing. */
.login-form {
    /* Use grid to create one clean vertical column. */
    display: grid;

    /* Place an equal gap between each field and the submit button. */
    gap: 20px;
}

/* Keep each label visually attached to its matching input. */
.form-field {
    /* Use grid to stack the label directly above its input. */
    display: grid;

    /* Add a compact gap between the label and input. */
    gap: 8px;
}

/* Give form labels a clear but restrained Threads appearance. */
.form-field label {
    /* Make labels slightly smaller than ordinary body text. */
    font-size: 13px;

    /* Use medium weight so labels remain easy to find. */
    font-weight: 500;

    /* Use the main ink colour for strong contrast. */
    color: var(--ink);
}

/* Give form inputs and dropdowns the same dark inset-surface appearance. */
.form-field input,
.form-field select {
    /* Allow each control to fill the complete width of its form column. */
    width: 100%;

    /* Create a comfortable typing or selection target. */
    min-height: 44px;

    /* Add internal space around typed text. */
    padding: 10px 12px;

    /* Draw the default Threads field boundary. */
    border: 1px solid var(--line);

    /* Round the field corners slightly less than the outer card. */
    border-radius: 7px;

    /* Place each field on a dark translucent surface. */
    background: rgb(20 22 27 / 72%);

    /* Use the primary ink colour for entered text. */
    color: var(--ink);

    /* Make form controls inherit Ubuntu from the page. */
    font: inherit;

    /* Animate focus feedback gently rather than changing it abruptly. */
    transition: border-color 130ms ease, box-shadow 130ms ease, background-color 130ms ease;
}

/* Replace the operating system's select styling with a consistent Threads control. */
.form-field select {
    /* Remove the browser's native grey dropdown surface and arrow. */
    appearance: none;

    /* Preserve the custom appearance in WebKit-based browsers such as Chrome and Safari. */
    -webkit-appearance: none;

    /* Leave room on the right so selected text cannot overlap the custom arrow. */
    padding-right: 42px;

    /* Draw a small light chevron that matches the rest of the interface. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='8' viewBox='0 0 14 8'%3E%3Cpath d='M1 1l6 6 6-6' fill='none' stroke='%23f4f3f6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");

    /* Keep the chevron aligned near the right edge of the field. */
    background-position: right 14px center;

    /* Display only one chevron. */
    background-repeat: no-repeat;

    /* Show that the field opens a list of choices. */
    cursor: pointer;
}

/* Keep dropdown choices readable when the browser opens its native option list. */
.form-field select option {
    /* Use the same dark family as the surrounding Threads form. */
    background: #17191f;

    /* Use the primary ink colour for each product name. */
    color: var(--ink);
}

/* Show a clear keyboard and editing focus state on either kind of form control. */
.form-field input:focus,
.form-field select:focus {
    /* Remove the browser's inconsistent default focus outline. */
    outline: none;

    /* Change the field boundary to Threads burgundy. */
    border-color: var(--accent-hover);

    /* Add an accessible glow around the active field. */
    box-shadow: 0 0 0 3px var(--accent-focus);

    /* Lighten the field surface without removing a dropdown's custom chevron. */
    background-color: rgb(28 30 36 / 82%);
}

/* Distinguish protected stable values from ordinary editable form fields. */
.form-field input[readonly] {
    /* Keep the locked value readable while reducing its editing emphasis. */
    color: var(--muted);

    /* Use a quieter surface to communicate that typing is unavailable. */
    background: rgb(15 17 21 / 60%);

    /* Replace the text cursor with the ordinary pointer for a locked value. */
    cursor: default;
}

/* Separate the Roles table from its heading when no filter toolbar sits between them. */
.role-table-wrapper {
    /* Match the breathing room created by the Users page toolbar. */
    margin-top: 40px;
}

/* Arrange the remember-me choice and password-recovery action on one row. */
.login-options {
    /* Use a flexible row that can adapt when the available width becomes narrow. */
    display: flex;

    /* Vertically align the checkbox label and the recovery button. */
    align-items: center;

    /* Place one control at each side of the login card. */
    justify-content: space-between;

    /* Preserve breathing room if the two controls move close together. */
    gap: 16px;

    /* Allow the controls to wrap instead of overflowing on a narrow screen. */
    flex-wrap: wrap;
}

/* Make the remember-me checkbox and its text behave as one clickable control. */
.remember-option {
    /* Keep the checkbox and its words beside each other. */
    display: inline-flex;

    /* Centre the checkbox against the text label. */
    align-items: center;

    /* Add a compact space between the checkbox and its words. */
    gap: 8px;

    /* Use the quieter Threads colour for this optional setting. */
    color: var(--muted);

    /* Keep supporting controls slightly smaller than the main form fields. */
    font-size: 13px;

    /* Show that the complete label can be clicked. */
    cursor: pointer;
}

/* Give the remember-me checkbox a compact Threads appearance. */
.remember-option input {
    /* Remove browser margins that would disturb our deliberate spacing. */
    margin: 0;

    /* Give the checkbox a consistent width. */
    width: 16px;

    /* Give the checkbox a matching height. */
    height: 16px;

    /* Colour the selected checkbox with Threads burgundy. */
    accent-color: var(--accent);

    /* Show the hand cursor when the pointer is directly over the checkbox. */
    cursor: pointer;
}

/* Style password recovery as a quiet secondary action. */
.forgot-password-button {
    /* Remove the ordinary button background so this resembles a text action. */
    background: transparent;

    /* Remove the ordinary button border. */
    border: 0;

    /* Remove built-in spacing so the text aligns neatly with the checkbox label. */
    padding: 0;

    /* Use the brighter Threads accent colour to identify an available action. */
    color: var(--accent-hover);

    /* Inherit the Ubuntu font used by the rest of the page. */
    font: inherit;

    /* Match the compact size of the remember-me label. */
    font-size: 13px;

    /* Show the hand cursor to communicate that the words are clickable. */
    cursor: pointer;
}

/* Brighten the recovery action when a pointer rests over it. */
.forgot-password-button:hover {
    /* Use the main ink colour for immediate hover feedback. */
    color: var(--ink);
}

/* Give keyboard users a clear focus marker around the recovery action. */
.forgot-password-button:focus-visible {
    /* Draw the same burgundy glow used by focused login fields. */
    outline: 2px solid var(--accent-hover);

    /* Leave a small gap between the words and the outline. */
    outline-offset: 4px;
}

/* Establish shared behaviour for clickable Threads buttons. */
.button {
    /* Keep production actions comfortably clickable while making their visible
       silhouette two pixels quieter than the earlier generous treatment. */
    min-height: 42px;

    /* Reduce each edge by only one pixel so labels and hierarchy stay stable. */
    padding: 9px 15px;

    /* Draw a subtle edge that remains visible against dark surfaces. */
    border: 1px solid rgb(255 255 255 / 12%);

    /* Match the compact rounding used by Threads controls. */
    border-radius: 7px;

    /* Inherit Ubuntu and the surrounding font size. */
    font: inherit;

    /* Make the action label visually confident. */
    font-weight: 500;

    /* Show the hand cursor to communicate that the button is clickable. */
    cursor: pointer;

    /* Animate colour and shadow feedback smoothly. */
    transition: background-color 130ms ease, box-shadow 130ms ease, transform 130ms ease;
}

/* Apply the primary Threads action colour to the sign-in button. */
.button--primary {
    /* Fill the button with Threads burgundy. */
    background: var(--accent);

    /* Use white text for strong contrast against burgundy. */
    color: var(--accent-ink);

    /* Add a subtle accent-coloured shadow beneath the action. */
    box-shadow: 0 8px 22px var(--accent-shadow);
}

/* Give secondary actions a quieter transparent Threads treatment. */
.button--secondary {
    /* Let the linen remain visible behind the secondary action. */
    background: transparent;

    /* Use the main Threads text colour for a readable action label. */
    color: var(--ink);

    /* Strengthen the shared button edge against the linen background. */
    border-color: var(--line-strong);
}

/* Apply a stronger destructive treatment to irreversible confirmation actions. */
.button--danger {
    /* Use a brighter burgundy-red fill to distinguish permanent deletion. */
    background: #a6253c;

    /* Keep the destructive label strongly contrasted. */
    color: #ffffff;

    /* Add a restrained red shadow beneath the confirmation action. */
    box-shadow: 0 8px 22px rgb(90 18 31 / 38%);
}

/* Brighten the destructive action while a pointer rests over it. */
.button--danger:hover {
    /* Increase the red brightness without changing the control's meaning. */
    background: #c33750;
}

/* Give keyboard users a visible marker around the destructive action. */
.button--danger:focus-visible {
    /* Draw a clear light outline beyond the red button edge. */
    outline: 2px solid var(--ink);

    /* Separate the outline from the button edge for clarity. */
    outline-offset: 3px;
}

/* Communicate that an AJAX submission button is temporarily unavailable. */
.button:disabled {
    /* Remove the active pointer cue during an in-flight request. */
    cursor: wait;

    /* Reduce emphasis without making progress text unreadable. */
    opacity: 0.66;
}

/* Give the secondary action clear pointer feedback. */
.button--secondary:hover {
    /* Add Threads's subtle raised-surface colour while the pointer rests over it. */
    background: var(--surface-hover);
}

/* Give keyboard users a visible focus indicator on secondary actions. */
.button--secondary:focus-visible {
    /* Draw a clear light outline outside the button. */
    outline: 2px solid var(--ink);

    /* Separate the outline from the button edge for clarity. */
    outline-offset: 3px;
}

/* Strengthen the button colour when a pointer rests over it. */
.button--primary:hover {
    /* Move to Threads's brighter burgundy interaction colour. */
    background: var(--accent-hover);
}

/* Give keyboard users a visible focus indicator on the primary button. */
.button--primary:focus-visible {
    /* Draw a clear light outline outside the burgundy button. */
    outline: 2px solid var(--ink);

    /* Separate the outline from the button edge for clarity. */
    outline-offset: 3px;
}

/* Let the login action fill the complete width of the form. */
.login-button {
    /* Stretch the button across its grid column. */
    width: 100%;
}

/* Centre the optional sign-out action below the compulsory password form. */
.password-change-logout {
    /* Separate this escape action from the primary permanent-password action. */
    margin-top: 22px;

    /* Centre the quiet text action inside the authentication card. */
    text-align: center;
}

/* Keep either button label centred when JavaScript switches between them. */
.login-button__label,
.login-button__loading {
    /* Treat each label as a block that fills the button's text area. */
    display: block;
}

/* Hide whichever login-button label currently has the HTML hidden attribute. */
.login-button [hidden] {
    /* Remove the hidden label from the page layout until JavaScript reveals it. */
    display: none;
}

/* Anchor temporary notifications to the bottom-right corner of the window. */
.toast-region {
    /* Keep the region fixed while the rest of the page remains stationary. */
    position: fixed;

    /* Place notifications above the login card and other page content. */
    z-index: 100;

    /* Leave a small gap between notifications and the right window edge. */
    right: 18px;

    /* Leave a small gap between notifications and the bottom window edge. */
    bottom: 18px;

    /* Stack multiple notifications vertically. */
    display: grid;

    /* Keep toasts compact while allowing them to fit narrow screens. */
    width: min(340px, calc(100vw - 36px));

    /* Separate multiple toasts with a small consistent gap. */
    gap: 8px;

    /* Let clicks pass through the empty areas surrounding the toasts. */
    pointer-events: none;
}

/* Style one temporary notification using Threads's compact message design. */
.toast {
    /* Arrange the icon, message, and close button in three columns. */
    display: grid;

    /* Give the message the flexible middle column. */
    grid-template-columns: 24px minmax(0, 1fr) 24px;

    /* Align the toast contents vertically in the centre. */
    align-items: center;

    /* Separate the icon, message, and close button. */
    gap: 9px;

    /* Add compact internal spacing around the notification. */
    padding: 10px;

    /* Draw Threads's stronger floating-surface boundary. */
    border: 1px solid var(--line-strong);

    /* Use the current toast colour as a clear state stripe. */
    border-left: 3px solid currentColor;

    /* Round the notification corners slightly. */
    border-radius: 8px;

    /* Place the notification on a raised dark surface. */
    background: #292d35;

    /* Use blue as the default information state colour. */
    color: var(--info);

    /* Lift the notification above the linen background. */
    box-shadow: var(--shadow-menu);

    /* Allow people to click buttons inside the notification. */
    pointer-events: auto;

}

/* Animate only a newly created toaster during its explicit one-time entrance state. */
.toast.is-entering {
    /* Settle the new notification into place without applying this motion after DOM moves. */
    animation: toast-enter 240ms cubic-bezier(0.2, 0, 0, 1);
}

/* Animate a toast out after JavaScript marks it as leaving. */
.toast.is-leaving {
    /* Run the exit animation once and retain its final invisible state. */
    animation: toast-leave 190ms cubic-bezier(0.4, 0, 1, 1) forwards;
}

/* Use green for successful login-related messages. */
.toast--success {
    /* Inherit Threads's success colour throughout the toast accents. */
    color: var(--success);
}

/* Use yellow for login messages that need careful review. */
.toast--warning {
    /* Inherit Threads's warning colour throughout the toast accents. */
    color: var(--warning);
}

/* Use pink-red for failed login and system error messages. */
.toast--danger {
    /* Inherit Threads's error colour throughout the toast accents. */
    color: var(--error);
}

/* Present the toast's short symbol inside a compact coloured circle. */
.toast__icon {
    /* Use grid to centre the symbol inside the circle. */
    display: grid;

    /* Give the icon a fixed compact width. */
    width: 22px;

    /* Give the icon a matching compact height. */
    height: 22px;

    /* Centre the symbol both horizontally and vertically. */
    place-items: center;

    /* Turn the icon background into a circle. */
    border-radius: 50%;

    /* Tint the icon background with the toast's current state colour. */
    background: color-mix(in srgb, currentColor 15%, transparent);

    /* Keep the small icon symbol readable. */
    font-size: 10px;

    /* Strengthen the icon symbol inside its circle. */
    font-weight: 700;
}

/* Place the toast title and supporting message on separate lines. */
.toast__content strong,
.toast__content span {
    /* Make each piece occupy its own line. */
    display: block;
}

/* Make the toast title visually stronger than its description. */
.toast__content strong {
    /* Use the primary ink colour for the title. */
    color: var(--ink);

    /* Keep the compact title readable. */
    font-size: 12px;
}

/* Style the explanatory text beneath the toast title. */
.toast__content span {
    /* Add a small separation below the title. */
    margin-top: 2px;

    /* Use the quieter Threads text colour for details. */
    color: var(--muted);

    /* Keep notification details compact. */
    font-size: 11px;
}

/* Style the small close button inside each toast. */
.toast button {
    /* Give the close button a compact fixed width. */
    width: 22px;

    /* Give the close button a matching fixed height. */
    height: 22px;

    /* Remove extra internal spacing around the close symbol. */
    padding: 0;

    /* Remove the browser's default button border. */
    border: 0;

    /* Round the button's hover surface. */
    border-radius: 5px;

    /* Keep the idle close button transparent. */
    background: transparent;

    /* Use the muted colour until the button receives attention. */
    color: var(--muted);

    /* Show the hand cursor over the clickable close button. */
    cursor: pointer;
}

/* Strengthen the close button when hovered or focused from the keyboard. */
.toast button:hover,
.toast button:focus-visible {
    /* Remove the browser's inconsistent default focus outline. */
    outline: 0;

    /* Add Threads's raised hover surface behind the close symbol. */
    background: var(--surface-hover);

    /* Brighten the close symbol while it is active. */
    color: var(--ink);
}

/* Define the motion used when a notification enters the window. */
@keyframes toast-enter {
    /* Begin slightly transparent and to the right. */
    from {
        /* Hide the toast at the first animation frame. */
        opacity: 0;

        /* Offset and shrink the toast slightly before it settles. */
        transform: translateX(16px) scale(0.98);
    }

    /* Finish fully visible in the notification region. */
    to {
        /* Reveal the toast completely. */
        opacity: 1;

        /* Return the toast to its natural position and size. */
        transform: translateX(0) scale(1);
    }
}

/* Define the motion used when JavaScript dismisses a notification. */
@keyframes toast-leave {
    /* Finish transparent, slightly smaller, and to the right. */
    to {
        /* Hide the toast at the final animation frame. */
        opacity: 0;

        /* Move and shrink the toast as it disappears. */
        transform: translateX(18px) scale(0.96);
    }
}
