﻿
:root {
    --logo200:            "images/jcmworks_logo_200px.png";

    /* Height of the pinned app banner (.MTView_title). One definition, so
       anything that has to sit clear of the bar stays in step with it. */
    --mt-banner-h: 52px;
    /* Height of the AI limit strip under the banner (MT.AiLimitStrip sets it
       on the document when it changes; 0 while it is hidden). */
    --mt-strip-h: 0px;
    /* Everything above the scrolling body: what sits clear of the bar uses
       this, so the next element placed under the banner changes one line. */
    --mt-chrome-h: calc(var(--mt-banner-h) + var(--mt-strip-h));

    /* Corner sizes. The first three repeat the shared framework sheet's
       values, for the page that does not load it (InteractionRenderer.html). */
    --radius-sm:             4px;
    --radius-md:             8px;
    --radius-lg:             12px;
    --radius-xl:             16px;
    --radius-2xl:            24px;
    --radius-3xl:            32px;
    --radius-full:           9999px;
    /* Corner sizes by what a thing IS. A rule names one of these, never a
       step of the scale above, so "less round buttons" is one line here.
       Buttons and fields share the control size. Things that are a circle
       on purpose (a radio, the round close and menu buttons, a scrollbar
       thumb) keep --radius-full. */
    --radius-control:        var(--radius-lg);
    --radius-field:          var(--radius-control);
    --radius-card:           var(--radius-lg);
    --radius-popup:          var(--radius-xl);
    --radius-tag:            var(--radius-md);

    /* The slim scrollbar (the rule further down, and the scoring view's
       in-root copy for the item's own scrollers, which this sheet cannot
       reach): the lane it takes, and the clear border that thins the thumb
       inside it. */
    --scrollbar-lane:        14px;
    --scrollbar-thumb-inset: 4px;

    /* The most a one-line text box grows to on a page, however wide the
       thing that holds it. */
    --field-max-width:       480px;
    /* The space between a popup's edge and its content. */
    --popup-space:           20px;

    /* The text size of a control: every button, and in time every field and
       table. In px on purpose: the sheets size text in rem and in em, and
       here those differ (the root is 13px, the body about 18.7px). */
    --control-text:          14px;

    /* Text sizes, one scale for the app's own screens (owner, 2026-10-06:
       medium). In px for the same reason as the control size. */
    --text-title:            28px;
    --text-section:          20px;
    --text-subsection:       17px;
    --text-body:             16px;
    --text-label:            15px;
    --text-note:             13px;
    --text-tag:              12px;

    /* One speed and curve for state changes, on colour, background and
       opacity only. */
    --motion-fast:           150ms cubic-bezier(.4, 0, .2, 1);
    --btn-radius:            var(--radius-control);
    --btn-transition:        background-color var(--motion-fast), border-color var(--motion-fast),
                             color var(--motion-fast), opacity var(--motion-fast);
}

/* With reduced motion asked for, state changes are instant. */
@media (prefers-reduced-motion: reduce) {
    :root {
        --motion-fast:       0ms linear;
    }
}

/* ── Theme tokens ───────────────────────────────────────────────────────────
   Every colour in the app's chrome comes from the names below. A rule never
   names a theme: the light values are the default, and the dark values
   replace them when <html> carries data-app-theme="dark" (set before first
   paint by the inline script in default.html). A rule that sets a
   background sets its text colour too, so neither is left to the browser.

   PAPER. The selector list is :root PLUS every element that shows authored
   content: item shadow hosts, rich-text editors and their toolbars, and the
   preview, scoring, markup, set and history displays, and the item engine's
   own stimulus and item panes wherever they are drawn, and its drop-down
   widget (a white button and list whose text is inherited, used in a few
   chrome panels as well as in items). Declaring the light
   values on those elements again makes everything inside them resolve light
   in a dark app, so an item looks as it was authored. The older names are
   repeated with them because a name defined from another is computed where
   it is declared. A new host of authored content joins BOTH lists: this one
   and the paper rule under the dark block.

   Status names carry the status- prefix: the item engine defines --success,
   --warning, --danger, --primary and --secondary on <body>, where the same
   names set here would be overridden.

   Contrast is WCAG 2.2 AA: 4.5:1 for text, 3:1 for controls and the focus
   ring, held against every surface and every fill. The checked table is in
   Documents/Documentation/ClaudePlans/AppRestylePlan.md. --text-tertiary and
   --text-quaternary are below 4.5:1 by design: disabled and decorative
   content only, never information.
   ───────────────────────────────────────────────────────────────────────── */
/* theme:light */
:root,
[data-shadow-item],
.ql-container,
.ql-toolbar,
.tq-scoring-display,
.tq-pv-display,
.tq-review-display,
.me-display-area,
.mc-display-area,
.sc-preview,
.tq-set-member-render,
.rq-preview-body,
.ih-display-div,
.ih-history-display,
.tq-rich-note-editor,
.tq-rubric-block-editor,
.tq-widget-label-editor,
.tq-outcome-label-editor,
.tq-option-label-editor-container,
.tq-hottext-editor,
.tq-stimulus-context-block-body,
.ts-preview-pane,
.tq-rubric-preview,
.tq-hottext-stim-body,
.tq-animation-preview-container,
.tq-svg-holder,
.te-source-preview,
.p-qti-stimulus,
.p-qti-item-container,
.p-qti-custom-select {
    color-scheme: light;

    /* Surfaces, back to front. */
    --bg-primary:            #FCFCFC;
    --bg-secondary:          #F3F4F5;
    --surface:               #FFFFFF;
    --surface-raised:        #FFFFFF;

    /* A soft fill for grouped rows, a selected item, and its hover and
       pressed steps. OPAQUE here on purpose, like the tints and the divider
       below: these are the values for authored content and for every page
       that does not run the app theme (examinee delivery, the demo), where
       the page behind may be any accessibility colour pair. A see-through
       fill there would put the rule's dark text straight onto a black or
       blue page. The app's own see-through versions follow this block. */
    --fill:                  #F2F2F2;
    --fill-hover:            #ECECEC;
    --fill-pressed:          #E6E6E6;

    /* --divider is decorative. --control-border is the edge that makes a
       text box or a checkbox findable, so it holds 3:1. */
    --divider:               #E6E6E6;
    --control-border:        #76797D;

    /* A text box, text area or drop-down at rest. On pages that do not run
       the app theme, and inside authored content, a field is a white box
       with the 3:1 edge. The app's own values follow in the blocks below. */
    --field-bg:              var(--surface);
    --field-border:          var(--control-border);

    --text-primary:          #111112;
    --text-secondary:        rgba(0, 4, 9, .59);
    --text-tertiary:         rgba(0, 7, 17, .37);

    /* The one accent. --accent is for text, links and edges; --accent-fill
       is the filled button under --text-on-accent. */
    --accent:                #0058BC;
    --accent-hover:          #004CA3;
    --accent-fill:           #0064D4;
    --accent-fill-hover:     #00479A;
    --accent-tint:           #E5EFFB;
    /* A tag (Shared, universal): a small label that looks the same on any
       row it sits on, a selected one included. Its fill is solid for that
       reason: a see-through tint would vanish on a filled row. */
    --tag-bg:                #E5EFFB;
    --tag-text:              var(--accent);
    /* A selected row, in any list: one soft fill and the row's usual text,
       never a heavier weight. The fill alone is faint against its panel
       (about 1.2:1), so the row also carries an edge at its start in the
       focus-ring colour, which is over 3:1 against the fill in both themes
       (4.1:1 light, 4.6:1 dark). Every selected-row rule reads these three. */
    --selected-bg:           var(--fill-pressed);
    --selected-text:         var(--text-primary);
    --selected-mark:         inset 3px 0 0 var(--focus-ring);
    --text-on-accent:        #FFFFFF;
    --focus-ring:            #0064D4;

    /* Colour otherwise appears only for status. Each is a text colour, a
       fill under --text-on-accent, and has a tint for its background. */
    --status-danger:         #C01F37;
    --status-danger-hover:   #8E1728;
    --status-danger-tint:    #FDE8E8;
    --status-success:        #007400;
    --status-success-tint:   #DEF6E7;
    --status-warning:        #B0461A;
    --status-warning-tint:   #FCF4DA;

    --scrim:                 rgba(0, 0, 0, .1);
    --scrollbar-thumb:       rgba(0, 0, 0, .43);
    /* The logo and the wait spinner are pictures with black ink. Dark has a
       copy of each with that ink turned white. */
    --icon-logo:             url(/Images/TestQuill_logo.png);
    --icon-wait-spinner:     url(/Images/TestQuillSpinnerSmall.png);
    /* The tick inside a chosen checkbox, in the colour of --bg-primary. A
       picture cannot read a variable, so each theme carries its own. */
    --check-glyph:           url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23FCFCFC' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    --shadow-1:              0 2px 8px rgba(17, 17, 18, .08), 0 2px 16px rgba(17, 17, 18, .04);
    --shadow-2:              0 4px 12px rgba(17, 17, 18, .12), 0 6px 24px rgba(17, 17, 18, .08);
    --shadow-3:              0 6px 16px rgba(17, 17, 18, .16), 0 8px 32px rgba(17, 17, 18, .12);

    /* One name per chrome icon. The files are drawn in ink, so the dark
       block points each name at a white copy under /Images/dark/. A new
       ink-drawn icon needs both lines and its white copy. */
    --icon-allgood:              url(/Images/allgood.svg);
    --icon-arrow-left-circle:    url(/Images/arrow-left-circle.svg);
    --icon-arrow-right-circle:   url(/Images/arrow-right-circle.svg);
    --icon-barcode:              url(/WAFScripts/images/barcode.svg);
    --icon-bug:                  url(/Images/bug.svg);
    --icon-chevron-down:         url(/Images/chevron-down.svg);
    --icon-chevron-left:         url(/Images/chevron-left.svg);
    --icon-chevron-right:        url(/Images/chevron-right.svg);
    --icon-chevron-up:           url(/Images/chevron-up.svg);
    --icon-circle-square:        url(/Images/circle-square.svg);
    --icon-clipboard:            url(/Images/clipboard.svg);
    --icon-close:                url(/Images/close.svg);
    --icon-x-circle-red:         url(/Images/x-circle-red.svg);
    --icon-long-description:     url(/images/long-description.svg);
    --icon-aria-label-tag:       url(/images/aria-label-tag.svg);
    --icon-copy:                 url(/Images/copy.svg);
    --icon-consider-replace:     url(/Images/consider-replace.svg);
    --icon-corner-down-left:     url(/Images/corner-down-left.svg);
    --icon-crosshair:            url(/Images/crosshair.svg);
    --icon-delete:               url(/Images/delete.svg);
    --icon-download:             url(/Images/download.svg);
    --icon-download-cloud:       url(/Images/download-cloud.svg);
    --icon-edit:                 url(/Images/edit.svg);
    --icon-edit-2:               url(/Images/edit-2.svg);
    --icon-edit-3:               url(/Images/edit-3.svg);
    --icon-external-link:        url(/Images/external-link.svg);
    --icon-frown:                url(/Images/frown.svg);
    --icon-help-circle:          url(/Images/help-circle.svg);
    --icon-image:                url(/Images/image.svg);
    --icon-intersects:           url(/Images/Intersects.svg);
    --icon-layout:               url(/Images/layout.svg);
    --icon-link:                 url(/Images/link.svg);
    --icon-log-out:              url(/Images/log-out.svg);
    --icon-mail:                 url(/Images/mail.svg);
    --icon-markup-button:        url(/Images/markup-button.svg);
    --icon-menu:                 url(/Images/menu.svg);
    --icon-minus-square:         url(/Images/minus-square.svg);
    --icon-paperclip:            url(/Images/paperclip.svg);
    --icon-plus:                 url(/Images/plus.svg);
    --icon-plus-square:          url(/Images/plus-square.svg);
    --icon-points-towards:       url(/Images/PointsTowards.svg);
    --icon-reply-all-line:       url(/Images/reply-all-line.svg);
    --icon-reply-line:           url(/Images/reply-line.svg);
    --icon-screen-reader-text:   url(/Images/screen-reader-text.svg);
    --icon-search:               url(/Images/search.svg);
    --icon-settings:             url(/Images/settings.svg);
    --icon-share-forward-line:   url(/Images/share-forward-line.svg);
    --icon-start-point:          url(/Images/startPoint.svg);
    --icon-staticbarcode:        url(/Images/staticbarcode.svg);
    --icon-trash:                url(/Images/trash.svg);
    --icon-trash-2:              url(/Images/trash-2.svg);
    --icon-upload-cloud:         url(/Images/upload-cloud.svg);
    --icon-x:                    url(/Images/x.svg);

    /* The shared framework's names (WAFBaseCSS.css), re-pointed so every rule
       that already uses one follows the theme. */
    --color-primary:         var(--accent);
    --color-primary-dark:    var(--accent-hover);
    --color-primary-tint:    var(--accent-tint);
    --color-accent:          var(--accent);
    --color-accent-dark:     var(--accent-hover);
    --color-accent-tint:     var(--accent-tint);
    --color-text-base:       var(--text-primary);
    --color-text-heading:    var(--text-primary);
    --color-text-muted:      var(--text-secondary);
    --color-surface:         var(--bg-secondary);
    --color-border:          var(--divider);
    --color-bg:              var(--bg-primary);
    --color-input-border:    var(--field-border);
    --color-hover-bg:        var(--fill-hover);
    --color-active-bg:       var(--fill-pressed);
    --color-disabled-bg:     var(--fill);
    --color-disabled-text:   var(--text-tertiary);
    --focus-outline:         2px solid var(--focus-ring);
    --focus-offset:          2px;

    /* The older Ments names, kept so existing rules need no edit. */
    --jcmaPurple:            var(--accent);
    --jcmaBlue:              var(--accent);
    --purpleText:            var(--text-primary);
    --activeBackground:      var(--accent-tint);
    --blueBackground:        var(--accent-tint);

    /* ── Button design system ── */
    --btn-primary:           var(--accent-fill);
    --btn-primary-hover:     var(--accent-fill-hover);
    --btn-ghost-text:        var(--accent);
    --btn-ghost-hover-bg:    var(--fill-hover);
    --btn-secondary:         var(--fill-hover);
    /* Under the pointer the grey button takes a hint of the accent, so the
       change is easy to see without being loud. */
    --btn-secondary-hover:   #D6E6F8;
    /* A secondary button is a soft fill with plain text and no edge. Named
       so the shared framework's own secondary buttons (Define Roles) can
       take the same look. */
    --btn-secondary-text:    var(--text-primary);
    --btn-secondary-border:  transparent;
    --btn-outline-border:    var(--control-border);
    --btn-destructive:       var(--status-danger);
    --btn-destructive-hover: var(--status-danger-hover);
}

/* The app's light theme: the same colours as above, with the fills, the
   divider and the tints see-through, so one value sits right on the page, a
   sidebar or a card alike. Only a page that runs the theme script gets these,
   and authored content inside it keeps the opaque values. */
/* theme:light-app */
:root[data-app-theme="light"] {
    /* In the app a field is a soft fill with no edge at rest; the edge
       appears, in the accent, when the field has focus. NOTE: the resting
       fill is far below 3:1 against its surface, so a field is found by its
       fill, its label and its placeholder, not by an edge. Setting
       --field-border back to var(--control-border), here and in the dark
       block, restores the edge everywhere at once. */
    --field-bg:              var(--fill);
    --field-border:          transparent;
    --fill:                  rgba(0, 0, 0, .05);
    --fill-hover:            rgba(0, 0, 0, .075);
    --fill-pressed:          rgba(0, 0, 0, .1);
    --divider:               rgba(0, 0, 0, .1);
    --accent-tint:           rgba(0, 100, 212, .1);
    --btn-secondary-hover:   rgba(0, 100, 212, .16);
    --status-success-tint:   rgba(34, 197, 94, .15);
    --status-warning-tint:   rgba(234, 179, 8, .15);
}

/* theme:dark */
:root[data-app-theme="dark"] {
    color-scheme: dark;

    --bg-primary:            #181819;
    --bg-secondary:          #1F1F20;
    --surface:               #28292B;
    /* Elevation in dark is a lighter surface more than a shadow. */
    --surface-raised:        #323435;

    --fill:                  rgba(255, 255, 255, .12);
    --fill-hover:            rgba(255, 255, 255, .15);
    --fill-pressed:          rgba(255, 255, 255, .18);

    --divider:               rgba(255, 255, 255, .12);
    --control-border:        #9A9DA1;
    --field-bg:              var(--fill);
    --field-border:          transparent;

    --text-primary:          #FFFFFF;
    --text-secondary:        rgba(242, 247, 255, .75);
    --text-tertiary:         rgba(241, 246, 255, .38);

    --accent:                #74BEFF;
    --accent-hover:          #9AD0FF;
    --accent-fill:           #1793FF;
    --accent-fill-hover:     #6FBBFF;
    --accent-tint:           rgba(23, 147, 255, .18);
    --btn-secondary-hover:   rgba(23, 147, 255, .34);
    --tag-bg:                #253C51;
    /* Dark text on the bright fill: white on it is only 3.2:1. */
    --text-on-accent:        #111112;
    --focus-ring:            #74BEFF;

    --status-danger:         #FF7A85;
    --status-danger-hover:   #FFA3AB;
    --status-danger-tint:    rgba(220, 38, 38, .15);
    --status-success:        #34CF4E;
    --status-success-tint:   rgba(34, 197, 94, .15);
    --status-warning:        #F7AE93;
    --status-warning-tint:   rgba(251, 191, 36, .15);

    --scrim:                 rgba(0, 0, 0, .4);
    --scrollbar-thumb:       rgba(255, 255, 255, .36);
    --icon-logo:             url(/Images/dark/TestQuill_logo.png);
    --icon-wait-spinner:     url(/Images/dark/TestQuillSpinnerSmall.png);
    --check-glyph:           url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23181819' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    --shadow-1:              0 2px 8px rgba(0, 0, 0, .24), 0 2px 16px rgba(0, 0, 0, .16);
    --shadow-2:              0 4px 12px rgba(0, 0, 0, .32), 0 6px 24px rgba(0, 0, 0, .24);
    --shadow-3:              0 6px 16px rgba(0, 0, 0, .4), 0 8px 32px rgba(0, 0, 0, .32);

    --icon-allgood:              url(/Images/dark/allgood.svg);
    --icon-arrow-left-circle:    url(/Images/dark/arrow-left-circle.svg);
    --icon-arrow-right-circle:   url(/Images/dark/arrow-right-circle.svg);
    --icon-barcode:              url(/Images/dark/barcode.svg);
    --icon-bug:                  url(/Images/dark/bug.svg);
    --icon-chevron-down:         url(/Images/dark/chevron-down.svg);
    --icon-chevron-left:         url(/Images/dark/chevron-left.svg);
    --icon-chevron-right:        url(/Images/dark/chevron-right.svg);
    --icon-chevron-up:           url(/Images/dark/chevron-up.svg);
    --icon-circle-square:        url(/Images/dark/circle-square.svg);
    --icon-clipboard:            url(/Images/dark/clipboard.svg);
    --icon-close:                url(/Images/dark/close.svg);
    --icon-x-circle-red:         url(/Images/dark/x-circle-red.svg);
    --icon-long-description:     url(/Images/dark/long-description.svg);
    --icon-aria-label-tag:       url(/Images/dark/aria-label-tag.svg);
    --icon-copy:                 url(/Images/dark/copy.svg);
    --icon-consider-replace:     url(/Images/dark/consider-replace.svg);
    --icon-corner-down-left:     url(/Images/dark/corner-down-left.svg);
    --icon-crosshair:            url(/Images/dark/crosshair.svg);
    --icon-delete:               url(/Images/dark/delete.svg);
    --icon-download:             url(/Images/dark/download.svg);
    --icon-download-cloud:       url(/Images/dark/download-cloud.svg);
    --icon-edit:                 url(/Images/dark/edit.svg);
    --icon-edit-2:               url(/Images/dark/edit-2.svg);
    --icon-edit-3:               url(/Images/dark/edit-3.svg);
    --icon-external-link:        url(/Images/dark/external-link.svg);
    --icon-frown:                url(/Images/dark/frown.svg);
    --icon-help-circle:          url(/Images/dark/help-circle.svg);
    --icon-image:                url(/Images/dark/image.svg);
    --icon-intersects:           url(/Images/dark/Intersects.svg);
    --icon-layout:               url(/Images/dark/layout.svg);
    --icon-link:                 url(/Images/dark/link.svg);
    --icon-log-out:              url(/Images/dark/log-out.svg);
    --icon-mail:                 url(/Images/dark/mail.svg);
    --icon-markup-button:        url(/Images/dark/markup-button.svg);
    --icon-menu:                 url(/Images/dark/menu.svg);
    --icon-minus-square:         url(/Images/dark/minus-square.svg);
    --icon-paperclip:            url(/Images/dark/paperclip.svg);
    --icon-plus:                 url(/Images/dark/plus.svg);
    --icon-plus-square:          url(/Images/dark/plus-square.svg);
    --icon-points-towards:       url(/Images/dark/PointsTowards.svg);
    --icon-reply-all-line:       url(/Images/dark/reply-all-line.svg);
    --icon-reply-line:           url(/Images/dark/reply-line.svg);
    --icon-screen-reader-text:   url(/Images/dark/screen-reader-text.svg);
    --icon-search:               url(/Images/dark/search.svg);
    --icon-settings:             url(/Images/dark/settings.svg);
    --icon-share-forward-line:   url(/Images/dark/share-forward-line.svg);
    --icon-start-point:          url(/Images/dark/startPoint.svg);
    --icon-staticbarcode:        url(/Images/dark/staticbarcode.svg);
    --icon-trash:                url(/Images/dark/trash.svg);
    --icon-trash-2:              url(/Images/dark/trash-2.svg);
    --icon-upload-cloud:         url(/Images/dark/upload-cloud.svg);
    --icon-x:                    url(/Images/dark/x.svg);
}

/* Paper: the hosts of authored content keep the item engine's own foreground
   and background, so they stay white in a dark app and still follow an
   accessibility colour pair. The fallbacks serve dialogs, which are appended
   to <html> where the engine's names (set on <body>) do not reach. The same
   list as the light block above, without :root and the item shadow hosts
   (those paint themselves from inside). */
.ql-container,
.ql-toolbar,
.tq-scoring-display,
.tq-pv-display,
.tq-review-display,
.me-display-area,
.mc-display-area,
.sc-preview,
.tq-set-member-render,
.rq-preview-body,
.ih-display-div,
.ih-history-display,
.tq-rich-note-editor,
.tq-rubric-block-editor,
.tq-widget-label-editor,
.tq-outcome-label-editor,
.tq-option-label-editor-container,
.tq-hottext-editor,
.tq-stimulus-context-block-body,
.ts-preview-pane,
.tq-rubric-preview,
.tq-hottext-stim-body,
.tq-animation-preview-container,
.tq-svg-holder,
.te-source-preview,
.p-qti-stimulus,
.p-qti-item-container,
.p-qti-custom-select {
    background-color: var(--background, #fff);
    color: var(--foreground, #212529);
}

/* Forced colours (Windows contrast themes). The browser drops fills and
   shadows there, so a state or an edge that was a fill or a shadow alone gets
   a line. A transparent 1px border turns visible in that mode on its own,
   which is how the stock button, the tag, the notice and the accordion row
   get theirs: each carries one in its shared rule, so no list is repeated
   here. A button with no border at all is given one (seen on the real Manage
   Workflows screen, 2026-10-06: its buttons and rows were bare text). */
@media (forced-colors: active) {
    .menu_active {
        outline: 2px solid Highlight;
        outline-offset: -2px;
    }

    html[data-app-theme] button {
        border: 1px solid ButtonBorder;
    }

    .CardMenu_controls,
    .MTView_title {
        outline: 1px solid CanvasText;
    }
}

/* Stamped by MTView.js on the AUTHORING shell's body only. Exams.html loads
   this same stylesheet, so a bare `body { margin: 0 }` would move examinee
   delivery too; this class cannot appear there. Without it the UA's 8px
   margin makes the document 16px taller than the viewport and the pinned
   banner drifts by that much on scroll. */
body.mt-app-shell {
    margin: 0;
}

/* The page itself. Keyed on the attribute the head script sets before first
   paint, NOT on a class: MTView adds .mt-app-shell only once every script
   has loaded, and until then a dark page was white. Only default.html carries
   the attribute, so the examinee and demo pages are untouched. It outranks
   the engine sheet's `body` rule and a pnp-color-* class on the body, so
   the page keeps the app theme whatever the item content is shown in. No
   background on <html>: the body's reaches the canvas. */
:root[data-app-theme] body {
    background-color: var(--bg-primary);
    color: var(--text-primary);
    /* The app's own text. The engine sheet sets the page to the item text
       size (14pt); the app's screens use the scale at the top of this sheet. */
    font-size: var(--text-body);
}

/* Headings. The heading element decides the kind of heading, and the text
   scale its size: h1 and h2 are the page's title (a popup's, inside one), h3
   a section, h4 a sub-section, h5 and legend the small label over a group
   (owner, 2026-10-06: plain: dark, no line under it, no capitals). These
   rules weigh nothing, so a heading with a name of its own (the lists further
   down) wins over its element. */
:where(html[data-app-theme]) :where(h1, h2) {
    font-size: var(--text-title);
    font-weight: 700;
    line-height: 1.25;
}

:where(html[data-app-theme]) :where(dialog, [role="dialog"], [role="alertdialog"]) :where(h1, h2),
:where(html[data-app-theme]) :where(h3) {
    font-size: var(--text-section);
    font-weight: 600;
    line-height: 1.25;
}

:where(html[data-app-theme]) :where(h4) {
    font-size: var(--text-subsection);
    font-weight: 600;
    line-height: 1.25;
}

:where(html[data-app-theme]) :where(h5, legend) {
    font-size: var(--text-note);
    font-weight: 600;
    line-height: 1.25;
    color: var(--text-secondary);
}

/* Test content keeps the item engine's text size. A paper host that takes
   its size from the page would otherwise shrink with the app's text. :where()
   gives this rule no weight at all, so a host that sets a size of its own
   (the rich-text editor does) keeps it. The list is the paper list; the
   test that guards the other two copies guards this one. */
:where(.ql-container,
       .ql-toolbar,
       .tq-scoring-display,
       .tq-pv-display,
       .tq-review-display,
       .me-display-area,
       .mc-display-area,
       .sc-preview,
       .tq-set-member-render,
       .rq-preview-body,
       .ih-display-div,
       .ih-history-display,
       .tq-rich-note-editor,
       .tq-rubric-block-editor,
       .tq-widget-label-editor,
       .tq-outcome-label-editor,
       .tq-option-label-editor-container,
       .tq-hottext-editor,
       .tq-stimulus-context-block-body,
       .ts-preview-pane,
       .tq-rubric-preview,
       .tq-hottext-stim-body,
       .tq-animation-preview-container,
       .tq-svg-holder,
       .te-source-preview,
       .p-qti-stimulus,
       .p-qti-item-container,
       .p-qti-custom-select) {
    font-size: 14pt;
}

/* A heading in test content is the author's, not the app's: it goes back to
   the browser's own look. This is the fourth copy of the paper list, and it
   has to follow the heading rules above to win over them. */
:where(.ql-container,
       .ql-toolbar,
       .tq-scoring-display,
       .tq-pv-display,
       .tq-review-display,
       .me-display-area,
       .mc-display-area,
       .sc-preview,
       .tq-set-member-render,
       .rq-preview-body,
       .ih-display-div,
       .ih-history-display,
       .tq-rich-note-editor,
       .tq-rubric-block-editor,
       .tq-widget-label-editor,
       .tq-outcome-label-editor,
       .tq-option-label-editor-container,
       .tq-hottext-editor,
       .tq-stimulus-context-block-body,
       .ts-preview-pane,
       .tq-rubric-preview,
       .tq-hottext-stim-body,
       .tq-animation-preview-container,
       .tq-svg-holder,
       .te-source-preview,
       .p-qti-stimulus,
       .p-qti-item-container,
       .p-qti-custom-select) :where(h1, h2, h3, h4, h5, legend) {
    font-size: revert;
    font-weight: revert;
    line-height: revert;
    color: revert;
}

/* Modal dialogs are appended to <html>, OUTSIDE <body>, so they inherit
   nothing the body sets: every dialog whose own rule says `font-family:
   inherit` (.app-dialog, the interaction editors, BasicDialog) rendered in
   the browser's default SERIF font (cert set 2026-10-01 item 12). The body's
   own font is set by the engine sheet (QtiBaseStyles.css), which still wins
   inside <body>; this only reaches what lives outside it. */
html {
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial,
        "Noto Sans", "Liberation Sans", sans-serif;
    color: var(--color-text-base);
}

/* The app shell is a flex COLUMN that exactly fills the viewport: the banner
   is a fixed-size first row, the body takes the rest and scrolls inside
   itself. The banner is therefore pinned by LAYOUT, not by position:fixed or
   sticky — which matters more than it sounds:

     - Nothing has to be offset. Every `position: sticky; top: 0` under here
       (.di-toolbar, .ib-dash-side, .tq-stimulus-context-header, the table
       headers, .tq-changes-panel) now sticks to the top of the SCROLLING
       BODY, which is exactly the strip under the banner. A fixed banner
       would have left all nine of them sticking underneath it.
     - Nothing can paint over the banner. Sticky content is clipped to its
       scroll container, so the body can never ride up into the bar.
     - The document itself no longer scrolls, so there is exactly one
       scrollbar instead of the inner-plus-page pair the old 90vh box gave.

   Height was 90vh with the body overflowing VISIBLY, which is what let the
   banner scroll away (owner, 2026-09-12). Authoring only: these classes are
   stamped by MTView.js alone, and examinee delivery has its own shell. */
.MTView_window {
    margin: 0px;
    width: 100%;
    top: 0;
    left: 0;
    height: 100vh;
    position: relative;
    display: flex;
    flex-direction: column;
}

    /* NO overflow override here. This rule used to force
       `.MTView_window .Dialog_normal { overflow: visible }`, written in 2023
       when a dialog had no height cap and "visible" simply meant "grow".
       The design system later capped the box at calc(100vh - 48px) and WAF
       made it scroll, but this selector is more specific and quietly won:
       every dialog inside the app shell kept a FIXED-height white box whose
       surplus content — a long language checklist, its Save button — painted
       outside the box onto the page behind it, unscrollable (owner report and
       testquill-user-bugs #10, 2026-09-06). Scrolling belongs to WAF's
       .Dialog_normal; do not re-clamp overflow from here. */

/*.CKEdit_header {
    height: 1.6em;
    display: flex;
    flex-direction: row;
}*/

div.DIView_window {
    position: relative;
}
/*div.DIView_window {
    width: calc(100% - 20px);
    position: fixed;

}
*/
div.ql-container.ql-snow {
    overflow: auto;
    max-height: calc(100% - 200px);
    /* Match the toolbar, which fills 100% of the parent. The editor was
       hardcoded to 95%, leaving the body ~5% (~100px on a wide view)
       short of the toolbar on the right. */
    width: 100%;
}

/*
 * Editor was previously position:fixed so it stayed pinned while
 * scrolling. That overlapped sibling elements (group-context panel,
 * attribute panel) that share its vertical region. Removed
 * position:fixed and made the editor toolbar sticky instead — same
 * "always-visible controls" effect, without yanking the editor out
 * of document flow.
 */
/* The passage and rubric editors are full TestQuill editors too, so they share
   the item editor's toolbar chrome: sticky positioning + z-index so an open
   picker (e.g. the alignment options menu) stacks above the editor body and
   the panels below it, plus the white background. Deliberately a PAGE-editor
   list (not the .tq-editor-toolbar marker): dialogs host editors too, and a
   sticky toolbar inside a dialog is wrong — so every full-PAGE editor view
   must be listed here. (Icon faces / sizing live in TestQuill.css and scope
   to the marker, so a missing entry HERE only costs stickiness.) */
.StimulusEditorView_window div.ql-toolbar.ql-snow,
.RubricEditorView_window div.ql-toolbar.ql-snow,
.DIView_window div.ql-toolbar.ql-snow {
    position: sticky;
    /* Pin just below the sticky .di-toolbar so both bars stay visible. */
    top: var(--di-toolbar-h, 65px);
    z-index: 10;
    background: #fff;
    /* Trim vertical real estate: Quill's snow default is padding:8px;
       the 44px touch-target buttons already define the bar height, so
       drop top/bottom padding to 2px (keep 8px sides). */
    padding: 2px 8px;
}

/* Stimulus context sidebar — left strip showing the BodyHtml of
   every stimulus the current item references. Collapses to a thin
   toggle-only strip. Anchored to the view container (DIView_window
   is position:relative) so it sits below the page header rather
   than over it. The editor's parent is padded so its content
   doesn't slide under the sidebar. */
.tq-stimulus-context-panel {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    /* Roomy like the other left panels — it holds a passage to READ, and now
       the item-set roster above it (owner, 2026-09-11). Proportional, with a
       floor for small screens and a ceiling so it never dwarfs the editor. The
       editor's gutter is computed from the same value, below, so the two can
       no longer drift apart. */
    width: var(--stimulus-panel-w, 320px);
    background: var(--bg-secondary);
    border-right: 1px solid var(--divider);
    /* A TRACK, not a scroller (cert set 2026-10-01 #70): the panel runs the
       view's full height (at least the visible body, see
       .tq-stimulus-context-active) and its inner box below is what scrolls.
       It must stay overflow:visible, or the inner box would stick to the panel
       instead of to the app's scrolling body. */
    overflow: visible;
    z-index: 20;
    transition: width 0.2s ease;
    box-sizing: border-box;
}

/* The passage you read: sticks to the top of the app's scrolling body
   (.MTView_body) and is never taller than that body's visible height — the
   viewport under the banner — so a long passage scrolls INSIDE it, beside a
   short item and a long one alike, and a long item no longer scrolls the
   passage out of sight. The header is sticky within it, as before. */
.tq-stimulus-context-scroll {
    position: sticky;
    top: 0;
    max-height: calc(100vh - var(--mt-chrome-h, 52px));
    overflow-y: auto;
    box-sizing: border-box;
}

.tq-stimulus-context-panel.tq-stimulus-context-collapsed {
    width: 32px;
}

/* The sizing grip for that panel. The panel is docked absolutely here, so the
   grip is placed by coordinates (the panel keeps it on its right edge) rather
   than by flex order — and it sits OUTSIDE the panel, so the panel's own
   scrollbar can never cover it (owner, 2026-09-11). */
.mt-panel-resize.tq-stimulus-context-grip {
    position: absolute;
    width: 6px;
    z-index: 21;
}

.tq-stimulus-context-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-bottom: 1px solid var(--divider);
    background: var(--bg-secondary);
    position: sticky;
    top: 0;
    z-index: 1;
}

.tq-stimulus-context-toggle {
    cursor: pointer;
    background: transparent;
    border: 1px solid var(--divider);
    border-radius: var(--radius-sm);
    width: 22px;
    height: 22px;
    line-height: 1;
    padding: 0;
    color: var(--text-primary);
}

.tq-stimulus-context-panel.tq-stimulus-context-collapsed .tq-stimulus-context-title,
.tq-stimulus-context-panel.tq-stimulus-context-collapsed .tq-stimulus-context-top,
.tq-stimulus-context-panel.tq-stimulus-context-collapsed .tq-stimulus-context-body {
    display: none;
}

.tq-stimulus-context-body {
    padding: 8px 12px;
}

.tq-stimulus-context-block + .tq-stimulus-context-block {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px dashed var(--divider);
}

.tq-stimulus-context-block-title {
    margin: 0 0 6px 0;
}

.tq-stimulus-context-block-body {
    font-size: 0.92rem;
    word-wrap: break-word;
}

/* A passage image fits the sidebar's width rather than running past its right
   edge (#70); the passage is read here, the full size is in the editor. */
.tq-stimulus-context-block-body img {
    max-width: 100%;
    height: auto;
}

/* Reserve space on the left of the editor area only when the
   stimulus panel actually has content to show. The panel JS adds
   .tq-stimulus-context-active to the DIView_window once at least
   one stimulus block has rendered, and removes it again when there
   are none — so items without stimuli get no gutter at all. The
   collapsed selector still covers the user-toggled narrow strip. */
.DIView_window {
    box-sizing: border-box;
    /* Height of the sticky .di-toolbar (44px button row + 10px*2 padding
       + 1px border). The Quill toolbar pins just below it, so both the
       di-toolbar height and the ql-toolbar's sticky offset read this. */
    --di-toolbar-h: 65px;
    /* Start content just below the app header's drop shadow (~4px reach)
       so the sticky .di-toolbar doesn't paint over it at the top. The
       offset lives on the scroll container, not the sticky bar, so the
       bar still pins flush to top:0 once scrolled. */
    padding-top: 4px;
}

/* The gutter belongs to ANY view that shows the passage sidebar, not to the
   item editor alone: the class is added to the view's own window div by
   StimulusContextPanel, and every review and markup step shows the sidebar now
   (owner, 2026-09-11). The panel's width lives here too, so the panel (a
   descendant) and the gutter read one value — and box-sizing is restated
   because a view window that did not need it before now carries padding. */
.tq-stimulus-context-active {
    --stimulus-panel-w: clamp(320px, 28vw, 520px);
    box-sizing: border-box;
    padding-left: calc(var(--stimulus-panel-w, 320px) + 16px);
    /* The panel is docked absolutely at left:0 / top:0 — it must be
       positioned against THIS box, the one that carries the gutter, or it
       lands wherever the nearest positioned ancestor happens to be (on the
       translation editor that was the page's main region, already pushed
       right by this very padding, so the panel covered the item). */
    position: relative;
    /* The panel's track reaches the bottom of the visible body even when the
       item is short (#70): the view fills at least the app's scrolling body,
       of which it is a direct child (MTView_body is a flex item with a
       definite height, so the percentage resolves; where it cannot, it falls
       back to auto and nothing changes). */
    min-height: 100%;
}

.tq-stimulus-context-active:has(.tq-stimulus-context-panel.tq-stimulus-context-collapsed) {
    padding-left: 48px;
}

/* =============================================================
 * COMMON TOOLBAR STANDARD — review + content-creation screens
 * (owner ruling 2026-09-01; applied across DraftItemView,
 * TrackedSuggestReviewView, PostEditorial* (inherited),
 * ReviewCommentView / ClientReviewView, StimulusEditorView,
 * RubricEditorView, MarkupCreationView, TranslationEditorView,
 * AssetDeliverView)
 *
 * Layout: one bar, two groups.
 *   .di-toolbar            the bar (flex, space-between, sticky)
 *   .di-toolbar-actions    LEFT — work actions, in order:
 *                          Save (btn--primary; the only primary in
 *                          this group), Comments next when present,
 *                          then the screen's other work tools
 *                          (New/Select, Set Up-View Scoring / Score,
 *                          Preview, Attributes, panel toggles) as
 *                          btn--outline, Help icon LAST.
 *   .di-toolbar-complete   RIGHT — workflow exits, fixed order:
 *                          Complete Activity (btn--primary — the
 *                          affirmative exit), Reject
 *                          (btn--destructive — the ONLY solid-red
 *                          button on the bar; reviews only),
 *                          Release Item (btn--outline), Step Away /
 *                          Exit (btn--outline, ALWAYS last).
 * Sizing: toolbar buttons are btn--md (btn--sm only inside compact
 * floating-panel footers). Colors come ONLY from the .btn variant
 * classes below / their --btn-* tokens — never inline styles; all
 * variants are WCAG AAA (>=7:1) against their backgrounds
 * (#5B34A8 primary 8.4:1, #991b1b destructive 8.3:1 on white text;
 * outline text #3D2080 >10:1 on white).
 * Views that cannot mount a literal .di-toolbar (MarkupCreation's
 * mc-toolbar, TranslationEditor's header, AssetDeliver's nav) still
 * use the two group classes and the same button classes/order.
 * ============================================================= */
.di-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--divider);
    /* Keep the action buttons pinned to the top of a long item. The
       Quill toolbar (below) offsets its own sticky top by
       --di-toolbar-h so the two bars stack instead of overlapping. */
    position: sticky;
    top: 0;
    z-index: 11;
    background: var(--surface);
}

.di-toolbar-actions,
.di-toolbar-complete {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.menu_window {
    border: none;
}

.MTView_menu.menu_window div:focus {
    border: none;
}

.MTView_menu.menu_window:focus {
    /*border: thin solid var(--blueBackground);*/
    outline: none;
}

.MTView_right, .MenuButton_window {
    height: 44px;
    width: 44px;
    padding: 0;
    margin: 0;
    border: none;
    cursor: pointer;
}

div.AccGroup_window {
    height: 100%;
    overflow: auto;
}
/* The row of an accordion: the title of a block that opens and closes. One
   look for every accordion. The text starts at the left, a chevron turns
   when the block is open, and the row lays its content out in a line, so a
   screen can put a mark (a count, a warning) at the right-hand end. It was
   a centred bar, which also broke any row that held more than one piece.
   A screen that builds its blocks from the browser's own disclosure element
   (Manage Workflows: Items, Stimuli, Rubrics) names its summary here. */
div.AccGroup_window span.AccBlock_title,
summary.bw-branch-summary,
button.tq-sel-acc-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    box-sizing: border-box;
    width: 100%;
    min-height: 44px;
    /* 6px 12px in all, a transparent 1px of it as a border (see the tag). */
    padding: 5px 11px;
    border: 1px solid transparent;
    text-align: left;
    background-color: var(--fill);
    color: var(--text-primary);
    border-radius: var(--radius-md);
    /* A row that is a real button (the selection accordion) keeps its heading's size. */
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    user-select: none;
    transition: background-color var(--motion-fast), color var(--motion-fast);
}

div.AccGroup_window span.AccBlock_title::before,
summary.bw-branch-summary::before,
button.tq-sel-acc-toggle::before {
    content: '\203A';
    flex: none;
    font-size: 1.25em;
    line-height: 1;
    color: var(--text-secondary);
    transition: transform var(--motion-fast);
}

div.AccGroup_window span.AccBlock_title:hover,
summary.bw-branch-summary:hover,
button.tq-sel-acc-toggle:hover {
    background-color: var(--fill-hover);
}

div.AccGroup_window span.AccBlock_title.AccBlock_active::before,
details[open] > summary.bw-branch-summary::before,
button.tq-sel-acc-toggle[aria-expanded="true"]::before {
    transform: rotate(90deg);
}

/* The chevron above stands in for the browser's own triangle. */
summary.bw-branch-summary::-webkit-details-marker {
    display: none;
}

/* A little air between one block and the next, and under an open row. */
div.AccGroup_window div.AccBlock_window + div.AccBlock_window,
details.bw-branch + details.bw-branch {
    margin-top: 4px;
}

details.bw-branch[open] > summary.bw-branch-summary {
    margin-bottom: 8px;
}

div.AccGroup_window div.AccBlock_body {
    border: 1px solid var(--divider);
    border-radius: var(--radius-lg);
    margin: .5em 1em .5em  1em;
}

.AccGroup_title,
.AccGroup_markup,
.Nav_title,
.Nav_header,
.MainRegion_header,
.MainRegion_title {
    display: block;
    font-size: smaller;
    font-family: 'Courier New';
    height: 0px;
    width: 0px;
    overflow: hidden;
    margin-top: 0px;
    margin-bottom: 0px;
}

.Nav_menu {
    background-color: var(--surface);
    color: var(--text-primary);
    margin-top: 0;
}

.menu_menu {
    text-align: left;
    text-indent: 10px;
    border: 1px solid transparent;
    border-radius: var(--radius-lg);
}

    .menu_active,
    .menu_menu:hover {
        background-color: var(--fill-hover);
        color: var(--text-primary);
        text-indent: 10px;
        /* The shared sheet makes the current item bold, which widens the
           label as the pointer moves down a menu. */
        font-weight: inherit;
    }

.MainRegion.Window {
    z-index: 0;
}

.Delete_window {
    background-image: var(--icon-delete);
    background-repeat: no-repeat;
    border: none;
}

    .Delete_window[disabled] {
        background-color: var(--fill);
        opacity: 0.5;
    }

    .UploadView_window .MTV_controls .MTV_attention input[type=button] {
        background-color: var(--accent-fill);
        /*color: white;*/
        /*border: outset;
            border-bottom:none;*/
    }

    .UploadView_window .MTV_controls input[type=button] {
        background-color: var(--blueBackground);
        border-radius: 0px;
        height: 3em;
    }

    .UploadView_window .MTV_controls input[type=button] {
        background-color: var(--blueBackground);
        border-radius: 0px;
        height: 3em;
    }

.UploadView_button button:nth-child(1) {
    background-image: var(--icon-upload-cloud);
    width: auto;
    height: 1.2em;
    background-repeat: no-repeat;
    background-size: contain;
    border: none;
    color: var(--text-primary);
    text-indent: 1.5em;
}

.UploadView_button button:nth-child(2) {
    margin-left: 2em;
    background-image: var(--icon-download-cloud);
    width: auto;
    height: 1.2em;
    background-repeat: no-repeat;
    background-size: contain;
    border: none;
    color: var(--text-primary);
    text-indent: 1.5em;
}

.InfoDialog_window select,
.InfoDialog_window button.Dialog_window select {
    background-color: inherit;
}

.InfoDialog_window .MultiSelect_window {
    background-color: initial;
    overflow: auto;
    display: inline-flex;
    width: 100%
}

/* Dialog buttons previously rendered theme-purple text on a #151616
   (near-black) background — illegible. The defect was the dark
   background, not the text colour, so flip the background to white (the
   dialog's own colour) and add a visible border so the button reads
   against the dialog. The existing text colour (theme purple, ~10.8:1 on
   #fff = AAA) is left untouched — deliberately NOT setting `color` here
   so intentional per-button colours (.bw-btn-danger red, etc.) survive
   inside dialogs. Only background/border change, so layouts don't shift. */
/* WAF widget buttons (Button_window) inside dialogs get a clean white base. */
.Dialog_window button.Button_window:not(.Dialog_right) {
    background-color: var(--btn-secondary);
    border: 1px solid transparent;
    border-radius: var(--btn-radius);
}

    .Dialog_window button.Button_window:not(.Dialog_right):hover:not(:disabled),
    .Dialog_window button.Button_window:not(.Dialog_right):focus-visible {
        background-color: var(--btn-secondary-hover);
    }

    .Dialog_window button.Button_window:not(.Dialog_right):focus-visible {
        outline: var(--focus-outline);
        outline-offset: var(--focus-offset);
    }

    .InfoDialog_body button.Button_disabled,
    .Dialog_window button.Button_disabled {
        background-color: var(--color-disabled-bg);
        color: var(--color-disabled-text);
    }

.InfoDialog_normal,
.Dialog_normal {
    min-width: 300px;
}

/* The framework's alert box takes the same corners as its dialogs. */

.AlertThen_title {
    border-radius: var(--radius-popup) var(--radius-popup) 0 0;
}

/* The wait spinner has black ink, so each theme names its own picture. It
   takes the place of the one the script loaded. */
.waf-spinner-img {
    content: var(--icon-wait-spinner);
}

/* A box that scrolls AND has large corners. The browser draws a scrollbar
   as a square strip that ignores the corner radius, so the two corners on
   the scrollbar's side came out sharp. A slim thumb on a clear track, kept
   clear of the curved ends, leaves all four corners round. Every dialog box
   that takes --radius-popup is listed, and the cards that scroll, which say
   in --scroll-corner that their corner is the smaller one. The scoring
   display is listed for another reason: a styled scrollbar is always a
   classic one with a real width, and the locked item's shield can only pass
   a drag through to a bar it can measure (an overlay bar has none). The
   item's own scrollers carry the same bar from inside its shadow root
   (DefineItemScoringView, _ITEM_SCROLLBAR_CSS). */
.wc-panel,
.bw-panel,
.pub-selected-container {
    --scroll-corner: var(--radius-card);
}

:is(.Dialog_normal, .InfoDialog_normal, .AlertThen_normal, .app-dialog,
    dialog.tq-charpicker, dialog.tq-pnp-dialog, dialog.tq-equation-dialog,
    dialog.tq-basic-dialog, .wc-panel, .bw-panel, .pub-selected-container,
    .tq-scoring-display)::-webkit-scrollbar {
    width: var(--scrollbar-lane);
    height: var(--scrollbar-lane);
}

:is(.Dialog_normal, .InfoDialog_normal, .AlertThen_normal, .app-dialog,
    dialog.tq-charpicker, dialog.tq-pnp-dialog, dialog.tq-equation-dialog,
    dialog.tq-basic-dialog, .wc-panel, .bw-panel, .pub-selected-container,
    .tq-scoring-display)::-webkit-scrollbar-track {
    background: transparent;
    /* Stop short of the curve at each end. */
    margin: calc(var(--scroll-corner, var(--radius-popup)) - 6px);
}

:is(.Dialog_normal, .InfoDialog_normal, .AlertThen_normal, .app-dialog,
    dialog.tq-charpicker, dialog.tq-pnp-dialog, dialog.tq-equation-dialog,
    dialog.tq-basic-dialog, .wc-panel, .bw-panel, .pub-selected-container,
    .tq-scoring-display)::-webkit-scrollbar-thumb {
    /* The clear border is what makes the thumb slim inside its lane. */
    border: var(--scrollbar-thumb-inset) solid transparent;
    border-radius: var(--radius-full);
    background-color: var(--scrollbar-thumb);
    background-clip: content-box;
}

:is(.Dialog_normal, .InfoDialog_normal, .AlertThen_normal, .app-dialog,
    dialog.tq-charpicker, dialog.tq-pnp-dialog, dialog.tq-equation-dialog,
    dialog.tq-basic-dialog, .wc-panel, .bw-panel, .pub-selected-container,
    .tq-scoring-display)::-webkit-scrollbar-corner {
    background: transparent;
}

/* Browsers without those pseudo-elements (Firefox) take the standard
   properties. They are kept out of the others' way on purpose: where both
   are set, the standard ones win and the track margin above is ignored. */
@supports not selector(::-webkit-scrollbar) {
    :is(.Dialog_normal, .InfoDialog_normal, .AlertThen_normal, .app-dialog,
        dialog.tq-charpicker, dialog.tq-pnp-dialog, dialog.tq-equation-dialog,
        dialog.tq-basic-dialog, .wc-panel, .bw-panel, .pub-selected-container,
        .tq-scoring-display) {
        scrollbar-width: thin;
        scrollbar-color: var(--scrollbar-thumb) transparent;
    }
}

/* Workflow-change confirm dialog: its acknowledgement checkbox carries a full
   sentence, not a short field caption. Override the generic two-column,
   nowrap-label Dialog_body layout so the warning stacks in one column and wraps
   instead of forcing horizontal scrolling. */
.ba-wf-change-dialog .Dialog_body {
    grid-template-columns: 1fr;
}
.ba-wf-change-dialog .Dialog_body > label {
    white-space: normal;
}
/* The acknowledgement row carries its own text, so the dialog's label cell
   for it is empty — drop the blank line it would otherwise leave. Scoped to
   this one-column dialog: in the default two-column grid an empty label
   still holds the first column. */
.ba-wf-change-dialog .Dialog_body > label:empty {
    display: none;
}

/* Acknowledgement checkbox (Scripts/Widgets/AcknowledgementCheckbox.js): the
   sentence is the <label> wrapping the box and the whole row is the hit
   target — at least 44 CSS px tall (WCAG 2.5.5 AAA) with a 24 px box in
   place of the browser's 13 px default. Same palette as .bw-global-notice so
   it reads as part of the warning family; #0b3b66 on #eef5fc holds above
   7:1, the ticked #d9e8f7 above 9:1. */
.mt-ack {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    box-sizing: border-box;
    min-height: 44px;
    margin: 12px 0 4px;
    padding: 10px 12px;
    border: 1px solid var(--accent);
    border-left: 6px solid var(--accent);
    border-radius: var(--radius-sm);
    background: var(--accent-tint);
    color: var(--accent);
    font-weight: 600;
    line-height: 1.4;
    white-space: normal;
    cursor: pointer;
}
/* Outranks the dialog's generic label rule (.Dialog_normal .Dialog_body
   label { padding-right: 1em }) so the row keeps its own inset. */
.Dialog_normal .Dialog_body .mt-ack {
    padding-right: 12px;
}
.mt-ack input[type="checkbox"] {
    flex: 0 0 auto;
    margin: 0;
}
.mt-ack:has(input[type="checkbox"]:checked) {
    background: var(--accent-tint);
}
.mt-ack input[type="checkbox"]:focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 3px;
}

    /* Override image path to Ments-specific /Images/ (case-sensitive on Linux) */
    .Dialog_normal .NosisLog_right,
    .Dialog_normal .Dialog_right {
        background-image: var(--icon-close);
        background-size: 75%;
    }

    .Dialog_normal .Dialog_body {
        min-width: 265px;
    }

        .Dialog_normal .Dialog_body label {
            padding-right: 1em;
        }

        .Dialog_normal .Dialog_body .Select_window {
            margin-bottom: 15px;
            border: 1px solid var(--color-input-border);
            border-radius: var(--radius-field);
            width: 100%;
            padding: 10px;
            /* Room for the chevron. */
            padding-right: 34px;
        }

.Dialog_body, .InfoDialog_body {
    grid-template-columns: auto 5fr;
}
/* Settings: the options that change how test content is drawn sit in one
   titled group (SettingsDialog._groupContentRenderOptions). It spans the
   dialog's two columns and lines its rows up on them; a browser without
   subgrid gives the group two columns of its own. Its look is the card's,
   and its title's the group label's. */
.settings-group {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: auto 5fr;
    grid-template-columns: subgrid;
    gap: 10px 16px;
    align-items: start;
    min-width: 0;
    margin: 0;
    padding: 12px;
}

.settings-group-title {
    grid-column: 1 / -1;
}

/* The forced Settings dialog's note (SettingsDialog._addNote): why the
   bank choice is being asked for, between the title and the settings. */
.settings-note {
    padding: 0 20px 12px 20px;
    color: var(--color-text-heading);
    max-width: 32em;
}
select:hover, select:focus {
    cursor: pointer;
}

/* =============================================================
 * DESIGN SYSTEM
 * Token-driven UI primitives. One sub-section per component.
 * ============================================================= */

/* --- Buttons ---------------------------------------------------
 * Compose: .btn + size modifier + variant modifier
 * Sizes:    --sm  --md  --lg
 * Variants: --primary  --secondary  --ghost  --outline  --destructive
 * --------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    font-family: inherit;
    font-weight: 500;
    border-radius: var(--btn-radius);
    border: none;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    transition: var(--btn-transition);
    text-decoration: none;
}

/* The look of a button, for the screens that named their own before .btn
   existed. Their names are kept, so no markup changed; what they look like is
   defined here and in the variant rules below, once. A screen's own rule now
   sets only its own business: size, spacing and position. A NEW button uses
   .btn and a variant; this list should only ever get shorter. */
.au-btn,
.au-btn-danger,
.bm-btn,
.cc-btn,
.db-danger-btn,
.ib-dash-panel button.ib-load-btn,
.ib-search-bar button,
.ih-btn,
.mc-btn,
.mc-btn-danger,
.mc-btn-primary,
.mc-btn-secondary,
.mc-btn-success,
.pub-action-buttons button,
.pub-dlg-actions button,
.pub-dlg-actions button:first-child,
.pub-dlg-actions button:nth-child(2),
.pub-dlg-search button,
.pub-dlg-selall button,
.pub-publish-btn,
.tq-add-scene-button,
.tq-button-danger,
.tq-button-primary,
.tq-button-secondary,
.tq-delete-scene-button,
.tq-new-assertion-btn,
.tq-restore-btn,
.tq-submit-button,
.wa-btn,
.wa-search-btn,
.wc-btn,
.wf-btn,
.wf-btn-danger,
.wf-btn-primary,
.wf-btn-secondary,
.wf-btn-warning,
button.imp-btn-primary,
button.imp-btn-secondary,
button.tq-video-watch,
.DRV_controls .drv-action {
    border-radius: var(--btn-radius);
    font-weight: 500;
    cursor: pointer;
    transition: var(--btn-transition);
    text-decoration: none;
    font-size: var(--control-text);
    line-height: 1.2;
    padding: 8px 16px;
    min-height: 44px;
}

/* One size. The three size names stay because markup and scripts carry them;
   they no longer differ. */
.btn--sm,
.btn--md,
.btn--lg { font-size: var(--control-text); padding: 8px 16px; min-height: 44px; }

/* Secondary comes first: a screen's base class that is itself a secondary
   button (.mc-btn) is worn together with its primary or danger class, and
   the later rule must be the one that wins. */
.au-btn,
.bm-btn,
.cc-btn,
.ib-dash-panel button.ib-load-btn,
.ih-btn,
.mc-btn,
.mc-btn-secondary,
.pub-action-buttons button,
.pub-dlg-actions button:nth-child(2),
.pub-dlg-search button,
.pub-dlg-selall button,
.tq-button-secondary,
.tq-new-assertion-btn,
.tq-restore-btn,
.wa-btn,
.wa-search-btn,
.wc-btn,
.wf-btn-secondary,
button.imp-btn-secondary,
.DRV_controls .drv-action.drv-secondary,
.btn--secondary {
    background-color: var(--btn-secondary);
    color: var(--text-primary);
}
.au-btn:hover:not(:disabled),
.bm-btn:hover:not(:disabled),
.cc-btn:hover:not(:disabled),
.ib-dash-panel button.ib-load-btn:hover:not(:disabled),
.ih-btn:hover:not(:disabled),
.mc-btn:hover:not(:disabled),
.mc-btn-secondary:hover:not(:disabled),
.pub-action-buttons button:hover:not(:disabled),
.pub-dlg-actions button:nth-child(2):hover:not(:disabled),
.pub-dlg-search button:hover:not(:disabled),
.pub-dlg-selall button:hover:not(:disabled),
.tq-button-secondary:hover:not(:disabled),
.tq-new-assertion-btn:hover:not(:disabled),
.tq-restore-btn:hover:not(:disabled),
.wa-btn:hover:not(:disabled),
.wa-search-btn:hover:not(:disabled),
.wc-btn:hover:not(:disabled),
.wf-btn-secondary:hover:not(:disabled),
button.imp-btn-secondary:hover:not(:disabled),
.DRV_controls .drv-action.drv-secondary:hover:not(:disabled),
div.DISView_window > div.DISView_body div.tq-assertion-panel div.tq-header button:hover:not(:disabled),
.btn--secondary:hover:not(:disabled):not(.btn--loading),
.btn--secondary:focus:not(:disabled):not(.btn--loading) {
    background-color: var(--btn-secondary-hover);
}

.mc-btn-success,
.tq-submit-button,
.ib-search-bar button,
.mc-btn-primary,
.mc-btn-warning,
.pub-dlg-actions button:first-child,
.pub-publish-btn,
.tq-add-scene-button,
.tq-button-primary,
.wf-btn-primary,
.wf-btn-warning,
button.imp-btn-primary,
.DRV_controls .drv-action:not(.drv-secondary),
.btn--primary {
    background-color: var(--btn-primary);
    color: var(--text-on-accent);
    font-weight: 600;
}
.ib-search-bar button:hover:not(:disabled),
.mc-btn-primary:hover:not(:disabled),
.mc-btn-warning:hover:not(:disabled),
.pub-dlg-actions button:first-child:hover:not(:disabled),
.pub-publish-btn:hover:not(:disabled),
.tq-add-scene-button:hover:not(:disabled),
.tq-button-primary:hover:not(:disabled),
.wf-btn-primary:hover:not(:disabled),
.wf-btn-warning:hover:not(:disabled),
button.imp-btn-primary:hover:not(:disabled),
.mc-btn-success:hover:not(:disabled),
.tq-submit-button:hover:not(:disabled),
.DRV_controls .drv-action:not(.drv-secondary):hover:not(:disabled),
div.DISView_window > div.DISView_body div.tq-numeric-buttons > span.tq-control-span > button.Button_window:hover:not(:disabled),
.btn--primary:hover:not(:disabled):not(.btn--loading),
.btn--primary:focus:not(:disabled):not(.btn--loading) {
    background-color: var(--btn-primary-hover);
}

.btn--ghost {
    background-color: transparent;
    color: var(--btn-ghost-text);
}
.btn--ghost:hover:not(:disabled):not(.btn--loading),
.btn--ghost:focus:not(:disabled):not(.btn--loading) {
    background-color: var(--btn-ghost-hover-bg);
}

.au-btn-danger,
.db-danger-btn,
.mc-btn-danger,
.tq-button-danger,
.tq-delete-scene-button,
.wf-btn-danger,
.btn--destructive {
    background-color: var(--btn-destructive);
    color: var(--text-on-accent);
}
.db-danger-btn:hover:not(:disabled),
.mc-btn-danger:hover:not(:disabled),
.tq-button-danger:hover:not(:disabled),
.tq-delete-scene-button:hover:not(:disabled),
.wf-btn-danger:hover:not(:disabled),
.au-btn-danger:hover:not(:disabled),
.btn--destructive:hover:not(:disabled):not(.btn--loading),
.btn--destructive:focus:not(:disabled):not(.btn--loading) {
    background-color: var(--btn-destructive-hover);
}

button.tq-video-watch,
.btn--outline {
    background-color: transparent;
    color: var(--text-primary);
    border: 1.5px solid var(--btn-outline-border);
}
button.tq-video-watch:hover:not(:disabled),
.btn--outline:hover:not(:disabled):not(.btn--loading),
.btn--outline:focus:not(:disabled):not(.btn--loading) {
    background-color: var(--btn-ghost-hover-bg);
}

.au-btn:disabled,
.au-btn-danger:disabled,
.bm-btn:disabled,
.cc-btn:disabled,
.db-danger-btn:disabled,
.ib-dash-panel button.ib-load-btn:disabled,
.ib-search-bar button:disabled,
.ih-btn:disabled,
.mc-btn:disabled,
.mc-btn-danger:disabled,
.mc-btn-primary:disabled,
.mc-btn-warning:disabled,
.mc-btn-secondary:disabled,
.mc-btn-success:disabled,
.pub-action-buttons button:disabled,
.pub-dlg-actions button:disabled,
.pub-dlg-actions button:first-child:disabled,
.pub-dlg-actions button:nth-child(2):disabled,
.pub-dlg-search button:disabled,
.pub-dlg-selall button:disabled,
.pub-publish-btn:disabled,
.tq-add-scene-button:disabled,
.tq-button-danger:disabled,
.tq-button-primary:disabled,
.tq-button-secondary:disabled,
.tq-delete-scene-button:disabled,
.tq-new-assertion-btn:disabled,
.tq-restore-btn:disabled,
.tq-submit-button:disabled,
.wa-btn:disabled,
.wa-search-btn:disabled,
.wc-btn:disabled,
.wf-btn:disabled,
.wf-btn-danger:disabled,
.wf-btn-primary:disabled,
.wf-btn-secondary:disabled,
.wf-btn-warning:disabled,
button.imp-btn-primary:disabled,
button.imp-btn-secondary:disabled,
button.tq-video-watch:disabled,
.DRV_controls .drv-action:disabled,
.btn:disabled,
.btn--loading {
    opacity: 0.5;
    cursor: not-allowed;
}
.btn:focus-visible {
    outline: var(--focus-outline);
    outline-offset: var(--focus-offset);
}

/* Headings with a name of their own. The heading elements have their look
   near the top of this file ("Headings"); these are the headings that are
   not such an element, or whose kind is not the one their element gives. A
   screen's own rule sets only where its heading sits. A NEW heading uses the
   element; these lists should only ever get shorter. */
/* a popup's title */
.app-dialog-title,
.tq-dialog-title,
.tq-standards-title,
.tq-pnp-dialog-title,
.wf-force-unlock-title,
.tq-charpicker-title,
.ip-panel-title,
.bp-header-title {
    font-size: var(--text-section);
    font-weight: 600;
    line-height: 1.25;
    color: var(--text-primary);
}

/* a sub-section */
.tq-stimulus-context-title,
.bug-reports-detail-title,
.ih-panel-title,
.ih-element-title,
.tq-ad-align-title,
.tq-preview-section h3,
.tq-pnp-section-title,
.tq-changes-heading,
.tq-template-changes-heading,
.tq-media-heading,
.ba-subtab-head,
.bp-panel-header,
.ht-video-title,
.ht-player-title,
.tq-sim-tab-title,
.tq-assertion-selector div.tq-title,
.tq-assertion-mapping div.tq-title,
div.tq-simple-scoring-fullcredit-heading,
.fb-section-head {
    font-size: var(--text-subsection);
    font-weight: 600;
    line-height: 1.25;
    color: var(--text-primary);
}

/* the small label over a group */
.bw-collection h4,
.ib-attr-panel-section h4,
.ib-dash-side-head h3,
.ib-dash-panel h3,
.imp-card h4,
.tq-deleted-accordion-header,
.tq-deleted-section-title,
div.tq-scoring-section-title,
div.tq-property-widget-title,
.tq-charpicker-heading,
.wa-content-search-matches-heading,
.tq-mapping-head,
.tq-evalto-heading,
.settings-group-title,
.tq-simulation-title-bar-group label,
.be-chooser-label,
.fb-chart-title,
.fb-subhead {
    font-size: var(--text-note);
    font-weight: 600;
    line-height: 1.25;
    color: var(--text-secondary);
}

/* a field's label that is not a label element of its own */
.wa-content-search-caption {
    font-size: var(--text-label);
    font-weight: 500;
    color: var(--text-primary);
}

/* a note beside or under something */
.rd-caption,
.wa-entity-subtitle {
    font-size: var(--text-note);
    font-weight: 400;
    color: var(--text-secondary);
}

/* Tags. One look for a small status label (owner, 2026-10-06: tinted): a
   tinted fill with text in the same colour family, never an outline. The
   kinds are the theme's own: neutral, information, success, warning,
   danger. A screen's own rule sets only where its tag sits. A NEW tag uses
   one of these names; these lists should only ever get shorter. */
.bw-shared-badge,
.tq-pnp-chip,
.imp-attr-badge,
.tq-rubric-badge,
.ih-status-indicator,
.wa-lifecycle-state span[class^="wa-lifecycle-state-"],
.be-chip,
.be-role,
.be-cat,
.fb-pill,
.fb-chip,
.fb-role,
.fb-need,
.fb-section-ft .fb-section-name {
    display: inline-block;
    /* 2px 8px in all, a transparent 1px of it as a border: under the Windows
       contrast setting the browser drops the fill and shows that border. */
    padding: 1px 7px;
    border: 1px solid transparent;
    border-radius: var(--radius-tag);
    font-size: var(--text-tag);
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
}

.ih-status-skipped,
.wa-lifecycle-state-archived,
.wa-lifecycle-state-unknown,
.be-chip,
.be-role,
.fb-pill,
.fb-chip,
.fb-role {
    background-color: var(--fill-hover);
    color: var(--text-primary);
}

.bw-shared-badge,
.tq-pnp-chip,
.ih-status-in-progress,
.wa-lifecycle-state-released,
.be-role-content,
.fb-role-content,
.fb-status-exported {
    background-color: var(--tag-bg);
    color: var(--tag-text);
}

.imp-attr-badge,
.ih-status-complete,
.wa-lifecycle-state-listo,
.be-role-collection,
.fb-role-collection,
.be-cat,
.fb-status-final,
.fb-need-within {
    background-color: var(--status-success-tint);
    color: var(--status-success);
}

.tq-rubric-badge,
.ih-status-pending,
.wa-lifecycle-state-in_development,
.be-role-marginal,
.fb-role-marginal,
.fb-preliminary-pill,
.fb-chip-dev,
.fb-chip-warn,
.fb-need-under {
    background-color: var(--status-warning-tint);
    color: var(--status-warning);
}

.ih-status-invalidated,
.wa-lifecycle-state-rejected,
.be-role-fieldtest,
.fb-role-fieldtest,
.fb-chip-danger,
.fb-need-over,
.fb-section-ft .fb-section-name {
    background-color: var(--status-danger-tint);
    color: var(--status-danger);
}

/* Notices. One look for a box that tells the user something (owner,
   2026-10-06: tinted, with a bar): a tinted box, a bar in the status colour
   at its start, and ordinary dark text, which reads better at length than
   coloured text. */
.ht-notice,
.bw-global-notice,
.tq-info-message,
.tq-acc-hint,
.au-drift-banner,
.au-scope-notice,
.imp-unknown-banner,
.tq-evalto-warning,
.tq-undefined-ref-warning,
.tq-pv-notice,
.tq-cartesian-regions-notice,
div.tq-simple-scoring-panel div.tq-simple-scoring-warning,
.tq-rights-panel .tq-rights-message,
dialog.tq-score-dialog div.tq-score-notice,
.wc-global-warning,
.tq-property-textcontains-notice,
.tq-error-message,
.tq-dnf-error,
.be-save-status.be-save-error,
.be-save-status.be-save-stale,
.td-save-error,
.td-save-stale,
.tp-save-error,
.tp-save-stale,
.fb-save-error,
.fb-save-stale,
.fb-hover-readout,
.fb-msgbox,
.fb-msg-list .fb-msg-item,
.be-save-status.be-save-incomplete,
.be-delete-dialog .be-delete-warning,
.be-delete-dialog .be-delete-blocked,
.pub-nonstandard-group {
    padding: 10px 12px;
    /* Unseen until the Windows contrast setting drops the fill and the bar.
       The fill stops inside it, so the bar stays flush with the box. */
    border: 1px solid transparent;
    background-clip: padding-box;
    border-radius: var(--radius-md);
    font-size: var(--control-text);
    font-weight: 400;
    line-height: 1.45;
    color: var(--text-primary);
}

.ht-notice {
    background-color: var(--bg-secondary);
    box-shadow: inset 3px 0 0 var(--control-border);
}

.bw-global-notice,
.tq-info-message,
.tq-acc-hint,
.fb-hover-readout,
.fb-msgbox.fb-msg-note,
.fb-msg-list .fb-msg-note {
    background-color: var(--accent-tint);
    box-shadow: inset 3px 0 0 var(--accent-fill);
}

.au-drift-banner,
.au-scope-notice,
.imp-unknown-banner,
.tq-evalto-warning,
.tq-undefined-ref-warning,
.tq-pv-notice,
.tq-cartesian-regions-notice,
div.tq-simple-scoring-panel div.tq-simple-scoring-warning,
.tq-rights-panel .tq-rights-message,
dialog.tq-score-dialog div.tq-score-notice,
.be-save-status.be-save-incomplete,
.be-delete-dialog .be-delete-blocked,
.fb-msgbox.fb-msg-warning,
.fb-msg-list .fb-msg-warning {
    background-color: var(--status-warning-tint);
    box-shadow: inset 3px 0 0 var(--status-warning);
}

.wc-global-warning,
.tq-property-textcontains-notice,
.tq-error-message,
.tq-dnf-error,
.be-save-status.be-save-error,
.be-save-status.be-save-stale,
.td-save-error,
.td-save-stale,
.tp-save-error,
.tp-save-stale,
.fb-save-error,
.fb-save-stale,
.be-delete-dialog .be-delete-warning,
.fb-msgbox.fb-msg-error,
.fb-msg-list .fb-msg-error,
.pub-nonstandard-group {
    background-color: var(--status-danger-tint);
    box-shadow: inset 3px 0 0 var(--status-danger);
}

/* The publication warnings dialog: a document published although it misses
   the QTI standard is a danger notice over its own problem list. Layout only. */
.pub-nonstandard-group {
    margin: 0 0 12px;
}

.pub-nonstandard-group p {
    margin: 0 0 4px;
}

.pub-nonstandard-group ul {
    margin: 0;
}

/* Popups. One frame for every box that opens over the page: the surface, a
   faint edge, the popup corner and the deepest shadow. The first selector
   weighs nothing and reaches any dialog element that has no rule of its own
   (several of the item editor's popups had none, and showed the browser's
   black box); it leaves out the item engine's dialogs and the framework's
   see-through wrappers. The names after it are the popup systems. A NEW
   popup uses .app-dialog; this list should only ever get shorter. */
:where(html[data-app-theme]) dialog:where(:not([class*="p-qti-"]):not([class*="_window"])),
.Dialog_normal,
.InfoDialog_normal,
.AlertThen_normal,
.app-dialog,
dialog.tq-basic-dialog,
dialog.tq-pnp-dialog,
dialog.tq-charpicker,
dialog.tq-equation-dialog,
.tq-variable-values-dialog,
.tq-mapping-dialog,
.wf-force-unlock-dialog,
.wf-save-rejected-dialog,
.mc-force-unlock-dialog,
.mc-save-rejected-dialog,
.tq-ctv-panel {
    background-color: var(--surface);
    color: var(--text-primary);
    border: 1px solid var(--divider);
    border-radius: var(--radius-popup);
    box-shadow: var(--shadow-3);
}

/* The space inside (owner, 2026-10-06: 20px). A popup either keeps its
   content clear of its edge itself, or leaves that to its parts (a title
   bar, a body and a row of buttons, each with its own space). Both say
   which they are in --popup-inset, so a title bar knows how far it is from
   the popup's edge. The second rule follows the first so that a popup which
   is both (an .app-dialog that is also the scoring popup) is the second. */
:where(html[data-app-theme]) dialog:where(:not([class*="p-qti-"]):not([class*="_window"])),
.app-dialog,
dialog.tq-basic-dialog,
.tq-variable-values-dialog,
.tq-mapping-dialog,
.wf-force-unlock-dialog,
.wf-save-rejected-dialog,
.mc-force-unlock-dialog,
.mc-save-rejected-dialog,
.tq-ctv-panel {
    --popup-inset: var(--popup-space);
    padding: var(--popup-inset);
}

.Dialog_normal,
.InfoDialog_normal,
.AlertThen_normal,
dialog.tq-pnp-dialog,
dialog.tq-charpicker,
dialog.tq-equation-dialog,
dialog.tq-score-dialog,
dialog.tq-assertion-dialog,
.tq-simulation-template-dialog {
    --popup-inset: 0px;
    padding: 0;
}

/* The title bar: a line under the title, from edge to edge of the popup
   (owner, 2026-10-06). It reaches the edges by stepping out over the
   popup's own space. The framework's popups draw the same bar themselves. */
.app-dialog-header,
.app-dialog > .app-dialog-title,
dialog > .tq-dialog-title,
.tq-ctv-panel > .tq-dialog-title,
.wf-force-unlock-dialog > h2,
.wf-save-rejected-dialog > h2,
.mc-force-unlock-dialog > h2,
.mc-save-rejected-dialog > h2,
.tq-pnp-dialog-title {
    box-sizing: border-box;
    min-height: 60px;
    margin: calc(-1 * var(--popup-inset, 0px)) calc(-1 * var(--popup-inset, 0px)) var(--popup-inset, 0px);
    padding: 8px var(--popup-space);
    border-bottom: 1px solid var(--divider);
}

/* A title that is the whole bar centres itself in it, and is as wide as the
   bar: the item editor's title carries a width of its own, which stopped
   the line short of the popup's far edge. */
.app-dialog > .app-dialog-title,
dialog > .tq-dialog-title,
.tq-ctv-panel > .tq-dialog-title,
.wf-force-unlock-dialog > h2,
.wf-save-rejected-dialog > h2,
.mc-force-unlock-dialog > h2,
.mc-save-rejected-dialog > h2,
.tq-pnp-dialog-title {
    display: flex;
    align-items: center;
    width: auto;
}

/* Cards. Two looks for a box that holds a piece of a screen, as the brief
   set them: white with a faint edge and a soft shadow (owner, 2026-10-06),
   and softly filled with no edge and no shadow. Both have the card corner.
   A screen's own rule sets the box's padding, size and place. Two kinds of
   card need something more to be round: a card that scrolls is also named
   in the slim-scrollbar rule further up, and a frame whose content runs to
   its edges must clip it (overflow: hidden in its own rule), or the
   content's square corners show. A NEW card uses one of these names; these
   lists should only ever get shorter. */
.bug-reports-group,
.ba-tree-panel,
.ba-bank-panel,
.wa-fieldset,
.au-fieldset,
.cc-fieldset,
.ib-dash-panel,
.imp-card,
.imp-target-fieldset,
.lb-adjust-editor,
.lb-rate-editor,
.settings-group,
.wc-panel,
.bw-panel,
.pub-selected-container,
.ih-item-panel,
.ih-history-panel,
.tq-pnp-section,
.tq-deleted-section,
.tq-preview-section,
.fb-panel {
    background-color: var(--surface);
    color: var(--text-primary);
    border: 1px solid var(--divider);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-1);
}

.tq-simulation-prompt-section,
.tq-changes-panel,
.tq-media-panel,
.wa-lifecycle-state {
    background-color: var(--bg-secondary);
    color: var(--text-primary);
    border: none;
    border-radius: var(--radius-card);
}

/* Tables. One look for every table (owner, 2026-10-06: compact). Cells are
   8px by 12px with a hairline under each row; the heading row is a soft fill
   with smaller, quieter text; the text is the control size. No stripes: a
   selected or hovered row has to be the only filled one. A screen's own rule
   sets only what is its own business (a column's width or alignment, a row
   that means something). A NEW table uses one of these names; this list
   should only ever get shorter. */
:is(.Table2D_window,
    .TreeTable2D_window,
    .asvc-table,
    .au-scope-table,
    .au-table,
    .bm-table,
    .bw-sub-table,
    .bw-table,
    .cc-table,
    .ih-pub-table,
    .ih-table,
    .imp-queue-table,
    .imp-report-table,
    .imp-selection-table,
    .wa-audit-table,
    .wc-sub-table,
    .wc-table,
    .work-overview-table,
    .wq-table,
    .tq-hottext-region-table,
    .tq-mapping-table,
    .tq-simulation-output-table,
    .tq-variable-values-table,
    .td-levels-table,
    .fb-items) {
    /* A rounded frame with a faint edge, like a card. Separate borders, not
       collapsed ones: a collapsed table cannot have round corners. */
    border-collapse: separate;
    border-spacing: 0;
    border: 1px solid var(--divider);
    border-radius: var(--radius-card);
    overflow: clip;
    background-color: var(--surface);
    font-size: var(--control-text);
    color: var(--text-primary);
}

:is(.Table2D_window,
    .TreeTable2D_window,
    .asvc-table,
    .au-scope-table,
    .au-table,
    .bm-table,
    .bw-sub-table,
    .bw-table,
    .cc-table,
    .ih-pub-table,
    .ih-table,
    .imp-queue-table,
    .imp-report-table,
    .imp-selection-table,
    .wa-audit-table,
    .wc-sub-table,
    .wc-table,
    .work-overview-table,
    .wq-table,
    .tq-hottext-region-table,
    .tq-mapping-table,
    .tq-simulation-output-table,
    .tq-variable-values-table,
    .td-levels-table,
    .fb-items) :is(th, td) {
    padding: 8px 12px;
    border: none;
    border-bottom: 1px solid var(--divider);
}

:is(.Table2D_window,
    .TreeTable2D_window,
    .asvc-table,
    .au-scope-table,
    .au-table,
    .bm-table,
    .bw-sub-table,
    .bw-table,
    .cc-table,
    .ih-pub-table,
    .ih-table,
    .imp-queue-table,
    .imp-report-table,
    .imp-selection-table,
    .wa-audit-table,
    .wc-sub-table,
    .wc-table,
    .work-overview-table,
    .wq-table,
    .tq-hottext-region-table,
    .tq-mapping-table,
    .tq-simulation-output-table,
    .tq-variable-values-table,
    .td-levels-table,
    .fb-items) th {
    background-color: var(--bg-secondary);
    color: var(--text-secondary);
    font-size: var(--text-note);
    font-weight: 600;
    text-align: left;
}

/* The frame closes the table, so the last row has no line of its own, and the
   four corner cells follow the frame's corners (the heading row's fill would
   otherwise show square in a round corner). */
:is(.Table2D_window,
    .TreeTable2D_window,
    .asvc-table,
    .au-scope-table,
    .au-table,
    .bm-table,
    .bw-sub-table,
    .bw-table,
    .cc-table,
    .ih-pub-table,
    .ih-table,
    .imp-queue-table,
    .imp-report-table,
    .imp-selection-table,
    .wa-audit-table,
    .wc-sub-table,
    .wc-table,
    .work-overview-table,
    .wq-table,
    .tq-hottext-region-table,
    .tq-mapping-table,
    .tq-simulation-output-table,
    .tq-variable-values-table,
    .td-levels-table,
    .fb-items) > tbody:last-child > tr:last-child > :is(th, td) {
    border-bottom: none;
}

:is(.Table2D_window,
    .TreeTable2D_window,
    .asvc-table,
    .au-scope-table,
    .au-table,
    .bm-table,
    .bw-sub-table,
    .bw-table,
    .cc-table,
    .ih-pub-table,
    .ih-table,
    .imp-queue-table,
    .imp-report-table,
    .imp-selection-table,
    .wa-audit-table,
    .wc-sub-table,
    .wc-table,
    .work-overview-table,
    .wq-table,
    .tq-hottext-region-table,
    .tq-mapping-table,
    .tq-simulation-output-table,
    .tq-variable-values-table,
    .td-levels-table,
    .fb-items) > thead > tr:first-child > :first-child {
    border-top-left-radius: calc(var(--radius-card) - 1px);
}

:is(.Table2D_window,
    .TreeTable2D_window,
    .asvc-table,
    .au-scope-table,
    .au-table,
    .bm-table,
    .bw-sub-table,
    .bw-table,
    .cc-table,
    .ih-pub-table,
    .ih-table,
    .imp-queue-table,
    .imp-report-table,
    .imp-selection-table,
    .wa-audit-table,
    .wc-sub-table,
    .wc-table,
    .work-overview-table,
    .wq-table,
    .tq-hottext-region-table,
    .tq-mapping-table,
    .tq-simulation-output-table,
    .tq-variable-values-table,
    .td-levels-table,
    .fb-items) > thead > tr:first-child > :last-child {
    border-top-right-radius: calc(var(--radius-card) - 1px);
}

:is(.Table2D_window,
    .TreeTable2D_window,
    .asvc-table,
    .au-scope-table,
    .au-table,
    .bm-table,
    .bw-sub-table,
    .bw-table,
    .cc-table,
    .ih-pub-table,
    .ih-table,
    .imp-queue-table,
    .imp-report-table,
    .imp-selection-table,
    .wa-audit-table,
    .wc-sub-table,
    .wc-table,
    .work-overview-table,
    .wq-table,
    .tq-hottext-region-table,
    .tq-mapping-table,
    .tq-simulation-output-table,
    .tq-variable-values-table,
    .td-levels-table,
    .fb-items) > tbody:last-child > tr:last-child > :first-child {
    border-bottom-left-radius: calc(var(--radius-card) - 1px);
}

:is(.Table2D_window,
    .TreeTable2D_window,
    .asvc-table,
    .au-scope-table,
    .au-table,
    .bm-table,
    .bw-sub-table,
    .bw-table,
    .cc-table,
    .ih-pub-table,
    .ih-table,
    .imp-queue-table,
    .imp-report-table,
    .imp-selection-table,
    .wa-audit-table,
    .wc-sub-table,
    .wc-table,
    .work-overview-table,
    .wq-table,
    .tq-hottext-region-table,
    .tq-mapping-table,
    .tq-simulation-output-table,
    .tq-variable-values-table,
    .td-levels-table,
    .fb-items) > tbody:last-child > tr:last-child > :last-child {
    border-bottom-right-radius: calc(var(--radius-card) - 1px);
}

/* Tabs. One look for every set of tabs (owner, 2026-10-06: the underline).
   The bar is a hairline. A tab is plain text standing on it. The open tab
   has darker text and an accent line under it, and no heavier weight, so the
   row does not shift when another tab opens. A screen's own rule sets only
   where its bar sits. A NEW set of tabs uses one of these pairs of names;
   this list should only ever get shorter. */
.bw-tab-bar,
.ih-toggle-bar,
.ra-tabs,
.pub-tabs,
.tq-tab-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    border-bottom: 1px solid var(--divider);
}

.bw-tab-btn,
.ih-toggle-btn,
.ra-tab,
.pub-tabs [role="tab"],
.tq-tab-button {
    appearance: none;
    min-height: 44px;
    margin: 0 0 -1px;
    padding: 10px 16px;
    border: none;
    border-bottom: 2px solid transparent;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    background: transparent;
    color: var(--text-secondary);
    font-family: inherit;
    font-size: var(--control-text);
    font-weight: 400;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    transition: color var(--motion-fast), border-color var(--motion-fast), background-color var(--motion-fast);
}

.bw-tab-btn:hover,
.ih-toggle-btn:hover,
.ra-tab:hover,
.pub-tabs [role="tab"]:hover,
.tq-tab-button:hover {
    background-color: var(--fill-hover);
    color: var(--text-primary);
}

/* The open tab. After the hover rule and at its weight, so an open tab under
   the pointer keeps its look. */
.bw-tab-btn[aria-selected="true"],
.ih-toggle-btn.ih-toggle-active,
.ra-tab.ra-tab-on,
.pub-tabs [role="tab"][aria-selected="true"],
.tq-tab-button.tq-tab-button-active {
    background-color: transparent;
    color: var(--text-primary);
    border-bottom-color: var(--accent-fill);
}

.btn:focus:not(:focus-visible) {
    outline: none;
}

@keyframes btn-spin {
    to { transform: rotate(360deg); }
}

.btn--loading::before {
    content: '';
    width: 0.875em;
    height: 0.875em;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: btn-spin 0.6s linear infinite;
    flex-shrink: 0;
}

/* --- Dialogs ---------------------------------------------------
 * Generic chrome for native <dialog> elements (non-WAF modals).
 * Header and footer are optional; omit either if not needed.
 *
 *   <dialog class="app-dialog">
 *     <div class="app-dialog-header">
 *       <span class="app-dialog-title" id="my-title">Title</span>
 *       <button class="app-dialog-close" type="button" aria-label="Close">&times;</button>  <!-- optional -->
 *     </div>
 *     <div class="app-dialog-body">…content…</div>
 *     <div class="app-dialog-footer">…buttons (use .btn)…</div>  <!-- optional -->
 *   </dialog>
 * --------------------------------------------------------------- */

.app-dialog {
    min-width: 340px;
    max-width: 480px;
    width: 100%;
    box-sizing: border-box;
    font-family: inherit;
}

.app-dialog--wide {
    max-width: 85%;
    width: 90%;
}

/* A literal on purpose: before 2024 a ::backdrop did not inherit custom
   properties, so a token here would leave older browsers with no scrim. */
.app-dialog::backdrop {
    background: rgba(15, 23, 42, 0.55);
}

.app-dialog-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.app-dialog-close {
    appearance: none;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 1.25rem;
    color: var(--text-secondary);
    line-height: 1;
    min-width: 44px;
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-full);
    transition: background-color var(--motion-fast), color var(--motion-fast);
}

.app-dialog-close:hover {
    background: var(--fill-hover);
    color: var(--text-primary);
}

.app-dialog-close:focus-visible {
    outline: var(--focus-outline);
    outline-offset: var(--focus-offset);
}

.app-dialog-body {
    margin-bottom: 20px;
}

.app-dialog-footer {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.75rem;
}

/* --- Form Controls -------------------------------------------
 * .form-label  — block label above a control.
 * .form-select — styled <select>; always pair with .form-label.
 * --------------------------------------------------------------- */

.form-label {
    display: block;
    font-weight: 500;
    color: var(--color-text-base);
    margin-bottom: 6px;
}

.form-select {
    width: 100%;
    cursor: pointer;
    transition: border-color var(--motion-fast);
}

.form-input {
    width: 100%;
    transition: border-color var(--motion-fast);
    box-sizing: border-box;
}

/* ===== END DESIGN SYSTEM ===== */

.MTView_body .LEColl_window {
    background-color: var(--activeBackground);
}

.MTView_div1 {
    width: 44px;
    height: 44px;
    background-image: var(--icon-mail);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 22px;
    background-color: transparent;
    border: none;
    cursor: pointer;
}

.MTView_div2 {
    width: 44px;
    height: 44px;
    background-image: url(/Images/havemail.svg);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 22px;
    background-color: transparent;
    border: none;
    cursor: pointer;
}

.MTView_div3 {
    width: 44px;
    height: 44px;
    background-image: var(--icon-frown);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 22px;
    background-color: transparent;
    border: none;
    cursor: pointer;
}

/* rmsource updates ********************************************************************/

/*body*/

.MTView_body {
    display: block;
    /* THE scroll container for the whole app. It used to be overflow:visible
       with a calc'd height, which spilled content out of the shell and made
       the DOCUMENT scroll — taking the banner with it. Scrolling here instead
       keeps the bar still and leaves one scrollbar, which is what the old
       "removes inner page scroll" comment was really after.
       min-height:0 is required: a flex child's default min-height:auto is its
       content height, so without it the body refuses to shrink and overflows
       the shell instead of scrolling. */
    overflow-y: auto;
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    position: relative;
    /*WI-130897*/
    padding-left: 15px;
    padding-right: 15px;
}

/* The AI limit strip (LlmBillingPlan.md C1): a row of the shell's column
   between the banner and the body, so the body shrinks rather than slides
   under it. Near is amber, reached is the error-note red. */
.MTView_aiLimitStrip {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 12px;
    box-sizing: border-box;
    width: 100%;
    padding: 4px 15px;
    border-bottom: 1px solid var(--status-warning);
    background: var(--status-warning-tint);
    color: var(--status-warning);
}

.MTView_aiLimitStrip_reached {
    border-bottom-color: var(--status-danger);
    background: var(--status-danger-tint);
    color: var(--status-danger);
}

.MTView_aiLimitStrip_message {
    flex: 1 1 auto;
}

/* New version available (Scripts/NewVersionNotice.js): a calm corner notice,
   never a modal. Fixed, so it moves no layout; above page content, below
   dialogs (<dialog> sits in the top layer). Dark text on white: 17:1. */
.MT_newVersionNotice {
    position: fixed;
    right: 16px;
    bottom: 16px;
    z-index: 900;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    box-sizing: border-box;
    max-width: min(520px, calc(100vw - 32px));
    padding: 12px 16px;
    border: 1px solid var(--accent);
    border-left: 6px solid var(--accent);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--text-primary);
    box-shadow: var(--shadow-2);
    font-size: 0.9rem;
    line-height: 1.4;
}

.MT_newVersionNotice_message {
    flex: 1 1 240px;
}

.MT_newVersionNotice_actions {
    display: flex;
    gap: 8px;
}

/*header*/

h1.MTView_header {
    display: inline-block;
    flex-grow: 1;
    text-align: center;
    background-color: transparent;
    /* The heading holds the logo; its own text was white on white and stays
       unseen. */
    color: transparent;
    margin-top: 0px;
    font-size: 1em;
    margin-block-start: 0px;
    margin-block-end: 0px;
    margin-inline-start: 0px;
    margin-inline-end: 0px;
    font-weight: normal;
    /* Not a heading in look: it keeps the page's line height too. */
    line-height: inherit;
}

h1.MTView_header img {
    height: 40px;
    width: auto;
    display: block;
    /* The logo's lettering is black, so each theme names its own picture.
       It takes the place of the one the script loaded. */
    content: var(--icon-logo);
    /* A banner too narrow for it makes the logo smaller, never squashed. */
    object-fit: contain;
}

.MTView_title {
    /*WI-130897
    display: flex;
    align-items: stretch;
    flex-direction: row;
    left: 0px;
    top: 0px;
    width: 100%;
    padding-top: 1px;
    height: 20px;*/

    display: flex;
    align-items: center;
    flex-direction: row;
    left: 0px;
    top: 0px;
    width: 100%;
    box-sizing: border-box;
    /* 44px touch-target row (WCAG AAA 2.5.5) + 4px top/bottom = 52px total.
       Published as --mt-banner-h so the few things that must reach around
       the bar (the fixed attribute panel) do the arithmetic from one place,
       the way the editor toolbar already uses --di-toolbar-h. */
    height: var(--mt-banner-h, 52px);
    /* flex-shrink:0 — without it the banner is squeezed by a tall body on a
       short viewport and the logo row collapses. */
    flex: 0 0 auto;
    /* Positioned so the drop shadow paints OVER the scrolling body; an
       in-flow banner's shadow is painted under a later sibling's background. */
    position: relative;
    z-index: 1;
    background-color: var(--bg-primary);
    color: var(--text-primary);
    padding: 4px 15px;
    /* A hairline, not a drop shadow: regions are parted by a fill or a 1px
       line. Still a box-shadow so it paints over the scrolling body. */
    box-shadow: 0 1px 0 var(--divider);
}

/*menu*/
.MenuButton_window {
    /*WI-130897
    background-image: url(..//Images/menu.svg);
    margin-left: 5px;
    float: left;
    */

    background-image: var(--icon-menu);
    margin-right: 15px;
    width: 44px;
    height: 44px;
    background-repeat: no-repeat;
    background-size: 24px;
    background-position: center center;
    background-color: transparent;
    border-radius: var(--radius-full);
}
    /*WI-130897*/
    .MenuButton_window:hover {
        background-color: var(--fill-hover);
    }

.MTView_menu.menu_window {
    /*WI-130897
    z-index: 2;
    position: fixed;
    top: 0;
    float: left;
    background-color: white;
    border-style: none;
    */

    z-index: 2;
    position: fixed;
    top: 0px;
    bottom: 0;
    left: 0;
    width: 250px;
    margin: 0;
    padding: 8px;
    box-sizing: border-box;
    background-color: var(--bg-secondary);
    color: var(--text-primary);
    border-style: none;
    border-radius: 0;
    box-shadow: var(--shadow-3);
    overflow-y: auto;
}

@media screen and (min-width: 480px) {
    .MTView_menu.menu_window {
        width: 300px;
    }
}

@media screen and (min-width: 300px) {
    .MTView_menu.menu_window {
        width: 265px;
    }
}

.FileGet_window button:hover,
.FileGet_window button:focus,
.MTView_menu .menu_menu:hover {
    /*WI-130897
    background-color: #00c2f4;
    color: #fff;
    font-style: normal;
    text-indent: 10px;
    */
    background-color: var(--fill-hover) !important;
    color: var(--text-primary);
    font-style: normal;
    text-indent: 0px;
}

.MTView_menu .menu_menu {
    /*WI-130897  
    color: #fff;
    font-style: normal;
    text-indent: 10px;
    padding: 10px 15px;
    */

    color: var(--text-primary);
    font-style: normal;
    text-indent: 0px;
    padding: 10px 15px;
}

.MTView_menu .menu_menu {
    border-bottom: 1px solid transparent !important;
    border-left: none;
    border-right: none;
    border-top: none;
}

.MTView_menu.menu_window li:nth-last-child() {
    border-bottom: none;
}

.MTView_right:focus,
.MenuButton_window:focus {
    outline: var(--focus-outline);
    outline-offset: var(--focus-offset);
    background-color: transparent;
}

/*settings */
.MTView_right {
    background-image: var(--icon-settings);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 22px;
    background-color: transparent;
    width: 44px;
    height: 44px;
    margin-right: 5px;
    margin-left: auto;
}

    .MTView_right:hover {
        background-color: var(--fill-hover) !important;
    }

/* Help & Training — the ?-in-a-circle beside the settings wheel (the screen
   left the card menu 2026-09-01; the banner is its only entry point). */
.MTView_help {
    background-image: var(--icon-help-circle);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 22px;
    background-color: transparent;
    width: 44px;
    height: 44px;
    margin-right: 5px;
    margin-left: 5px;
    border: none;
    cursor: pointer;
}

    .MTView_help:hover {
        background-color: var(--fill-hover) !important;
    }

    .MTView_help:focus {
        outline: var(--focus-outline);
        outline-offset: var(--focus-offset);
        background-color: transparent;
    }

/* Report a bug — the bug glyph between the settings wheel and the '?'
   (owner decision 2026-09-05; BugReportingPlan.md). Same 44px target and
   22px Feather icon as .MTView_help; no margin-left:auto here — the wheel's
   auto margin is what right-aligns the whole cluster. */
.MTView_bug {
    background-image: var(--icon-bug);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 22px;
    background-color: transparent;
    width: 44px;
    height: 44px;
    margin-right: 5px;
    margin-left: 5px;
    border: none;
    cursor: pointer;
}

    .MTView_bug:hover {
        background-color: var(--fill-hover) !important;
    }

    .MTView_bug:focus {
        outline: var(--focus-outline);
        outline-offset: var(--focus-offset);
        background-color: transparent;
    }

/* Work overview — the clipboard glyph between the settings wheel and the bug
   icon (Documents/WorkOverviewPlan.md). Same 44px target and 22px Feather icon
   as .MTView_bug; the wheel's auto margin right-aligns the whole cluster. */
.MTView_work {
    background-image: var(--icon-clipboard);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 22px;
    background-color: transparent;
    width: 44px;
    height: 44px;
    margin-right: 5px;
    margin-left: 5px;
    border: none;
    cursor: pointer;
}

    .MTView_work:hover {
        background-color: var(--fill-hover) !important;
    }

    .MTView_work:focus {
        outline: var(--focus-outline);
        outline-offset: var(--focus-offset);
        background-color: transparent;
    }

/* The work overview dialog: one full-width content row (hint, notices, table)
   and one button row, both spanning the dialog's label/widget grid with their
   empty labels hidden — the bug-report dialog's arrangement. */
.work-overview-dialog .Dialog_body > label:empty {
    display: none;
}

/* The content row is its own SCROLL REGION. A WAF dialog whose body outgrows
   its max height paints the later rows (here Refresh / Download / Close) over
   the earlier ones (the open WAF dialog-overflow defect; fix owed in WAF).
   Capping this row and scrolling inside it keeps the dialog title, the
   notices' first lines, the table's header row and the button row in place
   for a 50-row overview. 60vh leaves room for the title bar, the hint and
   the button row inside the dialog's calc(100vh - 48px). */
.work-overview-content {
    grid-column: 1 / -1;
    max-width: 80vw;
    max-height: 60vh;
    overflow-x: auto;
    overflow-y: auto;
}

/* The header row stays visible while the rows scroll beneath it. The
   background is opaque so scrolled rows do not show through. */
.work-overview-content .work-overview-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background-color: var(--bg-secondary);
}

.work-overview-hint,
.work-overview-notice {
    margin: 0 0 0.5rem 0;
}

.work-overview-notice {
    font-weight: 600;
}

.work-overview-buttons {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.75rem;
}

/* A bank row carries the bank's totals in bold; its steps sit beneath it,
   indented so they read as "within" the bank. Columns: collection, bank,
   step, then the counts, which right-align. */
.work-overview-table tr.work-overview-bank td {
    font-weight: 600;
}

.work-overview-table tr.work-overview-activity td:nth-child(3) {
    padding-left: 1.5rem;
}

.work-overview-table td:nth-child(n + 4) {
    text-align: right;
}

/* A step row that has a work queue opens it; bank (total) rows and steps with
   no queue (Preview) are plain rows. The pointer marks the open rows only; the
   hover and focus look is the work queue's clickable row, shared below. */
.work-overview-table tbody tr.work-overview-link {
    cursor: pointer;
}

/* Submit and Cancel share one row of the report dialog's label/widget grid
   (owner request 2026-09-05): the shared row spans both columns and the two
   buttons' empty labels are hidden so they do not leave a blank grid row.
   The reports view (Scripts/Widgets/BugReportsDialog.js) lays its rows and
   its Refresh / Close row out the same way. */
.bug-report-dialog .Dialog_body > label:empty,
.bug-reports-dialog .Dialog_body > label:empty {
    display: none;
}

.bug-report-buttons,
.bug-reports-buttons {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.75rem;
}

/* "View History" and the line saying who can read a report: the first row of
   the report dialog, full width, with a rule under it to set it off from the
   fields of the form. */
.bug-report-view {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--color-border);
}

/* The reports view (Scripts/Widgets/BugReportsDialog.js): two tables of six
   or seven columns, so the box is wider than a form dialog's 720px. */
.Dialog_normal.bug-reports-box {
    max-width: min(72rem, 94vw);
}

/* Each table with its title and the line that says how to read it: one
   bordered group (the app's fieldset look), a full-width row of the dialog's
   grid. min-width: a fieldset is otherwise as wide as its widest content, so
   a wide table would stretch the dialog instead of scrolling. */
.bug-reports-group {
    grid-column: 1 / -1;
    min-width: 0;
    margin: 0 0 0.75rem 0;
    padding: 0.5rem 0.75rem 0.75rem 0.75rem;
}

.bug-reports-group > legend {
    padding: 0 6px;
}

/* Only the table scrolls, inside its group: the group's title and line, the
   other group, the description under them and the Refresh / Close row stay
   in view together however many reports there are. 26vh, not the 30vh the
   tables had before they were framed: the two frames, with their titles,
   take about that much of the dialog's height. */
.bug-reports-table {
    position: relative;
    max-height: 26vh;
    overflow: auto;
}

/* The group's legend is the title the eye reads. The table's own caption is
   its accessible name, so it stays in the page and is only taken out of
   sight. */
.bug-reports-table .Table2D_title {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* The reference opens the report's description. WAF.Table2D renders a
   clickable cell as a bare div, so the link look is given here. */
.bug-reports-table tbody td:first-child > div {
    cursor: pointer;
    text-decoration: underline;
    white-space: nowrap;
}

/* Above each table, inside its group: how to read it, or that it is empty.
   Shown by the dialog because Table2D's own summary is not painted (WAF
   collapses it; it is the table's accessible description). */
.bug-reports-line {
    margin: 0 0 0.5rem 0;
    font-size: smaller;
}

/* The all-clients notice above the groups: a row of the dialog's grid. */
.bug-reports-notice {
    grid-column: 1 / -1;
    margin: 0 0 0.5rem 0;
    font-weight: 600;
}

/* The selected report's description: a row of its own between the tables
   and the buttons, with its own scroll for a long one. */
.bug-reports-detail {
    grid-column: 1 / -1;
    max-height: 22vh;
    overflow: auto;
    margin-top: 0.75rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--color-border);
}

.bug-reports-detail-title {
    margin: 0 0 0.25rem 0;
}

/* The reporter's own words: line breaks kept by CSS, never by markup. */
.bug-reports-description {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* The banner rename (BR-65): on a drafting screen the content's name in the
   context banner is a button. It reads as the name it replaces — inherited
   font, no box — with a dotted underline and a pencil to say it is editable;
   hover and focus fill it like the other banner buttons. */
.MTView_rename {
    font: inherit;
    color: inherit;
    background: transparent;
    border: none;
    padding: 0 0.25em;
    margin: 0;
    cursor: pointer;
    border-radius: var(--radius-sm);
    text-decoration: underline dotted;
    text-underline-offset: 0.2em;
}

    .MTView_rename:hover {
        background-color: var(--fill-hover);
    }

    .MTView_rename:focus {
        outline: var(--focus-outline);
        outline-offset: var(--focus-offset);
    }

.MTView_rename_glyph {
    margin-left: 0.35em;
    font-size: 0.9em;
}

.content-rename-dialog .Dialog_body > label:empty {
    display: none;
}

.content-rename-buttons {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.75rem;
}

/* The report dialog's screenshot row: Choose button, caption, preview and
   Remove button share one grid cell; the preview takes the full row width
   under them and is capped in height so a full-screen capture stays a thumbnail. */
.bug-report-screenshot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

/* The hint / size caption takes a whole line under the buttons: sharing the
   button's line left it a sliver of width and an orphaned last word. */
.bug-report-screenshot > .bug-report-counter {
    flex-basis: 100%;
    text-align: left;
    margin-top: 0;
}

.bug-report-preview {
    flex-basis: 100%;
    /* Its own intrinsic width at most: a small pasted crop stays small
       instead of being stretched across the column and blurred. */
    max-width: min(100%, max-content);
    max-height: 200px;
    object-fit: contain;
    object-position: left;
    border: 1px solid var(--divider);
}

/* The report dialog's live length counter under the description textarea. */
.bug-report-counter {
    display: block;
    text-align: right;
    font-size: 0.8em;
    color: var(--text-secondary);
    margin-top: 2px;
}

.MTView_div4 {
    background-image: var(--icon-log-out);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 22px;
    background-color: transparent;
    width: 44px;
    height: 44px;
    margin-right: 5px;
    margin-left: 5px;
    border: none;
    cursor: pointer;
}

.Dialog_body input.TextInput_window, .Dialog_body div.ContentEditableDiv_window {
    width: 100%;
}

/* A one-line text box on a page stops at a comfortable width. It is set to
   fill what holds it, and on a form as wide as the page that made a box
   from one edge of the screen to the other. In a popup the box fills its
   column as before: the popup is what bounds it there. */
input.TextInput_window,
input.DateInput_window {
    max-width: var(--field-max-width);
}

/* Alone in its holder, the box is an ordinary block. The framework floats
   it, and a floated box that no longer fills the line lets whatever comes
   next (the following label) climb up beside it. */
div > input.TextInput_window:only-child,
div > input.DateInput_window:only-child {
    float: none;
    display: block;
}

.Dialog_body input.TextInput_window,
.Dialog_body input.DateInput_window {
    max-width: none;
}

.DateInput_window, .TextInput_window, .ContentEditableDiv_window {
    margin-bottom: 15px;
    border: 1px solid var(--color-input-border);
    border-radius: var(--radius-field);
    width: 100%;
    padding: 10px;
}

.InfoEdit_attention {
    display: grid;
    /*    grid-template-columns: 10% 20% 20% 20% 20% 10% !important;
*/
}

.InfoEdit_window:focus {
    outline: var(--focus-outline);
    outline-offset: var(--focus-offset);
}

.InfoEdit_div1 {
    border: none;
}

/*table delete button*/
.InfoEdit_window button.Delete_window {
    border-radius: 0;
    width: 20px;
    height: 20px;
    background-position: center;
    background-color: transparent;
}

    .InfoEdit_window button.Delete_window[disabled] {
        background-color: transparent;
        cursor: default;
        opacity: .2;
    }

/*site location - dialog button*/
.InfoDialog_button .Button_window {
    margin: 10px 10px 10px 0px;
}

.InfoDialog_body {
    text-align: left;
}

/*define new client*/
.CCV_DefineNew_window {
    margin-top: 50px;
    display: flex;
    flex-direction: column;
    max-width: 600px;
    margin-right: auto;
    margin-left: auto;
}

.CCV_DefineNew_div1 {
    /*WI-130897
    width: 70%;
    height: 2em;
    */

    width: auto;
    height: auto;
}

/*define new client button*/
.CCV_DNC_button {
    display: flex;
    flex-direction: column;
    margin: 10px;
}

    .CCV_DNC_button button {
        margin: 0 0 15px 0;
    }

@media screen and (min-width: 767.98px) {
    .CCV_DNC_button {
        display: flex;
        flex-direction: row;
    }

        .CCV_DNC_button button {
            margin: auto;
        }
}

.TreeNode_item label input {
    width: auto;
    /* A tree row is taller than its text (a 44px target) and centres its
       parts, so here the radio or checkbox is centred with them. */
    align-self: center;
    margin-top: 0;
    margin-bottom: 0;
}

.TreeNode_body, .Tree_menu {
    border: none;
    font-size: inherit;
    margin-top: 0px;
    position: relative;
    width: fit-content;
    z-index: 20;
    top: 0em;
    margin-top: 10px;
}

    .TreeNode_body ul {
        margin-left: 0px;
    }

        .TreeNode_body ul ul {
            margin: 0px 0px 0px 2em;
        }

            .TreeNode_body ul ul ul {
                margin: 0px 0px 0px 4em;
            }

                .TreeNode_body ul ul ul ul {
                    margin: 0px 0px 0px 6em;
                }

    .TreeNode_body input.TreeNode_button {
        width: auto;
    }

button.TreeNode_normal {
    background-color: transparent;
}

/* A tree row's hover and its current state belong on the ROW. The framework
   paints both on the whole <li>, and the <li> also holds the node's
   children, whose own background then cut the fill into an L-shaped block.
   That was always so; it only showed once the hover fill stopped being a
   near-white tint. So the <li> paints nothing, and its label, which is the
   row, takes the fill, the weight and the rounded ends. */
.TreeNode_item:hover, .Tree_active {
    /*WI-130897
    font-style: italic;
    font-size: medium;
    */
    font-style: inherit;
    font-size: inherit;
    background-color: transparent;
    color: inherit;
    font-weight: inherit;
}

.TreeNode_item > label {
    display: inline-flex;
    align-items: center;
    gap: 0.25em;
    padding-right: 8px;
    border-radius: var(--radius-md);
}

.TreeNode_item > label:hover {
    background-color: var(--fill-hover);
}

.Tree_active > label {
    background-color: var(--selected-bg);
    color: var(--selected-text);
    box-shadow: var(--selected-mark);
}

.SS_window button.Button_window {
    display: block;
    margin-bottom: 15px;
}

.SS_window .Tree_window.SS_body {
    position: relative;
    width: fit-content;
    z-index: 20;
    top: 0em;
    margin-top: 10px;
    border: solid var(--divider) 1px;
}

.Tree_title {
    background-color: var(--bg-secondary);
    padding: 10px;
}

/*Identify a site results*/
.UploadView_window {
    margin-top: 1.2em;
}

.UploadView_div1 {
    display: flex;
    align-items: center;
}

.UploadView_window:focus {
    outline: var(--focus-outline);
    outline-offset: var(--focus-offset);
}

.UploadView_button button {
    /*WI-130897
    width: 30px;
    height: 30px;
    background-image: url(..//Images/upload-cloud.svg);
    background-repeat: no-repeat;
    background-size: contain;
    border: none;
    */

    width: 40px;
    height: 40px;
    background-image: var(--icon-upload-cloud);
    background-repeat: no-repeat;
    background-size: contain;
    border: none;
    background-color: transparent;
    padding: 0px;
    margin-right: 15px;
    border-radius: 0px;
}

    .UploadView_button button:hover {
        background-color: var(--fill-hover);
    }

.UploadView_body {
    margin-top: 1em;
    background-color: transparent;
}

.UploadView_window .MTV_controls input[type=button] {
    /* Match the AAA-compliant secondary-button style — keep the
       taller height UploadView uses for stacked controls. */
    padding: 13px 22px;
    border: 1px solid var(--btn-secondary-border);
    border-radius: var(--btn-radius);
    background: var(--btn-secondary);
    color: var(--btn-secondary-text);
    font-weight: 600;
    font-size: 0.9rem;
    cursor: pointer;
    min-height: 44px;
    height: 5em;
    white-space: normal;
    transition: border-color 0.15s, box-shadow 0.15s, transform 0.1s;
}

.UploadView_window .MTV_controls input[type=button]:hover:not(:disabled) {
    border-color: var(--jcmaPurple);
    box-shadow: 0 2px 8px var(--accent-tint);
    transform: translateY(-1px);
}

.UploadView_window .MTV_controls input[type=button]:focus-visible {
    outline: 3px solid var(--jcmaPurple);
    outline-offset: 2px;
}

.UploadView_window .MTV_controls {
    margin-right: 0px;
    margin-left: 0px;
    font-size: initial;
    display: flex;
    flex-direction: column;
}

    .UploadView_window .MTV_controls:hover {
        cursor: pointer;
    }

    .UploadView_window .MTV_controls.MTV_attention {
        border-bottom: 5px solid var(--jcmaBlue);
    }

    .UploadView_window .MTV_controls.MTV_attention {
        padding-bottom: 15px;
    }

/*identify staff table*/
.TreeTable2D_title,
.Table2D_title {
    margin-bottom: 15px;
}

.Table2D_header {
    text-align: left;
}

.TreeTable2D_window {
    width: 100%;
}

.Table2D_window {
    /*WI-130897
    display: inline-table;
    width: 100%;
    */

    display: inline-table;
    width: 100%;
}

.Table2D_body {
    text-align: left;
}

    .TreeTable2D_body button,
    .Table2D_body button {
        /*WI-130897
    font-size: small;
    border: none;
    background-color: var(--jcmaBlue);
    */

        border: none;
        padding: 5px 20px;
        border: none;
        border-radius: var(--btn-radius);
        background-color: var(--btn-secondary);
        color: var(--text-primary);
        font-size: var(--control-text);
    }

        .TreeTable2D_body button:disabled,
        .Table2D_body button:disabled {
            color: var(--text-tertiary);
            background: var(--fill);
        }

        /* A button in a table is the secondary button, and under the pointer it
           takes the secondary button's hover step with its text unchanged. It
           used to turn to the accent fill with light text; where the button
           also carried the stock button's own hover fill, that fill won and
           the light text was left on it. (The comma after the first :hover
           was missing, which also dropped two of the four selectors.) */
        .TreeTable2D_body button:focus, .TreeTable2D_body button:hover,
        .Table2D_body button:focus, .Table2D_body button:hover {
            background-color: var(--btn-secondary-hover);
            color: var(--text-primary);
            border: none;
        }

/*identify site upload window*/
@media screen and (min-width: 767.98px) {
    .UploadView_window .MTV_controls {
        display: flex;
        flex-direction: row;
        justify-content: space-between;
    }

        .UploadView_window .MTV_controls > div {
            flex-grow: 1;
            width: auto;
            /*        width: 32%;
*/
        }

    .MTV_attention + .MTV_normal {
        padding: 50px 30px;
    }
}

.MTView_title.SK_hidden {
    display: none;
}

/*global Button styles — visually match imp-btn-secondary so the
   toolbar buttons WAF.Button stamps out (.Button_window) share the
   light secondary appearance with hand-rolled buttons like the
   Associated Stimuli action.

   WCAG AAA:
     - Text: #5e0691 (--jcmaPurple) on #fff  =  10.8:1   (AAA 7:1 ✓)
     - Border: #4a5568 on #fff               =   7.8:1   (AA 1.4.11 3:1 ✓)
     - Focus outline: --jcmaPurple on #fff   =  10.8:1   (AAA 2.4.13 ✓)
     - Target size: ≥44×44 CSS px via padding + line-height (AAA 2.5.5)
     - Disabled state is exempt from contrast criteria per WCAG 1.4.3.
   Focus uses outline + offset rather than a box-shadow so the
   indicator sits adjacent to the element with no gap, satisfying
   2.4.13's "solid outline" option. :focus-visible keeps it off for
   mouse activation while preserving keyboard-user visibility. */
.Button_window {
    padding: 8px 16px;
    border: 1px solid transparent;
    border-radius: var(--btn-radius);
    background: var(--btn-secondary);
    color: var(--text-primary);
    font-weight: 500;
    font-size: var(--control-text);
    min-height: 44px;
    cursor: pointer;
    transition: var(--btn-transition);
}

    .Button_window .Button_disabled {
        background: var(--fill);
        color: var(--text-tertiary);
        border-color: var(--divider);
        cursor: not-allowed;
    }

.Button_disabled:hover, .Button_disabled:focus, Button_disabled {
    background: var(--fill-hover) !important;
    color: var(--text-tertiary) !important;
    border-color: var(--divider) !important;
    cursor: not-allowed;
    box-shadow: none;
    transform: none;
}

.Button_window:hover:not(:disabled) {
    background-color: var(--btn-secondary-hover);
}

.Button_window:active:not(:disabled) {
    background-color: var(--btn-secondary-hover);
}

.Button_window:focus-visible {
    outline: var(--focus-outline);
    outline-offset: var(--focus-offset);
}

/* Stock buttons side by side. WAF.Button puts each into its parent with no
   space between, and a button is a fill with no edge, so neighbours read as
   one strip (they touched before as well, but each had a border then). In a
   row that has no layout of its own, each keeps the space a dialog's button
   row keeps: that is a parent with no class at all, or one of the classed
   rows named here, which set no spacing. A row laid out with a gap is not
   touched. The rule weighs no more than the button's own, so a screen's
   margin still wins, and it holds only on a page that carries the app theme:
   the examinee's buttons do not move. */
:where(html[data-app-theme]) :where(div:not([class]), .session-count-row, .tq-template-admin-form-buttons) > .Button_window:where(:has(+ .Button_window)) {
    margin-inline-end: 10px;
}

/*Global Form styles*/
.Select_window {
    border: 1px solid var(--field-border);
    border-radius: var(--radius-field);
    background-color: var(--field-bg);
    color: var(--text-primary);
    width: 100%;
    padding: 10px;
    margin-bottom: 15px;
}

/* The page-wide rule, as it has always been. It also reaches the text boxes
   an author put in an item where the item is drawn straight into a page with
   no app theme (the editor's interaction frames), and those keep the look the
   item was written against. The app's own fields are set just below. */
input {
    border: 1px solid #cecece;
    border-radius: 0;
    padding: 10px;
    margin-bottom: 15px;
}

:where(html[data-app-theme]) input {
    border: 1px solid var(--field-border);
    border-radius: var(--radius-field);
    background-color: var(--field-bg);
    color: var(--text-primary);
}

/* A field's label: one size, from the scale. Only on pages that run the app
   theme: the examinee pages keep their text sizes. */
:where(html[data-app-theme]) .form-label,
:where(html[data-app-theme]) .au-label,
:where(html[data-app-theme]) .cc-label,
:where(html[data-app-theme]) .Dialog_body > label,
:where(html[data-app-theme]) .Dialog_body > [role="group"] > label,
:where(html[data-app-theme]) .InfoDialog_body > label {
    font-size: var(--text-label);
}

/* A field on the same line as its label. The page-wide rule above gives
   every field 15px of space beneath it, for forms that stack their fields.
   In a row that centres its content, that space pushed the box up out of
   line with its label; a label's own stacking space does the same to the
   label. A row that holds a label and its field side by side lists itself
   here; the list is expected to grow as such rows are found. */
.ls-limit-row > label,
.ls-limit-row > input {
    margin-top: 0;
    margin-bottom: 0;
}
input[type=color] {
    padding: 0px;
}

/* Radio buttons and checkboxes: a ring that fills when chosen. Drawn here
   rather than by the browser, so both themes and every browser match. The
   state is never the fill alone: a chosen radio shows a dot, a chosen
   checkbox a tick, a mixed checkbox a bar. The ring is --control-border, the
   3:1 edge, so an empty control can still be found.

   Scoped to pages that run the app theme, so the examinee and demo pages
   keep the browser's own controls under any accessibility colour pair.
   :where() keeps the weight at one attribute and one tag, so a rule that
   means to restyle one control still can. The size is held by min- and max-,
   because many rules give every input a width (auto, 100%, 18px, 24px) that
   suited the browser's control and would stretch or collapse a drawn one.

   Not the choices of a test item: an item drawn straight into the page (the
   scoring and preview displays) keeps the browser's own control at the size
   the item engine gives it, as it has in delivery. Those sit inside one of
   the engine's p-qti- containers. */
:where(html[data-app-theme]) input[type="radio"]:not(:where([class*="p-qti-"] *)),
:where(html[data-app-theme]) input[type="checkbox"]:not(:where([class*="p-qti-"] *)) {
    appearance: none;
    -webkit-appearance: none;
    box-sizing: border-box;
    width: 20px;
    height: 20px;
    min-width: 20px;
    max-width: 20px;
    min-height: 20px;
    max-height: 20px;
    flex: none;
    padding: 0;
    /* Level with the FIRST line of its label, however the row is laid out
       and however many lines the label runs to. A drawn box has no text
       baseline, so a row that lines things up by baseline would sit it on
       the line with its label hanging below, and a row that centres would
       put it beside the middle of a wrapped label. So the box takes no part
       in the row's alignment: it starts at the top, and the space above and
       below it makes it exactly one line of text tall (1lh), which centres
       it on the first line. That space also replaces the stock 15px under
       every input. The 4px pair is for browsers without the lh unit. */
    vertical-align: middle;
    align-self: flex-start;
    margin-top: 4px;
    margin-bottom: 4px;
    margin-top: calc((1lh - 20px) / 2);
    margin-bottom: calc((1lh - 20px) / 2);
    border: 1.5px solid var(--control-border);
    border-radius: var(--radius-full);
    background-color: transparent;
    background-position: center;
    background-repeat: no-repeat;
    cursor: pointer;
    transition: background-color var(--motion-fast), border-color var(--motion-fast);
}

:where(html[data-app-theme]) input[type="checkbox"] {
    border-radius: 6px;
}

:where(html[data-app-theme]) input[type="radio"]:hover:not(:disabled),
:where(html[data-app-theme]) input[type="checkbox"]:hover:not(:disabled) {
    border-color: var(--text-primary);
}

:where(html[data-app-theme]) input[type="radio"]:checked,
:where(html[data-app-theme]) input[type="checkbox"]:checked,
:where(html[data-app-theme]) input[type="checkbox"]:indeterminate {
    border-color: var(--text-primary);
    background-color: var(--text-primary);
}

/* The dot. */
:where(html[data-app-theme]) input[type="radio"]:checked {
    background-image: radial-gradient(circle, var(--bg-primary) 0, var(--bg-primary) 30%, transparent 36%);
}

/* The tick. */
:where(html[data-app-theme]) input[type="checkbox"]:checked {
    background-image: var(--check-glyph);
    background-size: 14px 14px;
}

/* The bar of a mixed ("some of these") checkbox. */
:where(html[data-app-theme]) input[type="checkbox"]:indeterminate {
    background-image: linear-gradient(var(--bg-primary), var(--bg-primary));
    background-size: 10px 2px;
}

:where(html[data-app-theme]) input[type="radio"]:disabled,
:where(html[data-app-theme]) input[type="checkbox"]:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* A text area takes the same look as the text boxes (the rule for every
   input is above, beside the page-wide one). The selector weighs one tag, so
   a rule that shapes one field differently still wins. */
:where(html[data-app-theme]) textarea {
    border: 1px solid var(--field-border);
    border-radius: var(--radius-field);
    background-color: var(--field-bg);
    color: var(--text-primary);
}

/* A field with focus: an accent edge two pixels thick (its 1px border plus a
   1px ring drawn outside it, so nothing moves), and no separate outline. The
   same for every field; the rules for individual fields say the same. */
:where(html[data-app-theme]) textarea:focus,
:where(html[data-app-theme]) select:focus,
:where(html[data-app-theme]) input:where(:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]):not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="image"])):focus,
:where(html[data-app-theme]) .DateInput_window:focus,
:where(html[data-app-theme]) .TextInput_window:focus,
:where(html[data-app-theme]) .Select_window:focus,
:where(html[data-app-theme]) .ContentEditableDiv_window:focus {
    outline: none;
    border-color: var(--focus-ring);
    box-shadow: 0 0 0 1px var(--focus-ring);
}

/* Drop-downs. A closed <select> is drawn here, not by the browser, so it
   matches the text boxes beside it: the same surface, edge and corners, and
   the app's chevron in place of the browser's arrow. The open list is still
   the browser's (it follows color-scheme, so it is dark in the dark theme).
   List boxes (multiple, or a size) are left alone. Scoped to pages that run
   the app theme, like the controls above. A more specific rule can still
   set its own edge or padding; the few that outrank this one and set a
   padding carry the room for the chevron themselves. */
:where(html[data-app-theme]) select:not([multiple]):not([size]) {
    appearance: none;
    -webkit-appearance: none;
    border: 1px solid var(--field-border);
    border-radius: var(--radius-field);
    background-color: var(--field-bg);
    color: var(--text-primary);
    background-image: var(--icon-chevron-down);
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 16px 16px;
    padding-right: 34px;
    cursor: pointer;
    transition: background-color var(--motion-fast), border-color var(--motion-fast);
}

/* Focus is the accent edge above. The shared sheet also changed a focused
   drop-down's fill, which left it looking disabled while it held focus. */
:where(html[data-app-theme]) select:not([multiple]):not([size]):focus {
    background-color: var(--field-bg);
}

:where(html[data-app-theme]) select:not([multiple]):not([size]):hover:not(:disabled) {
    background-color: var(--fill-hover);
}

/* The rows of the open list state a SOLID surface and text colour of their
   own. Where the list is the browser's, it takes its background from these
   (or, failing them, from the closed control), and its window is black
   underneath: a see-through fill there made the whole list flash black as
   it opened. */
:where(html[data-app-theme]) select option,
:where(html[data-app-theme]) select optgroup {
    background-color: var(--surface);
    color: var(--text-primary);
}

:where(html[data-app-theme]) select:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* A field's size. One for every text box, drop-down and text area of the
   app: the control text, in the page's font, and for a single-line field the
   height of a button (a 22px line, 10px above and below it, and the edge
   make 44px), so a field and a button on one row line up. A screen's own
   rule sets only where its field sits and how wide it is. Test content is
   left out, as it is for the drawn checkboxes above: an author's text box
   keeps the size the item was written against. A field packed into a row (a
   table cell, the scoring header) states a smaller padding of its own and
   keeps it. */
:where(html[data-app-theme]) input:where(:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]):not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="image"])):where(:not(:where([class*="p-qti-"] *))),
:where(html[data-app-theme]) .TextInput_window:where(:not(:where([class*="p-qti-"] *))),
:where(html[data-app-theme]) .DateInput_window:where(:not(:where([class*="p-qti-"] *))) {
    padding: 10px 12px;
    font-family: inherit;
    font-size: var(--control-text);
    line-height: 22px;
}

:where(html[data-app-theme]) select:not([multiple]):not([size]):where(:not(:where([class*="p-qti-"] *))) {
    padding: 10px 34px 10px 12px;
    font-family: inherit;
    font-size: var(--control-text);
    line-height: 22px;
}

:where(html[data-app-theme]) textarea:where(:not(:where([class*="p-qti-"] *))) {
    padding: 8px 12px;
    font-family: inherit;
    font-size: var(--control-text);
    line-height: 1.4;
}

/* Placeholder text is the secondary text colour, which holds 4.5:1 on a
   field in both themes; the browser's own grey does not. Test content is
   left out: a placeholder there follows the item's colours. */
:where(html[data-app-theme]) :where(input, textarea):where(:not(:where([class*="p-qti-"] *)))::placeholder {
    color: var(--text-secondary);
    opacity: 1;
}

/* A drop-down with focus takes the accent edge like every other field. The
   rule that draws a drop-down outranks the shared focus rule above, so the
   edge is stated again here, at that rule's weight. */
:where(html[data-app-theme]) select:not([multiple]):not([size]):where(:not(:where([class*="p-qti-"] *))):focus {
    border-color: var(--focus-ring);
}

/* The OPEN list. A page cannot restyle the browser's own drop-down list: its
   highlight bar and its square frame are the browser's, whatever the closed
   control looks like. Browsers with a customisable select (appearance:
   base-select: Chrome and Edge 135 onward) draw the list in the page
   instead, where it takes the theme: a raised, rounded panel, a soft fill
   under the pointer, and a tick beside the chosen row, so the choice is not
   shown by colour alone. Other browsers skip this whole block and keep their
   own list; the closed control looks the same in both. */
@supports (appearance: base-select) {
    :where(html[data-app-theme]) select:not([multiple]):not([size]),
    :where(html[data-app-theme]) select:not([multiple]):not([size])::picker(select) {
        appearance: base-select;
    }

    /* The chevron is already drawn as the control's background. */
    :where(html[data-app-theme]) select:not([multiple]):not([size])::picker-icon {
        display: none;
    }

    :where(html[data-app-theme]) select:not([multiple]):not([size])::picker(select) {
        margin-block: 4px;
        padding: 4px;
        border: 1px solid var(--divider);
        border-radius: var(--radius-lg);
        background-color: var(--surface-raised);
        color: var(--text-primary);
        box-shadow: var(--shadow-2);
    }

    :where(html[data-app-theme]) select:not([multiple]):not([size]) option {
        padding: 8px 12px;
        border-radius: var(--radius-md);
        /* Clear, so the panel shows through and the fills below read as fills. */
        background-color: transparent;
        color: var(--text-primary);
        cursor: pointer;
    }

    :where(html[data-app-theme]) select:not([multiple]):not([size]) option:hover,
    :where(html[data-app-theme]) select:not([multiple]):not([size]) option:focus-visible {
        background-color: var(--fill-hover);
        outline: none;
    }

    :where(html[data-app-theme]) select:not([multiple]):not([size]) option:checked {
        font-weight: 600;
    }

    /* The tick, moved to the end of the row. */
    :where(html[data-app-theme]) select:not([multiple]):not([size]) option::checkmark {
        order: 1;
        margin-left: auto;
        padding-left: 12px;
    }

    :where(html[data-app-theme]) select:not([multiple]):not([size]) option:disabled {
        color: var(--text-tertiary);
        cursor: not-allowed;
    }
}

/* In forced colours the browser drops the fill a drawn control depends on,
   and a chevron drawn in ink would vanish on a dark contrast theme, so there
   these controls are the browser's own again. */
@media (forced-colors: active) {
    :where(html[data-app-theme]) input[type="radio"],
    :where(html[data-app-theme]) input[type="checkbox"] {
        appearance: auto;
        -webkit-appearance: auto;
        max-width: none;
        max-height: none;
    }

    :where(html[data-app-theme]) select:not([multiple]):not([size]) {
        appearance: auto;
        -webkit-appearance: auto;
        background-image: none;
    }
}

.UploadView_controls .Button_window {
    margin-bottom: 5px;
}

    .UploadView_controls .Button_window.search {
        background-image: var(--icon-search);
        background-repeat: no-repeat;
        background-size: contain;
        padding-left: 3em;
    }

    .UploadView_controls .Button_window.back {
        background-image: var(--icon-corner-down-left);
        background-repeat: no-repeat;
        background-size: contain;
        padding-left: 3em;
    }

.AlertThen_window.consent .AlertThen_normal {
    background-image: none;
    max-height: 80%;
    overflow-y: auto;
}

.AlertThen_window.consent .AlertThen_body {
    text-align: left;
}

    .AlertThen_window.consent .AlertThen_body p {
        text-indent: 0px;
        padding-left: 10px;
    }

.AlertThen_window.consent .AlertThen_title {
    display: none;
}

.AlertThen_window.consent .AlertThen_body {
    background-image: none;
    max-height: 75%;
    overflow-y: auto;
}

.AlertThen_body table {
    margin-left: 20%;
    text-align: left;
}

.CardMenu_body {
    display: flex;
    flex-flow: row wrap;
    position: absolute;
    top: 20px;
    left: 0px;
    width: 100%;
    text-align: center;
    justify-content: center;
}

.CardMenu_label {
    height: 3em;
    width: 100%;
    position: absolute;
    bottom: 0px;
    padding: .25em;
    box-sizing: border-box;
    color: var(--text-primary);
    background-color: var(--surface);
    border-top: 1px solid var(--divider);
    border-radius: 0 0 var(--radius-card) var(--radius-card);
    font-weight: 500;
}

.CardMenu_controls {
    width: 15em;
    height: 15em;
    background-color: var(--surface);
    color: var(--text-primary);
    position: relative;
    margin: 1em;
    border-radius: var(--radius-card);
    /* The card's edge, drawn as a shadow so the card keeps its size. */
    box-shadow: 0 0 0 1px var(--divider);
    transition: box-shadow var(--motion-fast);
}

    .CardMenu_controls:hover,
    .CardMenu_controls:focus-within {
        box-shadow: 0 0 0 1px var(--divider), var(--shadow-2);
    }

    .CardMenu_controls .menu_window {
        background-color: transparent;
        position: absolute;
        top: 0px;
    }

    .CardMenu_controls .CardMenu_image {
        width: 100%;
        height: calc(100% - 3em);
        background-repeat: no-repeat;
        background-size: cover;
        border-radius: var(--radius-card) var(--radius-card) 0 0;
    }

    .MOV_title .menu_window > .menu_menu,
    .Audit_title .menu_window > .menu_menu,
    .VPV_title .menu_window > .menu_menu,
    .RLV_title .menu_window > .menu_menu,
    .LDB_title .menu_window > .menu_menu,
    .CardMenu_controls .menu_window > .menu_menu {
        background-color: var(--surface);
        border: 1px solid var(--divider);
        font-size: large;
        border-radius: var(--radius-control);
        padding-left: 10px;
        padding-right: 10px;
        color: var(--text-primary);
    }

        .MOV_title .menu_window > .menu_menu:hover,
        .MOV_title .menu_window > .menu_active,
        .Audit_title .menu_window > .menu_active,
        .Audit_title .menu_window > .menu_menu:hover,
        .VPV_title .menu_window > .menu_active,
        .VPV_title .menu_window > .menu_menu:hover,
        .RLV_title .menu_window > .menu_active,
        .RLV_title .menu_window > .menu_menu:hover,
        .LDB_title .menu_window > .menu_active,
        .LDB_title .menu_window > .menu_menu:hover,
        .CardMenu_controls .menu_window > .menu_active,
        .CardMenu_controls .menu_window > .menu_menu:hover {
            /* The hover and the current item: the soft fill, and nothing that
               moves. The text used to step 5px sideways and go bold, and the
               edge to thicken, each of which shifted the label under the
               pointer. The pill sits over the card's picture, so the fill is
               laid over the pill's own solid surface rather than used alone. */
            text-indent: 10px;
            font-weight: inherit;
            border-radius: var(--radius-control);
            border: 1px solid var(--divider);
            background-color: var(--surface);
            background-image: linear-gradient(var(--fill-hover), var(--fill-hover));
            color: var(--text-primary);
        }

.menu_groupHeader {
    font-weight: 600;
}

.TDyn_window {
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}

.TDyn_attention {
    text-align: left;
    overflow: auto;
    max-height: 10em;
    padding-left: 3em;
    background-image: none;
    text-indent: unset;
}

.InboxView_window {
    display: grid;
    grid-template-columns: 20% 80%;
    grid-template-rows: 100%;
}

.InboxView_left .RadioGroup_menu input {
    display: none;
}

.InboxView_left li.RadioGroup_menu {
    font-size: large;
    margin-top: .5em;
}

.InboxView_left .RadioGroup_menu.RadioGroup_active {
    background-color: var(--selected-bg);
    color: var(--selected-text);
    box-shadow: var(--selected-mark);
}

.InboxView_right .CMV_body .CKEdit_window {
    left: auto;
    width: 100%;
    position: relative;
}

.InboxView_right .CMV_body > div > div > div.ck.ck-reset.ck-editor.ck-rounded-corners {
}

.InboxView_right .RLine_window {
    border: solid 1px;
    margin-right: 0px;
}

    .InboxView_right .RLine_window .CA_window {
        border: solid 1px;
        margin-right: 0px;
        margin-left: 0px;
    }

.InboxView_controls {
    width: 100%;
    min-height: 2em;
    display: flex;
    flex-direction: row;
    flex-flow: row-reverse;
}

    .InboxView_controls span {
        margin-right: 1em;
    }

    .InboxView_controls button {
        background-size: contain;
        background-repeat: no-repeat;
        background-color: var(--surface);
        width: 2em;
        height: 2em;
        padding: 0px;
    }

        .InboxView_controls button:disabled {
            background-color: var(--fill);
            opacity: 0.5;
        }

        .InboxView_controls button:nth-child(2) {
            background-image: var(--icon-chevron-left);
        }

        .InboxView_controls button:nth-child(1) {
            background-image: var(--icon-chevron-right);
        }

        .InboxView_controls button:nth-child(5) {
            background-image: url("/Images/send-green.svg");
            margin-left: 1em;
            margin-right: 1em;
            margin-top: 2px;
            margin-bottom: 2px;
        }

        .InboxView_controls button:nth-child(4) {
            background-image: var(--icon-x-circle-red);
            margin-left: 1em;
            margin-right: 1em;
            margin-top: 2px;
            margin-bottom: 2px;
        }

.InboxView_right .Table2D_body td {
    padding: 0px;
}

    .InboxView_right .Table2D_body td button {
        min-width: 100%;
        min-height: 1em;
        color: var(--text-primary);
        background-color: inherit;
        border: none;
        padding: 0px;
        margin: 0px;
        text-align: left;
    }

.InboxView_right .Table2D_body .DeleteButton {
    width: 1.1em;
    height: 1.1em;
    margin-left: 1em;
}

.MTView_window .Table2D_body td .CCD_body .CCD_left ul li {
    text-align: left;
    list-style-type: none;
    list-style-position: inside;
    font-style: normal;
    background-color: var(--surface);
    display: flex;
    min-width: 12em;
}

    .MTView_window .Table2D_body td .CCD_body .CCD_left ul li input {
        display: none;
    }

.MTView_window .Table2D_body td .CCD_body .RadioGroup_menu.RadioGroup_active {
    background-color: var(--text-primary);
    color: var(--bg-primary);
    font-size: inherit;
}

.MTView_window .Table2D_body td .CCD_body .RadioGroup_window {
    display: block;
}
.Dialog_normal .CCD_title {
    text-align: center;
}

    .Dialog_normal .CCD_title button {
        float: right;
    }

.IABH_window .RLine_window {
    border: dotted 1px var(--control-border);
    height: 2em;
    display: inline;
}

    /*.CMV_window .CMV_div2 .TextInput_window {
    display: inline-block;
    width: fit-content(stretch);
    border: none;
    margin: 0px;
    padding: 0px;
    margin-left: 1em;
}
*/
    .IABH_window .RLine_window .CA_window {
        display: inline-flex;
        min-height: 1.1em;
        padding-top: 1px;
        margin-left: 1.5em;
    }

        .IABH_window .RLine_window .CA_window label {
            margin: 3px;
            font-weight: 600;
        }

        .IABH_window .RLine_window .CA_window input {
            border: none;
            min-width: 20em;
        }

        .IABH_window .RLine_window .CA_window input {
            height: auto;
            min-height: 1.1em;
            padding: 2px;
            margin-bottom: 0px;
            text-indent: 1em;
        }

    .IABH_window .RLine_window span.RLine_item {
        border: outset;
        border-radius: 10px 10px;
        width: 5em;
        margin-left: 1em;
    }

.DLTV_body input[type='checkbox'] {
    width: auto;
}

/*    .CMV_window .CMV_div3 span.CMV_item:hover,
    .CMV_window .CMV_div3 span.CMV_item:focus {
        color: blue;
    }
*/

.IABH_window .RLine_window span.RLine_item button {
    height: 1em;
    width: 1em;
    background-image: var(--icon-x);
    background-position-x: right;
    background-size: contain;
    background-repeat: no-repeat;
    margin-left: .5em;
}

.Spuw_window {
    display: inline-grid;
    grid-auto-flow: column;
    grid-template-columns: 4fr 10fr 10fr 4fr 4fr;
    width: 100%;
}

    .Spuw_window button {
        background-color: transparent;
        padding: 10px 10px;
    }

        .Spuw_window button:disabled {
            background-color: var(--fill);
        }

.LTUpload_window .base_controls {
    background-color: var(--fill);
}

    .LTUpload_window .base_controls button {
        background-color: var(--fill);
        color: var(--text-primary);
    }

        .LTUpload_window .base_controls button.LTUpload_active {
            background-color: var(--text-primary);
            color: var(--bg-primary);
        }

.DLTV_window .Dialog_body .RLine_window .RLine_item {
    display: block;
}

    .DLTV_window .Dialog_body .RLine_window .RLine_item Button {
        height: 1.1em;
        background-image: var(--icon-x-circle-red);
        margin-left: 1em;
        margin-right: 1em;
        margin-top: 2px;
        margin-bottom: 2px;
        background-size: contain;
        background-repeat: no-repeat;
        background-color: inherit;
        background-color: transparent;
    }

.Clickable {
    color: var(--accent);
    text-decoration: underline;
}

    .Clickable:hover {
        color: var(--accent-hover);
        font-style: italic;
    }

.Table2D_body button.AddButton,
.Table2D_body button.DeleteButton,
.Table2D_body button.EditButton {
    background-color: transparent;
}

.AllGood {
    background-image: var(--icon-allgood);
    height: 3em;
    width: 3em;
    background-size: contain;
    background-repeat: no-repeat;
    background-color: inherit;
}

.NotGood {
    background-image: url("/Images/notgood.svg");
    height: 3em;
    width: 3em;
    background-size: contain;
    background-repeat: no-repeat;
    background-color: inherit;
}

.DeleteButton {
    background-image: var(--icon-x-circle-red);
    margin-left: 1em;
    margin-right: 1em;
    margin-top: 2px;
    margin-bottom: 2px;
    background-size: contain;
    background-repeat: no-repeat;
    background-color: inherit;
    height: fit-content;
    background-color: transparent;
}

.EditButton {
    background-image: var(--icon-edit-2);
    margin-left: 1em;
    margin-right: 1em;
    margin-top: 2px;
    margin-bottom: 2px;
    background-size: contain;
    background-repeat: no-repeat;
    background-color: inherit;
    height: fit-content;
    background-color: transparent;
}

.AddButton {
    background-image: var(--icon-plus);
    margin-left: 1em;
    margin-right: 1em;
    margin-top: 2px;
    margin-bottom: 2px;
    background-size: contain;
    background-repeat: no-repeat;
    background-color: inherit;
    height: fit-content;
    background-color: transparent;
}

.DeleteButton:disabled {
    background-color: var(--fill);
}

.PaperClipBold,
.PaperClip {
    text-indent: 2em;
    margin-left: 1em;
    background-image: var(--icon-paperclip);
    margin-top: 2px;
    margin-bottom: 2px;
    background-size: contain;
    background-repeat: no-repeat;
    background-color: inherit;
    height: 1em;
    width: 1em;
}

.PaperClipBold {
    font-weight: 600;
}

.Bold {
    font-weight: 600;
}

/*.InboxView_right div.RLine_window span:nth-child(1) {
    width: 5em;
    margin-left: 1em;
}
.InboxView_right div.RLine_window span:nth-child(3) {
    border: none;
    min-width: 19em;
    margin-left: 1em;
}
*/

.InboxView_right .RLine_window .CA_window {
    border: none;
}

.InboxView_label {
    margin-right: 2em;
}

.AdminView_body .Dialog_body {
    grid-template-rows: min-content;
}

.AdminView_window .Dialog_body .RadioGroup_window {
    display: inline-flex;
    margin: 0px;
}

.Dialog_body {
    overflow: auto;
}

.Courier_body table {
    table-layout: fixed;
    word-break: break-word;
}

.Courier_controls {
    display: inline-flex;
    flex-direction: row;
    margin-top: 2em;
    width: 100%;
}

    .Courier_controls .Courier_div0 {
        margin-right: 1em;
        overflow: scroll;
        max-height: 15em;
        width: 50%;
    }

        .Courier_controls .Courier_div0 > button {
            display: block;
            height: fit-content;
            width: auto;
            padding: 0px;
            margin: 0px;
            background-color: inherit;
            color: var(--text-primary);
            margin-top: 1em;
        }

    .Courier_controls .BCR_window {
        width: 100%;
    }

        .Courier_controls .BCR_window .BCR_body {
            width: 100%;
        }

.Courier_window .Courier_div1 {
    display: inline-flex;
}

    .Courier_window .Courier_div1 .Button_window {
        padding: 3px 3px 3px 3px;
        margin-left: 2px;
    }

        .Courier_window .Courier_div1 .Button_window[disabled] {
            background-color: var(--fill);
        }

.Courier_window .Dialog_body button {
    margin-top: 5px;
}

    .Courier_window .Dialog_body button:disabled {
        background-color: var(--fill);
    }

.Courier_attention {
    font-size: 20px;
    background-image: none;
    text-indent: 0px;
    align-content: center
}

.Courier_window .Courier_div0 .Button_window.Courier_button_1,
.Courier_window .Courier_div0 .Button_window.Courier_button_2 {
    background-color: var(--fill);
}

.Courier_window .Courier_div0 .Button_window.Courier_button_3,
.Courier_window .Courier_div0 .Button_window.Courier_button_4 {
    background-color: var(--status-danger-tint);
}

.AlertThen_body.Courier_attention1,
.AlertThen_window.Courier_attention1 .AlertThen_normal {
    margin-left: 0px;
    margin-right: 0px;
}

.BuildTestView_window .Dialog_body .MultiSelect_active,
.BuildTestView_window .Dialog_body .MultiSelect_window {
    background-color: inherit;
}
.BuildTestView_window .Dialog_body .MultiSelect_active {
    border: 1px solid var(--control-border);
}

.staticScan {
    height: 2em;
    background-image: var(--icon-staticbarcode);
    background-repeat: no-repeat;
    background-size: contain;
}

.courier {
    background-image: url(/Images/courier.png);
}

.indorders {
    background-image: url(/Images/individualOrder.jpg);
}

.developer {
    background-image: url(/Images/developer.jpg);
}

.projectmgt {
    background-image: url(/Images/PM.jpg);
}

.lab {
    background-image: url(/Images/lab.jpg);
}

.mydata {
    background-image: url(/Images/mydata.jpg);
}

.collectpools {
    background-image: url(/Images/collectPools.jpg);
}

.reports {
    background-image: url(/Images/reports.jpg);
}

.getsetup {
    background-image: url(/Images/GetSetup.jpg);
}

.clientsetup {
    background-image: url(/Images/ClientSetup.jpg);
}

.labadmin {
    background-image: url(/Images/LabSetup.jpg);
}
.testdevelop {
    background-image: url(/Images/GetSetup.jpg);
}

.markupcreation {
    background-image: url(/Images/AccessibilityMarkup.svg);
}

.workflowreview {
    background-image: url(/Images/Review.svg);
}

.assetstudio {
    background-image: url(/Images/AssetStudio.svg);
}

div.MTView_body > div > div.ql-toolbar.ql-snow > span:nth-child(2) > button.ql-qti-markup {
    background-color: antiquewhite;
    color: blue;
    content: "X";
}

/* ========== WORKFLOW CONFIG (.wc-) ========== */

.wc-layout {
    display: flex;
    gap: 16px;
    min-height: 400px;
}

.wc-panel {
    flex: 1;
    padding: 12px;
    overflow-y: auto;
    max-height: 600px;
}

.wc-panel h3 {
    margin: 0 0 8px 0;
}

.wc-table {
    width: 100%;
    margin-top: 8px;
}

.wc-table th,
.wc-table td {
    text-align: left;
}

.wc-table tr:hover {
    background: var(--fill-hover);
}

.wc-table tr.wc-selected {
    background: var(--fill);
}

.wc-sub-table {
    width: 100%;
    margin-top: 4px;
}

.wc-btn {
    border: 1px solid transparent;
    margin: 2px;
}

.wc-btn-sm {
    padding: 2px 6px;
    font-size: 0.85em;
}

/* Bank Workflow — shared/global workflow read-only notice + "shared" badge.
   High-contrast (dark blue on pale blue) for WCAG AAA. */
.bw-global-notice {
    margin: 8px 0;
}

.bw-readonly-list {
    margin: 10px 0 0 1.25em;
    line-height: 1.5;
}

/* ========== CREATE / EDIT ITEM BANK (.ba-) ========== */

/* Status region — matches the redesigned bank-workflow status line. */
.ba-status {
    padding: 6px 0;
    min-height: 2em;
    font-size: 0.875rem;
    color: var(--color-text-base);
}

/* Redesigned tab bar (MUI-style underline tabs), mirroring the .bw-tab-*
   tabs on the Bank Workflow page. Scoped to opted-in views: a screen using
   the shared MT.TabView widget gets this look by adding its marker class
   (.ba-view, .ma-view) to its root div; other MT.TabView consumers keep
   their default look. */
.ba-view .tq-tab-buttons,
.ma-view .tq-tab-buttons {
    margin-bottom: 0;
}
.ba-view .tq-tab-content,
.ma-view .tq-tab-content {
    padding-top: 20px;
}

/* Client → Collection → Bank tree (left) + selected-bank
   panel (right). */
.ba-layout {
    display: flex;
    gap: 16px;
    align-items: flex-start;
}

/* Card-style panels matching .bw-panel on the Bank Workflow page. */
.ba-tree-panel,
.ba-bank-panel {
    padding: 16px;
    margin: 0;
    min-width: 0;
}
.ba-tree-panel { flex: 1 1 40%; }
.ba-bank-panel { flex: 1 1 60%; }

.ba-tree-panel > legend,
.ba-bank-panel > legend {
    padding: 0 6px;
}

/* Context header: breadcrumb (client › collection) directly above the bank
   name. The crumb is essential orientation text, so it uses
   --color-text-base (10.4:1, AAA) — never AA-only --color-text-muted. */
.ba-crumb {
    margin: 0 0 2px 0;
    font-size: 0.8125rem;
    color: var(--color-text-base);
}
/* Each bank sub-tab (Workflows / Standards / Attributes / User access) opens
   with its own name and a help icon, since each panel does a different job.
   Uses --color-text-base (10.4:1, AAA) — it is a heading, not a hint. */
.ba-subtab-head {
    display: flex;
    align-items: center;
    gap: 4px;
    margin: 0 0 10px 0;
}
.ba-bank-panel h3 {
    margin: 0 0 12px 0;
}

.ba-tree,
.ba-tree-group {
    list-style: none;
    margin: 0;
    padding-left: 0;
}
.ba-tree-group { padding-left: 18px; }
.ba-tree-row {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 2px 0;
    border-radius: var(--radius-sm);
    transition: background-color 0.12s ease;
}
/* The whole row (label → kebab) is one hover/focus unit: pointing at the ⋯
   tints the row all the way back to its name, so it is always clear which
   row an action targets. focus-within also keeps the row lit while its
   kebab menu is open or the toggle has keyboard focus. */
.ba-tree-row:hover,
.ba-tree-row:focus-within {
    background: var(--color-hover-bg);
}
.ba-tree-toggle,
.ba-tree-bank-btn {
    display: inline-flex;
    align-items: center;
    min-height: var(--touch-target-min);   /* 44px — WCAG 2.5.5 AAA target size */
    background: none;
    border: none;
    cursor: pointer;
    font: inherit;
    text-align: left;
    padding: 4px 6px;
    color: var(--color-text-base);
    border-radius: var(--radius-sm);
    transition: background-color 0.12s ease;
}
/* The label/toggle stretches across the gap to the kebab — the whole strip
   is a single expand/collapse target (its highlight comes from the row). */
.ba-tree-toggle { flex: 1 1 auto; }
/* Bank rows have no .ba-tree-row wrapper; their full-width button is the
   row, so it keeps its own hover. */
.ba-tree-bank-btn:hover {
    background: var(--color-hover-bg);
}
.ba-tree-toggle:focus-visible,
.ba-tree-bank-btn:focus-visible {
    outline: var(--focus-outline);
    outline-offset: var(--focus-offset);
}
.ba-tree-client > .ba-tree-row > .ba-tree-toggle { font-weight: 600; }
.ba-tree-collection > .ba-tree-row > .ba-tree-toggle { font-weight: 600; }
.ba-tree-toggle::before { content: '\25B8\00A0'; }   /* ▸ collapsed */
.ba-tree-client[aria-expanded="true"] > .ba-tree-row > .ba-tree-toggle::before,
.ba-tree-collection[aria-expanded="true"] > .ba-tree-row > .ba-tree-toggle::before {
    content: '\25BE\00A0';                            /* ▾ expanded */
}

/* Kebab (⋯) per-row menu — WAI-ARIA menu-button pattern (see
   _buildKebabMenu in BankAdminView.js). Pushed to the row's right edge. */
.ba-kebab {
    position: relative;
    margin-left: auto;
}
.ba-kebab-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--touch-target-min);
    min-width: var(--touch-target-min);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--color-text-base);
    font: inherit;
    font-size: 1.125rem;
    font-weight: 600;
    cursor: pointer;
}
/* The row already tints on hover (same token), so the kebab's own hover
   needs a distinct cue within the tinted row: a primary ring + darkened
   glyph (10.8:1, AAA). */
.ba-kebab-btn:hover {
    color: var(--color-primary-dark);
    box-shadow: inset 0 0 0 1px var(--color-primary);
}
.ba-kebab-btn:focus-visible {
    outline: var(--focus-outline);
    outline-offset: -2px;
}
/* Open state: tinted + primary-dark (10.8:1, AAA) — reinforced by the popup
   itself being visible, so the state is not colour-only. */
.ba-kebab-btn[aria-expanded="true"] {
    background: var(--color-primary-tint);
    color: var(--color-primary-dark);
}
/* Trash can beside the row menu: same footprint as the kebab. Disabled look
   for a non-empty row (#767676 on white = 4.5:1; the control stays focusable
   and explains itself when activated, so the state is not colour-only). */
.ba-trash-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--touch-target-min);
    min-width: var(--touch-target-min);
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--color-text-base);
    font: inherit;
    font-size: 1.05rem;
    cursor: pointer;
}
.ba-trash-btn:hover {
    color: var(--status-danger);
    box-shadow: inset 0 0 0 1px var(--status-danger-tint);
}
.ba-trash-btn:focus-visible {
    outline: var(--focus-outline);
    outline-offset: -2px;
}
.ba-trash-btn.ba-trash-btn--disabled {
    color: var(--text-tertiary);
    cursor: not-allowed;
    opacity: 0.6;
}
.ba-trash-btn.ba-trash-btn--disabled:hover {
    color: var(--text-tertiary);
    box-shadow: none;
}
.ba-kebab-menu {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 30;
    min-width: 210px;
    padding: 4px;
    background: var(--surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-1);
}
/* A mouse open parks focus on the popup itself (so no item is
   pre-highlighted); the popup being visible IS the state indicator, so no
   focus ring on the container. */
.ba-kebab-menu:focus { outline: none; }
.ba-kebab-item {
    display: block;
    width: 100%;
    min-height: var(--touch-target-min);
    padding: 8px 12px;
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--color-text-base);
    font: inherit;
    font-size: 0.875rem;
    text-align: left;
    cursor: pointer;
}
/* Items are only ever FOCUSED via keyboard (mouse opens park focus on the
   popup), so plain :focus can safely share the hover highlight — it keeps
   arrow-key movement visible in browsers where programmatic focus doesn't
   match :focus-visible. */
.ba-kebab-item:hover,
.ba-kebab-item:focus { background: var(--color-hover-bg); }
.ba-kebab-item:focus-visible {
    outline: var(--focus-outline);
    outline-offset: -2px;
}

/* Zero-collection client call-to-action row ("Add a collection"). */
.ba-tree-cta {
    list-style: none;
    padding: 4px 0 4px 18px;
}

.ba-tree-bank { padding-left: 18px; }
/* The bank name shares its row with the trash can, so it grows rather than
   spanning the row (width:100% would push the trash can out of the row). */
.ba-tree-bank-btn { flex: 1 1 auto; min-width: 0; }
.ba-tree-bank.ba-selected .ba-tree-bank-btn {
    background: var(--color-primary-tint);
    color: var(--color-primary-dark);
    font-weight: 600;
}

/* Workflows sub-tab: one grid row per slot — label | current | actions.
   The label column is capped and the value column floored on purpose: with
   `max-content 1fr auto` a single long label (or a long control label) took
   the width from BOTH sides and the value column collapsed to ~10px, so a
   workflow name rendered one character per line. `.ba-wf-value` sets
   min-width: 0 and overflow-wrap: anywhere — which is right for a long
   workflow name — so 1fr alone has no floor of its own to fall back on. */
.ba-wf-grid {
    display: grid;
    grid-template-columns: fit-content(18rem) minmax(14rem, 1fr) auto;
    gap: 10px 16px;
    align-items: center;
}
.ba-wf-label {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--color-text-heading);
}
.ba-wf-value {
    color: var(--color-text-base);
    min-width: 0;
    overflow-wrap: anywhere;
}
/* Unassigned slots convey essential state, so base (AAA) not muted (AA). */
.ba-wf-none {
    color: var(--color-text-base);
    font-style: italic;
}
/* Dangling assignment (workflow_def row gone). Same AAA red-on-pale-red
   family as .wc-global-warning (#7a0000 on #fff0f0 > 10:1); the border and
   the ⚠ glyph keep the state from being colour-only. */
.ba-wf-missing {
    display: inline-block;
    padding: 2px 8px;
    border: 1px solid var(--status-danger);
    border-radius: var(--radius-sm);
    background: var(--status-danger-tint);
    color: var(--status-danger);
    font-size: 0.8125rem;
    font-weight: 600;
}
.ba-wf-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
}

/* Placeholder/empty-state text conveys essential state/guidance, so it uses
   --color-text-base (10.4:1, AAA) rather than AA-only --color-text-muted. */
.ba-bank-placeholder {
    color: var(--color-text-base);
    font-style: italic;
}
.ba-empty {
    color: var(--color-text-base);
    font-size: 0.9375rem;
    padding: 4px 0;
    margin: 0;
}

/* Manifest dialog file field. */
.ba-file-field {
    display: block;
    margin: 8px 0 12px 0;
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--color-text-base);
}
.ba-file-field input[type="file"] {
    display: block;
    margin-top: 6px;
    font: inherit;
}

/* User Access tab — assigned-user list. */
.ba-user-list {
    list-style: none;
    margin: 12px 0 0 0;
    padding: 0;
}
.ba-user-list li {
    padding: 8px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    margin-bottom: 4px;
    color: var(--color-text-base);
}

/* Dialog central-div content inset is now GLOBAL (WAFBaseCSS.css,
   .Dialog_normal > .Dialog_body ~ *) — only this page's extra:
   right-align trailing action buttons. */
.ba-view .Dialog_normal > .Dialog_body ~ .btn {
    align-self: flex-end;
    margin-bottom: 20px;
}

/* EXTREME warning banner for global (cross-client) changes — outcome editing on
   the developer Workflow Config screen. High-contrast (>10:1, WCAG AAA) red on
   pale red with a heavy left rule so it cannot be missed; paired with role="alert"
   in markup so it is announced to screen readers. */
.wc-global-warning {
    margin: 8px 0;
}

.wc-status {
    padding: 6px 0;
    min-height: 1.5em;
}

.wc-node-list {
    list-style: none;
    padding: 0;
    margin: 8px 0;
}

.wc-node-list li {
    padding: 4px 8px;
    border: 1px solid var(--divider);
    margin-bottom: 2px;
    border-radius: var(--radius-sm);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.wc-node-list li:hover {
    background: var(--fill-hover);
}

.wc-node-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding: 8px 0;
    margin-top: 8px;
    border-top: 1px solid var(--divider);
    min-height: 32px;
}

.wc-badge {
    display: inline-block;
    font-size: 0.8em;
    color: var(--text-secondary);
    margin-left: 6px;
    font-style: italic;
}

.wc-allowed-values {
    display: inline-block;
    font-size: 0.85em;
    color: var(--text-secondary);
    margin-left: 4px;
    padding: 2px 6px;
    background: var(--fill);
    border-radius: var(--radius-sm);
}

.wc-attr-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 0;
    flex-wrap: wrap;
}

/* ========== MANAGE ATTRIBUTES (.ma-) ========== */
/* Light-touch cleanup of the manageattributes state. All colors come from
   the WAFBaseCSS token palette; contrast ratios are documented per rule.
   .ma-view is also the opt-in marker for the shared tq-tab-* tab styling
   (see the CREATE / EDIT ITEM BANK section above). */

/* Status region — mirrors .ba-status; announced via role="status".
   --color-text-base on --color-bg = 10.4:1 (AAA). */
.ma-status {
    padding: 6px 0;
    min-height: 2em;
    font-size: 0.875rem;
    color: var(--color-text-base);
    transition: opacity 0.3s ease;
}

.ma-status--fading {
    opacity: 0;
}

/* Poll-failure / error state: #991b1b (= --btn-destructive) on --color-bg
   = 7.9:1 (AAA). The message text itself states the failure, so the
   state is never conveyed by color alone. */
.ma-status--alert {
    color: var(--status-danger);
    font-weight: 600;
}

/* Toolbar row above the definitions tree / value-set table. */
.ma-action-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 12px;
    align-items: center;
}

/* Search input — pairs with .form-input (which supplies the
   --color-input-border 5.9:1 border, ≥3:1 UI-component minimum,
   and the focus ring). */
.ma-search {
    flex: 1 1 220px;
    width: auto;
    min-width: 200px;
    max-width: 480px;
    /* The site-wide bare `input` rule adds margin-bottom: 15px; inside the
       center-aligned action row that phantom margin lifts the input ~7px
       above the buttons, so zero it here. */
    margin: 0;
}

/* Outline buttons on this page: the shared .btn--outline border token is
   the decorative --color-border (~1.5:1 — under the 3:1 UI-component
   minimum), so strengthen it to --color-primary (7.2:1 on --color-bg). */
.ma-view .btn--outline {
    border-color: var(--color-primary);
}

/* Definition count — own line under the search row.
   --color-text-base on --color-bg = 10.4:1 (AAA). The action row above
   already carries 12px bottom margin, so only pad below. */
.ma-count {
    font-size: 0.875rem;
    color: var(--color-text-base);
    margin: -4px 0 8px;
}

/* Card chrome around the definitions list (decorative border only). */
.ma-defs-host {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--surface);
    padding: 12px;
    margin-top: 4px;
}

/* Collapsible attribute group. The toggle is a real button carrying the
   disclosure state on aria-expanded; the ▸/▾ marker (not color) shows
   open/closed. Heading text 17.1:1, ≥44px target; focus ring comes from
   the global :focus-visible rule. */
.ma-group + .ma-group {
    margin-top: 8px;
}

.ma-group-toggle {
    display: block;
    width: 100%;
    text-align: left;
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--color-text-heading);
    font: inherit;
    font-size: 0.9375rem;
    font-weight: 600;
    padding: 8px 6px;
    min-height: var(--touch-target-min);
    cursor: pointer;
    transition: background-color 0.12s ease;
}

.ma-group-toggle:hover {
    background: var(--color-hover-bg);
}

.ma-group-toggle::before {
    content: '\25BE\00A0';                  /* ▾ expanded */
}

.ma-group-toggle[aria-expanded="false"]::before {
    content: '\25B8\00A0';                  /* ▸ collapsed */
}

.ma-group-body {
    padding: 2px 0 6px 6px;
}

/* One definition per row; the whole row is the click target (like the
   Bank Admin tree rows). Text --color-text-base 10.4:1 (AAA); 44px
   target; hover tint (plus cursor) marks interactivity, the "(Global)"
   suffix — not styling — marks read-only rows. */
.ma-def-row {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    text-align: left;
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--color-text-base);
    font: inherit;
    font-size: 0.875rem;
    padding: 6px 8px;
    min-height: var(--touch-target-min);
    cursor: pointer;
    transition: background-color 0.12s ease;
}

.ma-def-row:hover {
    background: var(--color-hover-bg);
}

.ma-def-key {
    font-weight: 600;
    white-space: nowrap;
}

.ma-def-desc {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* [type · validation] summary, inline right after the name/description so
   it visually belongs to its row even on wide screens. */
.ma-def-meta {
    white-space: nowrap;
    font-size: 0.8125rem;
}

/* Empty states — 10.4:1 (AAA); NOT .imp-empty's light gray (2.1:1). */
.ma-empty,
.ma-view .queue-empty {
    padding: 12px 0;
    font-style: italic;
    color: var(--color-text-base);
}

/* Import-queue host: reserves a line so the tab does not collapse
   while the first poll is in flight. */
.ma-queue {
    min-height: 1.5rem;
}

/* Dialog central-div content inset is now GLOBAL (WAFBaseCSS.css,
   .Dialog_normal > .Dialog_body ~ * — including the :last-child 20px
   bottom) — only this page's extras remain. */
/* .form-input is width:100% of the unpadded box — let flex stretch size
   it inside the side margins instead of overflowing past them. */
.ma-view .Dialog_normal > .Dialog_body ~ .form-input {
    width: auto;
}
/* Keep a field label snug against the field it labels (matches
   .form-label's own 6px, which the global ~ * rule would otherwise
   override). */
.ma-view .Dialog_normal > .Dialog_body ~ label {
    margin-bottom: 6px;
}

/* Action row at the bottom of WAF dialogs (Save / Delete / Close). */
.ma-dialog-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 12px;
    margin-top: 16px;
}

/* Value-set members textarea — pairs with .form-input. */
.ma-members-input {
    min-height: 8em;
    resize: vertical;
}

/* Per-row action button rendered inside Table2D Button cells (value-set
   "Edit"). Single composed class: TblHeader.classList.add() accepts one
   token. Text --color-primary-dark on white = 12.1:1 (AAA); border
   #4a5568 = 7.8:1 (≥3:1 UI minimum); 44px target (2.5.5); the focus
   ring comes from the global :focus-visible rule in WAFBaseCSS. */
.ma-cell-btn {
    background: var(--surface);
    color: var(--color-primary-dark);
    border: 1px solid var(--control-border);
    border-radius: var(--radius-md);
    padding: 8px 14px;
    min-height: var(--touch-target-min);
    cursor: pointer;
    font-weight: 600;
}

.ma-cell-btn:hover {
    border-color: var(--color-primary);
    background: var(--color-primary-tint);
}

@media (prefers-reduced-motion: reduce) {
    .ma-status {
        transition: none;
    }
}

/* ========== BANK WORKFLOW (.bw-) ========== */

.bw-layout {
    display: flex;
    gap: 16px;
    min-height: 400px;
    align-items: flex-start;
}

.bw-panel {
    flex: 1;
    padding: 16px;
    overflow-y: auto;
    max-height: 640px;
    min-width: 0;
}

.bw-panel-wide {
    flex: 2;
}

.bw-panel h3 {
    margin: 0 0 12px 0;
}

.bw-status {
    padding: 6px 0;
    min-height: 2em;
    font-size: 0.875rem;
    color: var(--color-text-base);
}

.bw-btn-bar {
    display: flex;
    gap: 8px;
    margin-bottom: 12px;
    flex-wrap: wrap;
    align-items: center;
}

.bw-collection {
    margin-bottom: 12px;
}

.bw-collection h4 {
    margin: 0 0 6px 0;
}

.bw-bank-btn {
    display: block;
    width: 100%;
    text-align: left;
    padding: 8px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    cursor: pointer;
    margin-bottom: 4px;
    font: inherit;
    color: var(--color-text-base);
    transition: background-color 0.12s ease, border-color 0.12s ease;
}

.bw-bank-btn:hover {
    background: var(--fill-hover);
    border-color: var(--color-primary);
}

.bw-bank-btn:focus-visible {
    outline: var(--focus-outline);
    outline-offset: var(--focus-offset);
}

.bw-bank-btn.bw-selected {
    background: var(--color-primary-tint);
    border-color: var(--color-primary);
    color: var(--color-primary-dark);
    font-weight: 500;
}

.bw-assigned {
    margin-bottom: 8px;
}

.bw-table {
    width: 100%;
    margin-top: 8px;
}

.bw-table th,
.bw-table td {
    text-align: left;
}

.bw-table tbody tr {
    height: 44px;
    transition: background-color 0.12s ease;
}

.bw-table tbody tr:hover {
    background: var(--fill-hover);
}

.bw-table tbody tr:focus-visible {
    outline: var(--focus-outline);
    outline-offset: -2px;
}

.bw-table tr.bw-selected {
    background: var(--color-primary-tint);
}

.bw-table-row-clickable {
    cursor: pointer;
}

.bw-toolbar {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
    margin-bottom: 12px;
}

/* MUI-style tab bar — flush at the top of the graph panel */
.bw-graph-panel {
    padding-top: 8px;
}

.bw-graph-placeholder {
    padding: 16px 0;
    color: var(--color-text-muted);
    margin: 0;
}

.bw-tab-panel {
    padding-top: 20px;
}

.bw-tab-panel:focus-visible {
    outline: var(--focus-outline);
    outline-offset: var(--focus-offset);
}

.bw-tab-empty {
    color: var(--color-text-muted);
    font-size: 0.9375rem;
    padding: 4px 0;
    margin: 0;
}

/* Work-queue dialog (WorkQueueRenderer): the rows are clickable AND
   keyboard-navigable (tabindex=0 + arrow keys), so make the row under
   the cursor or with focus show a clear border so the user knows which
   item the click/Enter will select. outline-offset:-2px keeps the
   border inside the row so it doesn't shift the table layout. */

.wq-content {
    flex: 1;
    overflow-y: auto;
    padding: 16px 20px;
    min-height: 0;
}

.wq-dialog-footer {
    display: flex;
    justify-content: flex-end;
    padding: 16px 20px;
    border-top: 1px solid var(--color-border);
}

.wq-table-container {
    overflow-x: auto;
    overflow-y: hidden;
    width: 100%;
}

.wq-table {
    width: 100%;
    min-width: 560px;
}

.wq-table th,
.wq-table td {
    text-align: left;
    white-space: nowrap;
}

.wq-table tbody tr {
    cursor: pointer;
    transition: background-color 0.12s ease;
    height: 44px;
}

.wq-table tbody tr:last-child {
    border-bottom: none;
}

/* Sortable headers (2026-09-05): each header cell is one button filling
   the cell; aria-sort on the th carries the state for assistive tech and
   the arrow is decorative. Click cycle: ascending, descending, back to
   the server's priority order. */
.wq-table thead th.wq-sortable {
    padding: 0;
}

.wq-sort-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    margin: 0;
    padding: 10px 16px;
    background: none;
    border: 0;
    font: inherit;
    font-weight: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    text-align: left;
    color: inherit;
    cursor: pointer;
}

.wq-sort-btn:hover,
.wq-sort-btn:focus-visible {
    background-color: var(--color-primary-tint);
    outline: none;
}

.wq-sort-btn:focus-visible {
    outline: var(--focus-outline);
    outline-offset: -3px;
}

.wq-sort-arrow {
    font-size: 0.75em;
    opacity: 0.45;
}

.wq-sort-btn--active .wq-sort-arrow {
    opacity: 1;
}

/* Force-unlock confirmation modal — pops over the WorkQueueRenderer's
   WAF.Dialog when the operator picks an item that another user holds.
   z-index 10000 is well above the work-queue dialog (which uses default
   stacking on its parent view); position:fixed centers over the viewport
   regardless of the queue dialog's own positioning. */
/* The markup tools build the same two boxes under mc- names (LockManager.js).
   They had no rule at all, overlay included, so they are named beside the
   workflow ones here and in the rules below. */
.wf-dialog-overlay,
.mc-dialog-overlay {
    position: fixed;
    inset: 0;
    background: var(--scrim);
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    box-sizing: border-box;
}

/* The lock-lost / save-rejected dialog (MT.LockWatch) shares the
   force-unlock dialog's card styling — same overlay, same shell. */
.wf-force-unlock-dialog,
.wf-save-rejected-dialog,
.mc-force-unlock-dialog,
.mc-save-rejected-dialog {
    max-width: 520px;
    width: 100%;
    box-sizing: border-box;
    font-family: inherit;
}

.wf-lock-lost-who,
.wf-lock-lost-reason {
    margin: 0 0 10px 0;
    font-size: 0.95rem;
    color: var(--text-primary);
    word-break: break-word;
}

.wf-save-rejected-dialog .wf-hint {
    display: block;
    margin: 12px 0 0 0;
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.wf-force-unlock-summary {
    background: var(--activeBackground);
    border-radius: var(--radius-md);
    padding: 12px 14px;
    margin-bottom: 18px;
    display: grid;
    row-gap: 4px;
}

.wf-force-unlock-summary-row {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: 0.95rem;
}

.wf-force-unlock-summary-label {
    color: var(--text-secondary);
    font-weight: 600;
    flex-shrink: 0;
}

.wf-force-unlock-summary-value {
    color: var(--text-primary);
    word-break: break-word;
}

.wf-force-unlock-reason-label,
.mc-force-unlock-dialog > label {
    display: block;
    margin-bottom: 6px;
    font-weight: 600;
    color: var(--text-primary);
}

/* The reason box is the shared text area; this says only how it sits. */
.wf-force-unlock-reason,
.mc-force-unlock-reason {
    display: block;
    width: 100%;
    box-sizing: border-box;
    resize: vertical;
    min-height: 72px;
}

.wf-force-unlock-reason[aria-invalid="true"],
.mc-force-unlock-reason[aria-invalid="true"] {
    border-color: var(--status-danger);
    background-color: var(--status-danger-tint);
    color: var(--text-primary);
}

.wf-dialog-buttons,
.mc-dialog-buttons {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 18px;
}

.wf-btn {
    appearance: none;
    border: 1px solid transparent;
    font-family: inherit;
}

    .wq-table tbody tr:hover,
    .wq-table tbody tr:focus,
    .work-overview-table tbody tr.work-overview-link:hover,
    .work-overview-table tbody tr.work-overview-link:focus {
        background-color: var(--color-primary-tint);
        outline: none;
    }

    .wq-table tbody tr:focus-visible,
    .work-overview-table tbody tr.work-overview-link:focus-visible {
        background-color: var(--color-primary-tint);
        outline: var(--focus-outline);
        outline-offset: -3px;
    }

    .wq-table tbody tr:hover td,
    .wq-table tbody tr:focus td,
    .wq-table tbody tr:focus-visible td,
    .work-overview-table tbody tr.work-overview-link:hover td,
    .work-overview-table tbody tr.work-overview-link:focus td,
    .work-overview-table tbody tr.work-overview-link:focus-visible td {
        background-color: transparent;
    }

.bw-subsection {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 12px;
    margin-top: 16px;
    background: var(--surface);
}

.bw-subsection legend {
    padding: 0 6px;
}

.bw-override-group {
    margin: 8px 0;
}

.bw-overridden {
    color: var(--color-accent);
    font-weight: 600;
}

/* Suppressed rows: text muted at 5.9:1 (supplementary — the status
   column already labels the state at full contrast for screen readers). */
.bw-suppressed td:not(:last-child) {
    color: var(--color-text-muted);
    text-decoration: line-through;
}

/* Override-added rows: accent tint background to distinguish from global rules. */
.bw-override-add {
    background: var(--color-accent-tint);
}

/* Activity picker tree: a disabled leaf is an activity whose prerequisite
   step is not yet in the workflow (e.g. a review before its content step).
   It stays visible but greyed and renders no selection control. */
.bw-tree-disabled {
    color: var(--color-text-muted);
    font-style: italic;
}

/* Disabled language label inside the config dialog — same muted treatment. */
.bw-label-disabled {
    color: var(--color-text-muted);
}

.bw-activity-tree {
    min-width: 0;
    max-height: 400px;
    overflow-y: auto;
}

/* Workflow graph editor: equal-width columns for the activity list and picker tree. */
.bw-graph-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    align-items: start;
}

.bw-activity-list {
    min-width: 0;
}

.bw-routing-line {
    padding: 4px 0;
    font-size: 0.9375rem;
    color: var(--color-text-base);
}

.bw-resolution-wrapper {
    margin-top: 12px;
}

.bw-resolution-container {
    margin-top: 8px;
}

.bw-attr-container {
    margin-top: 8px;
}

.bw-attr-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 0;
    flex-wrap: wrap;
}

/* Contains floated WAF widget children (TextInput_window / Select_window use float:left) */
.bw-field {
    display: flow-root;
    margin-bottom: 12px;
}

.bw-checkbox-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 0;
}

.bw-checkbox-row label {
    cursor: pointer;
    user-select: none;
}

/* ========== WORKFLOW ADMIN (.wa-) ========== */

/* --- Sections accordion ---------------------------------------------
   The four sections (Items / Stimuli / Recent bulk moves / Cleanup) are
   a WAF.AccordionGroup. These rules are SCOPED to .WorkflowAdminView_window
   so they override only this view's accordion — the plain global styling
   (black title bar + dotted body in the WAF base CSS) is replaced here
   with card-style panels in the purple/cyan brand. Collapse is left to
   the global .AccBlock_hidden / .AccBlock_show display rules, so these
   never set `display` on the body. */

/* Flow with the page rather than the group's default full-height inner
   scroll — height:auto !important neutralises the inline height the
   AccordionGroup sets so the heading above isn't double-scrolled. */
.WorkflowAdminView_window div.AccGroup_window {
    height: auto !important;
    overflow: visible;
    padding: 4px 2px 18px;
    outline: none;
}

.WorkflowAdminView_window div.AccGroup_window div.AccBlock_window {
    margin: 0 0 12px;
    border: 1px solid var(--divider);
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--surface);
    box-shadow: 0 1px 3px var(--accent-tint);
}

/* Panel body: white, padded, hairline separator under the header. */
.WorkflowAdminView_window div.AccGroup_window div.AccBlock_body {
    border: none;
    margin: 0;
    padding: 18px;
    background: var(--surface);
    border-top: 1px solid var(--divider);
}

.wa-status {
    padding: 6px 0;
    min-height: 1.5em;
}

.wa-fieldset {
    padding: 12px;
    margin-bottom: 16px;
}

.wa-fieldset legend {
    padding: 0 6px;
}

/* Workflow Administration: entity names are link-styled buttons that open
   the view-only preview dialog (owner, 2026-09-04). #0a4d7f holds >= 7:1 on
   white (AAA); the dialog takes almost the whole viewport and its body
   scrolls. */
/* Specificity note: .Table2D_body button (above) paints every grid button
   white-on-black, and its :hover/:focus rule repaints it; these selectors
   outrank both so the name reads as plain blue underlined text. */
.wa-entity-link,
.Table2D_body button.wa-entity-link,
.Table2D_body button.wa-entity-link:hover,
.Table2D_body button.wa-entity-link:focus {
    background: none;
    background-color: transparent;
    border: none;
    padding: 0;
    margin: 0;
    font: inherit;
    color: var(--accent);
    text-decoration: underline;
    cursor: pointer;
    text-align: left;
    box-shadow: none;
}

.Table2D_body button.wa-entity-link:hover {
    color: var(--accent-hover);
}

.Table2D_body button.wa-entity-link:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}

.wa-entity-dialog.app-dialog--wide {
    width: 96vw;
    max-width: 96vw;
    height: 92vh;
    max-height: 92vh;
    display: flex;
    flex-direction: column;
}

.wa-entity-dialog .app-dialog-header {
    flex: 0 0 auto;
}

.wa-entity-dialog .app-dialog-header-left {
    display: flex;
    align-items: baseline;
    gap: 12px;
}

.wa-entity-body {
    flex: 1 1 auto;
    overflow: auto;
    min-height: 0;
}

.wa-entity-status {
    color: var(--text-secondary);
    font-style: italic;
}

.wa-entity-rubric {
    max-width: 60em;
    margin: 0 auto;
    border: none;
}

.wa-btn-group {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 8px;
}

/* Lifecycle-stage filter (live / archived / rejected / released) above the admin tables. */
.wa-lifecycle-filter {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    margin: 12px 0;
}
.wa-lifecycle-filter-label {
    font-weight: 600;
    color: var(--color-text-heading);
}
/* Lay the WAF.RadioGroup options out in a horizontal row. */
.wa-lifecycle-filter ul[role="radiogroup"] {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    list-style: none;
    margin: 0;
    padding: 0;
}
.wa-lifecycle-filter ul[role="radiogroup"] > li {
    display: flex;
    align-items: center;
    gap: 4px;
    cursor: pointer;
}

/* Content search — sits beside/below the lifecycle filter, above the
   accordion. A successful search checks the matching rows in the item
   and stimulus tables. */
.wa-content-search-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 12px 0 4px 0;
}

.wa-content-search-label {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
}

.wa-content-search-input {
    flex: 0 0 320px;
}

/* Persistent pending / not-searchable / truncation counts. AAA
   contrast (#3f4a54 on white ≈ 9:1). */
.wa-content-search-notice {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin: 0 0 8px 0;
}

/* Matched text, one line per hit — the server's snippet with the match
   in <b>. Bounded height so a 50-hit page cannot push the tables off
   screen; the list scrolls inside its own box. */
.wa-content-search-matches {
    margin: 0 0 10px 0;
}

.wa-content-search-matches-heading {
    margin: 0 0 4px 0;
}

.wa-content-search-match-list {
    list-style: none;
    margin: 0;
    padding: 6px 10px;
    max-height: 220px;
    overflow-y: auto;
    border: 1px solid var(--control-border);
    border-radius: var(--radius-md);
    background: var(--surface);
}

.wa-content-search-match {
    padding: 4px 0;
    font-size: 0.9rem;
    line-height: 1.4;
}

.wa-content-search-match + .wa-content-search-match {
    border-top: 1px solid var(--control-border);
}

.wa-content-search-match-name {
    font-weight: 600;
    color: var(--color-text-heading);
    margin-right: 8px;
}

/* #3f4a54 on #fbfcfd is ≈ 8.7:1 — AAA, matching the notice line. */
.wa-content-search-match-snippet {
    color: var(--text-secondary);
}

.wa-content-search-match-snippet b {
    background: var(--status-warning-tint);
    font-weight: 600;
}

.wa-btn {
    border: 1px solid transparent;
}

/* Item Operations — shared item picker + state pill + action row */

.wa-item-picker {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
    flex-wrap: wrap;
}

.wa-item-picker label {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.wa-item-picker input[type="text"],
.wa-item-combo input[type="text"] {
    min-width: 300px;
    transition: border-color 0.15s, box-shadow 0.15s;
}

.wa-item-combo .CA_window,
.wa-item-combo > div {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.wa-item-combo .CA_window label {
    display: none;
}

.wa-item-state {
    padding: 10px 14px;
    background: var(--bg-secondary);
    border: 1px solid var(--divider);
    border-radius: var(--radius-lg);
    margin-bottom: 12px;
    font-size: 0.95rem;
}

.wa-item-state strong {
    color: var(--text-secondary);
    text-transform: uppercase;
    font-size: 0.8rem;
    letter-spacing: 0.04em;
    margin-right: 6px;
}

.wa-actions {
    margin-top: 4px;
}

/* Per-row action buttons (cells 6-9): keep them compact so the
   four-button strip doesn't blow out the row width. */
.wa-items-table td:nth-child(n+7) button {
    padding: 1px 8px;
    font-size: 0.85rem;
    cursor: pointer;
}

/* Conversion column (cell 6): the cell is always rendered as a
   <div> by the Table2D String renderer. Two clickable variants:
   the red errors button on needs_review / incomplete rows
   (conversion blocked persistence and must be addressed) and the
   unobtrusive notice button on complete rows that recorded
   info-severity entries (the body persisted but there is a
   coverage or classification signal worth seeing). */
.wa-conv-issues-btn-error,
.wa-conv-issues-btn-notice {
    display: inline-block;
    padding: 1px 8px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: 0.85rem;
}

.wa-conv-issues-btn-error {
    border: 1px solid var(--status-danger);
    background: var(--status-danger-tint);
    color: var(--status-danger);
    font-weight: 600;
}

.wa-conv-issues-btn-error:hover,
.wa-conv-issues-btn-error:focus {
    background: var(--fill-hover);
    border-color: var(--status-danger);
}

.wa-conv-issues-btn-notice {
    border: 1px solid var(--divider);
    background: var(--bg-secondary);
    color: var(--text-secondary);
    font-weight: normal;
}

.wa-conv-issues-btn-notice:hover,
.wa-conv-issues-btn-notice:focus {
    background: var(--fill-hover);
    border-color: var(--divider);
}

.wa-bulk-toolbar {
    margin: 8px 0;
}

/* Search bar above the items table — input + prev/next buttons +
   match counter on one line. */
.wa-search-bar {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 8px 0;
}

.wa-search-input {
    flex: 0 0 280px;
}

.wa-search-btn {
    border: 1px solid transparent;
}

.wa-search-count {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin-left: 4px;
}

/* Items-table search match highlights. wa-row-match colours every
   match faintly; wa-row-current-match (the one the user is on) gets
   a stronger highlight + a left-edge marker. */
.wa-items-table tbody tr.wa-row-match td {
    background: var(--status-warning-tint);
}

.wa-items-table tbody tr.wa-row-current-match td {
    background: var(--status-warning-tint);
}

.wa-items-table tbody tr.wa-row-current-match td:first-child {
    box-shadow: inset 3px 0 0 var(--status-warning);
}

.wa-bulk-queue {
    margin-top: 16px;
}

.wa-bulk-queue h3 {
    margin: 8px 0 4px 0;
}

.wa-bulk-error {
    color: var(--status-danger);
    font-style: italic;
}

/* Highlight the row whose item matches _currentItemId. Toggled by
   _highlightSelectedRow whenever an item is loaded. */
.wa-items-table tr.wa-row-selected td {
    font-weight: 600;
    font-size: 1.05rem;
    background: var(--accent-tint);
}

/* Keep legacy .wa-lifecycle-* selectors for backward compatibility */

.wa-lifecycle-picker {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
    flex-wrap: wrap;
}

.wa-lifecycle-picker label {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.wa-lifecycle-picker input[type="text"],
.wa-lifecycle-combo input[type="text"] {
    min-width: 300px;
    transition: border-color 0.15s, box-shadow 0.15s;
}

/* ComboActive inline wrapper inside the picker row */
.wa-lifecycle-combo .CA_window,
.wa-lifecycle-combo > div {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.wa-lifecycle-combo .CA_window label {
    display: none; /* label supplied by the picker row itself */
}

.wa-lifecycle-panel {
    margin-top: 8px;
}

.wa-lifecycle-panel:empty {
    display: none;
}

.wa-lifecycle-state {
    padding: 10px 14px;
    margin-bottom: 12px;
    font-size: 0.95rem;
}

.wa-lifecycle-state strong {
    color: var(--text-secondary);
    text-transform: uppercase;
    font-size: 0.8rem;
    letter-spacing: 0.04em;
    margin-right: 6px;
}

/* The state pill is the shared tag (its kinds are named in the tag rules);
   a state's name is written with a capital. */
.wa-lifecycle-state span[class^="wa-lifecycle-state-"] {
    text-transform: capitalize;
}

.wa-lifecycle-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 12px;
    align-items: center;
}

.wa-lifecycle-sendback {
    display: flex;
    gap: 8px;
    align-items: center;
}

.wa-lifecycle-sendback select {
    cursor: pointer;
}

.wa-lifecycle-history-btn {
    margin-top: 4px;
}

/* Send-back dialog — activity picker list, reverse-sequence */

.wa-sendback-intro {
    margin: 0 0 14px 0;
    color: var(--text-secondary);
    font-size: 0.9rem;
}

.wa-sendback-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-height: 420px;
    overflow: auto;
    min-width: 320px;
}

.wa-sendback-list li {
    margin: 0;
}

/* Higher-specificity selectors override `.Dialog_window button { background:#151616 }`
   and the global `button:hover { background:transparent }`. */
.Dialog_window button.wa-sendback-item,
.wa-sendback-item {
    display: block;
    width: 100%;
    text-align: left;
    padding: 12px 16px;
    border: 1px solid var(--divider);
    border-radius: var(--radius-lg);
    background-color: var(--surface);
    color: var(--jcmaPurple);
    font-weight: 600;
    font-size: 0.95rem;
    cursor: pointer;
    transition: border-color 0.15s;
}

.Dialog_window button.wa-sendback-item:hover,
.Dialog_window button.wa-sendback-item:focus,
.wa-sendback-item:hover,
.wa-sendback-item:focus {
    background-color: var(--fill-hover);
    color: var(--jcmaPurple);
    border-color: var(--jcmaBlue);
    outline: none;
}

.wa-audit-table {
    width: 100%;
    margin-top: 8px;
}

.wa-audit-table th,
.wa-audit-table td {
    text-align: left;
}

.wa-pager {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-top: 8px;
}

/* ========== BATCH MANAGE (.bm-) ========== */

.bm-status {
    padding: 6px 0;
    min-height: 1.5em;
}

.bm-table {
    width: 100%;
    margin-top: 8px;
}

.bm-table th,
.bm-table td {
    text-align: left;
}

.bm-btn {
    border: 1px solid transparent;
    margin: 2px;
}

.bm-btn-sm {
    padding: 2px 6px;
    font-size: 0.85em;
}

.bm-details {
    margin: 8px 0;
}

.bm-details dt {
    font-weight: 600;
    margin-top: 8px;
}

.bm-details dd {
    margin-left: 16px;
}

/* ========== BATCH PROGRESS PANEL (.bp-) ========== */

.bp-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: var(--surface);
    z-index: 100;
    display: flex;
    flex-direction: column;
}

.bp-header {
    display: flex;
    align-items: center;
    padding: 10px 16px;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--divider);
}

.bp-header-title {
    flex: 1;
    margin: 0;
}

.bp-close-btn {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 1.4em;
    padding: 4px 8px;
    line-height: 1;
}

.bp-close-btn:hover {
    background: var(--fill-hover);
    border-radius: var(--radius-sm);
}

.bp-summary {
    display: flex;
    gap: 24px;
    padding: 8px 16px;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--divider);
    font-size: 0.95em;
}

.bp-summary-item {
    display: flex;
    gap: 6px;
    align-items: center;
}

.bp-summary-value {
    font-weight: 600;
}

.bp-container {
    display: flex;
    flex: 1;
    gap: 0;
    overflow: hidden;
}

.bp-left-panel {
    flex: 0 0 340px;
    display: flex;
    flex-direction: column;
    border-right: 1px solid var(--divider);
    overflow: hidden;
}

.bp-right-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
    overflow: hidden;
}

.bp-panel-header {
    padding: 8px 12px;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--divider);
}

.bp-panel-content {
    flex: 1;
    overflow: auto;
    padding: 0;
}

.bp-empty {
    padding: 24px;
    text-align: center;
    color: var(--text-secondary);
}

.bp-loading {
    padding: 24px;
    text-align: center;
    color: var(--text-secondary);
}

/* ========== ITEM HISTORY (.ih-) ========== */

.ih-status {
    padding: 6px 0;
    min-height: 1.5em;
}

.ih-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    padding: 4px 0 8px 0;
}

/* The four views are tabs, on a row of their own under the buttons. */
.ih-toggle-bar {
    flex: 1 1 100%;
}

.ih-heading {
    margin: 0;
    flex: 1;
}

.ih-container {
    display: flex;
    gap: 8px;
    height: calc(100vh - 140px);
}

.ih-item-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
    overflow: hidden;
}

.ih-item-panel.ih-expanded {
    flex: 3;
}

.ih-display-div {
    flex: 1;
    overflow: auto;
    padding: 8px;
}

.ih-version-indicator {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--divider);
    font-size: 0.9em;
}

.ih-return-btn {
    margin-left: auto;
}

.ih-history-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 260px;
    max-width: 50%;
    overflow: hidden;
    transition: flex 0.2s, min-width 0.2s, max-width 0.2s;
}

.ih-history-panel.ih-collapsed {
    flex: 0 0 36px;
    min-width: 36px;
    max-width: 36px;
    overflow: hidden;
}

.ih-panel-header {
    display: flex;
    align-items: center;
    padding: 6px 10px;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--divider);
}

.ih-panel-title {
    flex: 1;
}

.ih-collapsed .ih-panel-title,
.ih-collapsed .ih-timeline,
.ih-collapsed .ih-element-history {
    display: none;
}

.ih-timeline {
    flex: 1;
    overflow: auto;
    padding: 4px;
}

.ih-element-history {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 8px;
}

.ih-version-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 6px 0;
}

.ih-version-label {
    font-weight: 600;
    font-size: 0.95em;
    min-width: 100px;
    text-align: center;
}

.ih-nav-meta {
    text-align: center;
    font-size: 0.85em;
    color: var(--text-secondary);
    padding: 4px 0;
}

.ih-history-display {
    flex: 1;
    min-height: 200px;
    overflow: auto;
    border: 1px solid var(--divider);
    border-radius: var(--radius-sm);
    margin-top: 8px;
    padding: 8px;
}

.ih-table {
    width: 100%;
    margin-top: 4px;
}

.ih-table th,
.ih-table td {
    text-align: left;
}

.ih-table th {
    position: sticky;
    top: 0;
    z-index: 1;
    background-color: var(--bg-secondary);
}

.ih-btn {
    border: 1px solid transparent;
}

.ih-back-btn {
    align-self: flex-start;
    margin-bottom: 8px;
}

.ih-comment-draft {
    opacity: 0.6;
    font-style: italic;
}

.ih-empty {
    padding: 12px;
    color: var(--text-secondary);
    font-style: italic;
}

.ih-element-title {
    margin: 4px 0 8px 0;
}

.ih-birth-death {
    display: flex;
    gap: 8px;
    margin-bottom: 10px;
}

.ih-version-entry {
    border: 1px solid var(--divider);
    border-radius: var(--radius-sm);
    padding: 8px;
    margin-bottom: 8px;
}

.ih-version-meta {
    font-size: 0.8em;
    color: var(--text-secondary);
    margin-bottom: 4px;
}

.ih-version-content {
    padding: 4px;
    background: var(--bg-secondary);
    border-radius: var(--radius-sm);
    font-size: 0.9em;
    max-height: 120px;
    overflow: auto;
}

.ih-diff {
    margin-top: 6px;
    padding: 4px;
    background: var(--bg-secondary);
    border-radius: var(--radius-sm);
    font-size: 0.85em;
}

.ih-diff-add {
    background: var(--fill);
    color: var(--status-success);
}

.ih-diff-remove {
    background: var(--status-danger-tint);
    color: var(--status-danger);
    text-decoration: line-through;
}

.ih-historical-content {
    padding: 8px;
}

.ih-save-row {
    color: var(--accent);
}

/* ========== CONTENT REVIEW OUTCOMES (.cr-) ========== */

.cr-outcome-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 10px 0;
    border-top: 1px solid var(--divider);
    margin-top: 8px;
}

.cr-outcome-rework {
    border-color: var(--status-warning);
    background: var(--status-warning-tint);
    color: var(--status-warning);
}

.cr-outcome-rework:hover {
    box-shadow: inset 0 0 0 1px var(--status-warning);
}

.cr-outcome-skip {
    border-color: var(--control-border);
    background: var(--fill);
    color: var(--text-primary);
}

.cr-outcome-skip:hover {
    background: var(--fill-hover);
}

.cr-lock-status {
    padding: 8px 12px;
    margin-bottom: 8px;
    border: 1px solid var(--divider);
    border-radius: var(--radius-sm);
    background: var(--bg-secondary);
}

.cr-item-info {
    padding: 8px 0;
}

/* ========== EDITORIAL REVIEW (.er-) ========== */

.er-editor-container {
    border: 1px solid var(--divider);
    border-radius: var(--radius-sm);
    min-height: 300px;
    padding: 8px;
    margin: 8px 0;
    background: var(--surface);
}

.er-save-bar {
    display: flex;
    gap: 8px;
    padding: 8px 0;
}

/* ========== ADD USER (.au-) ========== */

.au-status {
    padding: 6px 0;
    min-height: 1.5em;
}

.au-section {
    margin-bottom: 16px;
}

.au-fieldset {
    padding: 12px;
    margin-bottom: 16px;
}

.au-fieldset legend {
    padding: 0 6px;
}

.au-btn {
    border: 1px solid transparent;
    margin: 2px;
}

.au-btn-sm {
    padding: 2px 6px;
    font-size: 0.85em;
}

.au-checkbox-group {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 8px 0;
}

.au-checkbox-group label {
    display: flex;
    align-items: center;
    gap: 4px;
    cursor: pointer;
}

.au-scope-table {
    width: 100%;
    margin-top: 8px;
}

.au-scope-table th,
.au-scope-table td {
    text-align: left;
}

.au-profile {
    padding: 8px 0;
}

.au-profile dt {
    font-weight: 600;
    margin-top: 8px;
}

.au-profile dd {
    margin-left: 16px;
}

/* ---- User management redesign (search/create cards, identity, drift) ---- */

.au-search-card,
.au-create-card {
    background: var(--bg-secondary);
}

.au-profile-section {
    margin-top: 16px;
}

.au-label {
    display: block;
    font-weight: 600;
    margin-top: 8px;
    margin-bottom: 2px;
}

.au-readonly {
    padding: 6px 0;
    color: var(--text-secondary);
}

.au-table {
    width: 100%;
    margin: 8px 0;
}

.au-table th,
.au-table td {
    text-align: left;
}

.au-checkbox-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px 0;
}

.au-save-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 12px;
}

.au-dirty-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--status-warning);
    display: inline-block;
}

.au-drift-banner {
    margin: 8px 0 12px;
}

.au-resend-row {
    margin: 8px 0 12px;
}

.au-empty-state {
    font-style: italic;
    color: var(--text-secondary);
    padding: 6px 0;
}

/* Bank Scopes: the server could not read some of the admin's own collections.
   #6b3400 on #fff8e1 holds >= 7:1 (WCAG AAA), as the language warning does. */
.au-scope-notice {
    margin: 8px 0;
    max-width: 40em;
}

/* Language overlay note + dialog (Add User). Colors hold >= 7:1 on their
   backgrounds (WCAG AAA): #0a4d7f on #fff, #6b3400 on #fff8e1. */
.au-languages-note {
    margin: 10px 0 4px;
}

.au-languages-btn {
    background: none;
    border: none;
    padding: 4px 6px;
    cursor: pointer;
    color: var(--accent);
    text-decoration: underline;
    font-size: inherit;
    text-align: left;
}

.au-languages-btn.au-languages-warning {
    color: var(--status-warning);
    background: var(--status-warning-tint);
    border: 1px solid var(--status-warning);
    border-radius: var(--radius-sm);
    text-decoration: none;
    font-weight: 600;
}

.au-lang-intro {
    max-width: 40em;
    margin: 4px 0 10px;
}

.au-lang-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 2px 16px;
    margin: 6px 0;
}

.au-lang-save,
.au-lang-cancel {
    margin: 10px 8px 0 0;
}

/* ========== CREATE CLIENT (.cc-) ==========
   Same card / table / button vocabulary as Add User (.au-) so the two
   client-setup screens read as one. Colors hold >= 7:1 on white
   (WCAG AAA): #444 text, #595959 muted, #b3261e danger. */

.cc-status {
    padding: 6px 0;
    min-height: 1.5em;
}

.cc-fieldset {
    padding: 12px;
    margin-bottom: 16px;
}

.cc-fieldset legend {
    padding: 0 6px;
}

/* The clients grid scrolls in place: about twenty rows, never more than the
   viewport holds, header row pinned. */
.cc-scroll {
    max-height: min(calc(100vh - 300px), 44em);
    overflow-y: auto;
    border: 1px solid var(--divider);
    border-radius: var(--radius-sm);
}

.cc-scroll .cc-table {
    margin: 0;
}

.cc-scroll .cc-table th {
    position: sticky;
    top: 0;
    z-index: 1;
    background-color: var(--bg-secondary);
}

.cc-table tr.cc-selected td {
    background: var(--accent-tint);
}

/* The organizations-and-sites dialog: wider than a form dialog, its table
   scrolling inside so the add / close bar stays put. */
.Dialog_normal.cc-orgsites-dialog {
    max-width: 960px;
}

.cc-orgsites-scroll {
    max-height: 50vh;
    margin: 0 20px;
}

.cc-btn {
    border: 1px solid transparent;
    margin: 2px;
}

.cc-btn-sm {
    padding: 2px 6px;
    font-size: 0.85em;
}

.cc-btn-danger {
    border-color: var(--status-danger);
    color: var(--status-danger);
}

.cc-btn-danger:hover {
    background: var(--status-danger-hover);
    color: var(--text-on-accent);
}

.cc-action-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
}

/* Pool analysis: a short number sits on its label's line, sized for its digits; a run row opens its report. */
.pa-field {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.pa-field .cc-label {
    display: inline;
    margin: 0;
}

.pa-start .pa-forms-planned,
.pa-start .pa-time-allowed {
    width: 8ch;
}

.pa-run-row {
    cursor: pointer;
}

.pa-row-actions {
    display: flex;
    flex-wrap: nowrap;
    gap: 4px;
}

.cc-label {
    display: block;
    font-weight: 600;
    margin-top: 8px;
    margin-bottom: 2px;
}

.cc-readonly {
    padding: 6px 0;
    color: var(--text-secondary);
}

.cc-table {
    width: 100%;
    margin: 8px 0;
}

.cc-table th,
.cc-table td {
    text-align: left;
    vertical-align: top;
}

.cc-table .cc-actions {
    white-space: nowrap;
}

.cc-table tr.cc-inactive td {
    color: var(--text-secondary);
    font-style: italic;
}

.cc-table tr.cc-org-row td {
    border-top: 2px solid var(--divider);
}

.cc-table tr.cc-org-row .cc-org-name {
    font-weight: 600;
}

.cc-table tr.cc-site-row td:nth-child(2) {
    padding-left: 20px;
}

.cc-empty-state {
    font-style: italic;
    color: var(--text-secondary);
    padding: 6px 0;
}

/* ========== AI FEATURES (.ls-) ==========
   Same card / button vocabulary as Create Client (.cc-) so the client-setup
   screens read as one; the .cc- rules above carry the shared look, these
   add only what this screen needs. Colors hold >= 7:1 on white (WCAG AAA). */

.ls-switch-row {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: 10px;
    row-gap: 2px;
    align-items: start;
    padding: 6px 0;
    border-bottom: 1px solid var(--divider);
}

.ls-switch-row:last-of-type {
    border-bottom: none;
}

.ls-switch-row input[type="checkbox"] {
    margin-top: 4px;
}

.ls-switch-label {
    font-weight: 600;
}

.ls-switch-desc {
    grid-column: 2;
    color: var(--text-secondary);
    font-size: 0.92em;
}

.ls-switch-unavailable {
    grid-column: 2;
    color: var(--text-secondary);
    font-style: italic;
    font-size: 0.92em;
}

.ls-limit-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

.ls-limit-input {
    width: 10em;
}

.ls-hint {
    color: var(--text-secondary);
    font-size: 0.92em;
    margin-top: 4px;
}

/* ---- Clearance Queue (Rights & Permissions S4, MT.RightsQueueView) ---- */

.rq-where {
    font-weight: 400;
    font-size: 0.8em;
    color: var(--text-secondary);
}

.rq-toolbar {
    display: flex;
    gap: 8px;
    margin: 6px 0 10px;
    justify-content: flex-end;
}

/* The workflow-outcome group, right-aligned: Complete / Release / Step away,
   the common toolbar standard every activity screen follows. */
.rq-outcomes {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

/* One permission request of the content on screen. */
.rq-request {
    margin-bottom: 14px;
}

.rq-claimed {
    margin-left: 10px;
}

/* What a refused Complete lists: the requests still undecided. */
.rq-outstanding {
    border: 1px solid var(--status-warning);
    background: var(--status-warning-tint);
    border-radius: var(--radius-sm);
    padding: 8px 12px;
    margin-bottom: 12px;
}

.rq-outstanding ul {
    margin: 4px 0 0;
    padding-left: 18px;
}

.rq-actions {
    display: inline-flex;
    gap: 6px;
    flex-wrap: wrap;
}

.rq-actions .cc-btn {
    padding: 2px 8px;
    font-size: 0.92em;
}

.rq-muted {
    color: var(--text-secondary);
    font-size: 0.92em;
}

.rq-detail-host {
    border-top: 1px solid var(--divider);
    padding-top: 10px;
}

.rq-detail-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
}

.rq-detail-head h3 {
    margin: 0;
}

.rq-detail-columns {
    display: flex;
    gap: 18px;
    align-items: flex-start;
    flex-wrap: wrap;
}

.rq-detail-left {
    flex: 1 1 380px;
    min-width: 300px;
}

.rq-detail-right {
    flex: 2 1 480px;
    min-width: 320px;
}

.rq-fields {
    display: grid;
    grid-template-columns: max-content 1fr;
    column-gap: 14px;
    row-gap: 4px;
    margin: 0 0 10px;
}

.rq-fields dt {
    font-weight: 600;
}

.rq-fields dd {
    margin: 0;
    overflow-wrap: anywhere;
}

.rq-note {
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: 4px 6px;
    border: 1px solid var(--control-border);
    border-radius: var(--radius-sm);
    margin: 4px 0 8px;
}

.rq-note:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}

.rq-decision-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.rq-activity ul,
.rq-coverage ul {
    margin: 0;
    padding-left: 18px;
}

.rq-activity li,
.rq-coverage li {
    margin-bottom: 4px;
}

.rq-preview-body {
    border: 1px solid var(--divider);
    border-radius: var(--radius-sm);
    padding: 10px;
    max-height: 70vh;
    overflow: auto;
}

/* ---- Rights Dashboard (Rights & Permissions S8, MT.RightsDashboardView) ---- */

.rd-where,
.ra-where {
    font-weight: 400;
    font-size: 0.8em;
    color: var(--text-secondary);
}

.rd-toolbar,
.ra-toolbar {
    display: flex;
    gap: 8px;
    margin: 6px 0 10px;
}

.rd-buckets {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 6px;
}

.rd-bucket {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    min-width: 9em;
    padding: 8px 12px;
    border: 1px solid var(--control-border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    cursor: pointer;
    text-align: left;
}

.rd-bucket:hover {
    background: var(--fill-hover);
}

.rd-bucket:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}

.rd-bucket-on {
    border-color: var(--accent);
    border-width: 2px;
    background: var(--accent-tint);
}

.rd-bucket-count {
    font-size: 1.5em;
    font-weight: 600;
    line-height: 1.1;
}

.rd-bucket-label {
    font-size: 0.9em;
}

.rd-caption {
    margin: 0 0 10px;
}

.rd-table-host {
    overflow-x: auto;
}

.rd-muted,
.ra-muted {
    color: var(--text-secondary);
    font-size: 0.92em;
}

.rd-flag {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: var(--radius-lg);
    background: var(--status-warning-tint);
    border: 1px solid var(--status-warning);
    color: var(--status-warning);
    font-size: 0.85em;
}

.rd-open {
    text-align: left;
}

/* ---- Agreements & Licensors (Rights & Permissions S8, MT.RightsAgreementsView) ---- */

.ra-tabs {
    margin-bottom: 10px;
}

.ra-columns {
    display: flex;
    gap: 18px;
    align-items: flex-start;
    flex-wrap: wrap;
}

.ra-list {
    flex: 1 1 380px;
    min-width: 300px;
    overflow-x: auto;
}

.ra-detail {
    flex: 1 1 420px;
    min-width: 320px;
}

.ra-detail-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
}

.ra-detail-head h3 {
    margin: 0;
}

.ra-fields {
    display: grid;
    grid-template-columns: max-content 1fr;
    column-gap: 14px;
    row-gap: 4px;
    margin: 0;
}

.ra-fields dt {
    font-weight: 600;
}

.ra-fields dd {
    margin: 0;
    overflow-wrap: anywhere;
}

.ra-actions {
    display: inline-flex;
    gap: 6px;
    flex-wrap: wrap;
}

.ra-actions .cc-btn {
    padding: 2px 8px;
    font-size: 0.92em;
}

.ra-doc-row,
.ra-doc-upload {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 6px;
}

.ra-doc-name {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.ra-doc-link {
    color: var(--accent);
}

.ra-activity ul {
    margin: 0;
    padding-left: 18px;
}

.ra-activity li {
    margin-bottom: 4px;
}

.ra-multi {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    align-items: center;
}

.ra-multi label {
    margin-right: 10px;
}

.ra-hint {
    color: var(--text-secondary);
    font-weight: normal;
}

.ls-summary {
    margin: 4px 0 8px;
}

.ls-summary strong {
    font-weight: 600;
}

.ls-limit-reached {
    color: var(--status-danger);
    font-weight: 600;
}

/* Why Pablo cannot take an asset request (LlmBillingPlan.md C1): the request
   and revision dialogs and the animation panel. */
.tq-ai-offer-note {
    margin: 4px 0;
    padding: 4px 8px;
    border-left: 3px solid var(--status-warning);
    background: var(--status-warning-tint);
    color: var(--status-warning);
}

/* 80% of the limit (LlmBillingPlan.md C1): the strip's amber, darkened to
   the text contrast the white page needs. */
.ls-limit-near {
    color: var(--status-warning);
    font-weight: 600;
}

.ls-meter {
    width: 100%;
    max-width: 32em;
    height: 12px;
    border: 1px solid var(--control-border);
    border-radius: var(--radius-md);
    background: var(--bg-secondary);
    overflow: hidden;
}

.ls-meter-fill {
    height: 100%;
    background: var(--accent-fill);
}

.ls-meter-fill.ls-meter-full {
    background: var(--status-danger);
}

.ls-meter-fill.ls-meter-near {
    background: var(--status-warning);
}

.ls-usage-table {
    margin-top: 6px;
}

/* AI billing and AI losses (LlmBillingView, LlmLossView): where their pieces
   sit. The look of every piece is the shared one: the buttons and labels
   carry the shared classes, the two forms are named in the card rule, and
   fields, tables and headings take theirs from the element. */
.lb-month,
.ll-month {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
}

.lb-month > label,
.lb-month > select,
.ll-month > label,
.ll-month > select {
    width: auto;
    margin-top: 0;
    margin-bottom: 0;
}

.lb-field {
    display: flex;
    flex-direction: column;
    max-width: var(--field-max-width);
    margin-bottom: 12px;
}

.lb-field > input,
.lb-field > select,
.lb-field > textarea {
    margin-bottom: 0;
}

.lb-adjust-editor,
.lb-rate-editor {
    padding: 12px;
    margin: 0 0 16px;
}

.lb-totals,
.ll-totals {
    display: grid;
    grid-template-columns: max-content max-content;
    gap: 4px 24px;
    margin: 0 0 12px;
}

.lb-totals dd,
.ll-totals dd {
    margin: 0;
}

/* Narrow: each total sits under its label, so a long label wraps instead of
   pushing its figure off the screen. */
@media (max-width: 600px) {
    .lb-totals,
    .ll-totals {
        grid-template-columns: minmax(0, 1fr);
    }

    .lb-totals dd,
    .ll-totals dd {
        margin-bottom: 8px;
    }
}

/* Metadata Administration: the row of two tools above its tabs. Where they
   sit, nothing of how they look. */
.ma-tools {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0 0 12px;
}

/* Rubric widget: the per-client "not included" note (DefineItemScoring). */
.tq-property-textcontains-notice {
    margin-top: 6px;
}

/* ========== ITEM ATTRIBUTE PANEL (shared side panel) ========== */

/* Starts BELOW the banner. It is a fixed, 75%-wide side panel with no scrim,
   so while it is open the app is still live — and covering the bar would take
   the menu, settings, help, bug and logout controls away with it. Modal
   overlays (.bp-overlay, .ip-overlay, the dialogs) still cover everything,
   which is what modal means. The attributes panel's script lowers its top
   (inline) to below the host's step toolbar while it is open; the top here
   is the fallback, and the Rights panel's. */
.ib-attr-panel {
    position: fixed;
    right: 0;
    top: var(--mt-chrome-h, 52px);
    width: 75%;
    height: calc(100vh - var(--mt-chrome-h, 52px));
    background: var(--surface);
    border-left: 1px solid var(--divider);
    box-shadow: var(--shadow-2);
    z-index: 100;
    overflow-y: auto;
    padding: 0 16px 16px 16px;
}

/* The panel's resize grip (its look is the shared .mt-panel-resize): a
   fixed sibling straddling the panel's left edge, which the script moves
   with the width (style.right). Layout only. */
.ib-attr-panel-resize {
    position: fixed;
    top: var(--mt-chrome-h, 52px);
    bottom: 0;
    width: 6px;
    margin-right: -3px;
    z-index: 101;
    touch-action: none;
}

.ib-attr-panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 0;
    border-bottom: 1px solid var(--divider);
    margin-bottom: 12px;
    position: sticky;
    top: 0;
    background: var(--surface);
}

.ib-attr-panel-header h3 {
    margin: 0;
}

.ib-attr-panel-close {
    border: none;
    background: none;
    font-size: 1.4rem;
    cursor: pointer;
    color: var(--text-secondary);
    padding: 0 4px;
}

.ib-attr-panel-close:hover {
    color: var(--text-primary);
}

.ib-attr-panel-section {
    margin-bottom: 16px;
}

.ib-attr-panel-section h4 {
    margin: 0 0 8px 0;
}

/* Attribute rows: name | value, two columns; each value auto-saves
   on blur/change. Striping is scoped to the rows container so the
   section h4 doesn't offset the nth-child cadence. */
.ib-attr-rows {
    border: 1px solid var(--divider);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.ib-attr-row {
    display: grid;
    grid-template-columns: minmax(120px, max-content) 1fr;
    align-items: start;
    gap: 8px;
    padding: 6px 8px;
    border-bottom: 1px solid var(--divider);
}

.ib-attr-row:last-child {
    border-bottom: none;
}

.ib-attr-rows > .ib-attr-row:nth-child(even) {
    background: var(--bg-secondary);
}

.ib-attr-name {
    font-weight: 600;
    font-size: 0.85em;
    color: var(--text-primary);
    align-self: center;
    overflow-wrap: anywhere;
}

.ib-attr-value {
    width: 100%;
    box-sizing: border-box;
    padding: 4px 6px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--divider);
    font: inherit;
    line-height: 1.3;
    /* rows=1 in markup gives a single-line default; vertical-only
       resize lets authors grow the field for long values without
       disturbing the column layout. */
    resize: vertical;
    min-height: calc(1.3em + 10px);
    overflow: auto;
}

.ib-attr-value:disabled {
    background: var(--fill);
    color: var(--text-secondary);
    cursor: not-allowed;
}

/* A required attribute a completion refusal named, still blank
   (ItemAttributePanel.showMissing). Builds on the shared invalid-field rule
   in PaldroeStyles.css (input/textarea/select[aria-invalid="true"]: red
   border, pale red fill) with a 2px border in the panel's own required red
   (#b3261e, the asterisk's colour) so it reads at a glance, and a text note
   under the widget so the state is not colour alone. Every colour is an
   explicit pair: the panel's background is a fixed white under all 14
   colour themes, so the contrast below holds in every theme —
   #b3261e border on #fff 6.5:1, on the striped row 6.3:1 (non-text needs 3:1);
   note #8c1d18 on #fdecea 7.97:1 (AAA); the text on the fill 15:1. */
.ib-attr-value.ib-attr-value--missing,
.ib-attr-value.ib-attr-value--missing:disabled {
    border: 2px solid var(--status-danger);
    background-color: var(--status-danger-tint);
    color: var(--text-primary);
}

.ib-attr-missing-note {
    grid-column: 2;
    justify-self: start;
    margin-top: -4px;
    padding: 1px 6px;
    border-radius: var(--radius-sm);
    font-size: 0.8em;
    font-weight: 600;
    color: var(--status-danger);
    background: var(--status-danger-tint);
}

/* Alignment two-column scroll layout */
.ib-align-scroll {
    max-height: 50vh;
    overflow-y: auto;
    border: 1px solid var(--divider);
    border-radius: var(--radius-md);
}

/* Stacked alignments (owner direction 2026-08-13): each target (whole item /
   assertion) is a BLACK header row with white text; its aligned standards
   follow as black-on-white rows indented 5em for visual distinction. */
.ib-align-target-row {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--text-primary);
    color: var(--bg-primary);
    padding: 7px 12px;
    font-size: 0.85em;
    font-weight: 600;
    line-height: 1.4;
}

.ib-align-target-text {
    flex: 1;
    min-width: 0;
}

.ib-align-target-row .ib-align-add-btn {
    margin-top: 0;
    flex-shrink: 0;
}

.ib-align-assertion-inf {
    color: var(--text-tertiary);
    font-style: italic;
    margin-top: 2px;
}

.ib-align-standards-stack {
    margin-left: 5em;
    padding: 6px 12px 8px 0;
    font-size: 0.85em;
    color: var(--text-primary);
    background: var(--surface);
}

/* The assertion dialog's aligned-standards section (AssertionPanel) still
   uses this class for its list body. */
.ib-align-standards {
    padding: 8px 12px;
    font-size: 0.85em;
}

.ib-align-std-row {
    display: flex;
    gap: 6px;
    align-items: center;
    padding: 1px 0;
}

.ib-align-std-fw {
    color: var(--text-secondary);
    min-width: 60px;
}

/* Standards text: the FULL statement stays in the DOM, clamped to one line;
   hovering (or keyboard-focusing) the row reveals the whole text IN PLACE.
   Native title tooltips were too slow/unreliable for long CASE statements. */
.ib-align-std-code {
    font-weight: 500;
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ib-align-std-row:hover .ib-align-std-code,
.ib-align-std-row:focus-within .ib-align-std-code,
.ib-align-std-row:focus .ib-align-std-code {
    white-space: normal;
    overflow: visible;
}

/* Blocked notice when the bank targets no framework (no "+" buttons rendered). */
.ib-align-blocked {
    margin: 0 0 8px 0;
    padding: 8px 10px;
    font-size: 0.82em;
    line-height: 1.4;
    color: var(--status-warning);
    background: var(--status-warning-tint);
    border: 1px solid var(--divider);
    border-radius: var(--radius-md);
}

/* "+" add-alignment affordance at the end of each target's standards cell. */
.ib-align-add-btn {
    margin-top: 6px;
    width: 26px;
    height: 26px;
    line-height: 1;
    font-size: 1.05em;
    font-weight: 600;
    color: var(--text-on-accent);
    background: var(--accent-fill);
    border: none;
    border-radius: 50%;
    cursor: pointer;
}

.ib-align-add-btn:hover {
    filter: brightness(1.08);
}

.ib-align-add-btn:focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 2px;
}

/* ---------- Add-alignment dialog (search + browsable tree) ---------- */
.ib-align-dlg {
    min-width: 420px;
    max-width: 560px;
}

.ib-align-dlg-search {
    display: flex;
    gap: 6px;
    margin-bottom: 6px;
}

.ib-align-dlg-search input {
    flex: 1;
}

.ib-align-dlg-results {
    max-height: 26vh;
    overflow-y: auto;
}

.ib-align-dlg-divider {
    display: flex;
    align-items: center;
    text-align: center;
    color: var(--text-secondary);
    font-size: 0.8em;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin: 10px 0 6px;
}

.ib-align-dlg-divider::before,
.ib-align-dlg-divider::after {
    content: "";
    flex: 1;
    border-top: 1px solid var(--divider);
}

.ib-align-dlg-divider span {
    padding: 0 10px;
}

.ib-align-dlg-tree {
    max-height: 34vh;
    overflow-y: auto;
    border: 1px solid var(--divider);
    border-radius: var(--radius-md);
    padding: 4px 6px;
}

/* A selectable standard row (checkbox + code + description) — used by results and tree. */
.ib-align-dlg-std {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 4px 4px;
    font-size: 0.86em;
    line-height: 1.35;
    cursor: pointer;
    border-radius: var(--radius-sm);
}

.ib-align-dlg-std:hover {
    background: var(--fill-hover);
}

.ib-align-dlg-std input[type="checkbox"] {
    flex: 0 0 auto;
    align-self: center;
}

/* Same one-line clamp + in-place hover/focus reveal for the add-alignment
   dialog's search results, tree standards, and tree headings. */
.ib-align-dlg-std-info {
    flex: 1;
    min-width: 0;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ib-align-dlg-std:hover .ib-align-dlg-std-info,
.ib-align-dlg-std:focus-within .ib-align-dlg-std-info,
.ib-align-tree-row:hover .ib-align-dlg-std-info,
.ib-align-tree-row:focus-within .ib-align-dlg-std-info {
    white-space: normal;
    overflow: visible;
}

.ib-align-dlg-std-desc {
    color: var(--text-secondary);
}

.ib-align-dlg-hint {
    color: var(--text-secondary);
    font-size: 0.82em;
    padding: 6px 2px;
}

/* Tree scaffolding inside the dialog. */
.ib-align-tree {
    list-style: none;
    margin: 0;
    padding-left: 0;
}

.ib-align-tree .ib-align-tree {
    padding-left: 1.3em;
}

.ib-align-tree-row {
    display: flex;
    align-items: baseline;
    gap: 4px;
}

.ib-align-tree-toggle {
    flex: 0 0 auto;
    width: 1.4em;
    border: none;
    background: none;
    color: var(--text-secondary);
    cursor: pointer;
    font-size: 0.9em;
}

.ib-align-tree-toggle:focus-visible {
    outline: 2px solid var(--jcmaBlue);
    outline-offset: 1px;
    border-radius: var(--radius-sm);
}

.ib-align-tree-spacer {
    display: inline-block;
    width: 1.4em;
    flex: 0 0 auto;
}

.ib-align-tree-heading {
    font-size: 0.86em;
    color: var(--text-primary);
}

.ib-align-dlg-count {
    flex: 1;
    color: var(--text-secondary);
    font-size: 0.85em;
}

/* ========== ITEM HISTORY TOGGLE ========== */

.ih-attr-history {
    width: 100%;
}

.ih-attr-history h4 {
    margin: 12px 0 8px 0;
}

/* ========== ITEM BANK DASHBOARD ========== */

/* --- Dashboard root & grid layout (§10.3) --- */
.ib-dash-root {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto;
    gap: 24px;
    padding: 32px 24px;
    max-width: 1400px;
    margin: 0 auto;
}

.ib-dash-root > h2 {
    grid-column: 1 / -1;
    margin: 0 0 4px 0;
}

.ib-dash-full-width {
    grid-column: 1 / -1;
}

/* --- Filter side panel (collapsible accordion) --- */
.ib-dash-shell {
    display: flex;
    align-items: flex-start;
    gap: 0;
}

.ib-dash-main {
    flex: 1 1 auto;
    min-width: 0;
}

.ib-dash-side {
    /* width AND min-width: a flex item's min-width:auto floors it at its
       content's natural width, so flex-basis alone cannot narrow the
       panel below the widest accordion head. */
    flex: 0 0 150px;
    width: 150px;
    max-width: 150px;
    min-width: 0;
    position: sticky;
    top: 0;
    align-self: stretch;
    background: var(--surface);
    border-right: 1px solid var(--divider);
    box-shadow: var(--shadow-1);
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.ib-dash-side-collapsed {
    flex: 0 0 42px;
    width: 42px;
    max-width: 42px;
}

/* User-resize grip beside a docked panel (MT.PanelResizer: drag, or
   arrow keys when focused; double-click resets). A flex SIBLING of the
   panel, never a child — a panel that scrolls its own content would
   clip an edge-hugging child. Shared by every sizable side panel. */
.mt-panel-resize {
    flex: 0 0 6px;
    align-self: stretch;
    min-height: 40px;
    cursor: col-resize;
    border-radius: var(--radius-sm);
    background: var(--fill);
}

.mt-panel-resize:hover,
.mt-panel-resize:focus-visible {
    background: var(--accent-fill-hover);
    outline: none;
}

.mt-panel-resize-hidden {
    display: none;
}

/* The pointer outruns the 6px grip mid-drag; keep the resize cursor
   page-wide and suppress text selection until the drag ends. */
.mt-panel-resizing,
.mt-panel-resizing * {
    cursor: col-resize !important;
    user-select: none !important;
}

.ib-dash-side-collapsed .ib-dash-side-head h3,
.ib-dash-side-collapsed .ib-side-apply,
.ib-dash-side-collapsed .ib-dash-side-body {
    display: none;
}

.ib-dash-side-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 10px;
    border-bottom: 1px solid var(--divider);
}

.ib-dash-side-head h3 { /* 7.3:1 on white */
    margin: 0;
    white-space: nowrap;
    flex: 1 1 auto;
}

.ib-side-toggle {
    border: 1px solid var(--divider);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--text-secondary);
    font-size: 1rem;
    line-height: 1;
    padding: 4px 8px;
    cursor: pointer;
}

.ib-side-apply {
    flex: 1 1 auto;
    padding: 7px 10px;
    border: none;
    border-radius: var(--radius-md);
    background: var(--accent-fill);
    color: var(--text-on-accent);
    font-weight: 600;
    font-size: 0.85rem;
    cursor: pointer;
}

.ib-dash-side-body {
    overflow-y: auto;
    overflow-x: hidden;
    flex: 1 1 auto;
    min-height: 0;
    padding: 8px;
}

/* Accordion block heads: name over description, both truncated with the
   full text on the title tooltip; status area (warning triangle / badge)
   pinned right. The row itself is the shared accordion row. */

.ib-facc-text {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.ib-facc-name {
    font-weight: 600;
    font-size: 0.9rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ib-facc-desc {
    font-size: 0.75rem;
    color: var(--text-secondary); /* 7.3:1 on white */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ib-facc-status {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 6px;
}

.ib-facc-warn {
    width: 24px;
    height: 22px;
}

/* Closed-with-filter state: #1c3f5f on #fff badge text is 10.6:1 and the
   white head text on #1c3f5f is the same pair reversed — WCAG AAA. The
   badge count doubles as the non-color cue. */
/* Outranks the shared accordion row, which sets the resting fill. */
div.AccGroup_window span.AccBlock_title.ib-facc-active {
    background-color: var(--accent-fill);
    color: var(--text-on-accent);
}

div.AccGroup_window span.AccBlock_title.ib-facc-active::before {
    color: var(--text-on-accent);
}

.ib-facc-head.ib-facc-active .ib-facc-name,
.ib-facc-head.ib-facc-active .ib-facc-desc {
    color: var(--text-on-accent);
}

.ib-facc-badge {
    background: var(--surface);
    color: var(--accent);
    font-weight: 600;
    font-size: 0.75rem;
    border-radius: var(--radius-lg);
    min-width: 20px;
    text-align: center;
    padding: 1px 6px;
}

.ib-facc-head.ib-facc-disabled,
.waf-acc-disabled .ib-facc-head {
    cursor: default;
    opacity: 0.55;
}

.ib-facc-body {
    padding: 6px 10px 12px 10px;
}

.ib-facc-list {
    max-height: 240px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.ib-facc-option {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.85rem;
    padding: 3px 2px;
    cursor: pointer;
}

.ib-facc-range {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.ib-facc-bound {
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-secondary);
}

.ib-facc-bound input,
.ib-facc-textinput {
    width: 100%;
    box-sizing: border-box;
}

/* --- Dashboard panel (shared card style) --- */
.ib-dash-panel {
    padding: 24px;
    animation: ibPanelFadeIn 0.3s ease-out both;
    position: relative;
    overflow: hidden;
}

.ib-dash-panel::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: var(--accent-fill);
    border-radius: 14px 14px 0 0;
}

.ib-dash-panel h3 {
    margin: 0 0 16px 0;
}

/* --- Summary cards (inventory panel) --- */
.ib-cards {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
}

.ib-card {
    border-radius: var(--radius-lg);
    padding: 20px 16px;
    text-align: center;
    position: relative;
    overflow: hidden;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
    cursor: default;
}

.ib-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-2);
}

.ib-card-count {
    display: block;
    font-size: 2.8rem;
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: -0.03em;
    margin-bottom: 6px;
}

.ib-card-label {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

/* Card color variants */
.ib-card-ready {
    background: var(--status-success-tint);
    border: 1px solid var(--divider);
}
.ib-card-ready .ib-card-count { color: var(--status-success); }
.ib-card-ready .ib-card-label { color: var(--status-success); }

.ib-card-inprogress {
    background: var(--accent-tint);
    border: 1px solid var(--divider);
}
.ib-card-inprogress .ib-card-count { color: var(--accent); }
.ib-card-inprogress .ib-card-label { color: var(--accent); }

.ib-card-archived {
    background: var(--bg-secondary);
    border: 1px solid var(--divider);
}
.ib-card-archived .ib-card-count { color: var(--text-secondary); }
.ib-card-archived .ib-card-label { color: var(--text-secondary); }

.ib-card-rejected {
    background: var(--status-danger-tint);
    border: 1px solid var(--divider);
}
.ib-card-rejected .ib-card-count { color: var(--status-danger); }
.ib-card-rejected .ib-card-label { color: var(--status-danger); }

.ib-card-released {
    background: var(--accent-tint);
    border: 1px solid var(--divider);
}
.ib-card-released .ib-card-count { color: var(--accent); }
.ib-card-released .ib-card-label { color: var(--accent); }

/* --- Chart containers --- */
.ib-chart-wrap {
    position: relative;
    width: 100%;
    min-height: 260px;
}

.ib-chart-wrap canvas {
    max-width: 100%;
}

/* --- Coverage heatmap grid --- */
.ib-heatmap {
    display: grid;
    gap: 3px;
    margin-top: 12px;
}

.ib-heatmap-cell {
    border-radius: var(--radius-sm);
    min-width: 40px;
    min-height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    font-weight: 600;
    color: #fff;
    cursor: pointer;
    transition: transform 0.15s, box-shadow 0.15s;
}

.ib-heatmap-cell:hover {
    transform: scale(1.08);
    box-shadow: var(--shadow-1);
    z-index: 1;
}

.ib-heatmap-header {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--text-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Heatmap intensity scale (0–5+) */
.ib-heat-0 { background: var(--bg-secondary); color: var(--text-tertiary); }
.ib-heat-1 { background: var(--accent-tint); color: var(--accent); }
.ib-heat-2 { background: color-mix(in srgb, var(--accent-fill) 25%, var(--surface)); color: var(--text-primary); }
.ib-heat-3 { background: color-mix(in srgb, var(--accent-fill) 50%, var(--surface)); color: var(--text-primary); }
.ib-heat-4 { background: color-mix(in srgb, var(--accent-fill) 75%, var(--surface)); color: var(--text-primary); }
.ib-heat-5 { background: var(--accent-fill); color: var(--text-on-accent); }

/* --- Ready-items panel: bounded scrollable table --- */
.ib-ready-scroll {
    width: 100%;
    max-height: 28rem;
    overflow-y: auto;
    overflow-x: hidden;
}
.ib-ready-scroll table {
    width: 100%;
    table-layout: fixed;
}
.ib-ready-scroll th,
.ib-ready-scroll td {
    word-break: break-word;
    overflow-wrap: anywhere;
    white-space: normal;
}

/* --- Lazy-load buttons --- */
.ib-dash-panel button.ib-load-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 1px solid transparent;
}

/* --- DeleteBankView --- */
.db-root {
    padding: 24px;
    max-width: 720px;
}
.db-root h2 {
    color: var(--status-danger);
    margin-top: 0;
}
.db-intro {
    color: var(--text-secondary);
    margin-bottom: 16px;
}
.db-panel {
    border: 2px solid var(--status-danger);
    border-radius: var(--radius-md);
    padding: 16px 20px;
    background: var(--status-danger-tint);
}
.db-row {
    margin: 12px 0;
}
.db-warn {
    background: var(--status-danger-tint);
    color: var(--status-danger);
    border-left: 4px solid var(--status-danger);
    padding: 8px 12px;
    margin: 12px 0;
}
.db-picker {
    min-width: 280px;
}
.db-input {
    margin-left: 8px;
    min-width: 240px;
}
.db-danger-btn {
    border: 1px solid transparent;
}
.db-status {
    margin-top: 16px;
    padding: 8px;
    color: var(--text-primary);
}
.db-status-line {
    margin: 4px 0;
}

/* --- Search section --- */
.ib-dash-search {
    grid-column: 1 / -1;
}

.ib-search-bar {
    display: flex;
    gap: 10px;
    margin-bottom: 16px;
}

.ib-search-bar input[type="text"] {
    flex: 1;
    transition: border-color 0.15s, box-shadow 0.15s;
}

.ib-search-bar button {
    border: none;
}

/* --- Empty state --- */
.ib-empty-state {
    text-align: center;
    padding: 32px 16px;
    color: var(--text-tertiary);
    font-size: 0.95rem;
    font-style: italic;
}

/* --- Stat metric row --- */
.ib-stat-metrics {
    display: flex;
    gap: 24px;
    margin-bottom: 16px;
    flex-wrap: wrap;
}

.ib-stat-metric {
    background: var(--blueBackground);
    border-radius: var(--radius-lg);
    padding: 14px 20px;
    min-width: 160px;
    flex: 1;
}

.ib-stat-metric-value {
    font-size: 1.6rem;
    font-weight: 600;
    color: var(--purpleText);
    display: block;
}

.ib-stat-metric-label {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--accent);
    display: block;
    margin-top: 2px;
}

/* --- Animations --- */
@keyframes ibPanelFadeIn {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes ibCountUp {
    from { opacity: 0; transform: scale(0.7); }
    to   { opacity: 1; transform: scale(1); }
}

.ib-card-count {
    animation: ibCountUp 0.4s ease-out both;
}

.ib-dash-panel:nth-child(2) { animation-delay: 0.05s; }
.ib-dash-panel:nth-child(3) { animation-delay: 0.1s; }
.ib-dash-panel:nth-child(4) { animation-delay: 0.15s; }
.ib-dash-panel:nth-child(5) { animation-delay: 0.2s; }
.ib-dash-panel:nth-child(6) { animation-delay: 0.25s; }
.ib-dash-panel:nth-child(7) { animation-delay: 0.3s; }

@media (prefers-reduced-motion: reduce) {
    .ib-dash-panel,
    .ib-card-count,
    .ib-heatmap-cell,
    .ib-card {
        animation: none !important;
        transition: none !important;
    }
}

/* Responsive: stack to single column on narrow viewports */
@media (max-width: 900px) {
    .ib-dash-root {
        grid-template-columns: 1fr;
        padding: 16px;
        gap: 16px;
    }
    .ib-cards {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* ===================== IMPORT VIEW ===================== */

.imp-status {
    min-height: 20px;
    padding: 6px 12px;
    font-size: 0.9rem;
    color: var(--purpleText);
}

.imp-content {
    padding: 0 8px 24px 8px;
}

.imp-card {
    padding: 24px;
    margin-bottom: 20px;
    max-width: 720px;
}

.imp-card > hr {
    border: 0;
    border-top: 1px solid var(--divider);
}

.imp-card h3 {
    margin: 0 0 16px 0;
}

.imp-card h4 {
    margin: 16px 0 8px 0;
}

.imp-target-fieldset {
    padding: 12px 16px;
    margin: 0 0 16px 0;
}

.imp-target-fieldset legend {
    padding: 0 6px;
}

.imp-radio-label {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 0;
    cursor: pointer;
    font-size: 0.95rem;
    color: var(--text-primary);
}

.imp-file-row {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 16px;
}

.imp-file-row label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.imp-input,
.imp-select {
    transition: border-color 0.15s, box-shadow 0.15s;
    margin-bottom: 12px;
    display: block;
    width: 100%;
    box-sizing: border-box;
}

/* Selectors include the `button` tag so specificity beats the
   global `.Dialog_window button { background-color: #151616 }` rule
   at line 207 — otherwise dialog context inverts the palette and the
   purple text lands on near-black. Hover and focus use border-color
   and a soft shadow (not background) so the button surface stays
   white and the focus indicator is visible to keyboard users. */
/* Primary action button. AAA-compliant — same guarantees as
   .Button_window: text 10.8:1, border 7.8:1 on white, focus
   outline uses --jcmaPurple (10.8:1) with 3px thickness and
   offset for 2.4.13 Focus Appearance. Taller (min-height 44px)
   and heavier type-weight to read as the primary call-to-action. */
/* The import screen's main action: the app's primary button. It was a white
   box with a heavy edge and coloured text, which read as secondary. The 2px
   edge is kept, clear, so the button's size does not change. */
button.imp-btn-primary {
    border: 2px solid transparent;
    letter-spacing: 0.02em;
}

/* Secondary button. Shares the AAA guarantees above but in a
   lighter visual weight for inline actions (like the Associated
   Stimuli "Add" button on item-editor toolbars). */
button.imp-btn-secondary {
    border: 1px solid transparent;
    margin-bottom: 12px;
}

.imp-import-btn {
    margin-top: 16px;
    display: block;
}

.imp-sidecar-list {
    list-style: none;
    padding: 0;
    margin: 0 0 12px 0;
}

.imp-sidecar-list li {
    padding: 6px 12px;
    background: var(--status-success-tint);
    color: var(--status-success);
    border-radius: var(--radius-md);
    margin-bottom: 4px;
    font-size: 0.9rem;
    font-weight: 600;
}

.imp-unknown-list {
    list-style: none;
    padding: 0;
    margin: 8px 0;
}

.imp-unknown-list li {
    padding: 6px 12px;
    background: var(--status-warning-tint);
    color: var(--status-warning);
    border-radius: var(--radius-md);
    margin-bottom: 4px;
    font-family: monospace;
    font-size: 0.85rem;
}

.imp-dlg-actions {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    margin-top: 16px;
    padding-top: 12px;
    border-top: 1px solid var(--divider);
}

.imp-new-bank-section {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--divider);
}

.imp-new-bank-section label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    display: block;
    margin-bottom: 4px;
}

.imp-attr-list {
    max-height: 240px;
    overflow: auto;
    border: 1px solid var(--divider);
    border-radius: var(--radius-lg);
    padding: 8px;
    background: var(--bg-secondary);
}

/* Selection groups on the preview dialog — one section for items,
   one for stimuli. Each renders a header, a select-all/deselect-all
   toolbar, and a checkbox table the user uses to opt in or out per
   identifier. */
.imp-selection-section {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--divider);
}

.imp-selection-group {
    margin-bottom: 12px;
}

.imp-selection-group h4 {
    margin: 0 0 6px 0;
}

.imp-selection-toolbar {
    display: flex;
    gap: 8px;
    margin-bottom: 6px;
}

.imp-selection-table {
    width: 100%;
    max-height: 240px;
    display: block;
    overflow: auto;
    border: 1px solid var(--divider);
    border-radius: var(--radius-lg);
    background: var(--bg-secondary);
}

.imp-selection-table th,
.imp-selection-table td {
    text-align: left;
}

.imp-selection-table th {
    position: sticky;
    top: 0;
    background-color: var(--bg-secondary);
}

.imp-attr-check {
    display: flex !important;
    align-items: center;
    gap: 8px;
    padding: 4px 0;
    text-transform: none !important;
    font-size: 0.9rem !important;
    color: var(--text-primary) !important;
    cursor: pointer;
}

.imp-detected-attrs-section {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--divider);
}

.imp-detected-attrs-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 8px;
}

.imp-detected-attrs-toolbar h4 {
    margin: 0;
}

.imp-detected-attrs-toolbar-btns {
    display: flex;
    gap: 8px;
}

.imp-detected-attrs-scroll {
    max-height: 18em;
    overflow-y: auto;
    overflow-x: hidden;
    border: 1px solid var(--divider);
    border-radius: var(--radius-lg);
    background: var(--surface);
}

.imp-detected-attrs-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.imp-detected-attr-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--divider);
    font-size: 0.9rem;
    color: var(--text-primary);
}

.imp-detected-attr-item:last-child {
    border-bottom: none;
}

.imp-detected-attr-item:nth-child(even) {
    background: var(--bg-secondary);
}

.imp-detected-attr-name {
    flex: 1;
    word-break: break-word;
}

.imp-detected-attr-name em {
    color: var(--text-secondary);
    font-style: normal;
    font-size: 0.82rem;
    margin-left: 6px;
}

.imp-result {
    border-left: 4px solid var(--jcmaBlue);
}

.imp-error-list {
    list-style: none;
    padding: 0;
    margin: 0 0 12px 0;
}

.imp-error-list li {
    padding: 6px 12px;
    background: var(--status-danger-tint);
    color: var(--status-danger);
    border-radius: var(--radius-md);
    margin-bottom: 4px;
    font-size: 0.85rem;
}

/* Queue display */

.imp-queue-heading {
    margin: 24px 0 12px 8px;
}

.imp-queue {
    padding: 0 8px;
}

.imp-queue-table {
    width: 100%;
}

.imp-queue-table thead th {
    text-align: left;
}

.imp-queue-table tbody td {
    vertical-align: middle;
    height: 44px;
}

.imp-queue-table tbody tr:hover td {
    background: var(--fill-hover);
}

.imp-empty {
    text-align: center;
    padding: 24px 16px;
    color: var(--text-tertiary);
    font-style: italic;
    font-size: 0.95rem;
}

.imp-error-msg {
    color: var(--status-danger);
    font-size: 0.85rem;
    font-style: italic;
}

.imp-unknown-banner {
    margin: 12px 0;
}

/* ========== IMPORT DIALOGS (layout) ==========
   Every import-flow WAF.Dialog — Review import, Item details, Import results,
   the item detail and issue logs, the manifest attribute confirm — calls
   MT.ImportReportView.layoutDialog(dlg), which puts .imp-dialog on the
   central div and .imp-dialog-window on the backdrop.

   Why (owner report, 2026-10-03, Dev 39a8770c: "no right margin, a very small
   left margin, squeezed, a horizontal scroll seems necessary but is missing"):
   these dialogs append their content straight to the central div, and WAF's
   .Dialog_normal is overflow-x: hidden. A WAF.Table2D is display:inline-table,
   so a wide issue table ran past the right edge and was CLIPPED — no right
   margin, and no way to see the cut columns. The report table scrolled, but
   was unstyled, ran flush to its container's edge, and kept its horizontal
   bar at the foot of a 360px box. The manifest confirm inserts its content
   BEFORE .Dialog_body, where WAF's ".Dialog_body ~ *" inset never reaches,
   so it sat flush against the left edge. And the dialog's own widget row
   (Close) rendered ABOVE the content, with an empty padded .Dialog_body
   leaving a blank band under the title of the dialogs that have none.

   Scrolling stays WAF's: the central div remains the one vertical scroller
   (see the warning near the top of this file — no overflow override on
   .Dialog_normal here). Wide tables scroll sideways in their OWN focusable
   .imp-table-scroll container. */
.Dialog_normal.imp-dialog {
    max-width: min(1400px, 100%);
}

/* Every child gets the same inset on BOTH sides, whichever side of
   .Dialog_body it was inserted on. min-width:0 lets a child holding a wide
   table shrink to the box, so the table's own container does the scrolling. */
.Dialog_normal.imp-dialog > :not(.Dialog_title):not(.Dialog_body) {
    margin: 0 24px 16px;
    min-width: 0;
}

.Dialog_normal.imp-dialog > .Dialog_title {
    margin-bottom: 16px;
}

/* The dialog's own widget row (Close; Submit/Cancel) goes LAST and stays in
   view at the foot of the box. It is never squeezed to nothing by the content
   above it: WAF's .Dialog_body is flex: none for every dialog now (it used to
   be flex: 1 + overflow-y: auto, which shrank the body — and its buttons —
   to zero height), so no flex override is needed here. */
.Dialog_normal.imp-dialog > .Dialog_body {
    order: 1;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 10px;
    min-width: 0;
    padding: 12px 24px 20px;
    border-top: 1px solid var(--divider);
    background-color: var(--surface);
    position: sticky;
    bottom: 0;
    z-index: 1;
}

.Dialog_normal.imp-dialog > .Dialog_body:empty,
.Dialog_normal.imp-dialog > .Dialog_body > label:empty {
    display: none;
}

/* The page-built action row (Approve / Item details / Cancel) does the same. */
.Dialog_normal.imp-dialog > .imp-dlg-actions {
    margin: 0;
    padding: 12px 24px 20px;
    background-color: var(--surface);
    position: sticky;
    bottom: 0;
    z-index: 1;
    flex-wrap: wrap;
}

/* Small screens: the box fills the width with a 12px gutter. */
@media (max-width: 600px) {
    .Dialog_window.imp-dialog-window {
        padding: 12px;
    }

    .Dialog_normal.imp-dialog {
        min-width: 0;
        max-height: calc(100vh - 24px);
    }

    .Dialog_normal.imp-dialog > :not(.Dialog_title):not(.Dialog_body) {
        margin-left: 16px;
        margin-right: 16px;
    }

    .Dialog_normal.imp-dialog > .Dialog_body,
    .Dialog_normal.imp-dialog > .imp-dlg-actions {
        padding-left: 16px;
        padding-right: 16px;
    }
}

/* A wide table's own scroll container: .imp-table-scroll in the import dialogs
   (MT.ImportReportView.scrollRegion), .tq-table-scroll anywhere else (the
   scoring panel's Same Solutions As sample table, SameSolutionsTableView.js):
   focusable and named, so the keyboard can scroll it; capped in height so its
   horizontal bar is never far below the fold. */
.imp-table-scroll,
.tq-table-scroll {
    max-height: min(60vh, 520px);
    overflow: auto;
    border: 1px solid var(--divider);
    border-radius: var(--radius-sm);
    margin: 8px 0 16px;
    background-color: var(--surface);
    /* Its own stacking context: the sticky header row below must layer
       over the table rows only, never over the dialog's sticky title. */
    isolation: isolate;
}

.imp-table-scroll:focus-visible,
.tq-table-scroll:focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 2px;
}

/* The table fills the container and never gets narrower than a readable
   minimum; past that it scrolls sideways. Long identifiers, file paths and
   validator messages break anywhere rather than widening a column without
   end. border-collapse: separate keeps the sticky header's borders. */
.imp-table-scroll > table,
.tq-table-scroll > table {
    width: 100%;
    min-width: 720px;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 0.875rem;
    color: var(--text-primary);
}

/* Report columns: the reasons (Problems, Kept) get the most room, the
   identifier / title / file a middle share, the one-word columns the floor.
   The eleven floors sum to 84em, which fits the widened box at 1280px. */
.imp-table-scroll > table.imp-report-table {
    min-width: 0;
}

.imp-report-table th,
.imp-report-table td {
    min-width: 6em;
}

.imp-report-table th:nth-child(-n+2),
.imp-report-table td:nth-child(-n+2),
.imp-report-table th:nth-child(4),
.imp-report-table td:nth-child(4) {
    min-width: 8em;
}

.imp-report-table th:nth-child(6),
.imp-report-table td:nth-child(6),
.imp-report-table th:nth-child(7),
.imp-report-table td:nth-child(7) {
    min-width: 12em;
}

.imp-table-scroll > table.Table2D_window,
.tq-table-scroll > table.Table2D_window {
    display: table;
    border: none;
}

.imp-table-scroll > table th,
.imp-table-scroll > table td,
.tq-table-scroll > table th,
.tq-table-scroll > table td {
    padding: 6px 10px;
    border: none;
    border-bottom: 1px solid var(--divider);
    border-right: 1px solid var(--divider);
    vertical-align: top;
    text-align: left;
    min-width: 7.5em;
    overflow-wrap: anywhere;
}

.imp-table-scroll > table th:last-child,
.imp-table-scroll > table td:last-child,
.tq-table-scroll > table th:last-child,
.tq-table-scroll > table td:last-child {
    border-right: none;
}

/* Sticky header row: it stays on screen while the rows scroll under it. */
.imp-table-scroll > table > thead th,
.tq-table-scroll > table > thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background-color: var(--bg-secondary);
    font-weight: 600;
    white-space: normal;
}

.imp-table-scroll > table.Table2D_window > caption,
.tq-table-scroll > table.Table2D_window > caption {
    padding: 8px 10px 0;
}

/* The caption's title sits at the LEFT, where it is seen without scrolling
   (WAF centres it over the table, which is off screen on a narrow one). */
.imp-table-scroll .Table2D_titlebar,
.tq-table-scroll .Table2D_titlebar {
    grid-template-columns: auto 1fr auto;
}

.imp-table-scroll .Table2D_titletext,
.tq-table-scroll .Table2D_titletext {
    grid-column: 1;
    text-align: left;
}

/* The verdict pill is one short word: never split it. */
.imp-report-table td:nth-child(5) > span {
    white-space: nowrap;
}

.imp-report-table tr[data-verdict="invalid"] td {
    background-color: var(--status-warning-tint);
}

.imp-report-table tr[data-verdict="unreadable"] td {
    background-color: var(--status-danger-tint);
}

/* ========== SIMULATION LABEL EDITORS ========== */

/* ===================== PUBLICATION VIEW ===================== */

.pub-status {
    min-height: 20px;
    padding: 6px 12px;
    font-size: 0.9rem;
    color: var(--purpleText);
}

.pub-tabs {
    margin: 12px 0 20px 0;
    padding: 0 4px;
}

.pub-content {
    padding: 0 8px 24px 8px;
}

/* --- Tests and forms tab (PublicationTestsTab.js; TestExportPlan.md): layout only, the
   controls take the shared looks (.form-input, .btn, the app's checkboxes and radios). --- */

.pub-tf-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(260px, 340px);
    gap: 24px;
    align-items: start;
}

@media (max-width: 800px) {
    .pub-tf-layout {
        grid-template-columns: minmax(0, 1fr);
    }
}

.pub-tf-filter-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 12px 0;
}

.pub-tf-tests,
.pub-tf-forms {
    list-style: none;
    margin: 0;
    padding-left: 0;
}

.pub-tf-forms {
    margin-left: 28px;
}

.pub-tf-test {
    margin: 0 0 12px 0;
}

.pub-tf-test-head,
.pub-tf-form-head {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.pub-tf-form {
    margin: 4px 0;
}

.pub-tf-greyed .pub-tf-form-name {
    color: var(--text-secondary);
}

.pub-tf-reason {
    display: block;
    margin-left: 28px;
}

.pub-tf-package {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* --- Retiring a bank that tests are pinned to (PinnedTestsDialog.js) --- */

.pinned-tests-list {
    list-style: none;
    margin: 8px 0;
    padding: 0;
}

.pinned-tests-entry {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px 16px;
    padding: 6px 0;
}

.pinned-tests-name {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.pinned-tests-note {
    color: var(--text-secondary);
}

/* --- Summary header + selected-items card --- */

.pub-summary {
    display: flex;
    align-items: baseline;
    gap: 12px;
    margin: 8px 0 12px 0;
}

.pub-summary h3 {
    margin: 0;
}

.pub-selected-container {
    padding: 12px;
    margin-bottom: 16px;
    max-height: 340px;
    overflow: auto;
}

.pub-empty {
    text-align: center;
    padding: 18px;
    color: var(--text-tertiary);
    font-style: italic;
    font-size: 0.95rem;
    margin: 0;
}

/* --- Action buttons row (Add from list / batches / spreadsheet / clear) --- */

.pub-action-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 20px;
}

.pub-action-buttons button {
    border: 1px solid transparent;
}

/* --- Publish form --- */

.pub-publish-form {
    background: var(--surface);
    border: 1px solid var(--divider);
    border-radius: var(--radius-card);
    padding: 20px 24px;
    box-shadow: var(--shadow-1);
    max-width: 640px;
}

.pub-publish-form h3 {
    margin: 0 0 16px 0;
}

.pub-name-row {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 14px;
}

.pub-name-row label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.pub-name-row input[type="text"] {
    transition: border-color 0.15s, box-shadow 0.15s;
}

.pub-type-row {
    border: 1px solid var(--divider);
    border-radius: var(--radius-lg);
    padding: 12px 16px;
    margin: 0 0 16px 0;
    background: var(--surface);
}

.pub-type-row legend {
    padding: 0 6px;
}

.pub-type-row label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-right: 20px;
    font-size: 0.95rem;
    color: var(--text-primary);
    cursor: pointer;
}

/* Package format and PCI location: the same boxed fieldset as the type row.
   The PCI options are long sentences, so they stack one per line, indented
   under the legend and hint, instead of running together inline. */
.pub-format-row {
    border: 1px solid var(--divider);
    border-radius: var(--radius-lg);
    padding: 12px 16px;
    margin: 0 0 16px 0;
    background: var(--surface);
}

.pub-format-row legend {
    padding: 0 6px;
}

.pub-format-row label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-right: 20px;
    font-size: 0.95rem;
    color: var(--text-primary);
    cursor: pointer;
}

.pub-pci-mode-hint {
    margin: 0 0 8px 0;
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.pub-pci-mode-row label {
    display: flex;
    align-items: flex-start;
    margin: 0 0 6px 24px;
}

.pub-pci-mode-row label:last-child {
    margin-bottom: 0;
}

.pub-pci-mode-row input[type="radio"] {
    flex: 0 0 auto;
    margin-top: 3px;
}

/* Publish primary button — bold gradient, stands out */
.pub-publish-btn {
    border: none;
    letter-spacing: 0.02em;
}

/* --- Dialog interior (all three pub dialogs) --- */

.pub-dlg-search {
    display: flex;
    gap: 8px;
    margin-bottom: 12px;
    align-items: center;
}

.pub-dlg-search input[type="text"] {
    flex: 1;
    transition: border-color 0.15s, box-shadow 0.15s;
}

.pub-dlg-search button,
.pub-dlg-selall button {
    border: 1px solid transparent;
}

.pub-dlg-selall {
    display: flex;
    gap: 8px;
    margin-bottom: 12px;
}

.pub-dlg-tbl {
    max-height: 420px;
    overflow: auto;
    border: 1px solid var(--divider);
    border-radius: var(--radius-lg);
    background: var(--surface);
    padding: 4px;
}

.pub-dlg-actions {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    margin-top: 16px;
    padding-top: 12px;
    border-top: 1px solid var(--divider);
}

.pub-dlg-actions button {
    border: 1px solid transparent;
}

/* First button in actions row = primary (Add Selected) */
.pub-dlg-actions button:first-child {
    border: none;
}

/* Spreadsheet dialog preview */

.pub-dlg-spreadsheet-preview {
    margin-top: 12px;
    padding: 12px;
    background: var(--bg-secondary);
    border: 1px solid var(--divider);
    border-radius: var(--radius-lg);
    font-size: 0.9rem;
    color: var(--text-primary);
}

.pub-dlg-spreadsheet-ids {
    font-family: 'Courier New', monospace;
    font-size: 0.85rem;
    color: var(--text-secondary);
    word-break: break-all;
    max-height: 160px;
    overflow: auto;
    margin: 6px 0 0 0;
}

/* File input a bit nicer */
.pub-dlg-spreadsheet-preview + input[type="file"],
.pub-content input[type="file"] {
    font-size: 0.9rem;
    padding: 6px;
}

/* --- History tab --- */

.pub-hist-toggle {
    margin: 8px 0 16px 0;
}

.pub-hist-toggle label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.9rem;
    color: var(--text-primary);
    cursor: pointer;
}

.pub-hist-table {
    background: var(--surface);
    border: 1px solid var(--divider);
    border-radius: var(--radius-lg);
    padding: 12px;
    box-shadow: var(--shadow-1);
}

/* Buttons inside the pub-* Table2D rows (Remove, Download etc.) */

.pub-selected-container .Table2D_body button,
.pub-hist-table .Table2D_body button {
    padding: 6px 12px;
    border: 1px solid var(--divider);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--jcmaPurple);
    font-weight: 600;
    font-size: 0.8rem;
    cursor: pointer;
    transition: border-color 0.15s, box-shadow 0.15s, background 0.15s, color 0.15s;
}

.pub-selected-container .Table2D_body button:hover,
.pub-hist-table .Table2D_body button:hover {
    border-color: var(--jcmaBlue);
    color: var(--jcmaBlue);
    background: var(--fill-hover);
    box-shadow: 0 2px 6px var(--accent-tint);
}

/* Reclassify select in history table */

.pub-hist-table .Table2D_body select {
    padding: 6px 8px;
    /* Room for the chevron. */
    padding-right: 30px;
    border: 1px solid var(--field-border);
    border-radius: var(--radius-field);
    /* The colour alone, so the chevron picture is kept. */
    background-color: var(--field-bg);
    color: var(--text-primary);
    cursor: pointer;
}

.pub-hist-table .Table2D_body select:hover,
.pub-hist-table .Table2D_body select:focus {
    border-color: var(--jcmaBlue);
    outline: none;
    box-shadow: 0 0 0 3px var(--accent-tint);
}

/* ItemHistory publication-panel table (read-only) */

.ih-pub-table {
    width: 100%;
}

.ih-pub-table thead th {
    text-align: left;
}

.ih-pub-table tbody tr:hover td {
    background: var(--fill-hover);
}

/* Upgrade the existing .ih-btn to match the modern aesthetic */
.ih-btn {
    border: 1px solid transparent;
}

/* ── Interaction Picker Panel ──────────────────────────────────────── */
.ip-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0);
    z-index: 199;
    transition: background 0.25s ease;
}

.ip-overlay.ip-overlay--open {
    background: var(--scrim);
}

.ip-panel {
    position: fixed;
    right: 0;
    top: 0;
    bottom: 0;
    width: 460px;
    background: var(--surface);
    border-left: 1px solid var(--color-border);
    box-shadow: var(--shadow-2);
    z-index: 200;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    transform: translateX(100%);
    transition: transform 0.25s ease;
}

.ip-panel.ip-panel--open {
    transform: translateX(0);
}

.ip-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-bg);
    flex-shrink: 0;
}

.ip-panel-close {
    background: transparent;
    border: none;
    cursor: pointer;
    font-size: 1.4rem;
    line-height: 1;
    color: var(--color-text-base);
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    border-radius: var(--radius-sm);
}

.ip-panel-close:hover {
    background: var(--color-surface);
}

.ip-panel-close:focus-visible {
    outline: var(--focus-outline);
    outline-offset: var(--focus-offset);
}

.ip-panel-body {
    flex: 1;
    overflow-y: auto;
    padding: 8px;
    display: flex;
    flex-direction: column;
}

.ip-category-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    min-height: var(--touch-target-min);
    padding: 4px 8px;
    border: none;
    background: transparent;
    border-radius: var(--radius-sm);
    text-align: left;
    cursor: pointer;
    transition: background 0.12s ease;
    user-select: none;
}

.ip-category-title:hover {
    background: var(--color-hover-bg);
}

.ip-category-title:focus-visible {
    outline: var(--focus-outline);
    outline-offset: var(--focus-offset);
}

.ip-category-label {
    font-size: 1.15rem;
    font-weight: 500;
    color: var(--color-text-heading);
    transition: color 0.12s ease;
}

.ip-category-chevron {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    color: var(--color-text-muted);
    margin-right: 8px;
}

.ip-category-chevron svg {
    width: 16px;
    height: 16px;
    transition: transform 0.15s ease;
}

.ip-category-title--open .ip-category-chevron svg {
    transform: rotate(90deg);
}

.ip-category-items {
    padding-left: 8px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-bottom: 4px;
}

.ip-type-card {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: var(--touch-target-min);
    padding: 4px 8px;
    border: none;
    background: transparent;
    border-radius: var(--radius-sm);
    text-align: left;
    cursor: pointer;
    transition: background 0.12s ease;
}

.ip-type-card:hover {
    background: var(--color-hover-bg);
}

.ip-type-card:focus-visible {
    outline: var(--focus-outline);
    outline-offset: var(--focus-offset);
}

.ip-type-thumb {
    width: 36px;
    height: 28px;
    background: var(--fill);
    border-radius: var(--radius-sm);
    flex-shrink: 0;
    border: 1px solid var(--divider);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

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

.ip-type-name {
    font-size: 1.15rem;
    font-weight: 500;
    color: var(--color-text-base);
    line-height: 1.3;
}

.ip-type-desc {
    font-size: 1rem;
    color: var(--color-text-base);
    line-height: 1.3;
    margin-top: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .ip-panel,
    .ip-overlay,
    .ip-category-chevron svg,
    .ip-category-title,
    .ip-category-label,
    .ip-type-card {
        transition: none;
    }
}

/* Workflow-config dialog intro. "Must be followed by" is the INVERSE of a
   prerequisite, and the two buttons sit side by side on the same row, so the
   explanation has to be readable, not a footnote. AAA contrast. */
.wc-dlg-intro {
    margin: 0 0 12px 0;
    max-width: 60ch;
    line-height: 1.5;
    color: var(--text-primary);
}

/* ---- Bank admin: role-grouped user-access roster (BankUserRosterPanel) ---- */

.ba-roster-controls {
    display: flex;
    gap: 10px;
    margin-bottom: 12px;
}

.ba-roster-branch {
    border: 1px solid var(--divider);
    border-radius: var(--radius-md);
    margin-bottom: 6px;
    background-color: var(--surface);
}

.ba-roster-role {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    text-align: left;
    padding: 8px 10px;
    border: none;
    background-color: transparent;
    font-weight: 600;
    cursor: pointer;
}

.ba-roster-role:hover {
    background-color: var(--fill-hover);
}

.ba-roster-arrow {
    width: 1em;
}

.ba-roster-users {
    list-style: none;
    margin: 0;
    padding: 2px 10px 8px 30px;
    max-height: 16em;
    overflow-y: auto;
}

.ba-roster-user > label {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 4px 2px;
    cursor: pointer;
}

.ba-roster-user input[disabled] + span {
    color: var(--text-tertiary);
}

.ba-roster-wide {
    color: var(--text-secondary);
    font-size: 0.85em;
    font-style: italic;
    margin-left: 6px;
}

/* ── Item set branches in the work queue ──────────────────────────────────
   In set mode the queue's rows are grouped: a set header row, then that set's
   ordinary queue rows, then a bar to add another item. The item rows are
   untouched — same columns, same sorting, same click-to-open and force-unlock.
   See Documents/ItemSetBottleneckPlan.md. */

.wq-table tbody tr.wq-set-header {
    font-weight: 600;
    background-color: var(--bg-secondary);
}

.wq-table tbody tr.wq-set-header:hover,
.wq-table tbody tr.wq-set-header:focus {
    background-color: var(--color-primary-tint);
    outline: none;
}

/* Decorative: the row carries aria-expanded. */
.wq-set-twisty {
    display: inline-block;
    width: 1.1em;
    color: var(--text-secondary);
}

.wq-set-count {
    font-weight: 400;
    color: var(--text-secondary);                 /* AAA on the sunken surface */
    white-space: nowrap;
}

.wq-set-actions {
    text-align: right;
}

/* An item inside a branch is indented under its set. */
.wq-table tbody tr.wq-set-item td:first-child {
    padding-left: 2.4em;
}

/* The add bar: full width, a plus in the middle, and nothing else — what it
   does lives in its tooltip and accessible name. It is RAISED rather than
   dashed (owner, 2026-09-11): rounded, with a lit top edge and a shadow
   beneath, so it reads as a button to press rather than a placeholder. */
.wq-table tbody tr.wq-set-add-row {
    cursor: default;
}

.wq-table tbody tr.wq-set-add-row td {
    padding: 4px 0;
}

.wq-set-add {
    display: block;
    width: 100%;
    /* WCAG 2.5.5 AAA, the same 44px every .btn in this app honours. */
    min-height: var(--touch-target-min, 44px);
    padding: 5px 0;
    border: 1px solid transparent;
    border-radius: var(--btn-radius, 8px);
    background-color: var(--fill);
    color: var(--accent);
    font-size: 1.6rem;
    font-weight: 600;
    line-height: 1.2;
    text-align: center;
    cursor: pointer;
    transition: var(--btn-transition);
}

.wq-set-add:hover {
    background-color: var(--fill-hover);
}

.wq-set-add:focus-visible {
    outline: var(--focus-outline);
    outline-offset: 2px;
}

/* Pressed: one fill step darker, and the 1px nudge it always had. */
.wq-set-add:active {
    background-color: var(--fill-pressed);
    transform: translateY(1px);
}

/* The work queue dialog is wider than the stock 720px box: it holds a
   nine-column table, and in set mode a branch structure inside it. Same
   modifier shape as .tq-rubric-dialog — the WAF box is width:100% capped by
   max-width, so raising the cap is all it takes (owner, 2026-09-11: about 85%
   of the screen). */
.Dialog_normal.wq-dialog {
    max-width: 85vw;
}

/* The queue scrolls INSIDE the dialog, in BOTH directions, so neither scrollbar
   can wander out of sight. Before this the dialog body scrolled vertically while
   the table box scrolled horizontally, which put the horizontal bar at the foot
   of the whole table — you had to scroll down to the end of the queue to reach
   the control that moves it sideways (owner, 2026-09-11). Now one box scrolls
   both ways and its bars sit on the edges of what you can see. */
.wq-dialog .wq-content {
    display: flex;
    flex-direction: column;
    /* Column flex stretches its children: without this the "New item" button
       would span the whole dialog. The table box asks for the full width back,
       below. */
    align-items: flex-start;
    overflow: hidden;
}

.wq-dialog .wq-table-container {
    flex: 1 1 auto;
    min-height: 0;
    align-self: stretch;
    overflow: auto;
}

/* The asset-service queue dialog (AssetQueueView) is the work queue's twin: a
   seven-column table inside the stock 720px box, which clipped the Actions
   column off the right — and .Dialog_normal hides horizontal overflow, so no
   scrollbar ever appeared to reach it (owner, 2026-09-16: 80% of the screen,
   with a scrollbar when it still doesn't fit). Same treatment as .wq-dialog
   above, including scrolling the table in its OWN box in both directions so
   neither bar can wander out of sight. */
.Dialog_normal.asvc-queue-dialog {
    max-width: 80vw;
}

.asvc-queue-dialog .asvc-queue-content {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    /* Column flex stretches its children; the status line keeps its own size
       and the table box asks for the full width back, just below. */
    align-items: flex-start;
    overflow: hidden;
}

.asvc-queue-dialog .asvc-table-container {
    flex: 1 1 auto;
    min-height: 0;
    align-self: stretch;
    overflow: auto;
}

/* Table chrome matching .wq-table, so the two queues read alike. Cells WRAP
   rather than nowrap: the request column is a plain-text preview capped at 120
   characters, so the horizontal scrollbar is there for a narrow window, not as
   the normal way to read the queue. */
.asvc-table {
    width: 100%;
}

.asvc-table th,
.asvc-table td {
    text-align: left;
    vertical-align: top;
}

.asvc-table thead th {
    white-space: nowrap;
}

.asvc-table tbody tr:last-child {
    border-bottom: none;
}

/* The column header inside an open branch (2026-09-10). In set mode the
   table's top-level rows are stimuli, so the item columns belong beside the
   items they describe, not above the list of sets — the table carries no
   thead at all there. */
.wq-table tbody tr.wq-columns {
    cursor: default;
    background-color: transparent;
}

.wq-table tbody tr.wq-columns:hover,
.wq-table tbody tr.wq-columns:focus {
    background-color: transparent;
    outline: none;
}

.wq-table tbody tr.wq-columns th {
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: 0.8125rem;
    color: var(--color-text-base);
    border-bottom: 1px solid var(--color-border);
}

.wq-table tbody tr.wq-columns th.wq-sortable {
    padding: 0;
}

/* Line the header up with the items, which are indented under their set. */
.wq-table tbody tr.wq-columns th:first-child .wq-sort-btn {
    padding-left: 2.4em;
}

/* ========== SAVE CONFIRMATION (MT.SaveConfirmation) ========== */
/* The transient "Saved" every editing screen shows. FIXED, and appended to
   <body>, on purpose: the editors' action bars are sticky and they wrap, so a
   message that appeared and disappeared inside one would re-flow the bar and
   move the content under the user's mouse. Out of flow, it can reflow nothing
   and costs no permanent vertical space.

   Colours are palette tokens, so the message follows whichever of the colour
   themes is in use: --color-text-heading (#16132A) on --color-surface
   (#E6E3EF) = 14.2:1 (AAA). z-index 300 clears the highest in this file (200);
   a real modal is in the browser's top layer and still sits above it. */
.tq-save-confirmation {
    position: fixed;
    left: 50%;
    bottom: 2rem;
    transform: translateX(-50%);
    z-index: 300;
    max-width: min(90vw, 32rem);
    padding: 0.6rem 1.1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background-color: var(--color-surface);
    color: var(--color-text-heading);
    font-size: 0.9375rem;
    font-weight: 600;
    box-shadow: var(--shadow-1);
    /* It confirms; it is never in the way of the pointer. */
    pointer-events: none;
    transition: opacity 0.3s ease;
}

.tq-save-confirmation--fading {
    opacity: 0;
}

/* Respect a reduced-motion preference: appear and go, no fade. */
@media (prefers-reduced-motion: reduce) {
    .tq-save-confirmation {
        transition: none;
    }
}

/* ---- Publication report dialog (Publication history -> Report; PublicationReportView.js) ----
   Kept in its own block so a merge with other Publication-screen styling stays trivial. */
.pub-report-section {
    max-width: 36rem;
}
.pub-report-name {
    font-weight: 600;
}
.pub-report-downloads {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.75rem;
}

/* ---- The selection accordion (MT.SelectionAccordion: Blueprint Editor, Form Builder) ----
   Layout only: the row is the shared accordion row above, the alert the shared tag. */
.tq-sel-acc {
    margin-bottom: 12px;
}

.tq-sel-acc-heading {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 8px;
}

.tq-sel-acc-heading .tq-sel-acc-toggle {
    flex: 1 1 auto;
    min-width: 0;
}

.tq-sel-acc-summary {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.tq-sel-acc-alert {
    margin-left: auto;
    flex: none;
}

.tq-sel-acc-body {
    padding: 0 4px;
}

/* ---- The guided blueprint (BlueprintWizardBuildPlan.md slice 3, MT.BlueprintWizardView): layout only;
   its controls take the shared looks (cc-btn, form-input, cc-fieldset, be-chip, tq-error-message). ---- */

.bwz-body {
    display: grid;
    grid-template-columns: minmax(180px, 240px) 1fr;
    gap: 16px;
    align-items: start;
}

.bwz-rail-list {
    margin: 0 0 12px;
    padding: 0;
    list-style: none;
}

.bwz-rail-item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    margin-bottom: 4px;
}

.bwz-rail-step {
    width: 100%;
    text-align: start;
}

.bwz-step .cc-fieldset {
    padding: 12px 16px;
}

.bwz-range,
.bwz-metric,
.bwz-branch,
.bwz-depth,
.bwz-domain,
.bwz-same-row,
.bwz-together-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 4px 0;
}

.bwz-range .form-input {
    width: 7em;
}

.bwz-actions {
    margin-top: 12px;
}

/* The unfinished guided blueprints offered by New blueprint, Guided (MT.BlueprintWizardDraftList). */
.bwz-unfinished-list {
    margin: 8px 0 12px;
    padding: 0;
    list-style: none;
}

.bwz-unfinished {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 6px 0;
}

.bwz-yes-no,
.bwz-value,
.bwz-grouping-tick,
.bwz-same-each {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 4px 12px 4px 0;
}

.bwz-type,
.bwz-new-type,
.bwz-groupings {
    margin: 8px 0;
}

.bwz-draft-values {
    display: flex;
    flex-wrap: wrap;
}

.bwz-grid-scroll {
    overflow-x: auto;
    margin: 8px 0;
}

.bwz-grid .form-input {
    width: 4.5em;
}

.bwz-pair {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.bwz-grid-cell,
.bwz-grid-whole,
.bwz-grid-outside {
    white-space: nowrap;
}

.bwz-attr-block,
.bwz-attr-group,
.bwz-card,
.bwz-card-row,
.bwz-problem,
.bwz-subtotals {
    margin: 8px 0;
}

.bwz-subtotal,
.bwz-offer {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 4px 0;
}

.bwz-bounds .form-input {
    width: 4.5em;
}

.bwz-category,
.bwz-tree-row,
.bwz-check {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 4px 0;
}

.bwz-tree-list,
.bwz-check-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.bwz-create-area {
    margin-top: 16px;
}

@media (max-width: 720px) {
    .bwz-body {
        grid-template-columns: 1fr;
    }
}

/* ---- The blueprint editor (BlueprintDesign.html slice 3, MT.BlueprintEditorView) ---- */

.be-chooser {
    align-items: center;
    margin-bottom: 12px;
}

.be-note {
    color: var(--text-secondary);
}

.be-scopeline {
    margin: 0 0 10px;
    color: var(--text-secondary);
}

.be-name,
.be-description,
.be-level-label {
    width: 100%;
    max-width: 40em;
    box-sizing: border-box;
}

/* The two panels fill the window under what is above them (their height is set by the editor's script) and each
   scrolls on its own: the tree under its toolbar, the side column as a whole. The page itself does not scroll. */
.be-columns {
    display: flex;
    gap: 16px;
    align-items: stretch;
    flex-wrap: nowrap;
}

.be-tree-panel {
    flex: 1.6 1 520px;
    min-width: 320px;
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
}

.be-side {
    flex: 1 1 300px;
    min-width: 280px;
    overflow-y: auto;
    box-sizing: border-box;
}

.be-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-bottom: 6px;
}

.be-hint {
    margin: 4px 0;
}

.be-tree {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    border: 1px solid var(--divider);
    border-radius: 3px;
}

/* Stacked in a narrow window: the panels take their own heights and widths, and the page alone scrolls. */
@media (max-width: 899.98px) {
    .be-columns { flex-wrap: wrap; height: auto !important; }
    .be-columns > .mt-panel-resize { display: none; }
    .be-columns > .be-tree-panel,
    .be-columns > .be-side { width: auto !important; flex: 1 1 100% !important; max-width: 100% !important; overflow-y: visible; }
    .be-tree { overflow-y: visible; }
}

.be-level {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px 6px;
    border-bottom: 1px solid var(--divider);
    cursor: pointer;
}

.be-level:hover {
    background: var(--fill-hover);
    color: var(--text-primary);
}

.be-level:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: -2px;
}

.be-level.be-sel {
    background: var(--selected-bg);
    color: var(--selected-text);
    box-shadow: var(--selected-mark);
}

/* A selected level that is open: every row shown beneath it reads as selected with it, so the
   whole set it heads is marked (the selected-row fill and start edge). */
.be-level.be-in-sel {
    background: var(--selected-bg);
    color: var(--selected-text);
    box-shadow: var(--selected-mark);
}

/* A flagged level reads in the danger colour, its label with it. */
.be-level.be-flagged {
    color: var(--status-danger);
}

.be-toggle {
    width: 1.6em;
    border: none;
    background: transparent;
    cursor: pointer;
    padding: 0;
}

.be-toggle:disabled {
    cursor: default;
}

/* The role tag's look is the shared tag (its kinds are named in the tag rules). */
.be-role {
    flex: 0 0 auto;
}

.be-outline {
    flex: 0 0 auto;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
}

.be-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.be-bounds {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 2px;
}

.be-bound {
    width: 4.5em;
}

.be-chip {
    margin: 2px 4px 2px 0;
}

.be-field {
    margin-top: 6px;
}

.be-flag {
    display: flex;
    gap: 6px;
    align-items: center;
    margin: 4px 0;
}

/* A condition's values: one tick per value, scrolling when there are many; a range is two sliders. */
.be-cond-values {
    display: flex;
    flex-direction: column;
    max-height: 16em;
    overflow-y: auto;
}

.be-range {
    display: grid;
    grid-template-columns: 4em 1fr 5em;
    gap: 8px;
    align-items: center;
}

.be-tools {
    border: 1px solid var(--divider);
    border-radius: 3px;
    margin-top: 8px;
    padding: 6px 10px;
}

.be-verdict-pass {
    color: var(--status-success);
}

.be-check-list,
.be-version-list {
    margin: 0;
    padding-inline-start: 1.2em;
}

.be-check {
    margin: 3px 0;
}

.be-check-level {
    margin-right: 4px;
}

.be-verdict-fail {
    color: var(--status-danger);
}

/* Advisory layout warnings (LayoutNotices): laid out as checks, coloured as a warning, never blocking. */
.be-verdict-warn {
    color: var(--status-warning);
}

.be-branches {
    max-height: 14em;
    overflow-y: auto;
    border: 1px solid var(--divider);
    padding: 4px 8px;
}

.be-branch {
    display: flex;
    gap: 6px;
    align-items: flex-start;
    margin: 3px 0;
}

.be-chip-remove {
    margin-left: 4px;
}

.be-move-bar {
    align-items: center;
    background: var(--status-warning-tint);
    color: var(--text-primary);
    border: 1px solid var(--status-warning);
    border-radius: 3px;
    padding: 4px 8px;
    margin-bottom: 6px;
}

.be-add-condition {
    margin-top: 6px;
}

.be-save-status {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 8px;
}

/* Its error, stale and incomplete states are the shared notice (named in the notice rules). */

/* Delete blueprint: the stern warning and the tests that stop it. */
.be-delete-row {
    margin-top: 8px;
}

/* Both are the shared notice: the warning a danger one, the blockers a warning one. */
.be-delete-dialog .be-delete-warning,
.be-delete-dialog .be-delete-blocked {
    margin: 8px 0;
}

.be-delete-dialog .be-delete-warning p,
.be-delete-dialog .be-delete-blocked p {
    margin: 4px 0;
}

/* The editor hides with [hidden]; a display rule such as .cc-action-row's flex
   would otherwise win over it (the move bar showed on open). */
.be-editor [hidden] {
    display: none !important;
}

.be-cat {
    flex: 0 0 auto;
    max-width: 12em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.be-category {
    border-top: 1px solid var(--divider);
    padding: 6px 0;
}

.be-category-label {
    width: 100%;
    box-sizing: border-box;
}

.be-category-members {
    margin: 4px 0;
}

/* ---- Test definition (state testdefinition; Scripts/Blueprint/TestDefinitionView.js) ----
   BlueprintDesign.html slice 4. Kept in its own block so merges stay trivial. */
.td-editor .td-section {
    margin-bottom: 1rem;
}
.td-field {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}
.td-field .cc-label {
    min-width: 9rem;
}
.td-save-status {
    margin: 0.25rem 0 0.75rem;
}
.td-latent-list, .td-check-list {
    list-style: none;
    padding-left: 0;
}
.td-latent, .td-reporting-head, .td-adder {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.35rem;
}
.td-scale-name {
    font-weight: 600;
}
.td-reporting {
    border: 1px solid var(--color-border);
    border-radius: 4px;
    padding: 0.5rem;
    margin-bottom: 0.5rem;
}
.td-levels-table td, .td-levels-table th {
    text-align: left;
}
.td-note {
    font-style: italic;
}
/* A blocking finding reads in the danger colour; a warning in the ordinary one. */
.td-verdict-blocking {
    color: var(--status-danger);
}

/* ---- Test pools (state testpool; Scripts/Blueprint/TestPoolView.js) ----
   BlueprintDesign.html slice 4b. Kept in its own block so merges stay trivial. */
.tp-chooser, .tp-pool-bar, .tp-actions, .tp-new-form, .tp-dlg-search, .tp-dlg-selall, .tp-dlg-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}
.tp-field {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}
.tp-field .cc-label {
    min-width: 9rem;
}
.tp-save-status {
    margin: 0.25rem 0 0.75rem;
}
.tp-preliminary, .tp-calibration-problem {
    font-weight: 600;
}
.tp-items, .tp-dlg-tbl {
    max-width: 100%;
    overflow-x: auto;
}
.tp-dlg-bank {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

/* ---- The form builder (state formbuilder; Scripts/Blueprint/FormBuilderView.js) ----
   BlueprintDesign.html slice 7, FormBuilderMockups.html screen 3. Kept in its own block so
   merges stay trivial. */
.fb-chooser, .fb-form-bar, .fb-toolbar, .fb-dlg-actions, .fb-eligible-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}
.fb-field {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}
.fb-field .cc-label {
    min-width: 9rem;
}
.fb-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
}
.fb-title {
    margin: 4px 0 2px;
}
/* The status and preliminary pills are the shared tag (named in the tag rules). */
.fb-save-status {
    flex-basis: 100%;
    margin: 0.25rem 0 0.25rem;
}
.fb-scopeline {
    color: var(--text-secondary);
    margin: 0 0 0.5rem;
}
.fb-problem, .fb-preliminary, .fb-job {
    font-weight: 600;
}
.fb-job-failed {
    color: var(--status-danger);
}
.fb-draft-note, .fb-final-note {
    margin: 0.25rem 0;
}
.fb-describe .fb-scopeline { margin: 4px 0; }
.fb-form-details { align-items: center; }
.fb-msgbox { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 4px 0 8px; }
.fb-msg-top { flex: 1 1 0; min-width: 0; }
.fb-msg-top > * { margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fb-msg-list { flex-basis: 100%; display: flex; flex-direction: column; gap: 4px; }
.fb-msg-list > .fb-msg-item > * { margin: 0; }
.fb-problem-list { white-space: normal; display: flex; flex-direction: column; gap: 4px; margin-top: 4px; }
.fb-problem-item { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
/* The screen hides with [hidden]; a display rule (the message list's and the problem list's flex, a
   .cc-action-row) would otherwise win over it: every message and every problem row showed at once,
   and Show which changed nothing (owner, 2026-10-19). */
.FormBuilderView_window [hidden] {
    display: none !important;
}
.fb-draw-options {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}
.fb-curve-weight, .fb-slot-size {
    width: 5em;
}
.fb-columns {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: flex-start;
    margin-bottom: 12px;
}
.fb-panel {
    padding: 8px 10px;
    box-sizing: border-box;
}
.fb-graphs { flex: 1 1 300px; min-width: 280px; }
.fb-blueprint { flex: 1.2 1 340px; min-width: 300px; }
.fb-eligible { flex: 1.2 1 340px; min-width: 300px; }
.fb-form { width: 100%; }
/* The Arrange view (MT.FormArrangeView): layout only; chips and buttons are the shared ones. */
.fb-view-switch { display: inline-flex; gap: 6px; margin-right: 12px; }
/* The two panels sit side by side and fill the window under what is above them (the view's script sets the row's
   height); each scrolls on its own, so the list never runs into the test. The grip between them (MT.PanelResizer)
   sizes the list; the test takes what is left (owner, 2026-10-28). */
.fb-arr-columns {
    display: flex;
    flex-wrap: nowrap;
    gap: 8px;
    align-items: stretch;
    margin-bottom: 12px;
}
.fb-arr-list-panel { flex: 0 0 340px; width: 340px; min-width: 260px; overflow: auto; position: relative; }
.fb-arr-test-panel { flex: 1 1 0; min-width: 320px; overflow: auto; }
/* The list reads at 300 to 360px: it fills its panel (never wider), rows are tight, a passage set's items sit under
   its heading with a small indent, and a long name ends in an ellipsis (the whole name is its tooltip). */
.fb-arr-list .tq-reorderable-list { width: 100%; min-width: 0; }
.fb-arr-list .tq-reorderable-list ul { margin: 0; padding: 4px; }
.fb-arr-list .tq-reorderable-list-item { padding: 2px 4px; gap: 4px; min-width: 0; }
.fb-arr-list button.tq-draggable-indicator { margin-right: 2px; }
.fb-arr-list li.fb-arr-set { flex-wrap: wrap; }
.fb-arr-list li.fb-arr-set > .fb-arr-set-list { flex: 1 1 100%; min-width: 0; }
.fb-arr-set-list { padding-left: 0.5em; }
.fb-arr-list .fb-arr-set-list ul { padding: 2px 0 0; }
.fb-arr-label { display: flex; align-items: center; gap: 4px; flex: 1 1 auto; min-width: 0; }
.fb-arr-label .fb-chip { flex: 0 0 auto; }
.fb-arr-set-head { font-weight: 600; }
.fb-arr-name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fb-arr-break-line { flex-wrap: wrap; }
.fb-arr-words { flex-basis: 100%; min-width: 0; overflow-wrap: anywhere; color: var(--text-secondary); }
/* A page entered from another and left by Return (MT.SubPageFrame; the Arrange page first, owner 2026-10-28): its title,
   then its control panel - the .tq-controls row of a scoring page, Return first. */
.mt-subpage-title { margin: 0 0 6px; overflow-wrap: anywhere; }
.mt-subpage-controls { flex-wrap: wrap; margin-bottom: 8px; border-bottom: 1px solid var(--divider); }
.mt-subpage-controls .cc-btn { white-space: normal; }
.fb-arr-display-bar { display: inline-flex; align-items: center; gap: 8px; }
.fb-arr-page[inert] { cursor: progress; }
/* An item's details (MT.FormItemDetails; owner 2026-10-28): the shared popup (.app-dialog) placed over the list panel
   only, so the test beside it stays in view and scrolls. The list behind it is inert and holds still while it is open. */
.fb-arr-list-panel.fb-arr-has-details { overflow: hidden; }
.fb-arr-details.app-dialog {
    position: absolute;
    inset: 0;
    z-index: 2;
    width: auto;
    min-width: 0;
    max-width: none;
    margin: 0;
    overflow: auto;
    display: flex;
    flex-direction: column;
}
.fb-arr-details .app-dialog-title { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.fb-arr-details .app-dialog-body { flex: 1 0 auto; margin-bottom: 12px; }
.fb-arr-details-part h3 { margin: 12px 0 4px; }
.fb-arr-details-lines { margin: 0; padding-left: 1.2em; }
.fb-arr-details-lines li, .fb-arr-details-note { overflow-wrap: anywhere; }
.fb-preview-details { margin: 0 0 8px; }
.fb-preview-lines { margin: 0; padding-left: 1.2em; }
.fb-preview-lines li, .fb-preview-none { overflow-wrap: anywhere; }
.fb-preview-none { margin: 0; }
.fb-arr-details-none { margin: 0; color: var(--text-secondary); }
/* A block found from the list: marked for a moment with the focus ring (no motion of its own). */
.fb-arr-hit { outline: 3px solid var(--focus-ring); outline-offset: 4px; }
/* While an item's details are open the test panel is view-only (owner, 2026-10-28): its content is inert and takes
   no pointer, item frames included, so the wheel and the scroll bar still scroll the panel itself. */
.fb-arr-view-only > * { pointer-events: none; user-select: none; }
/* The anchor items page (MT.FormAnchorView; owner 2026-10-28): the pool on the left, the set on the right, Place below. */
.fb-anchor-columns { display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-start; }
.fb-anchor-pool-panel, .fb-anchor-set-panel { flex: 1 1 320px; min-width: 0; }
.fb-anchor-pool, .fb-anchor-items { list-style: none; margin: 0; padding: 0; max-height: 60vh; overflow: auto; }
.fb-anchor-pool-item, .fb-anchor-item { display: flex; align-items: center; gap: 6px; padding: 2px 0; min-width: 0; }
.fb-anchor-pool-name, .fb-anchor-item-name { min-width: 0; overflow-wrap: anywhere; }
.fb-anchor-bottom { margin-top: 8px; }
.fb-anchor-page[inert] { cursor: progress; }
.fb-arr-display-break { margin: 12px 0 6px; }
.fb-arr-block { margin: 8px 0 16px; }
/* The warning before Clear form or Generate first draft loses work (FormBuilderView._confirmLoss): a readable measure. */
.fb-lose-work .fb-lose-work-text { max-width: 36em; white-space: normal; }
/* Each block shows whole, sized to its content: the engine's panes (PaldroeStyles.css) take the viewport's height and
   scroll, which here put a scroll bar in every item. They flow instead, and the test panel is the one scroller. These
   panes are on the page, outside any item's root: StackedLayout.getDisplayDivs builds the .p-qti-item-container (and
   the .p-qti-stimulus of a block with a stimulus) in light DOM, and only each item inside it renders in a shadow root.
   That root gets the same rule, and the cap for a passage set's FILL-mode frame (FormArrangeView, BLOCK_FLOW_CSS). */
.fb-arr-display-area div.p-qti-stimulus,
.fb-arr-display-area div.p-qti-item-container,
.fb-arr-display-area .stimulus-layout-stacked .p-qti-stimulus,
.fb-arr-display-area .stimulus-layout-stacked .p-qti-item-container {
    height: auto;
    max-height: none;
    overflow: visible;
}
/* Stacked in a narrow window: the panels take their own heights and widths, and the page alone scrolls. */
@media (max-width: 899.98px) {
    .fb-arr-columns { flex-wrap: wrap; height: auto !important; }
    .fb-arr-columns > .mt-panel-resize { display: none; }
    .fb-arr-columns > .fb-panel { width: auto !important; flex: 1 1 100% !important; max-width: 100% !important; min-width: 0; }
}
.fb-arr-flag { display: flex; align-items: center; gap: 6px; }
.fb-arr-time { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.fb-arr-time input { width: 5em; }
.fb-legend {
    margin: 0 0 6px;
}
.fb-chart-title, .fb-subhead {
    margin-top: 6px;
}
.fb-svg { width: 100%; height: auto; display: block; }
.fb-grid { stroke: var(--divider); stroke-width: 1; }
.fb-axis { font-size: 9px; fill: var(--text-secondary); }
.fb-curve { fill: none; stroke-width: 2.2; }
.fb-curve-reference { stroke: var(--accent); }
.fb-curve-form { stroke: var(--status-success); }
/* A hover's curve (owner, 2026-10-18: it must be seen): dashed at full strength, over the others,
   with the area between it and the form's curve shaded. */
.fb-curve-hover { stroke: var(--status-warning); stroke-dasharray: 6 3; }
.fb-curve-band { stroke: none; }
.fb-band-with { fill: var(--status-success-tint); }
.fb-band-without { fill: var(--status-danger-tint); }
.fb-sw-hover { background: var(--status-warning); }
.fb-hover-target { background: var(--selected-bg); color: var(--selected-text); }
.fb-hover-readout { margin: 6px 0; }
/* The graphs stay in view beside the lists; stacked, the readout floats at the foot of the window. */
@media (min-width: 1200px) {
    .fb-graphs { position: sticky; top: 0; align-self: flex-start; max-height: 100vh; overflow-y: auto; }
}
@media (max-width: 1199.98px) {
    .fb-hover-readout { position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 20; }
}
.fb-curve-dashed { stroke-dasharray: 5 4; }
/* Replacements at an ability (owner 2026-10-29): the TCC's plot area is a slider over θ (click, or the arrow keys
   and Enter), and a dashed line marks the θ picked. */
.fb-theta-area { fill: var(--surface); fill-opacity: 0; cursor: crosshair; }
.fb-theta-area:focus { outline: none; }
.fb-theta-area:focus-visible { stroke: var(--focus-ring); stroke-width: 2; }
.fb-theta-hint { margin: 4px 0 6px; }
.fb-theta-marker { stroke: var(--text-primary); stroke-width: 1.5; stroke-dasharray: 2 2; pointer-events: none; }
.fb-legendrow {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 4px;
}
.fb-legend-item { display: inline-flex; align-items: center; gap: 4px; }
.fb-sw { display: inline-block; width: 14px; height: 3px; }
.fb-sw-reference { background: var(--accent); }
.fb-sw-form { background: var(--status-success); }
.fb-stats {
    display: grid;
    grid-template-columns: auto auto;
    gap: 2px 12px;
    margin: 8px 0 0;
}
.fb-stat-k { color: var(--text-secondary); }
.fb-stat-v { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; }
.fb-joint-risk { margin-bottom: 6px; }
.fb-risk-head { font-weight: 600; }
.fb-risk-impossible { color: var(--status-danger); }
.fb-risk-tight { color: var(--status-warning); }
.fb-risk-slack, .fb-risk-none { color: var(--status-success); }
.fb-scarce { margin: 4px 0 0 1.2em; padding: 0; font-size: 0.9em; }
.fb-tree {
    max-height: min(calc(100vh - 320px), 40em);
    overflow-y: auto;
    border: 1px solid var(--divider);
}
.fb-level {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    padding: 3px 6px;
    border-bottom: 1px solid var(--divider);
    cursor: pointer;
}
.fb-level:hover { background: var(--fill-hover); color: var(--text-primary); }
.fb-level:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
.fb-level-selected { background: var(--selected-bg); color: var(--selected-text); box-shadow: inset 3px 0 0 var(--selected-mark); }
/* The role tag's look is the shared tag (named in the tag rules). */
.fb-role { flex: 0 0 auto; }
.fb-level-label { flex: 1 1 10em; min-width: min(10em, 100%); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fb-risk-dot { color: var(--status-warning); }
.fb-risk-dot.fb-cannot { color: var(--status-danger); }
.fb-bounds { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* The need tag is the shared tag: under a warning, within a success, over a danger. */
.fb-need { margin-left: 6px; }
.fb-collections { flex-basis: 100%; display: flex; flex-wrap: wrap; gap: 6px; padding-left: 1.5em; font-size: 0.85em; }
.fb-filterline { margin-bottom: 6px; }
.fb-listbox {
    max-height: min(calc(100vh - 300px), 44em);
    overflow-y: auto;
}
.fb-grouphead {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.4rem;
    font-size: 0.8em;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--text-secondary);
    padding: 0.55rem 0.2rem 0.2rem;
}
.fb-itemrow {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    padding: 4px 2px;
    border-bottom: 1px solid var(--divider);
}
.fb-itemrow.fb-blocked { opacity: 0.7; }
.fb-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
/* The item's chips are the shared tag (named in the tag rules). */
.fb-sub { display: block; font-size: 0.85em; color: var(--text-secondary); }
.fb-would-exceed,
.fb-swap-misses { color: var(--status-danger); }
/* A transient notice under the message box (passing words, "All changes saved"): layout only; the text is the shared cc-status. */
.fb-notice { margin: 0 0 6px; }
/* A blueprint line keeps to one line (owner 2026-10-21) while it fits: the label ends in an ellipsis (.fb-level-label), the
   whole text is its tooltip, and a focused line shows it in full. A line too full for the panel (a stimulus set's passage and
   chooser) wraps them onto the next line, never squeezing its label out of view or the line past the panel. */
.fb-level:focus-visible .fb-level-label { white-space: normal; overflow: visible; }
.fb-level .fb-bounds { flex: 0 0 auto; }
.fb-level .fb-slot-fill { flex: 0 1 auto; min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fb-slot-pick { display: inline-flex; align-items: center; gap: 4px; flex: 0 1 auto; min-width: 0; max-width: 100%; }
.fb-slot-pick .fb-slot-select { min-width: 6em; max-width: 16em; }
.fb-set-actions { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 2px; flex: 0 1 auto; min-width: 0; max-width: 100%; }
/* The three panels' grips (MT.PanelResizer, .mt-panel-resize): only while the panels sit side by side. */
@media (max-width: 1199.98px) {
    .fb-columns > .mt-panel-resize { display: none; }
    /* Stacked, a remembered width never applies: the panels fill the row (the grip's inline styles yield). */
    .fb-columns > .fb-panel { width: auto !important; flex: 1 1 100% !important; max-width: 100% !important; }
}
.fb-notice .fb-notice-text { margin: 0; }
.fb-item-actions { display: flex; flex-wrap: wrap; gap: 4px; align-items: flex-start; }
.fb-section-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 10px 0 4px;
}
.fb-items { width: 100%; }
.fb-items th, .fb-items td { text-align: left; vertical-align: top; }
.fb-item-missing { color: var(--status-danger); }
/* Passages: the one worked within (region 3) and each passage's heading row in the form's list. Layout only. */
.fb-working-line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; margin-bottom: 6px; }
.fb-passage-actions { display: inline-flex; flex-wrap: wrap; gap: 4px; margin-left: 0.5rem; vertical-align: middle; }
.fb-passage-empty { margin-left: 0.5rem; }
/* The form in region 2: a level opens to the items whose content belongs there. Layout only; the remove icon is the shared tq_delete. */
.fb-holder-toggle { margin-right: 6px; }
.fb-level-items { padding-top: 2px; padding-bottom: 6px; }
.fb-placed { display: flex; flex-wrap: nowrap; align-items: center; gap: 6px; min-width: 0; }
.fb-placed .fb-item-link { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }
.fb-itemrow .fb-item-link { max-width: 100%; text-align: left; white-space: normal; overflow-wrap: anywhere; padding-left: 0; }
.fb-itemrow, .fb-scarce-pick { cursor: pointer; }
.fb-placed .fb-remove { flex: none; margin-left: auto; }
.fb-placed.fb-in-passage { margin-left: 1.5em; }
.fb-item-tools { margin-bottom: 0.5rem; }
.fb-replacing-line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; margin-bottom: 6px; }
.fb-item-calibration select { max-width: 14em; }
.fb-fixed-out { margin: 4px 0 0 1.2em; padding: 0; }
.fb-fixed-out-item { display: flex; gap: 8px; align-items: center; }
