﻿/* ================================================================
   Portal Design System Variables
   Site-wide custom properties for consistent theming across all pages.
   ================================================================ */
:root {
    /* Brand colors — must match PCE seed data in CreatePortalSubsidiaryTable.sql.
       These are the defaults before dynamic theme injection overrides them. */
    --pc-primary: #00337d;             /* brand deep blue — nav gradient, button hover, titles */
    --pc-primary-light: #19478a;       /* LightenColor(primary, 10%) — subtle gradient endpoint */
    --pc-accent: #0046ad;              /* brand royal blue — CTAs (Place Order/Save) + fills/borders/focus */
    --pc-accent-glow: rgba(0, 70, 173, 0.08);
    /* Accent "ink" — the accent used as TEXT/ICON foreground (menu-item icons,
       org-strip pill text / profile initials, selected nav-link text+icon,
       section-header links, cctx filter icon). A calm, brand-neutral slate
       (slate-500, same as the inactive nav text) — deliberately NOT re-injected
       by ThemeCssGenerator, so link/affordance ink stays readable on every brand
       instead of following a harsh accent (e.g. Street Fleet's red). The accent
       proper is reserved for the primary CTA button fills, borders and focus rings. */
    --pc-accent-ink: #64748b;
    /* Card-header color — the Place Order / Continuation / Dedicated Service
       folder-tab + S-curve + top strip. This default matches the PCE accent;
       ThemeCssGenerator now re-injects --pc-card-header = the subsidiary accent
       color so each brand's card headers follow its theme (e.g. Street Fleet
       red). Change the per-subsidiary value via ThemeAccentColor, not here. */
    --pc-card-header: #0046ad;
    /* Page-header box height (32px content row + 0.6rem padding + 1px border).
       In the Option C two-tier shell this is the WHITE COMMAND ROW height. */
    --pc-header-h: calc(32px + 0.6rem + 1px);
    /* The global single-tier header ("org strip") height — brand + title + pills
       + account on one row. Also the total chrome height that offsets the
       sidebar + content (no second tier). */
    --pc-orgstrip-h: 52px;
    --pc-chrome-h: var(--pc-orgstrip-h);
    --pc-success: #10b981;
    --pc-success-light: #d1fae5;
    --pc-warning: #f59e0b;
    --pc-warning-light: #fef3c7;
    --pc-surface: #f8fafc;
    --pc-surface-elevated: #ffffff;
    --pc-border: #e2e8f0;
    --pc-border-light: #f1f5f9;
    --pc-text: #1e293b;
    --pc-text-muted: #64748b;
    --pc-radius: 12px;
    --pc-radius-sm: 8px;
}

html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

a, .btn-link {
    color: #006bb7;
}

/* Primary buttons (Save / Submit / etc.) use the brand accent at rest and
   darken to the deep brand blue on hover — matching the Place Order button
   (.db-qa-primary) so every CTA is the same brand blue. */
.btn-primary {
    color: #fff;
    background-color: var(--pc-accent, #0046ad);
    border-color: var(--pc-accent, #0046ad);
}

.btn-primary:hover:not(:disabled),
.btn-primary:focus:not(:disabled),
.btn-primary:active:not(:disabled) {
    color: #fff;
    background-color: var(--pc-primary, #00337d);
    border-color: var(--pc-primary, #00337d);
}

/* Disabled primary buttons: keep the themed accent (faded via Bootstrap's opacity)
   instead of falling back to Bootstrap's default blue, which out-specifies our base
   .btn-primary and caused the "blue when disabled, red when enabled" flip on the
   continuation "Add Shipment" button. Buttons with a more-specific override
   (.cont-advance-btn slate, .up-save fixed blue) still win over this. */
.btn-primary:disabled,
.btn-primary.disabled {
    color: #fff;
    background-color: var(--pc-accent, #0046ad);
    border-color: var(--pc-accent, #0046ad);
}

/* Continuation stepper advance button (Next: Stop N / Continue) — a neutral
   slate fill instead of the brand accent, so the stepper's forward action reads
   calm on red-accent brands. Scoped to this modifier so other .btn-primary CTAs
   (Save, Submit, Add Shipment) keep the themed accent. */
.btn-primary.cont-advance-btn {
    background-color: #64748b;
    border-color: #64748b;
}

.btn-primary.cont-advance-btn:hover:not(:disabled),
.btn-primary.cont-advance-btn:focus:not(:disabled),
.btn-primary.cont-advance-btn:active:not(:disabled) {
    background-color: #475569;
    border-color: #475569;
}

/* Continuation "Add Shipment" (shipment editor submit) — slate when enabled,
   LIGHTER slate when disabled (its own :disabled beats the global themed-accent
   :disabled rule above via the extra class in the selector). */
.btn-primary.cont-add-shipment-btn {
    background-color: #64748b;
    border-color: #64748b;
}

.btn-primary.cont-add-shipment-btn:hover:not(:disabled),
.btn-primary.cont-add-shipment-btn:focus:not(:disabled),
.btn-primary.cont-add-shipment-btn:active:not(:disabled) {
    background-color: #475569;
    border-color: #475569;
}

.btn-primary.cont-add-shipment-btn:disabled,
.btn-primary.cont-add-shipment-btn.disabled {
    background-color: #94a3b8;
    border-color: #94a3b8;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.invalid {
    outline: 1px solid #e50000;
}

/* Disable validation styling on specific fields */
.no-validation-style.valid,
.no-validation-style.modified,
.no-validation-style.valid.modified,
.no-validation-style.invalid {
    outline: none;
    border-color: #dee2e6;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* ==============================================
   Form Validation Styles - Customer Portal
   ============================================== */

/* Form Groups */
.form-group {
    margin-bottom: .5rem;
}

.form-group > label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: 500;
    color: #2d3748;
    font-size: 0.9rem;
}

.form-group-inline {
    display: flex;
    align-items: center;
    margin-bottom: 1rem;
}

/* Form Controls - Compact floating labels */
/* Reduce Bootstrap's default vertical padding for a more compact look */
/* Ensure input value, placeholder, and label all use same font size for consistency */

.form-floating > .form-control,
.form-floating > .form-select,
.form-floating > .form-control:focus,
.form-floating > .form-select:focus {
    padding: 0.625rem 0.75rem !important;
    height: auto;
    min-height: calc(2.5rem + 2px);
    font-size: 0.9rem;
}

.form-floating > label {
    padding: 0.625rem 0.75rem;
    color: rgba(0, 0, 0, 0.65);
    font-size: 0.9rem;
}

.form-floating > .form-control::placeholder {
    font-size: 0.9rem;
}

/* iOS Safari auto-zooms any text input whose font-size is below 16px,
   and the zoom does not reliably reset on blur — leaves the user stuck
   at 1.5x scale until they pinch back out. The 0.9rem (14.4px) compact
   sizing above triggers that on every focused input. Forcing 16px on
   touch devices suppresses the auto-zoom entirely (iOS's threshold check).
   Desktop floating-label compact sizing preserved.

   NOTE: viewport-width queries (max-width: 768px) DON'T cover all
   iOS devices — iPad portrait is 768/834px wide, iPhones in landscape
   are 852-926px wide. All are touch devices and all trigger the
   auto-zoom regardless of viewport width. The `(hover: none) and
   (pointer: coarse)` query targets touch input as the actual signal
   the OS uses, so this fix lands on every device that would have
   triggered the zoom. */
@media (hover: none) and (pointer: coarse) {
    .form-control,
    .form-select,
    .form-floating > .form-control,
    .form-floating > .form-select,
    .form-floating > .form-control::placeholder,
    input[type="text"],
    input[type="email"],
    input[type="tel"],
    input[type="password"],
    input[type="search"],
    input[type="number"],
    input[type="date"],
    input[type="time"],
    input[type="datetime-local"],
    input[type="url"],
    textarea,
    select {
        font-size: 16px;
    }
}

/* Floated label state - adjust position for compact padding */
.form-floating > .form-control:focus ~ label,
.form-floating > .form-control:not(:placeholder-shown) ~ label,
.form-floating > .form-select ~ label {
    transform: scale(0.85) translateY(-0.6rem) translateX(0.15rem);
    background: #fff;
    padding: 0 0.15rem 0 0.25rem;
    height: auto;
}

.form-control:focus {
    outline: none;
    border-color: #3182ce;
    box-shadow: 0 0 0 3px rgba(49, 130, 206, 0.1);
}

.form-control.invalid,
.form-control.modified.invalid {
    border-color: #fc8181;
    outline: none;
}

.form-control.valid.modified {
    border-color: #48bb78;
    outline: none;
}

/* ==============================================================
   .pc-fieldset — static "fieldset legend" label
   --------------------------------------------------------------
   The Bootstrap floating-label LOOK (label parked on the top
   border, the border line cutting a gap through the text like a
   classic <fieldset>/<legend>) but WITHOUT the animation — the
   label is always up, identical whether the field is empty or
   filled. Distinct from .field-static-label, which sits ABOVE the
   field; this one sits ON the border.

   The border stays on the input (its normal .form-control border),
   so focus (#3182ce) and validation (.invalid/.valid) styling all
   come for free from the rules above — these fields focus exactly
   like every other field in the app. This block only adds the
   positioned, masked label.

   Opt a field in with this markup (no placeholder hack needed,
   unlike .form-floating):

       <div class="pc-fieldset">
           <input class="form-control" @bind="model.Company" />
           <label>Company name <span class="pc-fieldset-req">*</span></label>
       </div>

   Works the same wrapping a <select>, <textarea>, or InputText.
   ============================================================== */
.pc-fieldset {
    position: relative;   /* positioning context for the absolute label */
}

.pc-fieldset > label {
    position: absolute;
    top: 0;
    left: 0.55rem;                 /* indent from the corner */
    transform: translateY(-50%);   /* center the label box on the top border line */
    padding: 0 0.35rem;            /* breathing room L/R of the text inside the gap */
    margin: 0;
    /* The mask that cuts the border into a gap. Defaults to white; on a tinted
       panel set --pc-fieldset-bg to that panel's color so the gap doesn't smear:
       <div class="pc-fieldset" style="--pc-fieldset-bg: var(--pc-surface);"> */
    background: var(--pc-fieldset-bg, #fff);
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.1;
    color: #64748b;               /* resting: slate (--pc-text-muted) */
    pointer-events: none;         /* clicks fall through to the input */
    transition: color 0.12s ease;
    z-index: 2;
}

/* Focus: recolor the legend to match the input's focus border (#3182ce).
   :focus-within reacts to the inner input focusing — no JS needed. */
.pc-fieldset:focus-within > label {
    color: #3182ce;
}

/* Invalid: match the input's invalid border (#fc8181). :has() lets the wrapper
   react to Blazor's .invalid class landing on the inner .form-control. */
.pc-fieldset:has(> .form-control.invalid) > label {
    color: #fc8181;
}

/* Required asterisk inside the legend. */
.pc-fieldset-req {
    color: #fc8181;
    font-weight: 700;
    margin-left: 0.1rem;
}

/* Checkboxes */
.form-checkbox {
    width: 1rem;
    height: 1rem;
    margin-right: 0.5rem;
    cursor: pointer;
}

.checkbox-label {
    font-size: 0.875rem;
    color: #4a5568;
    cursor: pointer;
    user-select: none;
}

/* Validation Messages */
.validation-message {
    color: #c53030;
    font-size: 0.875rem;
    margin-top: 0.25rem;
    display: block;
}

/* Field Validation Summary (for forms with multiple errors) */
.validation-errors {
    color: #c53030;
    font-size: 0.875rem;
    margin-bottom: 1rem;
    padding: 0.75rem;
    background-color: #fed7d7;
    border: 1px solid #fc8181;
    border-radius: 4px;
}

.validation-errors ul {
    margin: 0;
    padding-left: 1.25rem;
}

/* Alerts */
.alert {
    padding: 0.75rem 1rem;
    border-radius: 4px;
    margin-bottom: 1rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.alert-icon {
    font-size: 1.1rem;
}

.alert-success {
    background-color: #c6f6d5;
    color: #276749;
    border: 1px solid #9ae6b4;
}

.alert-danger {
    background-color: #fed7d7;
    color: #c53030;
    border: 1px solid #fc8181;
}

.alert-warning {
    background-color: #fefcbf;
    color: #975a16;
    border: 1px solid #f6e05e;
}

.alert-info {
    background-color: #bee3f8;
    color: #3182ce;
    border: 1px solid #63b3ed;
}

/* ==============================================
   Card Component Styles (cp-card)
   Uses 'cp-card' prefix to avoid conflicts with Bootstrap's .card class
   ============================================== */

.cp-card {
    background: white;
    border: 1px solid rgba(0, 0, 0, 0.125);
    border-radius: 0.375rem;
    padding: 1rem;
}

.cp-card:hover {
    /* No hover effect by default - matches Bootstrap */
}

.cp-card-header {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.5rem;
}

.cp-card-icon {
    font-size: 1.25rem;
    color: inherit;
}

.cp-card-title {
    margin: 0;
    color: var(--pc-card-header, var(--pc-primary));
    font-size: 1rem;
    flex: 1;
}

.cp-card-body {
    color: #4a5568;
    font-size: 0.9rem;
    line-height: 1.5;
}

.cp-card-footer {
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid rgba(0, 0, 0, 0.125);
}

.cp-card-link {
    display: inline-block;
    color: #3182ce;
    text-decoration: none;
    font-weight: 500;
    font-size: 0.9rem;
}

.cp-card-link:hover {
    text-decoration: underline;
}

/* Card variants */
.cp-card-flat {
    border-color: #e2e8f0;
}

.cp-card-flat:hover {
    border-color: #cbd5e0;
}

.cp-card-compact {
    padding: 0.75rem;
}

.cp-card-compact .cp-card-header {
    margin-bottom: 0.5rem;
}

.cp-card-compact .cp-card-title {
    font-size: 0.95rem;
}

/* Card icon rotations for pickup/delivery */
.pickup-card .cp-card-icon i {
    transform: rotate(-90deg);
}

.delivery-card .cp-card-icon i {
    transform: rotate(90deg);
}

/* ==============================================
   Editable Combobox Styles
   Select from list OR type custom value
   ============================================== */

.editable-combobox {
    position: relative;
    width: 100%;
}

.editable-combobox-wrapper {
    position: relative;
}

.editable-combobox-wrapper.form-floating {
    width: 100%;
}

.editable-combobox-wrapper input {
    padding-right: 2.5rem; /* Space for dropdown toggle */
}

/* Only adjust padding-right for toggle button - let Bootstrap handle label positioning */
.editable-combobox-wrapper.form-floating > label {
    padding-right: 2.5rem;
}

/* Reset padding when label is floated */
.editable-combobox-wrapper.form-floating > .form-control:focus ~ label,
.editable-combobox-wrapper.form-floating > .form-control:not(:placeholder-shown) ~ label {
    padding-right: 0.15rem;
}

.editable-combobox-toggle {
    position: absolute;
    right: 0.75rem;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: #718096;
    cursor: pointer;
    padding: 0.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 5;
}

.editable-combobox-toggle:hover {
    color: #4a5568;
}

.editable-combobox-toggle i {
    transition: transform 0.2s ease;
}

.editable-combobox-toggle i.rotated {
    transform: rotate(180deg);
}

.editable-combobox-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: white;
    border: 1px solid #e2e8f0;
    border-top: none;
    border-radius: 0 0 0.375rem 0.375rem;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    max-height: 200px;
    overflow-y: auto;
    z-index: 1000;
}

.editable-combobox.open .editable-combobox-wrapper input {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    border-color: #3182ce;
}

.editable-combobox-option {
    padding: 0.5rem 0.75rem;
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.editable-combobox-option:hover,
.editable-combobox-option.selected {
    background-color: #edf2f7;
}

.editable-combobox-option:last-child {
    border-radius: 0 0 0.375rem 0.375rem;
}

/* Optional sticky footer (EditableCombobox DropdownFooter) — pins to the bottom
   of the scrolling option list so a modifier control stays in view. */
.editable-combobox-footer {
    position: sticky;
    bottom: 0;
    background: #fff;
    border-top: 1px solid #e2e8f0;
    border-radius: 0 0 0.375rem 0.375rem;
}

/* Style for the option matching the current input value (not keyboard-selected) */
.editable-combobox-option.current-value {
    background-color: #f8f9fa;
    font-weight: 500;
}

/* Checkmark icon indicating the current value */
.editable-combobox-option .current-check {
    float: right;
    color: #198754;
    font-size: 0.875rem;
}

/* Validation error for strict mode combobox */
.editable-combobox .validation-error {
    color: #dc3545;
    font-size: 0.875rem;
    margin-top: 0.25rem;
}

/* Hide Bootstrap's validation icon (red circle/X) but keep the red border */
.editable-combobox .form-control.is-invalid {
    background-image: none;
    border-color: #dc3545;
}

/* ==============================================
   Field History Input Styles
   Autocomplete input with MRU/popularity-ranked suggestions
   Used for Contact Name, Phone, Instructions on Place Order
   ============================================== */

.field-history-input {
    position: relative;
    width: 100%;
    /* The static label is now a legend (see .field-static-label) that overhangs
       this field's TOP edge by ~half its height. The location-card unit gaps
       (0.75rem, guarded by .location-fields flow-root) already clear that
       overhang, so no extra top margin is added here — keeping the tuned rhythm. */
}

.field-history-wrapper {
    position: relative;
}

.field-history-wrapper.form-floating {
    width: 100%;
}

/* Space for dropdown toggle - let Bootstrap handle label positioning */
.field-history-wrapper input,
.field-history-wrapper textarea {
    padding-right: 2.5rem !important;
}

.field-history-wrapper.form-floating > label {
    padding-right: 2.5rem;
}

/* Reset padding when label is floated */
.field-history-wrapper.form-floating > .form-control:focus ~ label,
.field-history-wrapper.form-floating > .form-control:not(:placeholder-shown) ~ label {
    padding-right: 0.15rem;
}

/* Auto-resize textarea - allow JS to control height, hide scrollbar.
   Applies whether or not the wrapper is form-floating (ContactInput and the
   Instructions field now use a static label above the field, not a floating one). */
.field-history-wrapper.form-floating > textarea,
.field-history-wrapper > textarea {
    overflow: hidden;
    resize: none;
}

/* Static field label (ContactInput / FieldHistoryInput). Sits above the input so
   the default star renders reliably in every state — unlike a Bootstrap floating
   label, which moves out of the way when the field is empty. */
.field-static-label {
    /* Legend riding the input's TOP BORDER — the .pc-fieldset "fieldset legend"
       treatment (see the .pc-fieldset block earlier). Previously this label sat
       ABOVE the field; now it's parked on the border, the line cutting a gap
       through the text like a classic <fieldset>/<legend>. Still always-visible
       (unlike a floating label), so the trailing default-star stays reliable.

       Flex row keeps the trailing default-star centered against the text line box
       (not the x-height midline inline flow would use). */
    display: inline-flex;
    align-items: center;
    position: absolute;
    top: 0;
    left: 0.55rem;                 /* indent from the corner */
    transform: translateY(-50%);   /* center the label box on the top border line */
    z-index: 3;
    margin: 0;
    padding: 0 0.35rem;            /* breathing room L/R of the text inside the gap */
    /* Mask that cuts the border into a gap. Defaults to white; on a tinted card
       set --pc-fieldset-bg on .field-history-input to that card's color. */
    background: var(--pc-fieldset-bg, #fff);
    /* Match the address combobox's floated label so every label on a location
       card reads the same: it renders at 0.9rem × scale(0.85) ≈ 0.765rem, weight
       400, color rgba(0,0,0,0.65). We set that rendered size directly (no scale). */
    font-size: 0.765rem;
    font-weight: 400;
    color: rgba(0, 0, 0, 0.65);
    line-height: 1.1;
    transition: color 0.12s ease;
}

/* Legend recolors WITH the input's own focus / invalid border, so it reads as
   one control. :focus-within reacts to the inner input focusing — no JS. */
.field-history-input:focus-within .field-static-label {
    color: #3182ce;
}

.field-history-input.is-invalid .field-static-label {
    color: #dc3545;
}

/* With the label now a legend on the border (not a tall floating label), the
   input uses the app's compact form sizing instead of Bootstrap's roomier default
   .form-control. Vertical padding only — the !important right-padding for the
   chevron is set elsewhere and must stay. */
.field-history-wrapper .form-control {
    padding-top: 0.3rem;
    padding-bottom: 0.3rem;
    min-height: 0;
    line-height: 1.4;
}

/* Single-line fields (Contact / Phone) → 37px: the "split the diff" height between
   the old compact 32px and the 42px combobox/reference fields. An input centers its
   value vertically, so min-height alone (padding unchanged) lands it centered at
   37px. The Instructions TEXTAREA is deliberately excluded (rule below keeps its
   min-height: 0 so it auto-resizes and stays multi-line/taller). */
.field-history-wrapper input.form-control {
    min-height: 37px;
}

.field-history-wrapper textarea.form-control {
    min-height: 0;
}

/* Compact font on non-touch only. On touch, the global rule above forces 16px to
   suppress iOS's <16px auto-zoom; scoping this to a fine pointer keeps that intact
   while matching the desktop form's 0.9rem compact size. */
@media (hover: hover) and (pointer: fine) {
    .field-history-wrapper .form-control {
        font-size: 0.9rem;
    }
}

.field-history-toggle {
    position: absolute;
    right: 0.75rem;
    top: 50%;
    transform: translateY(-50%);
    background: transparent;
    border: none;
    color: #718096;
    cursor: pointer;
    padding: 0.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 4;
}

.field-history-toggle:hover {
    color: #3182ce;
}

.field-history-toggle i {
    transition: transform 0.2s ease;
}

.field-history-toggle i.rotated {
    transform: rotate(180deg);
}

/* "Set as default" star (Option D) — a single star riding on the floating label
   carries BOTH state and action. The floating label is click-through
   (pointer-events: none in Bootstrap), so any interactive star must re-enable
   pointer events. Both variants match the gold marker used in the history
   dropdown. */

/* Passive "is default" marker (filled gold). */
/* Filled star = this value is the saved default. Now a clickable button that
   toggles the default off (mirrors the property-tag "Location Options" star and
   the set-default button's hit-target padding). Fades to grey on hover to signal
   the clear action. */
.field-label-default-star {
    pointer-events: auto;
    display: inline-flex;
    align-items: center;
    align-self: stretch;
    background: none;
    border: none;
    padding: 0 0.25rem;
    margin-left: 0.03rem;
    line-height: 1;
    font-size: 0.75em;
    color: #f6ad55;
    cursor: pointer;
}

.field-label-default-star:hover {
    color: #a0aec0;
}

/* Clickable "set as default" action (hollow → gold on hover). Horizontal-only
   padding gives a wider hit target; align-self: stretch makes the button fill the
   label's height (a taller tap area) WITHOUT adding height — vertical padding here
   overflowed below the label line and widened the gap to the field. */
.field-label-set-default {
    pointer-events: auto;
    display: inline-flex;
    align-items: center;
    align-self: stretch;
    background: none;
    border: none;
    padding: 0 0.25rem;
    margin-left: 0.15rem;
    line-height: 1;
    font-size: 0.75em;
    color: #a0aec0;
    cursor: pointer;
}

.field-label-set-default:hover {
    color: #f6ad55;
}

.field-label-set-default .spinner-border {
    width: 0.7rem;
    height: 0.7rem;
    border-width: 0.12em;
    color: #f6ad55;
}

.field-history-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: white;
    border: 1px solid #e2e8f0;
    border-radius: 0.375rem;
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
    z-index: 1000;
    max-height: 200px;
    overflow-y: auto;
    margin-top: 2px;
}

.field-history-input.open .field-history-wrapper input,
.field-history-input.open .field-history-wrapper textarea {
    /* Match the address combobox's open/focus treatment: just recolor the border
       and let the standard subtle .form-control:focus ring (3px / 0.1) show. The
       previous 0.2rem / 0.25 glow read as too bold and thick next to the combobox. */
    border-color: #3182ce;
}

/* Invalid state - red border and remove Bootstrap's icon */
.field-history-input.is-invalid .form-control.is-invalid {
    border-color: #dc3545;
    background-image: none; /* Remove Bootstrap's red exclamation icon */
    animation: contact-pulse 2s ease-in-out infinite;
}

.field-history-input .validation-message {
    color: #dc3545;
    font-size: 0.8rem;
    margin-top: 0.25rem;
}

.field-history-input .validation-message a {
    color: #0d6efd;
    text-decoration: underline;
    cursor: pointer;
}

.field-history-input .validation-message a:hover {
    color: #0a58ca;
}

.field-history-option {
    padding: 0.5rem 0.75rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.875rem;
}

.field-history-option:hover,
.field-history-option.selected {
    background-color: #edf2f7;
}

.field-history-option:last-child {
    border-radius: 0 0 0.375rem 0.375rem;
}

/* Star icon for saved default value */
.field-history-option .default-indicator {
    color: #f6ad55; /* Orange star */
    font-size: 0.75rem;
    flex-shrink: 0;
}

/* Value text */
.field-history-option .suggestion-value {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Use count indicator (subtle) */
.field-history-option .use-count {
    color: #a0aec0;
    font-size: 0.75rem;
    flex-shrink: 0;
}

/* ==============================================
   ContactInput Styles
   Wrapper for paired name+phone with shared MRU dropdown (ADR-015).
   Individual inputs use .field-history-input styling unchanged.
   ============================================== */

/* Outer wrapper — position anchor for the shared dropdown */
.contact-input-pair {
    position: relative;
    margin-top:.25rem;
}

/* ============================================================================
   LOCATION-CARD FIELD GROUP — single source of truth for formatting.

   The contact pair, instructions, and Location Options are three separate reused
   controls (ContactInput / FieldHistoryInput / PropertyTagSelector) composed as
   siblings on Place Order (pickup + delivery), Continuation stop cards, and
   Dedicated Service. Each site wraps them in <div class="location-fields">, and
   ALL formatting for the group lives here so it can't drift page-to-page.

   font-size is pinned (rather than inherited) so a future change to any one
   page's card cascade can't resize these fields on that page alone.
   ============================================================================ */
.location-fields {
    font-size: 0.9rem;
    /* flow-root makes this a block-formatting context so the contact pair's
       top margin can't collapse into the address card's bottom margin. Place
       Order's card body is flex (which already blocks that collapse, giving a
       12px gap); this makes the block-flow Continuation and Dedicated Service
       cards behave identically instead of collapsing to 8px. */
    display: flow-root;
}

/* Instructions field that follows the contact pair. 0.75rem (12px) matches the
   address-card → contact-fields gap, so the three stacked units on a location
   card are evenly spaced. The contact section has no bottom margin/padding, so
   this margin is the whole gap. */
.location-instructions {
    margin-top: .75rem;
}

/* Location Options (property tags) that follow the instructions. Same 0.75rem
   (12px) gap as the other units, so address → contact → instructions → options
   are evenly spaced. Both wrapper class names are covered so the value lives here
   once (Place Order uses .property-tags-footer; Continuation .cont-stop-property-
   tags). Place Order's freight card keeps its own .property-tags-footer padding
   in PlaceOrder.razor.css — that footer isn't inside .location-fields. */
.location-fields .property-tags-footer,
.location-fields .cont-stop-property-tags {
    margin-top: .75rem;
}

/* ── Per-leg reference override (Task #3445) ─────────────────────────────
   Delivery-stop disclosure for overriding the run-level Reference / Ref 2 /
   Billing Group. Kept visually light so the collapsed default reads as an
   optional nudge, not a required field. */
.cont-stop-references {
    margin-top: .85rem;
}

/* Collapsed affordance — a quiet link-style button, not a primary control. */
.cont-stop-ref-toggle {
    background: none;
    border: none;
    padding: 0;
    font-size: .85rem;
    color: var(--bs-primary, #0d6efd);
    cursor: pointer;
}

.cont-stop-ref-toggle:hover {
    text-decoration: underline;
}

/* Expanded editor sits in a tinted inset so it reads as "extra detail for
   this stop", visually subordinate to the address/contact block above it. */
.cont-stop-ref-panel {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: .5rem;
    background: var(--bs-tertiary-bg, #f8f9fa);
    padding: .75rem;
}

.cont-stop-ref-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    margin-bottom: .5rem;
}

.cont-stop-ref-panel-title {
    font-size: .85rem;
    font-weight: 600;
}

.cont-stop-ref-reset {
    background: none;
    border: none;
    padding: 0;
    font-size: .8rem;
    color: var(--bs-secondary-color, #6c757d);
    cursor: pointer;
}

.cont-stop-ref-reset:hover {
    text-decoration: underline;
}

.cont-stop-ref-hint {
    font-size: .78rem;
    color: var(--bs-secondary-color, #6c757d);
    margin-bottom: .6rem;
}

/* Shared dropdown sits below the form-row, spanning full width */
.contact-shared-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 1000;
}

/* Em-dash separator between name and phone in dropdown suggestions */
.contact-separator {
    color: #a0aec0;
    margin: 0 0.35rem;
}

/* "Use current order remarks" hint shown below instructions when duplicating an order */
.from-order-remarks-hint {
    margin-top: 0.15rem;
    text-align: right;
}

.from-order-remarks-refresh {
    background: none;
    border: none;
    color: #6c757d;
    font-size: 0.75rem;
    cursor: pointer;
    padding: 0.1rem 0.25rem;
    transition: color 0.15s;
}

.from-order-remarks-refresh:hover {
    color: #0d6efd;
}

.from-order-remarks-refresh i {
    margin-right: 0.25rem;
}

/* ==============================================
   Keyword Confirmation Banner (Task #2811)
   Appears below remarks when hazmat/medical/helper
   keywords are detected — prompts user to confirm.
   ============================================== */

.keyword-confirm-banner {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.35rem;
    padding: 0.45rem 0.65rem;
    background: #fff8e1;
    border: 1px solid #ffe082;
    border-radius: 6px;
    font-size: 0.8rem;
    color: #5d4037;
    animation: keyword-banner-in 0.2s ease;
}

@keyframes keyword-banner-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}

.keyword-confirm-banner > i {
    font-size: 1rem;
    color: #f57f17;
    flex-shrink: 0;
}

.keyword-confirm-banner > span {
    flex: 1;
    line-height: 1.3;
}

.keyword-confirm-actions {
    display: flex;
    gap: 0.35rem;
    flex-shrink: 0;
}

.keyword-confirm-actions .btn-sm {
    padding: 0.15rem 0.5rem;
    font-size: 0.75rem;
}

/* ==============================================
   Styled Dropdown Styles
   Select-only dropdown matching EditableCombobox look
   ============================================== */

.styled-dropdown {
    position: relative;
    width: 100%;
}

.styled-dropdown-wrapper {
    position: relative;
    cursor: pointer;
}

.styled-dropdown-wrapper.form-floating {
    width: 100%;
}

.styled-dropdown-display {
    padding-right: 2.5rem !important;
    cursor: pointer;
    user-select: none;
    min-height: calc(3.5rem + 2px);
    display: flex;
    align-items: center;
    padding-top: 1.625rem !important;
    padding-bottom: 0.625rem !important;
}

.styled-dropdown-display:focus {
    border-color: #3182ce;
    box-shadow: 0 0 0 0.2rem rgba(49, 130, 206, 0.25);
    outline: none;
}

.styled-dropdown-wrapper.form-floating > label {
    padding-right: 2.5rem;
    pointer-events: none;
}

/* Float label when there's a value */
.styled-dropdown-display:not(:empty) ~ label,
.styled-dropdown-display:focus ~ label {
    opacity: 0.65;
    transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
    padding-right: 0.15rem;
}

.styled-dropdown-toggle {
    position: absolute;
    right: 0.75rem;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: #718096;
    cursor: pointer;
    padding: 0.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 5;
    pointer-events: none;
}

.styled-dropdown-toggle i {
    transition: transform 0.2s ease;
}

.styled-dropdown-toggle i.rotated {
    transform: rotate(180deg);
}

.styled-dropdown-menu {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: white;
    border: 1px solid #e2e8f0;
    border-top: none;
    border-radius: 0 0 0.375rem 0.375rem;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    max-height: 250px;
    overflow-y: auto;
    z-index: 1000;
}

.styled-dropdown.open .styled-dropdown-display {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    border-color: #3182ce;
}

.styled-dropdown-option {
    padding: 0.5rem 0.75rem;
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.styled-dropdown-option:hover {
    background-color: #edf2f7;
}

.styled-dropdown-option.selected {
    background-color: #e2e8f0;
    font-weight: 500;
}

.styled-dropdown-option:last-child {
    border-radius: 0 0 0.375rem 0.375rem;
}

/* ==============================================
   Address Combobox Styles
   Combined address book + Google Places search
   ============================================== */

.address-combobox {
    position: relative;
    width: 100%;
    max-width: 100%; /* Prevent expansion beyond parent */
    min-width: 0; /* Allow shrinking in flex context */
    overflow: visible; /* Must be visible to show dropdown */
}

.combobox-input-wrapper {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
    max-width: 100%; /* Prevent expansion */
    min-width: 0; /* Allow shrinking in flex context */
    overflow: visible; /* Allow floating label to show above input */
}

/* Override Bootstrap's form-floating for combobox to accommodate action buttons */
.combobox-input-wrapper.form-floating {
    flex: 1;
    min-width: 0; /* Allow shrinking in flex context */
}

/* The address combobox uses the SAME static legend as the location-card fields
   (.field-static-label), NOT an animating Bootstrap floating label. The label is
   parked on the border in every state — empty, focused, or filled — so it reads
   identically to Contact/Instructions/Location Options. Styling mirrors
   .field-static-label exactly (0.765rem / 400 / rgba(0,0,0,0.65), left 0.55rem,
   masked gap). max-width keeps a long label from running under the action buttons;
   it truncates with an ellipsis instead. */
.combobox-input-wrapper.form-floating > label {
    position: absolute;
    top: 0;
    left: 0.55rem;
    height: auto;
    transform: translateY(-50%);   /* center on the top border line */
    padding: 0 0.35rem;
    background: var(--pc-fieldset-bg, #fff);
    font-size: 0.765rem;
    font-weight: 400;
    color: rgba(0, 0, 0, 0.65);
    line-height: 1.1;
    max-width: calc(100% - 1.1rem);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    z-index: 3;
}

/* Neutralize Bootstrap's float animation: on focus / when filled, keep the label
   fixed in the legend position (no scale/slide). Without this, the global
   .form-floating floated rule would animate it on focus/fill. */
.combobox-input-wrapper.form-floating > .form-control:focus ~ label,
.combobox-input-wrapper.form-floating > .form-control:not(:placeholder-shown) ~ label {
    transform: translateY(-50%);
}

.combobox-input-wrapper input,
.combobox-input-wrapper.form-floating > .form-control {
    padding-right: 5.5rem !important; /* Space for clear X and address book icons */
    text-overflow: ellipsis; /* Truncate long addresses with ... */
    overflow: hidden;
    white-space: nowrap;
}

/* Address combobox → 37px, the "split the diff" height shared with Contact/Phone
   and the Reference fields (was Bootstrap's 42px form-floating default). Overrides
   the global .form-floating padding/min-height !important; the input centers its
   value vertically at this height. Horizontal padding-right (buttons) is untouched. */
.combobox-input-wrapper.form-floating > .form-control {
    min-height: 37px !important;
    padding-top: 0.375rem !important;
    padding-bottom: 0.375rem !important;
}

/* The address combobox now shows a real in-field hint ("Type to search…") instead
   of the old empty floating-label spacer. The app's form-floating placeholder rule
   right-aligns placeholders (a holdover from when the floating label was the resting
   placeholder); force a left-aligned, muted, always-visible hint here. */
.combobox-input-wrapper.form-floating > .form-control::placeholder {
    text-align: start;
    color: var(--bs-secondary-color);
    opacity: 1;
}

/* Order Information reference fields (Reference / Reference 2 / Billing Group) →
   the same 37px. Scoped to .ord-ref-fields so OTHER .editable-combobox uses
   (freight, continuation, order list, ready-time) keep their 42px default. */
.ord-ref-fields .editable-combobox-wrapper.form-floating > .form-control {
    min-height: 37px !important;
    padding-top: 0.375rem !important;
    padding-bottom: 0.375rem !important;
}

/* Re-center the UNFLOATED (empty) floating label in the shrunk field. The input
   auto-centers its value; without this the label reads ~2-3px low because its
   block padding-top (sized for the old 42px field) leaves more space above than
   below. Flex-centering aligns it with the value. The FLOATED state sets
   height:auto, so it's unaffected and the label still parks on the top border. */
.ord-ref-fields .editable-combobox-wrapper.form-floating > label {
    display: flex;
    align-items: center;
}

/* Container for action buttons inside the input */
.combobox-actions {
    position: absolute;
    right: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.25rem;
    z-index: 5; /* Above floating label */
}

.combobox-action-btn {
    background: none;
    border: none;
    color: #718096;
    cursor: pointer;
    padding: 0.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.combobox-action-btn:hover {
    background-color: #e2e8f0;
    color: #4a5568;
}

/* Dropdown toggle chevron button */
.dropdown-toggle-btn {
    color: #64748b;
}

.dropdown-toggle-btn i {
    font-size: 0.75rem;
    transition: transform 0.2s ease;
}

.dropdown-toggle-btn.open i {
    transform: rotate(180deg);
}

.dropdown-toggle-btn:hover {
    color: #3182ce;
}

.combobox-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: white;
    border: 1px solid #e2e8f0;
    border-radius: 0 0 6px 6px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    z-index: 1000;
    max-height: 350px;
    overflow-y: auto;
    margin-top: -1px;
}

.combobox-section {
    border-bottom: 1px solid #e2e8f0;
}

.combobox-section:last-child {
    border-bottom: none;
}

.combobox-section-header {
    padding: 0.5rem 0.75rem;
    background: #f7fafc;
    color: #718096;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.combobox-section-header i {
    font-size: 0.875rem;
}

.combobox-option {
    padding: 0.625rem 0.75rem;
    cursor: pointer;
    border-bottom: 1px solid #f0f4f8;
    transition: background-color 0.1s ease;
}

.combobox-option:last-child {
    border-bottom: none;
}

.combobox-option:hover,
.combobox-option.selected {
    background-color: #ebf8ff;
}

.combobox-option .option-name {
    font-weight: 500;
    color: #2d3748;
    font-size: 0.9rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.option-favorite {
    color: #f59e0b;
    font-size: 0.75rem;
    margin-right: 0.35rem;
}

/* "Default" badge on the customer-default address seed in the order-entry pickers. */
.option-default-badge {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05rem 0.4rem;
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #1d4ed8;
    background: #eff6ff;
    border: 1px solid #bfdbfe;
    border-radius: 10px;
    vertical-align: middle;
}

.combobox-option .option-address {
    font-size: 0.8rem;
    color: #718096;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 0.125rem;
}

.combobox-option.search-all-link {
    color: #3182ce;
    font-size: 0.8rem;
    display: flex;
    align-items: center;
    gap: 0.375rem;
    border-top: 1px solid #e2e8f0;
    background: #f7fafc;
}

.combobox-option.search-all-link:hover {
    background-color: #ebf8ff;
}

.combobox-loading {
    padding: 0.75rem;
    color: #718096;
    font-size: 0.875rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.combobox-no-results {
    padding: 0.75rem;
    color: #a0aec0;
    font-size: 0.875rem;
    font-style: italic;
    text-align: center;
}

/* Focus state for the combobox input */
.address-combobox.open .combobox-input-wrapper input {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    border-color: #3182ce;
}

/* Address Book Dropdown - inline dropdown triggered by address book icon */
.address-book-dropdown {
    border-radius: 6px; /* Full radius since it's standalone, not attached to input focus */
    margin-top: 0.25rem;
}

.address-book-dropdown .combobox-section-header {
    position: sticky;
    top: 0;
    border-radius: 6px 6px 0 0;
}

.combobox-dropdown .view-all-link {
    margin-left: auto;
    background: none;
    border: none;
    color: #3182ce;
    font-size: 0.75rem;
    font-weight: 500;
    text-transform: none;
    letter-spacing: normal;
    cursor: pointer;
    padding: 0.125rem 0.375rem;
    border-radius: 4px;
    transition: background-color 0.15s ease;
}

.combobox-dropdown .view-all-link:hover {
    background-color: #ebf8ff;
    text-decoration: underline;
}

.address-book-dropdown-list {
    max-height: 280px;
    overflow-y: auto;
}

.address-book-dropdown .combobox-option.view-more {
    color: #3182ce;
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    justify-content: center;
    border-top: 1px solid #e2e8f0;
    background: #f7fafc;
}

.address-book-dropdown .combobox-option.view-more:hover {
    background-color: #ebf8ff;
}

.address-book-dropdown .combobox-no-results {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 1.5rem;
}

.address-book-dropdown .combobox-no-results i {
    font-size: 1.5rem;
    opacity: 0.5;
}

/* Address Combobox Container - flex layout for combobox + map button */
.address-combobox-container {
    display: flex;
    gap: 0.5rem;
    align-items: stretch; /* Make children full height */
    min-width: 0; /* Allow container to shrink below content size */
    max-width: 100%; /* Prevent expansion beyond parent */
    overflow: visible; /* Must be visible to show dropdown */
}

.address-combobox-container .address-combobox {
    flex: 1 1 0; /* Grow, shrink, start at 0 basis */
    min-width: 0; /* Allow shrinking */
    max-width: 100%; /* Prevent expansion */
    overflow: visible; /* Must be visible to show dropdown */
}

/* Map Picker Button */
.map-picker-btn {
    flex-shrink: 0;
    /* Pin to the same 37px the address input uses so the two line up.
       align-items: stretch on the container would otherwise let the button's
       taller intrinsic height (btn line-height + padding) set the row height. */
    height: 37px;
    padding: 0 0.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-color: #ced4da;
    color: #495057;
}

.map-picker-btn:hover {
    background-color: #e9ecef;
    border-color: #adb5bd;
    color: #212529;
}

.map-picker-btn i {
    font-size: 1.1rem;
}

/* Map Picker Modal */
.map-picker-container {
    width: 100%;
    height: 400px;
    border-radius: 6px;
    border: 1px solid #e2e8f0;
}

.selected-location-info .alert {
    font-size: 0.9rem;
}

/* Modal backdrop styling (ensure it's above other content) */
.modal-backdrop {
    z-index: 1040;
}

.modal {
    z-index: 1050;
}

/* ==============================================
   Address Selected Display (Read-Only View)
   Shows compact address when selection is locked
   ============================================== */

.address-selected-display {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
    border: 1px solid #dee2e6;
    border-radius: 8px;
    margin-bottom: 0.5rem;
}

/* Header row: address left, location type right */
.address-selected-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

.address-selected-content {
    flex: 1;
    min-width: 0;
}

/* Footer row: edit left, address book status right */
.address-selected-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 0.25rem;
    padding-top: 0.25rem;
    border-top: 1px solid #dee2e6;
}

.address-selected-footer .address-book-status {
    display: contents;
}

.status-separator {
    display: none;
}

.address-edit-link {
    font-size: 0.8rem;
    color: #6c757d;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
}

.address-edit-link:hover {
    color: #495057;
}

.address-selected-name {
    font-weight: 600;
    font-size: 1.05rem;
    color: #212529;
    margin-bottom: 0.0rem;
    word-wrap: break-word;
}

.address-selected-street {
    color: #495057;
    font-size: 0.95rem;
    margin-bottom: 0.05rem;
}

.address-selected-city {
    color: #6c757d;
    font-size: 0.9rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Streetless-pick warning on the location card. Deliberately NOT truncated like the
   lines above it — this one has to be readable in full or it isn't doing its job. */
.address-city-level-note {
    display: flex;
    align-items: flex-start;
    gap: 0.4rem;
    margin-top: 0.4rem;
    padding: 0.4rem 0.5rem;
    border-radius: 4px;
    background: #fff8e1;
    border: 1px solid #ffe082;
    color: #7a5b00;
    font-size: 0.82rem;
    line-height: 1.3;
}

.address-city-level-note i {
    flex-shrink: 0;
    margin-top: 0.1rem;
}

/* Nothing can be quoted at all — red, not amber. */
.address-city-level-note-blocked {
    background: #fdecea;
    border-color: #f5c2bd;
    color: #842029;
}

/* Truncate address lines to keep consistent height */
.address-selected-name,
.address-selected-street {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Empty state placeholder - matches address-selected-display height +
   margin-bottom so the gap to the next sibling (contact pair) reads
   identically whether or not an address has been picked. */
.address-empty-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 1rem;
    min-height: 133px;
    background: #f8f9fa;
    border: 1px dashed #dee2e6;
    border-radius: 8px;
    margin-bottom: 0.5rem;
}

.address-empty-content {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: #adb5bd;
    font-size: 0.9rem;
}

.address-empty-content i {
    font-size: 1.25rem;
}

.address-empty-placeholder .btn-link-subtle {
    color: #0d6efd;
    font-size: 1rem;
}

.address-empty-placeholder .btn-link-subtle:hover {
    color: #0a58ca;
}

/* ==============================================
   LocationAddressCard styles
   Used by LocationAddressCard on every page that
   hosts the component. These used to live in
   PlaceOrder.razor's inline <style>, which meant
   they only applied when PlaceOrder was rendered
   — DedicatedService and any future hosts didn't
   get them.
   ============================================== */

/* Inline company-name editor surfaced when Data is populated but
   Name is blank (e.g. Google-picked residential addresses). */
.address-name-edit {
    position: relative;
    margin-bottom: 0.25rem;
    padding-top: 0.75rem;
}

.address-name-edit .address-name-input {
    width: 100%;
    font-size: 1rem;
    font-weight: 600;
    color: var(--pc-primary);
    padding: 0.25rem 0;
    border: none;
    border-bottom: 2px solid #f59e0b;
    background: transparent;
    outline: none;
    transition: border-color 0.2s;
}

.address-name-edit .address-name-input:focus {
    border-bottom-color: #d97706;
}

.address-name-edit label {
    position: absolute;
    left: 0;
    top: 0.85rem;
    font-size: 1rem;
    font-weight: 600;
    color: #b45309;
    pointer-events: none;
    transition: all 0.2s ease;
}

.address-name-edit .address-name-input:focus + label,
.address-name-edit .address-name-input:not(:placeholder-shown) + label {
    top: 0;
    font-size: 0.7rem;
    font-weight: 500;
    color: #92400e;
}

/* "In Address Book" / "Add to Address Book" badges */
.address-status {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.address-status i {
    font-size: 0.9rem;
}

.address-status-saved {
    color: #059669;
}

.address-status-saved i {
    color: #10b981;
}

/* Read-only pick (customer-default seed / consolidated address) — neutral slate,
   no edit/save affordance. */
.address-status-readonly {
    color: #64748b;
}

.address-status-readonly i {
    color: #94a3b8;
}

.address-status-new {
    color: #6b7280;
}

.address-status-new i {
    color: #9ca3af;
}

/* Subtle-link button — Edit, Add to Address Book, Create New Address.
   Nested rule inside .address-empty-placeholder above overrides color
   for the empty-state "Create New Address" link. */
.btn-link-subtle {
    background: none;
    border: none;
    padding: 0.25rem 0.5rem;
    font-size: 1rem;
    color: #3b82f6;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    border-radius: 4px;
    transition: background-color 0.15s, color 0.15s;
}

.btn-link-subtle:hover:not(:disabled) {
    background-color: #eff6ff;
    color: #2563eb;
}

.btn-link-subtle:disabled {
    color: #9ca3af;
    cursor: not-allowed;
}

.btn-link-subtle i {
    font-size: 1rem;
}

/* ==============================================
   Order submit footer — shared between PlaceOrder
   and DedicatedService so both pages use the same
   prominent gradient submit button.
   ============================================== */
.order-submit-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 1.5rem;
    background: #f8fafc;
    border-top: 1px solid #e2e8f0;
    margin-top: 1.5rem;
    border-radius: 8px;
}

/* Keep every button in the footer on a single line regardless of which
   container the footer sits in. PlaceOrder/DedicatedService render the
   footer at root width and don't wrap; Continuation nests it inside a
   Card body whose narrower content-area was wrapping "Save as Template"
   and "Submit Order" labels. Forcing nowrap on every footer btn (the
   bookmark Save button uses Bootstrap's .btn .btn-outline-secondary
   which also lacked nowrap) makes the three flows visually consistent. */
.order-submit-footer .btn,
.order-submit-footer .btn-submit,
.order-submit-footer .btn-ghost {
    white-space: nowrap;
}

.order-submit-footer .footer-secondary {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.order-submit-footer .btn-ghost {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.6rem 1rem;
    background: transparent;
    border: 1px solid #cbd5e1;
    border-radius: 6px;
    font-size: 0.85rem;
    font-weight: 500;
    color: #64748b;
    cursor: pointer;
    transition: all 0.15s ease;
}

.order-submit-footer .btn-ghost:hover {
    background: white;
    border-color: #94a3b8;
    color: #1e293b;
}

.order-submit-footer .btn-submit {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.7rem 1.5rem;
    background: linear-gradient(135deg, var(--pc-primary) 0%, var(--pc-primary-light) 100%);
    border: none;
    border-radius: 6px;
    font-size: 0.9rem;
    font-weight: 600;
    color: white;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    transition: all 0.15s ease;
}

.order-submit-footer .btn-submit:hover:not(:disabled) {
    filter: brightness(1.15);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.order-submit-footer .btn-submit:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.order-submit-footer .btn-submit i {
    font-size: 1rem;
}

/* Split-button group: primary Submit + adjacent caret toggle that opens
   a menu of secondary actions (Save as Draft today). The group is
   inline-flex so the two buttons sit flush; the right radii on the
   submit are stripped and the toggle owns the right-rounding so the
   pair reads as one capsule. Menu pops UPWARD because the footer is
   pinned to the bottom of the form. */
.btn-submit-group {
    display: inline-flex;
    align-items: stretch;
    position: relative;
}

/* Toggle sits on the LEFT side of the group, so the submit gives up its
   left-side rounding and the toggle owns the left-rounded edge. The
   submit's right side keeps its natural rounding. */
.btn-submit-group .btn-submit {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}

.btn-submit-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 0.65rem;
    background: linear-gradient(135deg, var(--pc-primary) 0%, var(--pc-primary-light) 100%);
    border: none;
    border-right: 1px solid rgba(255, 255, 255, 0.25);
    border-top-left-radius: 6px;
    border-bottom-left-radius: 6px;
    color: white;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    transition: all 0.15s ease;
}

.btn-submit-toggle:hover:not(:disabled) {
    filter: brightness(1.15);
}

.btn-submit-toggle:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.btn-submit-toggle i {
    font-size: 0.95rem;
}

.btn-submit-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1090;
}

.btn-submit-menu {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 0;
    z-index: 1100;
    min-width: 200px;
    background: #fff;
    border: 1px solid rgba(15, 23, 42, 0.08);
    border-radius: 8px;
    box-shadow: 0 14px 38px rgba(15, 23, 42, 0.18), 0 4px 12px rgba(15, 23, 42, 0.10);
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.btn-submit-menu-item {
    display: flex;
    align-items: center;
    padding: 10px 12px;
    background: transparent;
    border: none;
    text-align: left;
    color: var(--pc-text, #1e293b);
    border-radius: 6px;
    cursor: pointer;
    font: inherit;
    font-size: 0.875rem;
    white-space: nowrap;
    width: 100%;
}

.btn-submit-menu-item:hover:not(:disabled) {
    background: rgba(49, 130, 206, 0.06);
}

.btn-submit-menu-item:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.btn-submit-menu-item > i {
    color: var(--pc-accent-ink, #3182ce);
    font-size: 1rem;
}

/* Mobile-stack override retired. The footer stays a horizontal row
   on every viewport so Save as Draft sits left and Submit Order sits
   right — same layout the desktop has. The leftover split-button
   stretch rules went with it (split button was reverted to two
   buttons). Base .order-submit-footer rule above keeps flex +
   justify-content: space-between, which is enough on its own. */

/* Contact picker modal styles moved to the scoped
   ContactPickerDialog.razor.css when the picker was extracted
   into a shared component (Variation A — aligned checkbox columns). */

/* ==============================================
   Notifications section (c4-* classes)
   Two-column split used inside the "Order Information"
   panel on PlaceOrder and the "Complete Order" card on
   DedicatedService. Global so both pages render
   identically.
   ============================================== */
.c4-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    margin-top: 0.6rem;
    margin-bottom: 0.25rem;
}

/* Title half of the header — kept as its own span so the uppercase /
   letter-spacing styling stays scoped to the label and doesn't bleed
   into the inline toggle stack on the right. */
.c4-section-header-title {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.78rem;
    font-weight: 600;
    color: #475569;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.c4-section-header-title i {
    color: #64748b;
    font-size: 0.8rem;
}

.c4-container {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding: 0.55rem 0.7rem;
    background: #f8fafc;
    border-radius: 6px;
}

.c4-recipients {
    min-width: 0;
}

.c4-input-row {
    display: flex;
    /* Stretch so the input and the Add/contacts buttons share one height — their
       natural heights differ ~1px (icon line-box vs text line-box). The label opts
       back to center via align-self. */
    align-items: stretch;
    gap: 0;
}

.c4-recipients-input {
    flex: 1;
    min-width: 0;
    padding: 0.45rem 0.7rem;
    border: 1px solid #cbd5e1;
    border-radius: 6px 0 0 6px;
    font-size: 0.85rem;
    background: white;
}

.c4-recipients-input:focus {
    outline: none;
    border-color: var(--pc-accent, #0046ad);
    box-shadow: 0 0 0 3px var(--pc-accent-glow, rgba(0, 70, 173, 0.08));
}

/* Submit button for the recipient box — same action as Enter or blurring the
   field. Joins the input's right edge; rounds its own right corner only when it
   is the last control (no contacts picker following it). */
.c4-add-btn {
    display: inline-flex;
    align-items: center;
    padding: 0.45rem 0.65rem;
    /* Themed "add" affordance — PCE blue / SF slate via --pc-accent-soft (never
       harsh red), darkening toward the themed primary on hover. */
    border: 1px solid var(--pc-accent-soft, var(--pc-accent, #0046ad));
    border-left: none;
    border-radius: 0;
    background: var(--pc-accent-soft, var(--pc-accent, #0046ad));
    color: white;
    cursor: pointer;
    font-size: 0.9rem;
    transition: background 0.15s;
}

.c4-add-btn:hover {
    background: var(--pc-primary, #00337d);
    border-color: var(--pc-primary, #00337d);
}

.c4-add-btn.last {
    border-radius: 0 6px 6px 0;
}

.c4-contacts-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.45rem 0.6rem;
    border: 1px solid #cbd5e1;
    border-left: none;
    border-radius: 0 6px 6px 0;
    background: #f8fafc;
    color: #64748b;
    cursor: pointer;
    font-size: 0.9rem;
    transition: all 0.15s;
}

.c4-contacts-btn:hover {
    background: #e2e8f0;
    color: #334155;
}

.c4-recipients-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin-top: 0.3rem;
}

.c4-recipient-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.2rem 0.4rem 0.2rem 0.55rem;
    background: white;
    border: 1px solid #e2e8f0;
    border-radius: 4px;
    font-size: 0.8rem;
    color: #475569;
}

.c4-recipient-chip button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    background: transparent;
    border: none;
    cursor: pointer;
    color: #94a3b8;
    font-size: 0.7rem;
}

.c4-recipient-chip button:hover {
    color: #dc2626;
}

.c4-notification-stack {
    display: inline-flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.15rem 0.55rem;
    /* Reset header's uppercase/letter-spacing inheritance so the
       toggle labels read like normal sentence-case form labels. */
    text-transform: none;
    letter-spacing: 0;
    font-weight: 400;
}

.c4-notification-item {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 0;
    cursor: pointer;
    transition: color 0.15s;
}

.c4-notification-item:hover span {
    color: var(--pc-accent-ink, #0046ad);
}

.c4-notification-item input {
    width: 16px;
    height: 16px;
    /* Themed control color: tracks the subsidiary accent, EXCEPT Street Fleet,
       whose harsh red is softened to slate via --pc-accent-soft (set on
       body.theme-sf below). Same expression in OrderNotifications.razor.css keeps
       the component self-contained + consistent across every host page. */
    accent-color: var(--pc-accent-soft, var(--pc-accent, #0046ad));
}

/* Street Fleet: --pc-accent-soft is the reusable "themed control" color — the
   brand accent for every subsidiary EXCEPT Street Fleet, whose harsh red is
   softened to slate here. Applied to checkboxes, toggles, the Save/CTA form
   controls, the quick-actions toolbar, the OAB selected tab and the cctx filter
   icon: PCE (and others) show blue via the fallback to --pc-accent; SF shows
   slate. Relies on the subsidiary body class wired in App.razor. */
body.theme-sf {
    --pc-accent-soft: #64748b;
}

.c4-notification-item span {
    font-size: 0.82rem;
    color: #64748b;
}

.c4-notification-item.active span {
    color: var(--pc-accent-ink, #0046ad);
    font-weight: 500;
}

/* Required-by-account event: checked + disabled (CXT fires it regardless of the
   checkbox — Task #3322). Signal it's not interactive. */
.c4-notification-item:has(input:disabled) {
    cursor: default;
    opacity: 0.75;
}

.c4-notification-item input:disabled {
    cursor: not-allowed;
}

/* Notifications control reads as one sentence ("Notify [edit recipients] on
   <events> [edit]"), so this row flows left-to-right instead of pushing the
   title and toggles to opposite ends like the default section header. */
.c4-section-header.c4-notif-flow {
    justify-content: flex-start;
    flex-wrap: wrap;
}

/* Sentence-case lead ("Notify … on") — distinct from c4-section-header-title,
   which uppercases. */
.c4-notif-lead {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.8rem;
    color: #475569;
}

.c4-notif-lead i {
    color: #64748b;
    font-size: 0.8rem;
}

/* The summary sentence doubles as the editor toggle — link-style affordance
   (pointer + underline on hover/focus) so users can open the detail form by
   clicking the text, not just the Edit pill. Underline rides the text span
   only so the bell icon isn't decorated. */
.c4-notif-lead-toggle {
    cursor: pointer;
}

.c4-notif-lead-toggle:hover .c4-notif-lead-text,
.c4-notif-lead-toggle:focus-visible .c4-notif-lead-text {
    text-decoration: underline;
    color: var(--pc-accent-ink, #0046ad);
}

.c4-notif-lead-toggle:focus-visible {
    outline: 2px solid var(--pc-accent, #0046ad);
    outline-offset: 2px;
    border-radius: 4px;
}

/* Small "Edit" pill at the end of the toggle row — reveals the recipients
   editor, which is collapsed by default since most orders notify just the
   logged-in user. */
.c4-notif-edit {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.05rem 0.45rem;
    border: 1px solid #e2e8f0;
    border-radius: 999px;
    background: #fff;
    color: #64748b;
    font-size: 0.7rem;
    font-weight: 500;
    line-height: 1.5;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}

.c4-notif-edit:hover {
    border-color: #cbd5e1;
    color: var(--pc-accent-ink, #0046ad);
}

.c4-notif-edit.open {
    border-color: var(--pc-accent, #0046ad);
    background: var(--pc-accent-glow, rgba(0, 70, 173, 0.08));
    color: var(--pc-accent-ink, #0046ad);
}

.c4-notif-edit i {
    font-size: 0.7rem;
}

/* Mobile: keep the title + three toggles inline on one row by shrinking
   the toggles aggressively. Earlier attempt stacked the header
   vertically — looked OK but cost a row of vertical space and made the
   toggles feel detached from the title; user prefers same-line. Sizes
   below were tuned for iPhone-portrait (~360px usable card width):
     title              ≈ 105px
     three toggles      ≈ 165px (10px box + ~45px label per × 3 + gaps)
     header gap         ≈ 8px
   Total ≈ 280px — comfortably within the available width. */
@media (max-width: 576px) {
    .c4-section-header {
        gap: 0.4rem;
    }

    .c4-notification-stack {
        flex-wrap: nowrap;
        gap: 0 0.4rem;
    }

    .c4-notification-item {
        gap: 0.2rem;
    }

    .c4-notification-item input {
        /* Override the touch-friendly min-width/min-height 24px rule
           below — these three notification toggles need to stay
           compact so the title + Placed / Picked Up / Delivered row
           fits on one line on iPhone-portrait. They're not standalone
           tap targets (the surrounding <label> is the tap target),
           so the touch-comfort minimum doesn't apply. */
        width: 10px;
        height: 10px;
        min-width: 0;
        min-height: 0;
        margin: 0;
    }

    .c4-notification-item span {
        font-size: 0.62rem;
        white-space: nowrap;
    }
}

/* ==============================================
   Compact Freight Selector (CFS)
   Three-mode segmented picker — Presets / Pallet / Custom — used by
   ContinuationShipmentEditor and intended for reuse anywhere we need
   a tight "rough shape, then refine" entry surface for parcel/freight
   numerics. See CompactFreightSelector.razor.
   ============================================== */

.cfs {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

/* Toggle row — optional leading content on the left (flex:1, e.g. the
   label input on ContinuationShipmentEditor), segmented pill in the
   middle/right, optional accessory at the far right (e.g. the hazmat
   / medical icon toggles). When no leading content is present the
   pills sit at the left edge as before. */
.cfs-toggle-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* Leading sizes naturally; the pills are pushed to the right via
   margin-left:auto so they sit flush with the accessory regardless of
   how wide the leading content is. */
.cfs-toggle-row-leading {
    display: flex;
    align-items: center;
    flex: 0 1 auto;
    min-width: 0;
}

/* Sits directly after the pills rather than at the far edge. Hazmat and medical describe
   THIS shipment, the same way the pills do — parking them across an empty row made them
   read as belonging to the card instead. No auto margin anywhere in this row now: every
   item packs left, and the row ends where its content ends. */
.cfs-toggle-row-accessory {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    flex-shrink: 0;
    margin-left: 0.15rem;
    padding-left: 0.4rem;
    border-left: 1px solid #e2e8f0;
}

/* Pills sit immediately after the leading slot rather than being flung to the right
   edge. They used to carry margin-left:auto, which put the mode you are choosing at the
   far side of the row from the pane it controls — the eye had to cross the whole card to
   connect the two. Left-packed, the pill and the panel beneath it share an edge.
   Task #3551. */

/* Segmented pill — three tabs (Presets / Freight / Custom). Active tab
   is brand-blue. */
.cfs-seg-toggle {
    display: inline-flex;
    background: white;
    border: 1px solid #e2e8f0;
    border-radius: 999px;
    padding: 2px;
}

.cfs-seg-toggle button {
    border: none;
    background: transparent;
    padding: 0.3rem 0.85rem;
    font-size: 0.78rem;
    border-radius: 999px;
    color: #64748b;
    cursor: pointer;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    transition: background 0.15s, color 0.15s;
}

.cfs-seg-toggle button:hover {
    color: #1e293b;
}

.cfs-seg-toggle button.active {
    background: #0046ad;
    color: white;
}

/* Mobile: drop the freight-mode pill ICONS and keep the text labels (Presets /
   Custom / Freight, and their medical variants). Text-only pills are narrower
   than icon+text, so the hazmat/medical accessory icons stay inside the toggle
   row instead of overflowing off the right. There is nothing in the leading slot
   competing for that room any more — the shipment-name field it used to hold is
   gone (Task #3551) — but the pills still earn the width back on a phone. */
@media (max-width: 768px) {
    .cfs-seg-toggle button > i {
        display: none;
    }

    .cfs-seg-toggle button {
        padding: 0.35rem 0.6rem;
    }
}

/* Preset pane — quick-select chip grid stacked above an editable refine
   row so the user can nudge Pieces/Weight without leaving Presets mode. */
.cfs-preset-pane {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

/* Chip grid — 4 across at desktop, 2 across on narrow screens. Mirrors
   the small-preset cards on PlaceOrder but tighter. */
/* ── Presets pane ───────────────────────────────────────────────────────
   The tile grid stays visible; the selected slot's spec fields render
   directly beneath it. */

/* Action line — empty unless something needs deciding, so the pane stays
   quiet in the common case of just picking a preset and moving on. */
.preset-actions {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
    margin-top: 0.6rem;
    min-height: 1.25rem;
    font-size: 0.76rem;
}

.preset-action-link {
    border: 0;
    background: none;
    padding: 0;
    color: var(--pce-blue, #2563eb);
    font-weight: 600;
    font-size: 0.76rem;
    cursor: pointer;
    text-decoration: none;
}

.preset-action-link:hover {
    text-decoration: underline;
}

.preset-action-link.subtle {
    color: #64748b;
    font-weight: 500;
}

.preset-action-link.subtle:hover {
    color: #334155;
}

.preset-action-hint {
    color: #94a3b8;
}

.preset-action-sep {
    color: #cbd5e1;
}

/* Icon picker. Deliberately not a <select> — the point is seeing the glyphs,
   which a native select cannot render. Class names are prefixed: bare
   "dropdown" would collide with Bootstrap's own JS behaviours. */
.preset-iconpick {
    position: relative;
    display: inline-flex;
}

.preset-iconpick-btn {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    height: 24px;
    padding: 0 5px;
    border: 1px solid #cbd5e1;
    border-radius: 6px;
    background: #fff;
    color: #475569;
    font-size: 0.82rem;
    line-height: 1;
    cursor: pointer;
    transition: all 0.12s ease;
}

.preset-iconpick-btn:hover {
    background: #f8fafc;
    border-color: #94a3b8;
}

.preset-iconpick-caret {
    font-size: 0.5rem;
    color: #94a3b8;
}

.preset-iconpick-menu {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: 20;
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 2px;
    padding: 5px;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    box-shadow: 0 6px 18px rgba(15, 23, 42, 0.12);
}

.preset-iconpick-choice {
    width: 26px;
    height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid transparent;
    border-radius: 6px;
    background: none;
    color: #475569;
    font-size: 0.9rem;
    cursor: pointer;
}

.preset-iconpick-choice:hover {
    background: #f1f5f9;
}

.preset-iconpick-choice.selected {
    border-color: var(--pce-blue, #2563eb);
    background: #eff6ff;
    color: var(--pce-blue, #2563eb);
}


/* The small-freight spec row: overall size, then total weight & pieces.
   Number-only fields throughout — the Pieces/Weight sliders were removed
   because a slider next to the dimension inputs implies the piece count
   scales them, which it never has. Two labelled groups rather than five
   loose fields, so weight and pieces read as one clause. */
/* ── Presets pane: the preset panel ──────────────────────────────────────
   One card, two jobs kept apart. The HEADER is the preset — which one you
   are on, what it is called, what it looks like, and whether it has been
   saved. The BODY is this shipment's values. Editing the body never
   rewrites the preset; the header's Save is the only thing that does.
   See docs/mockups/preset-accordion-treatments.html (treatment F). */
/* NOT overflow:hidden. The header's fill is clipped to the corners by giving
   the header its own radius instead — overflow:hidden here also clipped the
   size field's help tooltip, which escapes the panel by design. */
.preset-panel {
    margin-top: 0.5rem;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 8px;
}

/* Expanded: the editor REPLACES the tile grid rather than sitting under it, so it
   inherits the grid's footprint. min-height matches the two rows of tiles it stands
   in for — without it the card visibly shrinks the freight section when a preset is
   picked, and the whole page jumps under the cursor at the moment of the click. The
   margin-top goes because there is no longer a grid above to sit below. */
.preset-panel.expanded {
    margin-top: 0;
    min-height: 190px;
    display: flex;
    flex-direction: column;
}

/* The room this paradigm buys. Two labelled blocks, generously spaced, instead of one
   dense row: separation is what stops "weight & pieces" sitting directly on top of the
   dimensions and re-implying that the piece count multiplies them.

   The top is half the other sides on purpose. The panel header sits directly above with
   its own 0.35rem and a border under it, so a matching 1rem here stacked into a gap the
   other three edges don't have — the content read as having drifted down the card rather
   than starting at the top of it. The separation this rule is about is the GAP between
   the blocks, which is untouched. */
.preset-editor-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
    padding: 0.5rem 1.1rem 1.15rem;
}

/* Envelope's whole editor: one sentence and one field. It replaces a heading-plus-fields
   grid where four of the five inputs would have been disabled or hidden — the sentence does
   the reassuring the missing fields used to imply, rather than leaving a conspicuous gap.

   Centred rather than top-aligned. The panel holds a 190px min-height so replacing the tile
   grid doesn't jump the page (see .preset-panel.expanded), and Envelope's content is roughly
   a third of that. Left at the top it read as a pane that had failed to finish loading;
   centred, the same leftover space reads as deliberate — which suits the one preset whose
   whole point is that there is nothing to specify. */
.preset-envelope-ask {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.85rem;
    text-align: center;
}

/* Given the room, the line is the pane rather than a caption next to a field — this is the
   one slot where the answer to "what vehicle does this need" is "don't worry about it", and
   that's worth saying at a readable size. */
.preset-envelope-copy {
    font-size: 1.05rem;
    color: #334155;
}

.preset-envelope-count {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.9rem;
    color: #475569;
}

.preset-spec-heading {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    margin-bottom: 0.45rem;
    font-size: 0.78rem;
    font-weight: 700;
    color: #475569;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.preset-spec-fields {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    flex-wrap: wrap;
}

/* Input and its unit as one object, so "25 lb" reads as a quantity rather than a
   box next to a stray word. */
.preset-field {
    display: inline-flex;
    align-items: baseline;
    gap: 0.3rem;
}

/* Bigger than the collapsed row's 3-digit boxes — this is the space the expanded
   editor exists to spend. Still box-sizing: border-box (Bootstrap's reboot), so the
   width covers padding and border; ch keeps the digits sized to the font. */
/* Native spin buttons are LEFT ON here, unlike every other numeric input in the freight
   card. The others suppress them because they sit in cramped rows — the Custom pane pairs
   each box with a range slider, which is its increment control, and the old collapsed
   presets row was only wide enough for three digits. The expanded editor has the room, and
   without a slider beside it the spinner is the only way to nudge a value by one.

   The width carries an extra ~1.2rem over the digits for the spinner itself: border-box
   means `width` covers it, so without the allowance the arrows would eat into the digits
   rather than sit beside them. Left padding is trimmed to match the space the spinner takes
   on the right, so the centred number stays visually centred in the box. */
.preset-spec-input {
    /* Digit capacity, sized per field rather than one width for all three. A single 4ch
       box plus the spinner allowance read as room for five characters, which made every
       field look like it wanted a bigger number than it accepts.

       --digits is the real cap: dimensions max at 999 and pieces at 20, so three is
       generous for both; weight is uncapped and gets four. The extra 0.2ch is caret room,
       so the last digit isn't flush against it. The 1.8rem covers 0.7rem of horizontal
       padding declared below plus ~1.1rem for the spin buttons — border-box means `width`
       has to carry them, or the arrows eat into the digits. */
    --digits: 3;

    /* Room for an in-field prefix ("L:"), zero unless .with-prefix sets it. It has to be
       part of the width calc rather than padding alone: border-box means padding eats the
       digits otherwise, and a three-digit box that shows two is worse than no prefix. */
    --prefix: 0rem;

    box-sizing: border-box;
    width: calc(var(--digits) * 1ch + 0.2ch + 1.8rem + 2px + var(--prefix));
    padding: 0.45rem 0.2rem 0.45rem 0.5rem;
    border: 1px solid #cbd5e1;
    border-radius: 6px;
    background: #fff;
    font-size: 1.05rem;
    font-weight: 600;
    color: #1e293b;
    text-align: center;
}

/* ── In-field dimension prefix ──────────────────────────────────────────────
   The legacy portal labels each dimension box from the inside — a small "L:" against the
   left edge with "(in)" as the placeholder — rather than putting a letter after it. It
   does this with a background GIF and padding-left:27px (see .txtLn in the classic site's
   order-entry CSS). Same reading, without shipping three images: an absolutely positioned
   span inside the field wrapper.

   Why it is better than the trailing letter it replaces: the label is present while the
   box is EMPTY, which is exactly when you need to know which of the three you are in.
   A suffix only appears next to a value you have already typed. */
/* align-items: center, overriding .preset-field's baseline. With baseline alignment the
   wrapper reserves descender space below the input, so it is taller than the input and
   its midpoint sits below the input's — which is what put the prefix and the placeholder
   on visibly different lines. One in-flow child here (the unit span is gone on prefixed
   fields), so centring makes wrapper height equal input height. */
.preset-field.with-prefix {
    position: relative;
    align-items: center;
}

/* Stretched top-to-bottom and centred by its own flexbox rather than nudged with
   translateY(-50%). The input centres its single line of text in the same box, so the
   prefix and the value — and the placeholder, which the browser centres the same way —
   all land on one line without a magic offset to keep in sync with the padding. */
.preset-field-prefix {
    position: absolute;
    left: 0.5rem;
    top: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    font-size: 0.78rem;
    font-weight: 400;
    color: #94a3b8;
    /* Clicks fall through to the input, so the prefix can't become a dead zone at the
       left edge of a control people aim at. */
    pointer-events: none;
}

.preset-spec-input.with-prefix {
    --prefix: 1.1rem;
    padding-left: calc(0.5rem + var(--prefix));
    text-align: left;
}

/* "(in)" is four characters in a three-digit box, so it is set smaller than the value it
   stands in for. It reads as a unit hint rather than as something you typed. */
.preset-spec-input.with-prefix::placeholder {
    font-size: 0.78rem;
    font-weight: 500;
    color: #cbd5e1;
}

/* One dimension per line while the 3D preview is showing.
   Opt-in via .stack-dims rather than inferred from an ancestor, because the two hosts
   differ by available WIDTH and nothing else. Place Order's freight card sits in a narrow
   column — both its Custom pane and its preset editor — so once the preview takes its
   fixed width off the right there is no room for three prefixed boxes on one line.
   Stacked, each row is short and the fields column ends up about as tall as the box it
   sits beside. The compact selector spans a stop card and keeps them inline, so it simply
   doesn't ask for the class.

   Only under :not(.preview-hidden) — with the preview off the row gets its full width
   back and the three go inline again. Scoped to .dims-fields so the pieces/weight pair
   above stays on one line in both states; those two are a pair, not a series. */
.dims-preview-row.stack-dims:not(.preview-hidden) .dims-fields {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.4rem;
}

/* Weight is the only uncapped figure here, so it's the only one that needs four. */
.preset-spec-input.digits-4 {
    --digits: 4;
}

/* Commercial freight weight. Four digits stop at 9,999, and a trailer load runs to
   45,000 lb — the old slider's own ceiling — so the value the field exists to hold was
   the one it clipped. */
.preset-spec-input.digits-5 {
    --digits: 5;
}

.preset-spec-input:focus {
    outline: none;
    border-color: #3b82f6;
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
}

.preset-spec-input.is-invalid {
    border-color: #dc2626;
}

.preset-field-unit {
    font-size: 0.85rem;
    font-weight: 600;
    color: #64748b;
}

/* .preset-spec-x — the multiplication signs between L, W and H — is gone. Three boxes
   that each say which dimension they are don't also need joining into an expression, and
   the separators were competing with the new in-field prefixes for the same glance.
   Task #3551. */

/* LABEL MODE. The preset name is a label that opens the grid, not a text box — which is
   the whole reason a dropdown works here. When the name was an input doubling as a menu
   trigger, every click on it was a guess about which behaviour you'd get. */
.preset-picker {
    position: relative;
    flex: 1;
    min-width: 0;
}

.preset-picker-btn {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    width: 100%;
    padding: 0.28rem 0.45rem;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    /* Sits just above the section headings (0.78rem) because it labels the whole panel,
       and deliberately below the field values (1.05rem), which are the content. It was
       0.95rem on the theory that a dropdown trigger needs presence to read as clickable —
       the caret and the hover fill already do that job, and the size only made it the
       loudest text in the pane. Must stay in step with .preset-panel-name, or the name
       changes size the moment the pencil swaps one for the other. */
    font-size: 0.85rem;
    font-weight: 700;
    color: #0f172a;
    text-align: left;
    cursor: pointer;
}

.preset-picker-btn:hover,
.preset-picker-btn[aria-expanded="true"] {
    background: #fff;
    border-color: #cbd5e1;
}

/* Disabled = there is nothing to switch to (Custom under medical mode, or on a liftgate
   run where the presets can't serve). It becomes the panel's title rather than a dead
   control: no caret is rendered, so no hover, no pointer, and full-strength text — a
   greyed-out label would suggest the pane itself was unavailable. */
.preset-picker-btn:disabled {
    cursor: default;
    opacity: 1;
}

.preset-picker-btn:disabled:hover {
    background: transparent;
    border-color: transparent;
}

.preset-picker-icon {
    font-size: 0.95rem;
    color: #475569;
    flex-shrink: 0;
}

.preset-picker-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Pinned right so it stays put as names change length — a caret that slides around with
   the text reads as part of the word rather than as a control. */
.preset-picker-caret {
    margin-left: auto;
    font-size: 0.7rem;
    color: #94a3b8;
    flex-shrink: 0;
}

/* The same six tiles as the grid, so choosing a preset looks identical wherever you do it. */
.preset-picker-menu {
    position: absolute;
    z-index: 20;
    top: calc(100% + 5px);
    left: 0;
    right: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    padding: 8px;
    background: #fff;
    border: 1px solid #cbd5e1;
    border-radius: 10px;
    box-shadow: 0 10px 26px rgba(15, 23, 42, 0.16);
}

/* Outside the picker button so the two hit targets never overlap. Ghost-weight: renaming
   is rare next to specifying a shipment, and it shouldn't compete with the name. */
.preset-rename-btn {
    width: 24px;
    height: 24px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: #64748b;
    cursor: pointer;
    flex-shrink: 0;
}

.preset-rename-btn:hover {
    background: #e2e8f0;
    color: #0f172a;
}

/* EDIT MODE. Reached only by the pencil, and the only place the name and icon are editable.
   The border is present and blue here — unlike the old transparent-until-hover field, this
   input is unmistakably an input, because now it only exists when you asked for it. */
/* Live count rather than a silent stop at the cap: a maxlength that just refuses keystrokes
   reads as a broken keyboard. */
.preset-name-counter {
    flex-shrink: 0;
    font-size: 0.68rem;
    color: #94a3b8;
    font-variant-numeric: tabular-nums;
}

.preset-done-btn {
    padding: 0.2rem 0.5rem;
    border: 1px solid var(--pce-blue, #2563eb);
    border-radius: 6px;
    background: var(--pce-blue, #2563eb);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    white-space: nowrap;
    cursor: pointer;
    flex-shrink: 0;
}

.preset-done-btn:hover {
    background: #1d4ed8;
    border-color: #1d4ed8;
}

.preset-picker-btn:focus-visible,
.preset-rename-btn:focus-visible,
.preset-done-btn:focus-visible {
    outline: 2px solid rgba(37, 99, 235, 0.5);
    outline-offset: 1px;
}

/* Back to the grid. Deliberately chrome-less: a bordered button here sat next to the
   name field and read as a fire exit rather than a way back. A bare chevron with a
   hover fill carries the same affordance at a fraction of the visual weight, and keeps
   a 26px hit target. */
.preset-back-btn {
    width: 26px;
    height: 26px;
    flex: 0 0 26px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: #64748b;
    font-size: 1.1rem;
    cursor: pointer;
}

.preset-back-btn:hover {
    background: #e2e8f0;
    color: #0f172a;
}

.preset-back-btn:focus-visible {
    outline: 2px solid rgba(37, 99, 235, 0.5);
    outline-offset: 1px;
}

/* Phones: the two spec blocks stay stacked, but the fields get room to wrap without
   the inputs shrinking below a comfortable tap target. */
@media (max-width: 576px) {
    .preset-panel.expanded {
        min-height: 0;
    }

    .preset-editor-body {
        gap: 0.9rem;
        padding: 0.85rem 0.9rem 1rem;
    }
}

.preset-panel-head {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.6rem;
    background: #f8fafc;
    border-bottom: 1px solid #e2e8f0;
    /* One less than the panel's 8px, to sit inside its 1px border. */
    border-radius: 7px 7px 0 0;
}

/* Unsaved values tint the header, since that is where the decision lives. */
/* Unsaved changes. Deliberately NOT the amber warning ramp: nothing is wrong when a
   preset has pending edits, and dressing it as a warning made a normal state look like a
   problem to fix. A neutral lift is enough — the Update button below the fields is the
   actual notice. */
.preset-panel.pending .preset-panel-head {
    background: #f1f5f9;
    border-bottom-color: #cbd5e1;
}

/* The name field, which now exists ONLY in edit mode. It used to be transparent until
   hovered — a compromise forced by living permanently in the header where it had to pass
   for a heading, and the reason nobody discovered they could rename a preset. Behind the
   pencil it can just look like the input it is. */
.preset-panel-name {
    flex: 1 1 auto;
    min-width: 0;
    box-sizing: border-box;
    font-family: inherit;
    /* Matches .preset-picker-btn exactly — this input replaces that label in place, so any
       difference reads as the text jumping size under the cursor. */
    font-size: 0.85rem;
    font-weight: 700;
    color: #0f172a;
    background: #fff;
    border: 1px solid #cbd5e1;
    border-radius: 6px;
    padding: 0.24rem 0.4rem;
}

.preset-panel-name:focus {
    outline: none;
    border-color: var(--pce-blue, #2563eb);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.14);
}

.preset-panel-actions {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    flex-shrink: 0;
}

/* Appears only when there is something to save, and is both the notice and
   the action — no badge to read before finding the button. Names its
   destination: the fields below are the shipment's, this is what pushes
   them into the preset. */
/* The one control that writes to the preset — and deliberately the quietest thing in the
   editor. This pane exists to specify a shipment; updating the preset it came from is an
   optional extra, and as a filled primary button at the foot of the form it read as the
   thing you came to press. A link says "if you want to" in a way a button cannot. */
.preset-save-link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0;
    border: none;
    background: transparent;
    color: #64748b;
    font-size: 0.78rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

.preset-save-link i {
    font-size: 0.85rem;
    color: #94a3b8;
}

.preset-save-link:hover {
    color: var(--pce-blue, #2563eb);
}

.preset-save-link:hover i,
.preset-save-link:hover span {
    color: var(--pce-blue, #2563eb);
}

.preset-save-link:hover span {
    text-decoration: underline;
}

.preset-save-link:focus-visible {
    outline: 2px solid rgba(37, 99, 235, 0.5);
    outline-offset: 2px;
    border-radius: 4px;
}

/* No rule above it and no right-alignment: a bordered, right-aligned row reads as a form
   footer with a submit in it, which is the impression this is trying not to give. It just
   sits under the fields, left-aligned with them. */
.preset-editor-foot {
    display: flex;
    margin-top: -0.2rem;
}

/* Anchor for the Custom pane's "Save as a preset…" popup. The foot itself can't be the
   anchor — it is a flex row, and positioning the menu against it would tie the menu's
   width to the link's. */
.preset-saveas {
    position: relative;
    display: inline-flex;
}

/* Opens UPWARD, unlike the header picker. This menu hangs off the last line of the
   panel, which in the compact selector is often the last line of a stop card — dropping
   it downward put it under the card's own edge. Width is its own rather than the
   anchor's: the link is short and the tiles need room to show what each slot holds. */
.preset-saveas-menu {
    top: auto;
    bottom: calc(100% + 6px);
    left: 0;
    right: auto;
    width: max-content;
    min-width: 250px;
    max-width: 330px;
}

/* Names the stakes above the tiles. Without it the menu reads as "pick a preset", which
   is the one thing it is not doing — every tile here overwrites what it shows. */
.preset-saveas-heading {
    grid-column: 1 / -1;
    padding: 0 2px 2px;
    font-size: 0.72rem;
    font-weight: 700;
    color: #64748b;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* The header's reset/undo toggle. One style for both states — the arrow's
   direction carries which one you're on (counterclockwise resets, clockwise
   puts it back). The Undo state used to be a filled slate button, on the
   theory that a bare arrow swapped for another bare arrow was too subtle a
   change; in practice the heavy treatment made backing out of a reset look
   like a bigger commitment than the reset itself, which is the wrong way
   round for the control that exists to make the reset safe to try. */
.preset-reset-btn {
    width: 22px;
    height: 22px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #cbd5e1;
    border-radius: 6px;
    background: #fff;
    color: #64748b;
    cursor: pointer;
    flex-shrink: 0;
}

.preset-reset-btn:hover {
    border-color: #fca5a5;
    color: #b91c1c;
}

.preset-reset-btn:focus-visible {
    outline: 2px solid rgba(37, 99, 235, 0.5);
    outline-offset: 1px;
}

.cfs-preset-grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 0.3rem;
}

@media (max-width: 768px) {
    .cfs-preset-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

.cfs-chip {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.15rem;
    padding: 0.55rem 0.25rem;
    background: white;
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.15s;
    min-height: 64px;
    color: #1e293b;
}

.cfs-chip i {
    font-size: 1rem;
    color: #64748b;
}

.cfs-chip-name {
    font-size: 0.7rem;
    font-weight: 500;
    line-height: 1.1;
    text-align: center;
}

.cfs-chip-hint {
    font-size: 0.6rem;
    color: #64748b;
    line-height: 1.1;
}

.cfs-chip:hover {
    border-color: #0046ad;
}

.cfs-chip.selected {
    border-color: #0046ad;
    background: #e7eefa;
    color: #0046ad;
}

.cfs-chip.selected i {
    color: #0046ad;
}

/* Tooltip system. Moved here from PlaceOrder.razor's page-level style block, which only
   exists in the DOM while that page is rendered — so `cp-tooltip` markup on any other
   page rendered the icon and nothing else. CompactFreightSelector's "Overall size (in)"
   hint is the case that surfaced it. Unchanged; only the home moved. Task #3548. */
/* Custom tooltip - appears instantly with nice styling */
.cp-tooltip {
    position: relative;
    color: #64748b;
    cursor: help;
    outline: none;
    border-radius: 50%;
}

.cp-tooltip:hover,
.cp-tooltip:focus {
    color: #3b82f6;
}

.cp-tooltip:focus {
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
}

/* Tooltip container - holds both box and arrow */
.cp-tooltip::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%);
    background: #1e293b;
    color: #f1f5f9;
    padding: 0.625rem 0.875rem;
    border-radius: 8px;
    font-size: 0.8125rem;
    font-weight: 400;
    line-height: 1.5;
    white-space: normal;
    width: max-content;
    max-width: 300px;
    text-align: left;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.05);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.1s ease-out, visibility 0.1s ease-out;
    z-index: 1000;
    pointer-events: none;
}

/* Arrow - connected to bottom of tooltip */
.cp-tooltip::before {
    content: '';
    position: absolute;
    bottom: calc(100% + 2px);
    left: 50%;
    transform: translateX(-50%);
    border: 6px solid transparent;
    border-top-color: #1e293b;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.1s ease-out, visibility 0.1s ease-out;
    z-index: 1001;
    pointer-events: none;
}

.cp-tooltip:hover::before,
.cp-tooltip:hover::after,
.cp-tooltip:focus::before,
.cp-tooltip:focus::after {
    opacity: 1;
    visibility: visible;
}

/* Variant: tooltip renders BELOW the trigger. Use when the trigger sits
   near the top of the viewport (e.g. card-header chips) and the default
   above-positioning would clip off the page. Override both ::before
   (arrow) and ::after (box). */
.cp-tooltip-below::after {
    bottom: auto;
    top: calc(100% + 8px);
}

.cp-tooltip-below::before {
    bottom: auto;
    top: calc(100% + 2px);
    border-top-color: transparent;
    border-bottom-color: #1e293b;
}

/* Variant: preserve newlines in data-tooltip so multi-paragraph copy
   formats as paragraphs instead of collapsing to a single block. */
.cp-tooltip-multiline::after {
    white-space: pre-line;
    max-width: 360px;
}

/* Preset tiles. Moved here from PlaceOrder.razor's <style> block, which only exists in
   the DOM while that page is rendered — so these rules were absent everywhere else, and
   CompactFreightSelector's preset dropdown renders the same tiles. Unchanged; only the
   home moved. Task #3548. */
.preset-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 10px 6px 8px;
    border: 1.5px solid #e2e8f0;
    border-radius: 10px;
    background: #fff;
    cursor: pointer;
    transition: all 0.15s ease;
}

.preset-card:hover {
    border-color: #94a3b8;
    background: #f8fafc;
}

.preset-card.selected {
    border-color: var(--pce-blue, #2563eb);
    background: #eff6ff;
    box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
}

.preset-icon {
    font-size: 1.3rem;
    color: #64748b;
}

.preset-card.selected .preset-icon {
    color: var(--pce-blue, #2563eb);
}

.preset-name {
    font-size: 0.72rem;
    font-weight: 600;
    color: #334155;
    line-height: 1.1;
}

.preset-hint {
    font-size: 0.62rem;
    color: #94a3b8;
    letter-spacing: 0.02em;
}

/* ── Preset editor: takes over the grid once a preset is picked ─────────────
   Structure and type come from PlaceOrder's .preset-panel / .preset-spec-* rules, which
   this markup reuses directly rather than restating — that is what keeps the two panes
   identical as either one changes. Only the differences the narrower host needs live
   here, scoped by .cfs-preset-panel so nothing leaks back onto Place Order. */
.cfs-preset-panel {
    /* PlaceOrder pins 190px to match the two rows of tiles it replaces. The compact grid
       is shorter, so the editor matches ITS footprint instead — same purpose, which is
       that swapping grid for editor must not resize the card under the cursor. */
    min-height: 148px;
    margin-top: 0;
}

/* The header dropdown is the full width of the panel, so the selected preset reads as a
   select rather than a label with a caret parked next to it. */
.cfs-preset-panel .preset-picker {
    flex: 1;
    min-width: 0;
}

/* Two columns, not three: at ~460px three tiles leave the names truncating. */
.cfs-preset-panel .preset-picker-menu {
    grid-template-columns: repeat(2, 1fr);
}

/* ── 3D preview inside the compact selector ─────────────────────────────────
   One rule set, because there is now one panel. Both panes that carry the scene — the
   preset editor and Custom — render as .cfs-preset-panel, so what used to be two
   near-identical blocks scoped to .cfs-preset-panel and .cfs-custom-pane is a single
   scope that can't drift.

   These correct the defaults .dims-preview-row was written for on PlaceOrder, whose row
   holds only the dimensions. Here it also carries pieces/weight, and stretching made the
   box float in the middle of a taller column — visually detached from the fields it
   describes. Top-align the column and let the scene keep its natural height. */
.cfs-preset-panel .dims-preview-row {
    align-items: flex-start;

    /* Pack left. The base rule centres the two columns, which on a pane wider than the
       content leaves equal slack on both sides. */
    justify-content: flex-start;

    /* The base row is gap:0 — right for PlaceOrder, where .dims-col is flex:1 and pushes
       the preview to the far edge. Here the column shrinks to its fields, so without a gap
       the box sits flush against the last input. */
    gap: 1.25rem;
}

/* Size to the fields, don't grow. The base .dims-col is flex:1, so on PlaceOrder's wide
   panel it fills and the preview lands at the far right — correct there. Here it left a
   gap between the last input and the box, which is what read as the scene being
   right-aligned rather than sitting beside the controls.

   Padding goes because each .preset-spec-block supplies its own; the gap replaces the
   one the column inherited from .preset-editor-body before pieces/weight and size moved
   in here together — without it the two labelled groups run into each other. */
.cfs-preset-panel .dims-col {
    flex: 0 1 auto;
    padding: 0;
    gap: 1.1rem;
}

/* Sits directly beside the fields — no margin-left:auto, so the column follows the
   dimensions column rather than being pushed to the far edge. Padding goes because the
   row is top-aligned and the scene should start level with the first field.

   flex is pinned back to its natural width: the base column takes the leftover width and
   centres the scene in it, which is right on Place Order's wide card and wrong here —
   this pane is barely wider than its fields, so centring would only drift the scene a few
   pixels off the row's gap for no gain. */
.cfs-preset-panel .preview-col {
    flex: 0 0 auto;
    padding: 0;
}

/* Undoes the flex:1 that made the scene fill a stretched column. */
.cfs-preset-panel .preview-col .box-scene {
    flex: 0 0 auto;
    width: 150px;
    min-height: 150px;
}

/* Medical descriptor cards — multi-select grid shown inside the
   Labs/Pharma and Supplies panes when IsMedical is on. Same layout
   AND selected-state palette as cfs-preset-grid + cfs-chip so all
   "picked" states across the freight selector read consistently
   (brand blue). The medical context is signaled by the cards' content
   (Ambient / Refrigerated / etc.), not by a separate palette. */
.cfs-medical-descriptor {
    margin-bottom: 0.5rem;
}

.cfs-medical-descriptor-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.4rem;
}

@media (max-width: 768px) {
    .cfs-medical-descriptor-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* Commercial freight's typed fields, below the floor grid. Two labelled blocks with real
   space between them, the same shape every other freight pane uses. */
/* No top margin. This column starts its pane, exactly as generic freight's first
   .preset-spec-block starts that one, and the two panes have to begin on the same line —
   the pane's own .freight-fields margin is the space above them both. The 0.75rem this
   carried came from when the column sat below a pieces-and-weight block, and once that
   moved inside it showed up as commercial sitting lower than Custom. Task #3551. */
.commercial-spec {
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}

/* Present and legal to type, but tall enough to rule out most of the fleet — a different
   signal from is-invalid, which means "no answer yet". Amber, not red. */
.preset-spec-input.over-height-warning {
    border-color: #f59e0b;
    background: #fffbeb;
}

/* Labs/Pharma's numeric entry: a strip, not a panel. The pane asks two questions —
   pieces and weight — and the four descriptor cards above are its real selection
   surface. Wrapping two fields in the editor chrome the other panes use (frame, header,
   size block, 3D preview) made the count look like the main event. Borderless and inline,
   so it reads as a caption to the cards rather than a second section competing with them.
   The fields themselves are the shared .preset-field / .preset-spec-input controls, so a
   number typed here looks identical to one typed anywhere else in the selector. */
.freight-medical-spec {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.3rem 0.7rem;
    padding: 0.1rem 0.15rem;
    margin-top: 0.5rem;
}

/* Same micro-label treatment as .preset-spec-heading, set inline instead of stacked —
   the two fields fit on one line beside it at this pane's width. */
.freight-medical-spec-label {
    font-size: 0.78rem;
    font-weight: 700;
    color: #475569;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.cfs-medical-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.15rem;
    padding: 0.55rem 0.4rem;
    background: white;
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.15s;
    min-height: 64px;
    color: #1e293b;
}

.cfs-medical-card i {
    font-size: 1rem;
    color: #64748b;
}

.cfs-medical-card-name {
    font-size: 0.75rem;
    font-weight: 500;
}

.cfs-medical-card-hint {
    font-size: 0.65rem;
    color: #64748b;
}

.cfs-medical-card:hover {
    border-color: #0046ad;
}

.cfs-medical-card.selected {
    border-color: #0046ad;
    background: #e7eefa;
    color: #0046ad;
}

.cfs-medical-card.selected i {
    color: #0046ad;
}

/* The refine row and the Shape combobox that lived here are gone, and their styles with
   them: .cfs-preset-refine, .cfs-refine-* (fields / dims / input / unit / mobile caps)
   and .cfs-shape-combo. The row was a second set of Pieces / Weight / L x W x H inputs
   under whichever pane was showing; every pane now owns those fields itself, so the row
   was editing values already on screen. Task #3548. */

/* Freight pane — full commercial-freight layout ported from PlaceOrder.
   50/50 split: 2×13 trailer floor grid on the left, three sliders
   (Weight / Pieces / Height) stacked on the right. Stacks under md so
   neither side gets squeezed. */
/* The Freight pane's own box styling is gone: it carries .preset-panel
   .cfs-preset-panel now, like the preset editor and Custom, and takes its frame, padding
   and internal layout from those. What was here was `grid-template-columns: 1fr 1fr` —
   trailer in one half, three sliders in the other. Both halves are gone: the sliders were
   replaced by the same typed fields the other panes use, and the trailer moved into the
   shared .dims-preview-row as the right-hand visual. Task #3551. */

/* ── Freight: floor-space stepper ───────────────────────────────────────────
   The count is the value that gets submitted; the grid says WHICH spaces. Most runs
   want "n spaces" and never care which, so the stepper leads — and unlike the grid it
   can be used without aiming at a 16px target. */
.cfs-stepper {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid #cbd5e1;
    border-radius: 6px;
    overflow: hidden;
    background: #fff;
}

.cfs-stepper-btn {
    width: 30px;
    padding: 0;
    border: none;
    background: #fff;
    color: #64748b;
    cursor: pointer;
    font-size: 0.9rem;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, color 0.15s;
}

.cfs-stepper-btn:hover:not(:disabled) {
    background: #e7eefa;
    color: var(--pc-primary, #0046ad);
}

.cfs-stepper-btn:disabled {
    color: #cbd5e1;
    cursor: default;
}

/* Matches .preset-spec-input's type so a number typed here and one typed on any other
   pane read as the same kind of value. Borders come from the stepper shell instead. */
.cfs-stepper-input {
    width: 3.2rem;
    padding: 0.2rem 0.35rem;
    border: none;
    border-left: 1px solid #e2e8f0;
    border-right: 1px solid #e2e8f0;
    text-align: center;
    font-size: 1.05rem;
    font-weight: 600;
    color: #1e293b;
    font-variant-numeric: tabular-nums;
    background: #fff;
}

.cfs-stepper-input:focus {
    outline: none;
    box-shadow: inset 0 0 0 2px rgba(59, 130, 246, 0.25);
}

/* Same red border every other required field uses — see .preset-spec-input.is-invalid.
   It lands on the shell because the input inside has no border of its own. A tinted fill
   was wrong twice over: it invented a second way to say "required" alongside the border,
   and it read as a state of the value rather than a prompt for one. */
.cfs-stepper.is-invalid {
    border-color: #dc2626;
}

.cfs-stepper-input::-webkit-inner-spin-button,
.cfs-stepper-input::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.cfs-stepper-note {
    font-size: 0.72rem;
    color: #94a3b8;
}

/* ── Freight: the trailer as a fixed-size visual ────────────────────────────
   Sized like the 3D box scene rather than stretched. flex: 0 0 auto is the whole fix —
   the column no longer grows, so .cfs-floor-spot's fixed cell size decides the trailer's
   width instead of the trailer's width deciding the cell size. */
.cfs-trailer-col {
    flex: 0 0 auto;
    align-items: flex-start;
    padding: 0;

    /* Top edge level with the first INPUT rather than the heading above it — the line the
       3D box hits on the other panes. The offset is that heading's height plus its margin,
       which the trailer no longer has of its own now that "Trailer floor" is gone. Same
       value Place Order uses. */
    margin-top: calc(1.15rem + 0.45rem);
}

/* Wraps rather than running on: it lives in a ~7rem column beside the trailer now, not
   on a full-width line beneath it, and two swatches don't fit side by side there. */
.cfs-floor-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.15rem 0.7rem;
    font-size: 0.66rem;
    color: #94a3b8;
}

.cfs-floor-legend span {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

.cfs-legend-swatch {
    width: 9px;
    height: 9px;
    border-radius: 2px;
    border: 1px solid #d1d5db;
    display: inline-block;
}

.cfs-legend-swatch.selected {
    background: #3b82f6;
    border-color: #3b82f6;
}

.cfs-legend-swatch.occupied {
    background: #e2e8f0;
}

.cfs-floor-hint {
    margin-top: 0.3rem;
    font-size: 0.7rem;
    line-height: 1.25;
    color: #94a3b8;
}

/* Hidden with the same class the 3D preview uses, so both visuals collapse the same way. */
.dims-preview-row.preview-hidden .cfs-trailer-col {
    display: none;
}

/* The floor-grid header (.cfs-floor-grid-section / -label / -count-input / -hint) is
   gone: the count moved into the left column as .cfs-stepper, and the "click spots or
   type the count" hint became the legend under the trailer. Task #3551. */

/* Grid and its notes side by side, so the notes cost width — which this column has —
   rather than height, which the standing trailer does not. Matches Place Order's
   .floor-grid-aside. */
.cfs-floor-aside {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
}

.cfs-floor-notes {
    max-width: 7rem;
    padding-top: 0.1rem;
}

/* Standing: the container stacks, the grid lays its two rows out side by side as lanes,
   and each lane runs down the page. The markup still emits 2 rows of 13 and the indices
   still read row * 13 + col — flex direction alone transposes it, so nothing downstream
   changes. .cfs-floor-grid-cab is gone with the cab stripe it painted. */
.cfs-floor-grid-container {
    display: flex;
    flex-direction: column;
    width: max-content;
    background: #f8fafc;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
    overflow: hidden;
}

/* Tight padding and gutters: thirteen rows multiply every vertical pixel by thirteen, so
   the gaps are where the height actually goes. */
.cfs-floor-grid {
    flex: 0 0 auto;
    display: flex;
    flex-direction: row;
    justify-content: center;
    padding: 3px;
    gap: 2px;
    user-select: none;
    -webkit-user-select: none;
    min-width: 0;
}

.cfs-floor-grid-row {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

/* A FIXED cell, not flex: 1.
   With flex: 1 the thirteen columns absorbed whatever width the pane happened to offer,
   so the trailer grew for no reason connected to freight — it was simply the residue of a
   1fr 1fr split made to seat three sliders, and it made this the widest pane on the card.

   30x15 matches Place Order exactly. The spend goes into WIDTH rather than height because
   height is multiplied by thirteen and width only by two: 450px of target, twice the
   16x14 that read as too small, in a trailer that still stands well short of the fields
   beside it. It is also the right shape — a pallet space seen from above is 48 long by 40
   wide. Task #3551. */
.cfs-floor-spot {
    width: 30px;
    height: 15px;
    flex: 0 0 auto;
    background: white;
    border: 1px solid #d1d5db;
    border-radius: 2px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.6rem;
    color: transparent;
    user-select: none;
    -webkit-user-select: none;
    transition: background 0.1s ease, border-color 0.1s ease;
}

.cfs-floor-spot:hover {
    background: #e0f2fe;
    border-color: #7dd3fc;
}

.cfs-floor-spot:active {
    background: #bae6fd;
    border-color: #38bdf8;
}

.cfs-floor-spot.selected {
    background: #3b82f6;
    border-color: #2563eb;
    color: white;
}

.cfs-floor-spot.selected i {
    font-size: 0.7rem;
}

/* Occupied — the position belongs to another shipment riding the same
   leg span. Greyed out, subtle lock icon, hover/active disabled, and
   the cursor is not-allowed so the user reads "I can't put my pallet
   here." Click and drag handlers in CompactFreightSelector also bail
   on these so a no-op interaction can't leak through. */
.cfs-floor-spot.occupied {
    background: #e2e8f0;
    border-color: #cbd5e0;
    color: #94a3b8;
    cursor: not-allowed;
}

.cfs-floor-spot.occupied:hover,
.cfs-floor-spot.occupied:active {
    background: #e2e8f0;
    border-color: #cbd5e0;
}

.cfs-floor-spot.occupied i {
    font-size: 0.65rem;
    color: #94a3b8;
}

/* The Freight pane's three sliders are gone, and .cfs-slider-* with them. They were
   replaced by the same typed preset-spec-* fields the other panes use — one control
   vocabulary across the whole selector, and nobody liked the sliders. Task #3551. */

/* The Custom pane's own box styling is gone: it now carries .preset-panel
   .cfs-preset-panel alongside this class and takes its frame, padding and header from
   the same rules a selected preset uses. This class survives purely as a hook for the
   handful of places Custom still differs.

   Two earlier layouts lived here — a 50/50 grid for the old slider pane, then a single
   1fr column after .dims-preview-row took over the internal layout. Neither is needed:
   .preset-editor-body is the flex column now. Task #3548. */



/* Numeric cell — shared between pallet & custom panes. */
.cfs-num {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.cfs-num label {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #64748b;
    font-weight: 600;
}

.cfs-num input {
    width: 100%;
    padding: 0.3rem 0.4rem;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
    text-align: center;
}

.cfs-num input:focus {
    outline: none;
    border-color: #0046ad;
    box-shadow: 0 0 0 2px rgba(0, 70, 173, 0.12);
}

/* Bottom-of-component summary line — "X pc · Y lb · L×W×H" so the user
   has a quick read of the spec without scanning the inputs themselves. */
.cfs-summary {
    font-size: 0.75rem;
    color: #64748b;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.cfs-summary i {
    font-size: 0.85rem;
    color: #94a3b8;
}

/* ============================================
   Property Tag Selector Styles
   Task #2516: Property Tag Selection
   ============================================ */

/* Location Type Pills (Single-Select) */
.property-tag-selector .property-pill {
    padding: 0.375rem 0.75rem;
    font-size: 0.875rem;
    border-radius: 50rem; /* Pill shape */
    transition: all 0.15s ease-in-out;
}

.property-tag-selector .property-pill:hover {
    transform: translateY(-1px);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* Selected Properties Container - dropdown-style appearance */
.property-tag-selector .selected-properties {
    position: relative;
    border: 1px solid #ced4da;
    border-radius: 0.375rem;
    background-color: #fff;
    padding: 0.5rem 0.75rem;
    transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.property-tag-selector .selected-properties:hover {
    border-color: #94a3b8;
}

.property-tag-selector .selected-properties.expanded {
    border-color: #3182ce;
    box-shadow: 0 0 0 2px rgba(49, 130, 206, 0.15);
}

/* Empty state - dropdown-style appearance (all properties consolidated here) */
.property-tag-selector .property-empty-state {
    position: relative;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.5rem 0.75rem;
    border: 1px solid #ced4da;
    border-radius: 0.375rem;
    background-color: #fff;
    color: #64748b;
    font-size: 0.875rem;
    cursor: pointer;
    transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.property-tag-selector .property-empty-state:hover {
    border-color: #94a3b8;
}

.property-tag-selector .property-empty-state.expanded {
    border-color: #3182ce;
    box-shadow: 0 0 0 2px rgba(49, 130, 206, 0.15);
}

/* Editable string property text - shows it's clickable */
.property-tag-selector .property-pill-editable {
    cursor: pointer;
    border-bottom: 1px dashed rgba(0, 0, 0, 0.3);
}

.property-tag-selector .property-pill-editable:hover {
    border-bottom-color: rgba(0, 0, 0, 0.6);
}

/* Empty state container - positions dropdown relative to trigger */
.property-tag-selector .property-empty-state-container {
    position: relative;
}

/* Dropdown chevron indicator - lay flush inside the trigger row */
.property-tag-selector .property-empty-state .property-pill-unselected-dd,
.property-tag-selector .selected-properties .property-pill-unselected-dd {
    flex-shrink: 0;
}

/* Chevron rotation when dropdown is open */
.property-tag-selector .chevron-rotated {
    transform: rotate(180deg);
}

.property-tag-selector .fa-chevron-down {
    transition: transform 0.15s ease-in-out;
}

/* Add more link - shown below selected tags */
.property-tag-selector .property-add-more {
    color: #6c757d;
    font-size: 0.8rem;
    cursor: pointer;
    transition: color 0.15s ease-in-out;
}

.property-tag-selector .property-add-more:hover {
    color: #0d6efd;
}

/* Property container - positioning context for dropdown */
.property-tag-selector .property-container {
    position: relative;
}

/* Available tags container - dropdown style with expand animation */
.property-tag-selector .available-tags-inline {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 1001;
    padding: 0.75rem;
    background: #fff;
    border: 1px solid #e2e8f0;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    /* Expand animation */
    animation: dropdownExpand 0.2s ease-out forwards;
    transform-origin: top center;
}

@keyframes dropdownExpand {
    0% {
        opacity: 0;
        transform: scaleY(0);
    }
    100% {
        opacity: 1;
        transform: scaleY(1);
    }
}

.property-tag-selector .available-tags-close {
    display: none; /* Hidden for now - collapse via chevron toggle or clicking selected tags */
    position: absolute;
    bottom: 0.25rem;
    right: 0.25rem;
    padding: 0.25rem 0.5rem;
    font-size: 0.875rem;
    color: #a0aec0;
    background: transparent;
    border: none;
    cursor: pointer;
    line-height: 1;
}

.property-tag-selector .available-tags-close:hover {
    color: #718096;
}


/* Property tag pill sizing — shrink Bootstrap's btn primitive to tag-chip
   proportions via the button CSS variables. Targets the pill classes
   directly so the rule does NOT cascade onto the Cancel/Save/Remove
   buttons inside the string-input modal (which also lives under the
   .property-tag-selector wrapper). */
.property-tag-selector .btn.property-pill-selected,
.property-tag-selector .btn.property-pill-unselected,
.property-tag-selector .btn.property-pill-unselected-dd {
    --bs-btn-padding-y: 0.2rem;
    --bs-btn-padding-x: 0.65rem;
    --bs-btn-font-size: 0.78rem;
    --bs-btn-line-height: 1.35;
    padding: 0.2rem 0.65rem;
    font-size: 0.78rem;
    line-height: 1.35;
}

/* Selected pill — matches .cfs-chip.selected (freight-category brand blue):
   blue border + text on a very light blue fill. */
.property-tag-selector .btn.property-pill-selected {
    --bs-btn-color: #0046ad;
    --bs-btn-bg: #e7eefa;
    --bs-btn-border-color: #0046ad;
    --bs-btn-hover-color: #0046ad;
    --bs-btn-hover-bg: #d6e2f5;
    --bs-btn-hover-border-color: #0046ad;
    --bs-btn-active-color: #0046ad;
    --bs-btn-active-bg: #d6e2f5;
    --bs-btn-active-border-color: #0046ad;
}

/* Unselected pill — white fill, light slate border, text color matched
   to the parent .inline-tags-container (#4a5568) so the pills read as
   "tags in this list" rather than slightly-darker chips. Brand-blue
   border on hover (no fill change). */
.property-tag-selector .btn.property-pill-unselected,
.property-tag-selector .btn.property-pill-unselected-dd {
    --bs-btn-color: #4a5568;
    --bs-btn-bg: #ffffff;
    --bs-btn-border-color: #e2e8f0;
    --bs-btn-hover-color: #4a5568;
    --bs-btn-hover-bg: #ffffff;
    --bs-btn-hover-border-color: #0046ad;
    --bs-btn-active-color: #4a5568;
    --bs-btn-active-bg: #ffffff;
    --bs-btn-active-border-color: #0046ad;
}

/* Optional section header above the tag row (e.g. "Location Options"). Labels the
   section — matching the static field labels — and hosts the default star on its
   right. */
.property-tag-selector .property-section-header {
    display: flex;
    align-items: center;
    /* Match the field labels' tight label-to-body gap (was 0.35rem). */
    margin-bottom: 0.15rem;
}

.property-tag-selector .property-section-header-text {
    font-size: 0.8em;
    font-weight: 500;
    color: #4a5568;
    /* line-height: 1 hugs the glyphs so the header text centers with the star in
       the flex row (1.2 inflated the box and let the caps ride high — star low). */
    line-height: 1;
}

/* "Set as default" star for the whole tag set — a bare star (NOT a pill). Hollow
   grey = click to save the current set as the default; filled gold = the selection
   already matches the saved default (and is a toggle: click to clear). Matches the
   star convention on the Instructions/Contact fields. Lives on the section header. */
.property-tag-selector .property-tags-default-star {
    display: inline-flex;
    align-items: center;
    align-self: stretch;
    background: none;
    border: none;
    padding: 0 0.15rem;
    margin-left: 0.1rem;
    line-height: 1;
    /* 0.6em (not 0.75em) so this star matches the field stars' rendered size:
       the field star is 0.75em OF the 0.8em label (≈ 0.6em here), but this one
       resolves against the header's full-size font. */
    font-size: 0.6em;
    color: #a0aec0;
    cursor: pointer;
}

.property-tag-selector .property-tags-default-star:hover:not(:disabled) {
    color: #f0ad00;
}

.property-tag-selector .property-tags-default-star.is-default {
    color: #f0ad00;
}

/* Filled star is a toggle (click to clear the default); dim slightly on hover to
   signal it's actionable. */
.property-tag-selector .property-tags-default-star.is-default:hover {
    color: #c98f00;
}

.property-tag-selector .property-tags-default-star:disabled {
    cursor: default;
}

.property-tag-selector .property-tags-default-star .spinner-border {
    width: 0.85rem;
    height: 0.85rem;
    border-width: 0.15em;
    color: #f0ad00;
}

/* Dropdown styling */
.property-tag-selector .dropdown-item {
    font-size: 0.875rem;
    padding: 0.5rem 1rem;
}

.property-tag-selector .dropdown-item:hover {
    background-color: #e9ecef;
}

/* Modal styling for smaller modals */
.property-tag-selector .modal-sm {
    max-width: 380px;
}

/* Explicit colors on the string-input modal so the chrome doesn't inherit
   from a dark parent context (continuation stop card, address card header,
   etc.). Without this the title rendered dark-on-dark in some surfaces. */
.pts-string-modal .modal-content {
    background-color: #ffffff;
    color: #212529;
    border: 1px solid #dee2e6;
    border-radius: 0.5rem;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
}

.pts-string-modal .modal-header {
    padding: 0.75rem 1rem;
    background-color: #f8f9fa;
    border-bottom: 1px solid #e9ecef;
    border-top-left-radius: 0.5rem;
    border-top-right-radius: 0.5rem;
}

.pts-string-modal .modal-title {
    color: #1f2937;
    font-size: 1rem;
    font-weight: 600;
    display: flex;
    align-items: center;
}

.pts-string-modal .modal-title .fa-tag {
    color: #6b7280;
    font-size: 0.875rem;
}

.pts-string-modal .modal-body {
    padding: 1rem;
}

.pts-string-modal .modal-body .form-label {
    color: #6b7280;
    font-weight: 500;
}

.pts-string-modal .modal-footer {
    padding: 0.5rem 1rem;
    border-top: 1px solid #e9ecef;
    background-color: #fafafa;
    border-bottom-left-radius: 0.5rem;
    border-bottom-right-radius: 0.5rem;
}

/* ============================================
   INLINE MODE - All options always visible
   ============================================ */

.property-tag-selector.inline-mode .inline-tags-container {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
}

/* ---- Location Options as a fieldset ----------------------------------------
   Frame the pill row and float its section header onto the top border as a
   legend — the same treatment as the contact/instructions field legends, so a
   location card reads as one consistent family. Scoped with :has() to only fire
   when a section header exists; a headerless inline tag row stays borderless.
   #dee2e6 matches the field inputs' (Bootstrap default) border. */
.property-tag-selector.inline-mode:has(.property-section-header) .inline-tags-container {
    border: 1px solid #dee2e6;
    border-radius: var(--pc-radius-sm, 8px);
    padding: 0.7rem;
}

/* The header text + default-set star become the legend riding the frame's top
   border. .property-container is already position: relative (the positioning
   context); making the header absolute drops it out of flow so the pill frame
   rises to the top and the legend sits on its border. */
.property-tag-selector.inline-mode .property-section-header {
    position: absolute;
    top: 0;
    left: 0.55rem;
    transform: translateY(-50%);
    z-index: 3;
    margin: 0;                      /* was margin-bottom: 0.15rem (label-above) */
    padding: 0 0.35rem;            /* breathing room L/R of the text in the gap */
    background: var(--pc-fieldset-bg, #fff);   /* mask that cuts the border */
    line-height: 1.1;
}

.property-tag-selector.inline-mode .property-section-header-text {
    /* Same as the field legends / address combobox floated label. */
    font-size: 0.765rem;
    font-weight: 400;
    color: rgba(0, 0, 0, 0.65);
    line-height: 1.1;
}

/* Location Type dropdown selector (top right of address card) */
.address-location-type {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}

.location-type-dropdown .btn {
    padding: 0.2rem 0.5rem;
    font-size: 0.75rem;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    background: #f9fafb;
    border-color: #d1d5db;
    color: #4b5563;
}

.location-type-dropdown .btn:hover {
    background: #e5e7eb;
    border-color: #9ca3af;
    color: #374151;
}

.location-type-dropdown .btn i {
    font-size: 0.8rem;
}

.location-type-dropdown .dropdown-menu-sm {
    min-width: 140px;
    font-size: 0.8rem;
    padding: 0.25rem 0;
}

.location-type-dropdown .dropdown-item {
    padding: 0.35rem 0.75rem;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.location-type-dropdown .dropdown-item i {
    width: 1rem;
    text-align: center;
}

.location-type-dropdown .dropdown-item.active {
    background-color: #3b82f6;
    color: #fff;
}

/* Ensure dropdown menu displays when Blazor adds 'show' class */
.location-type-dropdown.show .dropdown-menu.show {
    display: block;
    position: absolute;
    z-index: 1000;
}

/* Legacy .address-edit-btn removed - now using .address-edit-link in footer */

/* Address Edit Modal */
.address-edit-modal {
    max-width: 500px;
    width: 90%;
}

.address-edit-modal .modal-body {
    padding: 1.5rem;
}

.address-edit-modal .form-group {
    margin-bottom: 1rem;
}

.address-edit-modal .form-group > label {
    display: block;
    margin-bottom: 0.35rem;
    font-weight: 500;
    color: #374151;
    font-size: 0.9rem;
}

.address-edit-modal .form-row {
    display: flex;
    gap: 1rem;
}

.address-edit-modal .form-row .form-group {
    flex: 1;
}

.address-edit-modal .form-row .form-group-small {
    flex: 0 0 80px;
}

.address-edit-modal .modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    padding: 1rem 1.5rem;
    border-top: 1px solid #e5e7eb;
}

.address-edit-modal .modal-footer .btn-outline-danger {
    margin-right: auto;
}

/* Address Book Modal List */
.address-book-list {
    max-height: 400px;
    overflow-y: auto;
}

.address-book-item {
    padding: 0.75rem 1rem;
    border: 1px solid #e5e7eb;
    border-radius: 6px;
    margin-bottom: 0.5rem;
    cursor: pointer;
    transition: all 0.15s ease;
}

.address-book-item:hover {
    background-color: #f3f4f6;
    border-color: #3b82f6;
}

.address-book-item:last-child {
    margin-bottom: 0;
}

.address-book-item-name {
    font-weight: 600;
    color: #1f2937;
    margin-bottom: 0.25rem;
}

.address-book-item-address {
    font-size: 0.9rem;
    color: #4b5563;
}

.address-book-item-city {
    font-size: 0.85rem;
    color: #6b7280;
}
  
/* ============================================
   Contact Fields Layout
   ============================================ */

.base-fields-section {
    margin-bottom: 0.0rem;
}

.base-fields-section .form-row {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); /* 60/40 split for Contact Person / Phone */
    gap: 1rem;
}

@media (max-width: 576px) {
    .base-fields-section .form-row {
        grid-template-columns: 1fr;
        /* Vertical gap between stacked Contact Person + Contact Phone fields
           when the 60/40 grid collapses to a single column on mobile. */
        gap: 0.75rem;
    }

    /* Breathing room between the contact pair and the Instructions
       textarea that follows the .base-fields-section wrapper. */
    .base-fields-section {
        margin-bottom: 0.75rem;
    }
}

/* Character counter for textareas */
.form-floating .char-counter {
    display: block;
    margin-top: 0.25rem;
}

/* ==============================================
   Error Display Component (Global)
   Shows API errors with stack traces in non-prod
   ============================================== */

.error-display {
    text-align: center;
    padding: 2rem;
    background: white;
    border-radius: 8px;
}

.error-details {
    text-align: left;
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
    font-size: 0.8rem;
    background: #fff5f5;
    border: 1px solid #feb2b2;
    border-radius: 4px;
    padding: 1rem;
    margin-bottom: 1rem;
    max-height: 400px;
    overflow-y: auto;
    white-space: pre-wrap;
    word-wrap: break-word;
    color: #c53030;
}
/* ==============================================
   Share Link Button (Footer)
   ============================================== */

.share-link-btn {
    background: transparent;
    border: none;
    color: #718096;
    cursor: pointer;
    font-size: 0.875rem;
    padding: 0;
    transition: color 0.2s;
}

.share-link-btn:hover {
    color: #3182ce;
}

.share-link-btn i {
    margin-right: 0.25rem;
}

/* ==============================================
   Contact Required Field - Pulsing Red Outline
   Applied when location type requires contact info
   ============================================== */

.contact-required-field,
.contact-required-field .form-control {
    border-color: #ef4444 !important;
    animation: contact-pulse 2s ease-in-out infinite;
}

/* Required-but-empty reference / billing fields (OrderReferenceFields applies
   `required-empty` to the EditableCombobox/input once HasAttemptedValidation flips).
   The class was applied but had no rule, so a missing required field showed only the
   submit toast and never highlighted. Shares the red border + pulse with
   .contact-required-field. */
.required-empty,
.required-empty .form-control {
    border-color: #ef4444 !important;
    animation: contact-pulse 2s ease-in-out infinite;
}

@keyframes contact-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }
    50% { box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.2); }
}

/* ==============================================
   Global Mobile Utility Styles
   Consistent mobile UX patterns across all pages
   ============================================== */

/* Touch target minimum size (44x44px per Apple HIG / Material Design).
   Applied to primary actions and form fields, but NOT inside compact UI areas
   like table toolbars, page headers, or data tables where density matters. */
@media (max-width: 768px) {
    /* Buttons — exclude compact header/toolbar controls */
    .btn,
    button:not(.btn-close):not(.btn-icon):not(.gh-btn) {
        min-height: 32px;
    }

    /* Form controls — touch-friendly sizing (exclude drum-input which must match its 36px container) */
    .form-control,
    input[type="text"],
    input[type="email"],
    input[type="password"],
    input[type="tel"],
    input[type="number"]:not(.drum-input),
    input[type="date"],
    input[type="time"],
    select,
    textarea {
        min-height: 32px;
    }

    /* Reset min-height inside compact areas (table toolbars, table containers, page headers,
       Card.razor header rows). Specificity must match or beat the rules above, so we
       repeat the full selectors scoped to the compact container. */
    .pc-table-container .btn,
    .pc-table-container button:not(.btn-close):not(.btn-icon):not(.gh-btn),
    .pc-table-container .form-control,
    .pc-table-container input[type="text"],
    .pc-table-container select,
    .page-header .btn,
    .page-header button:not(.btn-close):not(.btn-icon):not(.gh-btn),
    .page-header .form-control,
    .page-header input[type="text"],
    .cp-card-header-row .btn,
    .cp-card-header-row button:not(.btn-close):not(.btn-icon):not(.gh-btn) {
        min-height: unset;
    }

    /* Checkboxes and radios */
    .form-check-input,
    input[type="checkbox"],
    input[type="radio"] {
        min-width: 24px;
        min-height: 24px;
    }

    /* Links in touch context */
    a.nav-link,
    a.dropdown-item {
        min-height: 32px;
        display: flex;
        align-items: center;
    }

    /* Page titles smaller on mobile */
    h1 {
        font-size: 1.5rem;
    }

    h2 {
        font-size: 1.25rem;
    }

    /* Cards reduced padding on mobile */
    .cp-card {
        padding: 0.75rem;
    }

    /* Hide decorative elements on mobile to save space */
    .desktop-only {
        display: none !important;
    }
}

/* Show elements only on mobile */
.mobile-only {
    display: none;
}

@media (max-width: 768px) {
    .mobile-only {
        display: block;
    }
}

/* Prevent horizontal overflow on mobile */
@media (max-width: 768px) {
    body {
        overflow-x: hidden;
    }
}



/* ================================================================
   SHARED PAGE HEADER — consistent bar across all content pages.
   Structure: .page-header > .page-header-left + .page-header-right
   .page-header-left: title + breadcrumb (page-specific)
   .page-header-right: GlobalHeaderActions (chat, bell, account)
   Page-specific actions go in .page-action-bar below the header.
   ================================================================ */
.page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: white;
    /*border-bottom: 1px solid #e2e8f0;*/
    padding: 0.3rem 1.25rem;
}

/* Subsidiary brand icon at the left of the mobile header (the .page-header is
   mobile-only; the desktop strip has its own brand). */
.page-header-brand-icon {
    width: 28px;
    height: 28px;
    box-sizing: border-box;
    object-fit: contain;
    flex-shrink: 0;
    margin-right: 0.5rem;
    /* White chip (like the desktop strip) so the transparent, dark-foreground
       icon reads on a colored header (B) as well as the white ones (A/D). */
    background: #fff;
    border-radius: 6px;
    padding: 2px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
}

/* Text fallback (SubsidiaryBrandMark): subsidiaries with no RailIconUrl show
   their Code (e.g. "SF") centered in the same white chip, in brand color. */
.page-header-brand-icon-text {
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.72rem;
    line-height: 1;
    text-transform: uppercase;
    color: var(--pc-primary, #1a365d);
    overflow: hidden;
}

/* ============================================================================
   HEADER LAYOUT (desktop) — a single brand-blue "org strip" that IS the whole
   header on one row: subsidiary brand (left) + page title (projected from each
   page's <AppPageHeader> via SectionOutlet) + quick-action pills +
   GlobalHeaderActions (right). The per-page .page-header is the MOBILE header
   only (hidden on desktop). Sidebar/content offsets (var(--pc-chrome-h)) live in
   MainLayout.razor.css. */

.org-strip {
    display: none;   /* desktop-only; shown in the media query below */
}

@media (min-width: 769px) {
    /* The org strip is the whole desktop header; .page-header is mobile-only. */
    .page-header {
        display: none;
    }

    .org-strip {
        display: flex;
        align-items: center;
        gap: .5rem;
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        height: var(--pc-orgstrip-h);
        padding: 0 1rem;
        z-index: 1001;
    }

    .org-brand {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        text-decoration: none;
        color: inherit;                  /* follows the per-style strip text color */
        font-weight: 600;
        /*font-size: 0.9rem;*/
        white-space: nowrap;
    }

    .org-brand-icon {
        width: 24px;
        height: 24px;
        box-sizing: border-box;
        object-fit: contain;
        /* White chip — the icon is transparent with a dark foreground; the shadow
           keeps it defined on the white strips (A/D) too, not just the blue (B). */
        background: #fff;
        border-radius: 5px;
        padding: 2px;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
    }

    /* Text fallback (SubsidiaryBrandMark): subsidiaries with no RailIconUrl show
       their Code (e.g. "SF") centered in the same white chip, in brand color. */
    .org-brand-icon-text {
        display: flex;
        align-items: center;
        justify-content: center;
        font-weight: 700;
        font-size: 0.62rem;
        line-height: 1;
        text-transform: uppercase;
        color: var(--pc-primary, #1a365d);
        overflow: hidden;
    }

    /* Page title — projected from the active page's <AppPageHeader> into the
       SectionOutlet here, with a "›" breadcrumb before it. */
    .org-strip .gh-page-title {
        display: flex;
        align-items: center;
        min-width: 0;
    }

    .org-strip .gh-page-title::before {
        /* bi-chevron-right (the Bootstrap Icons font) instead of the "›" text
           glyph — icon glyphs are centered in their em box, so it sits level
           with the text instead of hanging at the baseline. */
        content: "\F285";
        font-family: "bootstrap-icons";
        font-weight: normal;
        font-size: 0.85rem;
        line-height: 1;
        margin: 0 0.4rem 0 0.15rem;
        opacity: 0.5;
    }

    .org-strip .gh-page-title h1 {
        margin: 0;
        font-size: 1rem;
        font-weight: 600;
        color: inherit;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .org-pills {
        display: flex;
        align-items: center;
    }

    /* Push GlobalHeaderActions (account etc.) to the right edge of the strip.
       Also drop the base .gh-actions `padding-top: 0.1rem` here: on the org strip
       that padding sits the whole cluster (help, bell, account) ~0.8px below the
       Quick Actions split button's centerline — the split button has no such
       padding, so it defines the strip's true center. Zeroing it re-centers the
       cluster on that line. (Base padding-top stays for the mobile page-header.) */
    .org-strip .gh-actions {
        margin-left: auto;
        padding-top: 0;
    }

    /* The strip's quick-actions trigger is a compact CTA on EVERY page now (not
       just the dashboard): let the title flex-grow so it right-aligns next to the
       support / profile cluster instead of sitting beside the title. */
    .org-strip .gh-page-title {
        flex: 1 1 auto;
    }

    /* Widen the button to the dropdown's width so the menu can left-align exactly
       under it, and rest in the highlighted (previously hover) look: light fill +
       accent outline + accent text. */
    .org-strip .org-pills .gh-btn {
        box-sizing: border-box;
        width: 240px;
        justify-content: flex-start;
        /*background: #f7fafc;*/
        /*border-color: var(--pc-accent);*/
        /*color: var(--pc-accent-ink);*/
        transition: box-shadow 0.15s ease;
    }

    /* Hover adds a soft neutral glow to signal the pointer is over it (slate,
       not the brand accent, so it stays calm on red-accent brands). */
    .org-strip .org-pills .gh-btn:hover {
        background: #f7fafc;
        border-color: #cbd5e1;
        color: var(--pc-accent-ink);
        box-shadow: 0 0 10px rgba(100, 116, 139, 0.25);
    }

    /* The dropdown gets a soft neutral outline + drop shadow (slate, not the
       brand accent), detached a little below the button, left-aligned under it. */
    .org-strip .org-pills .db-ham-panel.qah-panel {
        left: 0;
        right: auto;
        top: calc(100% + 4px);
        border: 1px solid #e2e8f0;
        border-radius: 8px;
        box-shadow: 0 0 0 3px rgba(100, 116, 139, 0.10),
                    0 0 18px rgba(100, 116, 139, 0.18),
                    0 10px 28px rgba(15, 23, 42, 0.18);
    }

    /* The Recent / Templates / Pinned sub-views widen the panel (~480px). The
       button sits on the right, so a left-anchored wide panel runs off the right
       edge — right-anchor it instead, so the extra width extends LEFT (toward the
       title) and stays on screen. */
    .org-strip .org-pills .db-ham-panel.qah-panel.db-ham-panel-wide {
        left: auto;
        right: 0;
    }

    /* ── Org strip colors — brand header ──────────────────────────────────────
       The strip tracks --pc-card-header (the header-block color), NOT the raw
       accent. For PCE that variable falls back to the accent (#0046ad blue), so
       PCE is unchanged; Street Fleet sets ThemeHeaderColor to its charcoal so the
       header isn't a harsh red block while red stays on links/CTAs/focus. The
       Quick Actions pill and account avatar render near-solid white with
       accent-colored content so they pop as clear affordances against the header. */
    .org-strip {
        background: var(--pc-card-header);
        color: #fff;
    }

    /* White icon buttons on the brand-blue strip. */
    .org-strip .gh-btn {
        color: rgba(255, 255, 255, 0.9);
        background: transparent;
        border-color: transparent;
    }

    .org-strip .gh-btn:hover {
        background: rgba(255, 255, 255, 0.15);
        border-color: transparent;
        color: #fff;
    }

    /* The Quick Actions pill: near-solid white with accent content. */
    .org-strip .org-pills .gh-btn {
        background: rgba(255, 255, 255, 0.92);
        border-color: transparent;
        color: var(--pc-accent-ink);
    }

    .org-strip .org-pills .gh-btn:hover {
        background: #fff;
        border-color: transparent;
        color: var(--pc-accent-ink);
        box-shadow: 0 0 12px rgba(255, 255, 255, 0.6);
    }
}

/* Account trigger rendered as an initials avatar (replaces the person icon).
   Filled accent rounded-rect by default; the desktop org strip + mobile header
   override it to a near-solid-white chip with accent initials (rules below). */
.gh-btn.gh-acct-trigger {
    /* CustID badge: a rounded RECTANGLE (not a fixed circle) that grows to fit the
       full customer id at a readable size — so long ids stay legible instead of
       being shrunk to fit a 32px circle. Height stays 32px (from .gh-btn) to line
       up with the other header buttons. */
    width: auto;
    padding: 0 0.55rem;
    border-radius: 7px;
    background: var(--pc-primary);
    color: #fff;
    border: none;
    font-weight: 600;
    font-size: 0.78rem;
    white-space: nowrap;
}

.gh-btn.gh-acct-trigger:hover {
    background: var(--pc-accent);
    color: #fff;
}

@media (min-width: 769px) {
    /* 3D-raised chip to match the Quick Actions split button beside it: the same
       light top-to-bottom gradient face, a 1px inset top highlight, and a raised
       ring + soft cast shadow. Kept as box-shadow (not a real border) so it adds
       no width — the chip still grows to fit the full CustID. */
    .org-strip .gh-acct-trigger {
        background: linear-gradient(#ffffff, #e4e9f1);
        color: var(--pc-accent-ink);
        box-shadow: 0 1px 2px rgba(15, 23, 42, 0.28),
                    0 0 0 1px rgba(15, 23, 42, 0.18),
                    inset 0 1px 0 rgba(255, 255, 255, 0.9);
    }

    .org-strip .gh-acct-trigger:hover {
        background: linear-gradient(#ffffff, #d7deea);
        color: var(--pc-accent);
    }

    /* ── LIGHT BLADE ─────────────────────────────────────────────────────────
       The left nav is light so it never clashes with the brand-blue header.
       The `theme-brand` body class (applied permanently by MainLayout) gives
       these desktop overrides enough specificity to beat the scoped DARK defaults
       in NavMenu / MainLayout / CustomerContextSelector — those scoped rules still
       drive the MOBILE slide-over nav (this override is desktop-only via the media
       query). Flyout popups (cctx-flyout, admin-flyout) stay dark — they're overlays. */
    body.theme-brand .sidebar {
        background: #f8fafc;
        border-right: 1px solid #e2e8f0;
    }

    body.theme-brand .sidebar-nav .nav-link,
    body.theme-brand .sidebar-footer .nav-link,
    body.theme-brand .sidebar-nav .nav-sublink {
        color: #64748b;
    }

    body.theme-brand .sidebar-nav .nav-link:hover,
    body.theme-brand .sidebar-footer .nav-link:hover,
    body.theme-brand .sidebar-nav .nav-sublink:hover {
        background: #f1f5f9;
        color: #1e293b;
    }

    body.theme-brand .sidebar-nav .nav-link.active,
    body.theme-brand .sidebar-nav .nav-sublink.active {
        background: rgba(100, 116, 139, 0.12);
        box-shadow: none;
        color: var(--pc-accent-ink);
    }

    body.theme-brand .sidebar-nav .nav-link.active .nav-icon {
        color: var(--pc-accent-ink);
    }

    /* User identity card — static (single-customer). */
    body.theme-brand .user-card-static {
        background: #eef2f7;
        border-color: #e2e8f0;
    }

    body.theme-brand .user-card-name {
        color: #1e293b;
    }

    body.theme-brand .user-card-acct {
        color: #94a3b8;
    }

    /* NOTE: CustomerContextSelector styles itself entirely in its scoped CSS
       (per page focus: write = flat underline / no box, read = soft card). The
       cctx theme-brand overrides that used to live here were removed — the
       .cctx-card background override in particular forced a card on the write
       control, which should be just the underline. */

    /* Borders, dividers, collapse + admin toggles. */
    body.theme-brand .sidebar-footer,
    body.theme-brand .nav-divider {
        border-color: #e2e8f0;
    }

    body.theme-brand .nav-divider {
        background-color: #e2e8f0;
    }

    body.theme-brand .sidebar-collapse-toggle {
        background: #f1f5f9;
        color: #64748b;
    }

    body.theme-brand .sidebar-collapse-toggle:hover {
        background: #e2e8f0;
        color: #1e293b;
    }

    body.theme-brand .admin-toggle {
        color: #94a3b8;
    }

    body.theme-brand .admin-toggle:hover {
        background: #f1f5f9;
        color: #1e293b;
    }
}

.page-body {
    padding: 0.75rem 1.25rem;
}

.page-header-left {
    display: flex;
    align-items: center;
    flex: 1;
    min-width: 0;
}

.page-header h1 {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--pc-primary);
    margin: 0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 32px;
}


/* Sub-line below title — hidden; reserved for future use */
.page-header-sub {
    display: none;
}

/* Record count pill — inline with title */
.page-header .record-count {
    font-size: 0.7rem;
    font-weight: 400;
    color: #718096;
    background: #edf2f7;
    padding: 0.1rem 0.5rem;
    border-radius: 10px;
    white-space: nowrap;
}

/* Inline action buttons inside page header (e.g., Place Order's Recent/Templates).
   On desktop these sit in the header row between title and GlobalHeaderActions. */
.page-header-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-left: auto;
    padding-right: 0.5rem;
}


/* ================================================================
   PAGE ACTION BAR — page-specific tools below the header.
   Search, refresh, Add/New buttons, etc. Only shown when needed.
   ================================================================ */
.page-action-bar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 1.25rem;
    background: #fafbfc;
    border-bottom: 1px solid var(--pc-border-light, #f1f5f9);
}

/* Standard action bar buttons — compact, consistent sizing */
.page-action-bar .btn {
    padding: 0.4rem 0.85rem;
    border-radius: 6px;
    font-size: 0.8rem;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 0.2s;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    white-space: nowrap;
    border: 1px solid var(--pc-border, #e2e8f0);
    background: white;
    color: var(--pc-text, #2d3748);
}

.page-action-bar .btn:hover {
    border-color: var(--pc-accent, #3182ce);
    color: var(--pc-accent-ink, #3182ce);
}

.page-action-bar .btn-primary {
    background-color: var(--pc-accent);
    color: white;
    border-color: var(--pc-accent);
}

.page-action-bar .btn-primary:hover:not(:disabled) {
    background-color: var(--pc-primary);
    border-color: var(--pc-primary);
}

.page-action-bar .btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* Inline search box in action bar */
.page-action-bar .toolbar-search {
    position: relative;
    display: flex;
    align-items: center;
}

.page-action-bar .toolbar-search .form-control {
    padding: 0.3rem 0.6rem 0.3rem 1.8rem;
    font-size: 0.8rem;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
    width: 180px;
}

.page-action-bar .toolbar-search .search-icon {
    position: absolute;
    left: 0.6rem;
    color: #a0aec0;
    font-size: 0.75rem;
    pointer-events: none;
}

/* Refresh button in action bar */
.page-action-bar .btn-refresh {
    background: transparent;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
    padding: 0.35rem 0.6rem;
    color: #718096;
    cursor: pointer;
    transition: all 0.15s ease;
    flex-shrink: 0;
}

.page-action-bar .btn-refresh:hover:not(:disabled) {
    background: #f7fafc;
    border-color: #3182ce;
    color: #3182ce;
}

.page-action-bar .btn-refresh:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.page-action-bar .btn-refresh i {
    font-size: 1rem;
}

.page-action-bar .btn-refresh i.spinning {
    animation: spin 1s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* ================================================================
   SHARED TABLE STYLES (pc-table)
   Consistent look for all data tables across the portal:
   AddressBook, OrderTemplates, OrderTracking, Billing, Dashboard.
   Use .pc-table-container > .pc-table for the standard pattern.
   ================================================================ */

/* Container: white card with border, rounded corners, horizontal scroll on overflow.
   overflow-y: visible allows context menu dropdowns to escape the container bounds. */
.pc-table-container {
    background: white;
    border-radius: 8px;
    border: 1px solid #ddd;
    overflow-x: auto;
    overflow-y: visible;
    -webkit-overflow-scrolling: touch;
}

/* Shared table toolbar — compact bar above the table for search, counts, actions.
   Matches any toolbar class pattern used across pages. */
.ab-table-toolbar,
.olc-toolbar,
.table-wrapper .toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 4px 0.75rem;
    background: white;
    gap: 0.5rem;
    font-size: 0.78rem;
}

/* Shared compact search input inside table areas.
   Only set height and font — leave padding to component-scoped CSS
   since search inputs with icons need custom left/right padding. */
.pc-table-container input[type="text"],
.pc-table-container .form-control,
.olc-toolbar input[type="text"],
.olc-toolbar .form-control {
    height: 30px;
    font-size: 0.78rem;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
}

/* Other form-row companions inside a pc-table-container — input-group
   addons, side buttons, dropdowns, and the QuickGrid Paginator. They
   should all match the 30px / 0.78rem search-box scale instead of
   towering over it at Bootstrap default sizes. */
.pc-table-container .form-select {
    height: 30px;
    font-size: 0.78rem;
    padding: 0.15rem 1.75rem 0.15rem 0.5rem;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
}

.pc-table-container .input-group-text {
    height: 30px;
    font-size: 0.78rem;
    padding: 0 0.5rem;
    border: 1px solid #e2e8f0;
    background-color: #f8fafc;
}

.pc-table-container .input-group .btn,
.pc-table-container .btn-sm {
    height: 30px;
    font-size: 0.78rem;
    padding: 0 0.5rem;
    line-height: 1;
}

/* Compact label inside checkbox addons (e.g. "Exact" toggle). */
.pc-table-container .input-group-text .form-check-label {
    font-size: 0.75rem;
}

/* QuickGrid Paginator nav — the prev/next/page buttons sit below the
   table and inherit Bootstrap btn padding by default which makes them
   noticeably bulky next to the compact table. */
.pc-table-container nav.paginator,
.pc-table-container .paginator,
.pc-table-container nav.paginator button,
.pc-table-container .paginator button,
.pc-table-container nav.paginator .col-form-label,
.pc-table-container .paginator .col-form-label {
    font-size: 0.78rem;
}

.pc-table-container nav.paginator button,
.pc-table-container .paginator button {
    padding: 0.15rem 0.5rem;
    min-height: 24px;
    line-height: 1;
}


/* Table base */
.pc-table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 0;
}

/* Header cells — !important wins over Bootstrap .table / .table-light defaults */
.pc-table th {
    background-color: #edf2f7 !important;
    text-align: left;
    padding: 0.25rem 0.5rem !important;
    font-weight: 600;
    color: #0f172a !important;
    font-size: 0.7rem !important;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    white-space: nowrap;
    user-select: none;
    border-bottom: 1px solid #cbd5e0 !important;
}

/* Body cells — !important wins over Bootstrap .table defaults */
.pc-table td {
    padding: 0.35rem 0.5rem !important;
    border-bottom: 1px solid #e2e8f0 !important;
    vertical-align: middle;
    font-size: 0.82rem !important;
    color: #475569;
    white-space: nowrap;
}

/* Hover effect on body rows */
.pc-table tbody tr:hover {
    background-color: #f8fafc;
}

/* Selected row highlight */
.pc-table tbody tr.selected {
    background: #ebf8ff;
}

/* Clickable rows */
.pc-table tbody tr.clickable-row {
    cursor: pointer;
}

/* Primary identifier column (order #, name, etc.) */
.pc-table .pc-col-primary {
    font-weight: 600;
    color: var(--pc-primary, #1a365d);
}

/* Truncated text columns */
.pc-table .pc-col-truncate {
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Wrapping text columns (e.g. descriptions) — overrides the default
   td { white-space: nowrap } so long prose flows onto multiple lines
   instead of forcing horizontal scroll. */
.pc-table .pc-col-wrap {
    white-space: normal;
    min-width: 200px;
    max-width: 340px;
    line-height: 1.35;
}

/* Right-aligned columns (prices, totals) */
.pc-table .text-end {
    text-align: right;
}

/* Responsive: tighter padding on small screens */
@media (max-width: 768px) {
    .pc-table th {
        padding: 0.5rem 0.35rem;
        font-size: 0.65rem;
    }

    .pc-table td {
        padding: 0.5rem 0.35rem;
        font-size: 0.8rem;
    }
}

/* QuickGrid adds .table class automatically — compound selector overrides
   Bootstrap's .table padding for tables that also carry our .pc-table class.
   This lets all admin QuickGrid pages share one style definition. */
.table.pc-table {
    margin-bottom: 0;
}

.table.pc-table > thead > tr > th {
    background-color: #edf2f7 !important;
    color: #0f172a !important;
    font-size: 0.7rem !important;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.25rem 0.5rem !important;
    white-space: nowrap;
    border-bottom: 1px solid #cbd5e0 !important;
}

.table.pc-table > tbody > tr > td {
    padding: 0.35rem 0.5rem !important;
    border-bottom: 1px solid #e2e8f0 !important;
    vertical-align: middle;
    font-size: 0.82rem !important;
    color: #475569;
    white-space: nowrap;
}

.table.pc-table > tbody > tr:hover > * {
    background-color: #f8fafc !important;
    --bs-table-bg-state: #f8fafc;
}

/* ================================================================
   GLOBAL HEADER ACTIONS (gh-*) — right side of every page header.
   Chat button, notification bell, account pill.
   Rendered by Shared/GlobalHeaderActions.razor component.
   ================================================================ */
.gh-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding-top: 0.1rem;
    /* Anchor for the absolutely-positioned .gh-announce-panel popup. Without
       a positioned ancestor the panel falls back to the initial containing
       block and lands off-screen below page content. */
    position: relative;
}

/* Icon buttons (chat, bell) and base for gh-btn-text variant. Anchors
   styled with .gh-btn (OrderTypeQuickActions navigates via <a>) need
   the underline reset since the original rule was authored for
   <button>; default browser anchor styles otherwise show an underline
   on both idle and :hover. */
.gh-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    background: transparent;
    border: 1px solid var(--pc-border, #e2e8f0);
    border-radius: 6px;
    color: #718096;
    cursor: pointer;
    transition: all 0.15s;
    position: relative;
    text-decoration: none;
}

.gh-btn:hover {
    background: #f7fafc;
    border-color: #3182ce;
    color: #3182ce;
    text-decoration: none;
}

/* Text variant of gh-btn — same style but auto-width with label text. */
.gh-btn.gh-btn-text {
    width: auto;
    padding: 0 0.6rem;
    gap: 0.3rem;
    font-size: 0.75rem;
    font-weight: 500;
    font-family: inherit;
    white-space: nowrap;
}

/* Dashboard traffic dot indicator */
.db-traffic-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
}

.db-traffic-light { background: #48bb78; }
.db-traffic-moderate { background: #f6ad55; }
.db-traffic-heavy { background: #fc8181; }

.gh-btn i {
    font-size: 1rem;
}

/* Help menu — surfaces when the current page has both a tour AND a brain entry */
.gh-help-wrap {
    position: relative;
}

.gh-help-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1090;
}

.gh-help-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 1100;
    width: 290px;
    background: #fff;
    border: 1px solid rgba(15, 23, 42, 0.08);
    border-radius: 10px;
    box-shadow: 0 14px 38px rgba(15, 23, 42, 0.18), 0 4px 12px rgba(15, 23, 42, 0.10);
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.gh-help-item {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 10px 12px;
    border: none;
    background: transparent;
    text-align: left;
    color: var(--pc-text, #1e293b);
    text-decoration: none;
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.12s ease;
    font: inherit;
}

.gh-help-item:hover {
    background: rgba(49, 130, 206, 0.06);
    color: var(--pc-text, #1e293b);
}

.gh-help-item > i {
    flex-shrink: 0;
    color: var(--pc-accent-ink, #3182ce);
    font-size: 1.05rem;
    margin-top: 2px;
}

.gh-help-item-title {
    display: block;
    font-size: 0.88rem;
    font-weight: 600;
    line-height: 1.2;
}

.gh-help-item-sub {
    display: block;
    font-size: 0.76rem;
    color: var(--pc-text-muted, #64748b);
    margin-top: 2px;
    line-height: 1.3;
}

/* ================================================================
   ORDER-TYPE QUICK ACTIONS (OrderTypeQuickActions.razor)
   ----------------------------------------------------------------
   Always renders as a hamburger-triggered dropdown (.otq-wrap) on
   every viewport width. The inline .otq-links markup is preserved
   in the razor file so a future ramp can re-enable the desktop
   inline-links layout by flipping these display rules; for now the
   chrome stays uniform across desktop and mobile so users learn
   one interaction pattern. Wrap/menu visuals mirror gh-help-menu
   so the two right-edge dropdowns in the same header row read as
   one family.
   ================================================================ */

.otq-links {
    display: none;
}

.otq-wrap {
    display: inline-flex;
    position: relative;
}

.otq-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1090;
}

.otq-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 1100;
    min-width: 220px;
    background: #fff;
    border: 1px solid rgba(15, 23, 42, 0.08);
    border-radius: 10px;
    box-shadow: 0 14px 38px rgba(15, 23, 42, 0.18), 0 4px 12px rgba(15, 23, 42, 0.10);
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.otq-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: none;
    background: transparent;
    text-align: left;
    color: var(--pc-text, #1e293b);
    text-decoration: none;
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.12s ease;
    font: inherit;
    font-size: 0.88rem;
    white-space: nowrap;
}

.otq-menu-item:hover {
    background: rgba(49, 130, 206, 0.06);
    color: var(--pc-text, #1e293b);
}

.otq-menu-item > i {
    flex-shrink: 0;
    color: var(--pc-accent-ink, #3182ce);
    font-size: 1.05rem;
}

/* .otq-wrap's position: relative anchors the absolute .otq-menu inside
   this wrap so the dropdown pops directly below the hamburger trigger,
   right-aligned to the same edge regardless of how wide the menu text
   gets. Set on the base rule above since the layout no longer toggles
   between desktop and mobile. */

/* ================================================================
   QUICK ACTIONS HAMBURGER (QuickActionsHamburger.razor)
   ----------------------------------------------------------------
   Per-page right-edge hamburger that surfaces the user's configured
   quick-action buttons (loaded from /api/quickactions). Read-only
   view of the user's toolbar — Customize is Dashboard-only, so the
   drill-down + its db-config-* styles live in Home.razor's local
   <style> block, not here.

   Replaces the OrderTypeQuickActions hamburger on the order-
   submission and confirmation pages. db-ham-* rules below are
   shared between this component and Home's hamburger so the
   in-page dropdown looks identical to the Dashboard's.
   ================================================================ */

.qah-wrap {
    display: inline-flex;
    position: relative;
}

/* Quick Actions trigger — OPEN ("active") state. While the dropdown is shown,
   fill the button with the brand accent and force a white icon so the "+" stays
   legible. Without this the open trigger reads as a dark, low-contrast box on
   the blue header (a dark icon on a translucent/blue fill = invisible). The
   context-scoped variants raise specificity above the per-context .gh-btn
   background rules (org-strip pill, page-header-actions) so the active fill
   wins wherever the trigger lives. */
/* Quick Actions trigger — styled to match the profile/account trigger exactly:
   a near-solid white pill with accent-ink content that HOLDS in every state
   (idle, hover, dropdown-open), with no glow. The plain .gh-btn otherwise picked
   up `.page-header .gh-btn:hover`'s translucent fill on tap — a dark-blue box
   that hid the dark icon — plus the header-actions glow. Mirrors
   `.page-header`/`.org-strip .gh-acct-trigger` so both header buttons read alike. */
.page-header-actions .qah-wrap > .gh-btn,
.page-header-actions .qah-wrap > .gh-btn:hover,
.page-header-actions .qah-wrap.qah-open > .gh-btn,
.org-strip .org-pills .qah-wrap > .gh-btn,
.org-strip .org-pills .qah-wrap > .gh-btn:hover,
.org-strip .org-pills .qah-wrap.qah-open > .gh-btn {
    background: rgba(255, 255, 255, 0.92);
    color: var(--pc-accent-ink);
    border-color: transparent;
    box-shadow: none;
}

.page-header-actions .qah-wrap > .gh-btn i,
.org-strip .org-pills .qah-wrap > .gh-btn i {
    color: var(--pc-accent-ink);
}

/* ── Quick Actions SPLIT BUTTON (right split: "+ label" navigates, caret opens) ─
   The labeled org-strip CTA is split into a wide LEFT action segment ("+" icon +
   "Place Order" label) that navigates straight to order entry, and a narrow RIGHT
   caret segment (chevron) that opens this dropdown. Two .gh-btn segments joined
   into one 240px pill (so the dropdown, min 240px, mirrors the button width).
   They sit one level below .qah-wrap (not a direct child), so the single-trigger
   `.qah-wrap > .gh-btn` pill rules above don't reach them — the 3D-raised
   treatment is restated here for both header contexts. */
.qa-split {
    display: inline-flex;
    align-items: stretch;
    border-radius: 6px;
    /* 3D-raised: a soft cast shadow below + a slightly darker hairline ring around
       the edge lift the whole pill off the header as one raised control. The ring
       is a box-shadow (not a real border) so it adds no layout width — keeping the
       "+" icon column-aligned with the dropdown rows below it. */
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.28), 0 0 0 1px rgba(15, 23, 42, 0.18);
}

/* Join the inner corners so the two segments read as one pill: the action
   segment rounds LEFT, the caret rounds RIGHT. */
.qa-split .qa-split-nav {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.qa-split .qa-split-menu {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}

/* Keep the trigger's original 240px footprint so the dropdown (min 240px,
   anchored under .qah-wrap) mirrors the button width exactly. The 240px lives on
   the .qa-split shell; the caret takes a fixed slice on the right, the action
   segment flexes to fill the rest. Without this the single-trigger's
   `.org-strip .org-pills .gh-btn { width:240px }` would inflate BOTH segments to
   240px each. Context-scoped to out-specify that rule. */
.org-strip .org-pills .qah-wrap .qa-split,
.page-header-actions .qah-wrap .qa-split {
    width: 240px;
    box-sizing: border-box;
}

.org-strip .org-pills .qah-wrap .qa-split-menu,
.page-header-actions .qah-wrap .qa-split-menu {
    flex: 0 0 40px;
    width: 40px;
    justify-content: center;      /* center the caret in its slice */
}

.org-strip .org-pills .qah-wrap .qa-split-nav,
.page-header-actions .qah-wrap .qa-split-nav {
    flex: 1 1 auto;
    width: auto;                  /* undo the per-.gh-btn 240px; the shell owns it now */
    justify-content: flex-start;  /* "+" icon + label sit left */
}

/* 3D-raised faces: each half is a light top-to-bottom gradient (white → pale
   slate) with a 1px inset top highlight, so the face reads as convex/raised.
   Light by default; the seam divider + per-half hover do the rest. Restated
   per-segment because they aren't direct children of .qah-wrap (so the
   single-trigger pill rules don't reach). */
.org-strip .org-pills .qah-wrap .qa-split > .gh-btn,
.page-header-actions .qah-wrap .qa-split > .gh-btn {
    background: linear-gradient(#ffffff, #e4e9f1);
    color: var(--pc-accent-ink);
    border-color: transparent;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
}

.org-strip .org-pills .qah-wrap .qa-split > .gh-btn i,
.page-header-actions .qah-wrap .qa-split > .gh-btn i {
    color: var(--pc-accent-ink);
}

/* The split divider: a single dark hairline at the seam (the caret half's LEFT
   edge), like the step between two raised keys. Kept as an inset box-shadow (not
   a border) so it adds no width. It re-declares the top highlight too because
   box-shadow doesn't accumulate across rules — this same-specificity rule sits
   after the base and fully replaces its shadow, so both shades live here. */
.org-strip .org-pills .qah-wrap .qa-split > .qa-split-menu,
.page-header-actions .qah-wrap .qa-split > .qa-split-menu {
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9),
                inset 1px 0 0 rgba(15, 23, 42, 0.16);
}

/* Hover — deepen the gradient (the face presses down a touch) + accent color so
   each half reads as its own target. The box-shadow (top highlight + seam
   divider) persists since :hover doesn't re-declare it. */
.org-strip .org-pills .qah-wrap .qa-split > .gh-btn:hover,
.page-header-actions .qah-wrap .qa-split > .gh-btn:hover {
    background: linear-gradient(#ffffff, #d7deea);
    color: var(--pc-accent);
}

.org-strip .org-pills .qah-wrap .qa-split > .gh-btn:hover i,
.page-header-actions .qah-wrap .qa-split > .gh-btn:hover i {
    color: var(--pc-accent);
}

/* Open (dropdown visible): intentionally NO background change on the toggle when
   it isn't hovered — the open dropdown itself is the "active" cue. The toggle
   keeps the default light pill; only :hover brightens it. */

/* Cohesive control: anchor the split's MAIN dropdown to the button's LEFT edge
   so the two share a left edge. The "+" toggle icon (centered in its 40px slice
   = 20px in) then lines up exactly under the menu-row icons (16px box at 0.75rem
   padding = also 20px in), so the button and menu read as one column-aligned
   control. The panel still sizes naturally to the RIGHT for long labels. The
   wide drill-in sub-views (Recent/Templates/Pinned) keep the base right-anchor
   so they open leftward and stay on-screen. */
.org-strip .org-pills .qah-wrap .db-ham-panel.qah-panel:not(.db-ham-panel-wide) {
    left: 0;
    right: auto;
    /* Mirror the button's 240px so the main menu and the button read as one
       control: a shared left edge (so the "+" toggle lines up over the menu-row
       icons) and matching width. The widest row ("Repeat a Recent Order") needs
       ~238px, so everything fits at 240 with no wrap or scroll. An explicit width
       is needed anyway — left:0 alone caps the panel at its 240px containing
       block (.qah-wrap). The wide drill-in sub-views keep the base right-anchor,
       so they grow leftward from this box with the right edge pinned. */
    width: 240px;
}

.qah-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1090;
}

/* Config-host mode (the MainLayout instance opened from the profile menu):
   no trigger to anchor to, so the Customize config opens as a centered modal. */
.qah-wrap.qah-confighost {
    position: static;
}

.qah-confighost .qah-backdrop {
    z-index: 1990;
    background: rgba(15, 23, 42, 0.45);
}

.qah-confighost .db-ham-panel.qah-panel {
    position: fixed;
    top: 50%;
    left: 50%;
    right: auto;
    transform: translate(-50%, -50%);
    max-height: 80vh;
    z-index: 2000;
}

.qah-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 1100;
    min-width: 220px;
    background: #fff;
    border: 1px solid rgba(15, 23, 42, 0.08);
    border-radius: 10px;
    box-shadow: 0 14px 38px rgba(15, 23, 42, 0.18), 0 4px 12px rgba(15, 23, 42, 0.10);
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.qah-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: none;
    background: transparent;
    text-align: left;
    color: var(--pc-text, #1e293b);
    text-decoration: none;
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.12s ease;
    font: inherit;
    font-size: 0.88rem;
    white-space: nowrap;
}

.qah-menu-item:hover {
    background: rgba(49, 130, 206, 0.06);
    color: var(--pc-text, #1e293b);
}

.qah-menu-item > i {
    flex-shrink: 0;
    color: var(--pc-accent-ink, #3182ce);
    font-size: 1.05rem;
}

/* Primary item — visual emphasis so a Dashboard-marked Primary action
   (e.g. Place Order) reads as the preferred entry point even in the
   dropdown. */
.qah-menu-item-primary {
    background: rgba(49, 130, 206, 0.08);
    font-weight: 600;
}

.qah-menu-item-primary:hover {
    background: rgba(49, 130, 206, 0.14);
}

.qah-menu-empty {
    padding: 10px 12px;
    font-size: 0.85rem;
    color: #64748b;
    font-style: italic;
}

.qah-menu-empty-link {
    color: var(--pc-accent-ink, #3182ce);
    text-decoration: none;
    font-style: normal;
}

.qah-menu-empty-link:hover {
    text-decoration: underline;
}

/* Recent Orders row inside the QAH sub-view — two-line label so the
   order number is bold + the route reads as a quieter caption beneath
   it. Overrides db-ham-item's single-line whitespace:nowrap so the
   route doesn't push the row off-screen on narrow viewports. */
.db-ham-item.qah-recent-row {
    align-items: flex-start;
    white-space: normal;
    padding-top: 0.55rem;
    padding-bottom: 0.55rem;
}

.qah-recent-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
    flex: 1;
}

.qah-recent-number {
    font-weight: 600;
    color: #1e293b;
    font-size: 0.85rem;
}

.qah-recent-route {
    font-size: 0.72rem;
    color: #64748b;
    line-height: 1.25;
    word-break: break-word;
}

.qah-recent-route i {
    font-size: 0.65rem;
    color: #94a3b8;
    margin: 0 0.15rem;
}

/* Dashboard-flavored hamburger panel + Customize drill-down — the markup
   uses the same class names as Home.razor's local <style> so behavior +
   visuals stay in lockstep. */

.db-ham-panel {
    background: white;
    border: 1px solid #e2e8f0;
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
    min-width: 240px;
    max-height: 70vh;
    overflow-y: auto;
    /* Zero top padding so a tinted .db-ham-header meets the panel's top edge; the
       border-radius + overflow then clip the (square) header into the rounded
       corners so the tint fills them. Bottom padding keeps the last row off the edge. */
    padding: 0 0 0.25rem;
}

/* Widen the hamburger panel when the Recent Orders sub-view is active —
   each row carries an order number + Origin → Destination route that
   stacks tall when squeezed into the 240px main-view width. min(480px,
   90vw) doubles the budget on desktop while staying within the viewport
   on iPhone-portrait. Applied by both Home's hamburger and
   QuickActionsHamburger via the .db-ham-panel-wide modifier class. */
.db-ham-panel.db-ham-panel-wide {
    min-width: min(480px, 90vw);
}

/* Shared by QuickActionsHamburger (.qah-wrap) AND the desktop toolbar popovers
   (.qa-pop-wrap): an absolute dropdown anchored to its trigger's bottom-right.
   Both wrappers are position:relative so the panel pins to its own button. */
.db-ham-panel.qah-panel {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 1100;
}

/* Mobile hamburger ONLY: the WIDE Recent/Pinned sub-view can't right-anchor to
   a mid-header button without its left edge running off screen (the quick-
   actions button sits left of the Support/Profile icons on most pages). Switch
   the wide sub-view to a fixed, viewport-spanning sheet with small side margins
   below the header so the whole sub-menu is visible.
   IMPORTANT: scoped to .qah-wrap:not(.qa-toolbar). The DESKTOP toolbar's root
   is `qah-wrap qa-toolbar`, so a bare `.qah-wrap` selector would also fix-
   position the toolbar's popovers (floating them to the far left). The :not()
   excludes the toolbar, whose popovers keep their button-anchored absolute
   positioning via QuickActionsToolbar's scoped CSS. */
@media (max-width: 768px) {
    /* All quick-actions dropdowns span ~full width on mobile (not just the wide
       sub-views), so the right-aligned icon trigger doesn't drag a narrow menu
       off the edge — alignment is moot when it's full-bleed. Excludes the
       config-host, which is a centered modal (its own transform would otherwise
       fling it off-screen when re-anchored to top/left here). */
    .qah-wrap:not(.qa-toolbar):not(.qah-confighost) .db-ham-panel.qah-panel {
        position: fixed;
        /* Align with the Support/Profile dropdowns next to it: their absolute
           panels open at trigger-bottom + 4px (≈42px on the mobile header row).
           52px sat ~10px too low. */
        top: 42px;
        left: 0.5rem;
        right: 0.5rem;
        width: auto;
        min-width: 0;
        max-width: none;
    }
}

.db-ham-header {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.75rem 0.35rem;
    border-bottom: 1px solid #f1f5f9;
    margin-bottom: 0.15rem;
    /* Tinted section-heading bar — shared by every drill-in menu (dashboard
       toolbar, header menu, place-order menu) so they read identically. */
    background: #f1f5f9;
}

/* Marks a sub-view header whose whole row pops back. Cursor cue +
   subtle hover so the affordance reads. The .db-ham-back arrow inside
   is decorative — the click handler lives on the row. */
.db-ham-header-clickable {
    cursor: pointer;
}

.db-ham-header-clickable:hover {
    /* Same tint as the header's resting background — the row is a collapse
       affordance, not a menu item, so it shouldn't flash a lighter hover. */
    background: #f1f5f9;
}

.db-ham-title {
    font-size: 0.72rem;
    font-weight: 700;
    /* Darker than the faint #94a3b8 so the heading reads against the tinted bar. */
    color: #334155;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.db-ham-back {
    background: none;
    border: none;
    padding: 0.15rem 0.3rem;
    cursor: pointer;
    /* Neutral grey (matches .db-ham-collapse-caret and .db-ham-title) — the
       drill-in back/collapse affordance is not themed, so these sub-view lists
       read identically wherever they're invoked (header menu, dashboard toolbar,
       place-order menu). */
    color: #94a3b8;
    font-size: 0.85rem;
    border-radius: 4px;
}

.db-ham-back:hover { background: rgba(100, 116, 139, 0.10); }

/* Drill-in sub-view header (Recent / Pinned / Templates): the whole .db-ham-header
   row pops the sub-view back, so instead of a themed left back-arrow it shows a
   neutral, right-aligned up-caret (a collapse affordance). The title flex-grows to
   push the caret (and the pinned gear) to the right; the header keeps the standard
   .db-ham-header look. */
.db-ham-header-collapse .db-ham-title {
    flex: 1;
}

.db-ham-collapse-caret {
    color: #94a3b8;
    font-size: 0.8rem;
}

.db-ham-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.45rem 0.75rem;
    border: none;
    background: none;
    text-align: left;
    font-size: 0.8rem;
    font-weight: 500;
    color: #2d3748;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.1s;
    white-space: nowrap;
    font-family: inherit;
}

.db-ham-item:hover {
    background: #f7fafc;
    text-decoration: none;
    color: #2d3748;
}

.db-ham-item i:first-child {
    width: 16px;
    color: #718096;
    font-size: 0.82rem;
}

/* Favorite icon intentionally inherits the panel's muted color — the
   outline-only bi-lightning glyph is the marker, no amber accent. */
.db-ham-item.db-qa-popular i:first-child { color: #e53e3e; }
.db-ham-item.db-qa-draft i:first-child { color: #3182ce; }

.db-ham-divider {
    height: 1px;
    background: #e2e8f0;
    margin: 0.25rem 0;
}

/* Customize ("Customize Toolbar") styles — used by QuickActionsHamburger's
   Customize panel, which now renders on every page (compact menu) and on the
   dashboard (always-compact). Restored here from Home.razor's local <style>
   so the panel is styled wherever the shared hamburger mounts. */
.db-ham-config-gear {
    margin-left: auto;
    background: none;
    border: none;
    padding: 0.1rem 0.25rem;
    line-height: 1;
    color: #94a3b8;
    cursor: pointer;
    border-radius: 4px;
    transition: color 0.15s, background 0.15s;
}

.db-ham-config-gear:hover {
    color: var(--pc-primary, #0046ad);
    background: #f1f5f9;
}

.db-ham-config-chevron {
    margin-left: auto;
    font-size: 0.65rem;
    color: #cbd5e1;
}

.db-config-row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.75rem;
    font-size: 0.78rem;
    transition: background 0.1s;
}

.db-config-drag-handle {
    color: #cbd5e1;
    cursor: grab;
    font-size: 0.85rem;
    flex-shrink: 0;
    padding: 0.1rem;
}

.db-config-drag-handle:hover { color: #94a3b8; }
.db-config-row:active .db-config-drag-handle { cursor: grabbing; }

.db-config-row-dragover {
    background: rgba(43, 108, 176, 0.08);
    box-shadow: inset 0 -2px 0 var(--pc-accent);
}

.db-config-row-icon {
    width: 16px;
    color: #718096;
    flex-shrink: 0;
    font-size: 0.75rem;
}

.db-config-row-label {
    flex: 1;
    color: #334155;
    font-weight: 500;
    min-width: 0;
    white-space: nowrap;
}

.db-config-row-drilldown {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    background: none;
    border: none;
    padding: 0;
    text-align: left;
    font: inherit;
    color: inherit;
    cursor: pointer;
    min-width: 0;
}

.db-config-row-drilldown:hover .db-config-row-label {
    color: var(--pc-accent-ink, #3182ce);
}

.db-config-row-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.1rem;
    padding: 0 0.4rem;
    background: #e2e8f0;
    color: #475569;
    font-size: 0.7rem;
    font-weight: 600;
    border-radius: 999px;
}

.db-config-row-actions {
    display: flex;
    align-items: center;
    gap: 0.1rem;
    margin-left: auto;
    flex-shrink: 0;
}

.db-config-row-btn {
    background: none;
    border: none;
    padding: 0.2rem;
    color: #94a3b8;
    cursor: pointer;
    font-size: 0.7rem;
    border-radius: 3px;
}

.db-config-row-btn:hover { color: var(--pc-accent-ink); background: #f1f5f9; }
.db-config-row-remove:hover { color: #e53e3e; background: #fff5f5; }
.db-config-row-btn:disabled { opacity: 0.3; cursor: default; }
.db-config-row-btn:disabled:hover { color: #94a3b8; background: none; }

.db-config-fav-name {
    border: 1px solid transparent;
    border-radius: 3px;
    padding: 0.05rem 0.2rem;
    font-size: 0.78rem;
    font-weight: 500;
    color: #334155;
    background: transparent;
    outline: none;
    min-width: 0;
    flex: 1;
}

.db-config-fav-name:hover { border-color: #e2e8f0; }
.db-config-fav-name:focus { border-color: #2b6cb0; background: white; }

.db-config-divider {
    height: 1px;
    background: #e2e8f0;
    margin: 0.2rem 0;
}

.db-config-add-row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    width: 100%;
    padding: 0.3rem 0.75rem;
    border: none;
    background: none;
    font-size: 0.78rem;
    color: #64748b;
    cursor: pointer;
    text-align: left;
}

.db-config-add-row:hover { background: #f7fafc; color: #334155; }

.db-config-add-plus {
    margin-left: auto;
    color: var(--pc-accent-ink);
    font-size: 0.7rem;
}

.db-config-popular-row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.75rem;
    font-size: 0.78rem;
    color: #334155;
}

.db-config-kpi-toggle {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    margin-left: auto;
    padding: 0.25rem 0.6rem;
    border-radius: 4px;
    border: 1px solid var(--pc-border-light);
    background: var(--pc-surface-elevated);
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--pc-accent-ink);
    cursor: pointer;
    transition: all 0.15s;
    font-family: inherit;
}

.db-config-kpi-toggle:hover { background: rgba(43, 108, 176, 0.06); border-color: var(--pc-accent); }

.db-config-reset-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    width: calc(100% - 1rem);
    margin: 0.1rem 0.5rem 0.25rem;
    padding: 0.3rem;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
    background: transparent;
    color: #94a3b8;
    font-size: 0.7rem;
    cursor: pointer;
}

.db-config-reset-btn:hover { background: #fef2f2; color: #ef4444; border-color: #fca5a5; }

/* Bell notification badge */
.gh-bell-wrap {
    position: relative;
}

.gh-bell-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    background: #e53e3e;
    color: white;
    font-size: 0.55rem;
    font-weight: 700;
    min-width: 16px;
    height: 16px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 3px;
    border: 2px solid white;
}

/* Account-menu wrapper hosts the user-circle trigger + dropdown panel
   on desktop. Display was `none` historically (when desktop context
   switching ran through the sidebar's CustomerContextSelector and the
   pill in the toolbar was considered redundant). It's back now as the
   sole right-edge entry point for User Profile / Announcements / Help /
   Sign Out — so it has to be visible. The .gh-desktop-only modifier
   on the wrapper handles the mobile breakpoint, where the mobile card
   takes over. */
.gh-acct-wrap {
    position: relative;
    display: inline-flex;
}

.gh-account-pill {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    background: var(--pc-surface-elevated, #fff);
    border: 1px solid var(--pc-border, #e2e8f0);
    padding: 0.4rem 0.75rem;
    border-radius: var(--pc-radius-sm, 8px);
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--pc-text, #2d3748);
    cursor: pointer;
    transition: border-color 0.15s;
    font-family: inherit;
}

.gh-account-pill:hover {
    border-color: var(--pc-accent, #3182ce);
}

.gh-acct-wrap.gh-acct-open .gh-account-pill {
    border-color: var(--pc-border, #e2e8f0);
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    border-bottom-color: transparent;
}

.gh-acct-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--pc-success, #48bb78);
}

.gh-acct-chevron {
    font-size: 0.55rem;
    color: var(--pc-text-muted, #718096);
    margin-left: 0.15rem;
    transition: transform 0.15s ease;
}

.gh-acct-open .gh-acct-chevron {
    transform: rotate(180deg);
}

.gh-acct-backdrop {
    position: fixed;
    inset: 0;
    z-index: 99;
}

/* On mobile the backdrop must sit above page content but below the fixed bar + sheet */
.gh-mobile-card-wrap .gh-acct-backdrop {
    z-index: 1008;
}

/* ── Support quick-contact dropdown (page-header help icon) ──
   Mirrors the account-menu dropdown chrome; opens a small card with the
   phone, per-team email routes, optional chat, and a footer link to the
   full Support page. */
.gh-support-wrap {
    position: relative;
    display: inline-flex;
}

.gh-support-menu {
    position: absolute;
    top: calc(100% + 4px);
    right: -1px;
    min-width: 300px;
    max-width: calc(100vw - 1rem);
    max-height: 80vh;
    overflow-y: auto;
    background: var(--pc-surface, #f8fafc);
    border: 1px solid var(--pc-border, #e2e8f0);
    border-radius: var(--pc-radius-sm, 8px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    z-index: 100;
    padding: 0.5rem;
}

.gh-support-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.4rem 0.5rem 0.6rem;
}

.gh-support-title {
    font-weight: 600;
    font-size: 0.85rem;
    color: #1e293b;
    /* Now an <a> to the Support hub — reads as the header caption at rest,
       but on hover it lights up like a button (tinted fill, rounded). The
       padding is baked in with an equal negative margin so the resting
       position is unchanged and hovering doesn't shift the layout. */
    text-decoration: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.45rem;
    margin: -0.2rem -0.45rem;
    border-radius: 6px;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.gh-support-title:hover {
    background: #ebf3fb;
    color: #3182ce;
}

.gh-support-title i {
    color: #3182ce;
    margin-right: 0.3rem;
}

.gh-support-hours {
    font-size: 0.7rem;
    color: #64748b;
}

.gh-support-phone {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.6rem 0.65rem;
    border-radius: 8px;
    background: #ebf8ff;
    border: 1px solid #bee3f8;
    text-decoration: none;
}

.gh-support-phone:hover {
    background: #e1f0fb;
    border-color: #90cdf4;
}

.gh-support-phone > i {
    font-size: 1.1rem;
    color: #2b6cb0;
}

.gh-support-phone-body {
    display: flex;
    flex-direction: column;
}

.gh-support-phone-label {
    font-size: 0.68rem;
    color: #4a6b8a;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.gh-support-phone-number {
    font-size: 1rem;
    font-weight: 700;
    color: #1e3a5f;
}

.gh-support-divider {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.6rem 0.3rem;
    font-size: 0.66rem;
    color: #94a3b8;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.gh-support-divider::before,
.gh-support-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: #e2e8f0;
}

.gh-support-row {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    padding: 0.45rem 0.5rem;
    border-radius: 6px;
    color: #334155;
    text-decoration: none;
    background: transparent;
    border: none;
    cursor: pointer;
    font-family: inherit;
    text-align: left;
}

.gh-support-row:hover {
    background: #eef2f7;
}

/* Feature-tour row — promoted "learn about this page" action at the top of
   the support menu. Blue-tinted card so it reads as the featured entry point
   rather than another contact row. */
.gh-support-tour {
    background: #eef5fc;
    border: 1px solid #cfe2f5;
}

.gh-support-tour:hover {
    background: #e1f0fb;
    border-color: #90cdf4;
}

.gh-support-tour > i {
    color: #2b6cb0;
}

.gh-support-row > i {
    font-size: 0.95rem;
    color: #64748b;
    width: 1.1rem;
    text-align: center;
}

.gh-support-row-text {
    display: flex;
    flex-direction: column;
    line-height: 1.25;
}

.gh-support-row-label {
    font-size: 0.8rem;
    color: #1e293b;
}

.gh-support-row-value {
    font-size: 0.72rem;
    color: #64748b;
}

.gh-support-all {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-top: 0.4rem;
    padding: 0.55rem 0.65rem;
    border-top: 1px solid #e2e8f0;
    color: #2b6cb0;
    text-decoration: none;
    font-size: 0.8rem;
    font-weight: 600;
}

.gh-support-all:hover {
    color: #1d4ed8;
}

.gh-support-all i {
    font-size: 0.7rem;
}

/* "Email a team" accordion header — a normal support row whose trailing chevron
   is pushed to the right edge to signal it expands/collapses inline. The chevron
   rotates from pointing right (collapsed) to down (expanded). */
.gh-support-drill-caret {
    margin-left: auto;
    font-size: 0.7rem !important;
    color: #94a3b8 !important;
    transition: transform 0.15s ease;
}

.gh-support-drill-open .gh-support-drill-caret {
    transform: rotate(90deg);
}

/* Revealed per-team email routes — indented under the accordion header with a
   left rule so they read as children of "Email a team", matching the collapse
   pattern used elsewhere. */
.gh-support-emaillist {
    margin: 0.1rem 0 0.15rem 0.85rem;
    padding-left: 0.35rem;
    border-left: 2px solid #e2e8f0;
}

.gh-acct-menu {
    position: absolute;
    top: calc(100% + 4px);
    right: -1px;
    min-width: 280px;
    max-width: calc(100vw - 1rem);
    max-height: 80vh;
    overflow-y: auto;
    background: var(--pc-surface, #f8fafc);
    border: 1px solid var(--pc-border, #e2e8f0);
    border-radius: var(--pc-radius-sm, 8px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    z-index: 100;
}

/* ── Account pill: dot color when switched away from primary ── */
.gh-acct-dot-switched {
    background: #f59e0b;
}

/* User-circle icon trigger — always-visible right-edge entry point to
   the account menu (Profile / Announcements / Help / Sign Out). Sits
   next to the other .gh-btn icons in the header so the toolbar reads
   uniformly. The status dot in the corner mirrors the customer-switch
   indicator from the retired pill. */
.gh-acct-trigger {
    position: relative;
}

.gh-acct-trigger i {
    font-size: 1.1rem;
}

/* Compact customer/user identification header at the top of the
   single-customer dropdown (the multi-customer case is covered by the
   Ordering As context-switcher inside the menu body). */
.gh-acct-customer-header {
    display: flex;
    flex-direction: column;
    padding: 0.75rem 0.85rem 0.5rem;
    border-bottom: 1px solid var(--pc-border, #e2e8f0);
    margin-bottom: 0.25rem;
}

.gh-acct-customer-name {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--pc-text, #1e293b);
    line-height: 1.2;
}

.gh-acct-customer-user {
    font-size: 0.75rem;
    color: var(--pc-text-muted, #64748b);
    margin-top: 2px;
}

/* ── Context Switcher Sections ── */
.gh-ctx-section {
    padding: 0.5rem 0;
}

.gh-ctx-label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.85rem 0.35rem;
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--pc-text-muted, #64748b);
}

.gh-ctx-label i {
    font-size: 0.72rem;
}

/* Inset card grouping for context options (used by "Viewing Data For" toggles) */
.gh-ctx-group {
    margin: 0.15rem 0.55rem 0.35rem;
    background: var(--pc-surface-elevated, #fff);
    border: 1px solid var(--pc-border, #e2e8f0);
    border-radius: 6px;
    overflow: hidden;
}

/* ── Ordering As: select-trigger + dropdown (mirrors flyout pattern) ── */
.gh-ctx-select-wrap {
    position: relative;
    padding: 0 0.55rem 0.25rem;
}

.gh-ctx-select-trigger {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    width: 100%;
    padding: 0.45rem 0.6rem;
    background: var(--pc-surface-elevated, #fff);
    border: 1px solid var(--pc-border, #e2e8f0);
    border-radius: 6px;
    color: var(--pc-text, #1e293b);
    font-size: 0.8rem;
    font-family: inherit;
    font-weight: 500;
    cursor: pointer;
    text-align: left;
    transition: border-color 0.15s;
}

.gh-ctx-select-trigger:hover:not(:disabled) {
    border-color: var(--pc-accent, #3182ce);
}

.gh-ctx-select-trigger:disabled {
    opacity: 0.6;
    cursor: default;
}

.gh-ctx-select-value {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gh-ctx-select-id {
    flex-shrink: 0;
    font-size: 0.68rem;
    color: var(--pc-text-muted, #64748b);
}

.gh-ctx-select-chevron {
    flex-shrink: 0;
    font-size: 0.55rem;
    color: var(--pc-text-muted, #64748b);
    transition: transform 0.2s ease;
}

.gh-ctx-chevron-flip {
    transform: rotate(180deg);
}

/* Dropdown options list */
.gh-ctx-select-dropdown {
    position: absolute;
    top: calc(100% - 0.15rem);
    left: 0.55rem;
    right: 0.55rem;
    z-index: 10;
    background: var(--pc-surface-elevated, #fff);
    border: 1px solid var(--pc-border, #e2e8f0);
    border-radius: 0 0 6px 6px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    max-height: 180px;
    overflow-y: auto;
}

.gh-ctx-select-option {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    width: 100%;
    padding: 0.45rem 0.6rem;
    background: none;
    border: none;
    border-bottom: 1px solid var(--pc-border-light, #f1f5f9);
    color: var(--pc-text, #1e293b);
    font-size: 0.8rem;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
    transition: background 0.1s;
}

.gh-ctx-select-option:last-child {
    border-bottom: none;
}

.gh-ctx-select-option:hover:not(:disabled) {
    background: var(--pc-accent-glow, rgba(49, 130, 206, 0.06));
}

.gh-ctx-select-option:disabled {
    cursor: default;
}

.gh-ctx-select-option-active {
    background: var(--pc-accent-glow, rgba(49, 130, 206, 0.06));
    color: var(--pc-accent-ink, #3182ce);
    font-weight: 600;
}

.gh-ctx-select-option-active:hover:not(:disabled) {
    background: var(--pc-accent-glow, rgba(49, 130, 206, 0.06));
}

.gh-ctx-check {
    flex-shrink: 0;
    color: var(--pc-accent-ink, #3182ce);
    font-size: 0.85rem;
}

.gh-ctx-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gh-ctx-id {
    font-size: 0.68rem;
    color: var(--pc-text-muted, #64748b);
    flex-shrink: 0;
}

/* ── Viewing Data For: toggle switches ── */
.gh-ctx-toggle {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.5rem 0.65rem;
    background: none;
    border: none;
    border-bottom: 1px solid var(--pc-border-light, #f1f5f9);
    font-size: 0.8rem;
    color: var(--pc-text, #1e293b);
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    transition: background 0.1s;
}

.gh-ctx-toggle:last-child {
    border-bottom: none;
}

.gh-ctx-toggle:hover {
    background: rgba(0, 0, 0, 0.02);
}

/* "Only" quick single-select — isolates the view to one customer. Dim at rest
   (kept visible so it works on touch, where there's no hover), brighter on
   row hover/focus. */
.gh-ctx-only {
    flex-shrink: 0;
    background: none;
    border: none;
    color: var(--pc-primary, #2563eb);
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    cursor: pointer;
    padding: 0.1rem 0.35rem;
    border-radius: 4px;
    opacity: 0.55;
    transition: opacity 0.12s, background 0.12s, color 0.12s;
}

.gh-ctx-toggle:hover .gh-ctx-only,
.gh-ctx-toggle:focus-within .gh-ctx-only {
    opacity: 1;
}

.gh-ctx-only:hover {
    background: rgba(37, 99, 235, 0.1);
}

.gh-ctx-track {
    width: 32px;
    height: 18px;
    border-radius: 9px;
    background: #cbd5e0;
    position: relative;
    flex-shrink: 0;
    transition: background 0.2s;
}

.gh-ctx-toggle-on .gh-ctx-track {
    background: #48bb78;
}

.gh-ctx-thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: white;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
    transition: transform 0.2s;
}

.gh-ctx-toggle-on .gh-ctx-thumb {
    transform: translateX(14px);
}

/* ── Switching overlay ── */
.gh-ctx-switching {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.75rem;
    font-size: 0.8rem;
    color: var(--pc-text-muted, #64748b);
}

/* ── Navigation links ── */
.gh-acct-nav {
    padding: 0.35rem 0;
    border-top: 1px solid var(--pc-border, #e2e8f0);
}

.gh-acct-menu-item {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.5rem 0.85rem;
    font-size: 0.8rem;
    color: var(--pc-text, #1e293b);
    text-decoration: none;
    transition: background 0.1s, color 0.1s;
    white-space: nowrap;
}

.gh-acct-menu-item:hover {
    background: var(--pc-accent-glow, rgba(49, 130, 206, 0.06));
    color: var(--pc-accent-ink, #3182ce);
    text-decoration: none;
}

/* Reset native <button> defaults so button-based menu items
   (Announcements, Replay tour, Replay: <stage>) render identically
   to the <a>-based nav items above. Without this the browser leaks
   its own background / border / centered text / clipped font, which
   made those rows look out-of-place in the dropdown. Mirrors the
   button.more-menu-item reset used by MobileBottomNav. */
button.gh-acct-menu-item {
    width: 100%;
    background: none;
    border: none;
    cursor: pointer;
    text-align: left;
    font: inherit;
    font-size: 0.8rem;
    font-family: inherit;
}

/* Icon circle for nav items — gives visual weight without clutter */
.gh-acct-menu-icon {
    width: 26px;
    height: 26px;
    border-radius: 6px;
    background: var(--pc-border-light, #f1f5f9);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: background 0.1s;
}

.gh-acct-menu-icon i {
    font-size: 0.78rem;
    color: var(--pc-text-muted, #64748b);
    transition: color 0.1s;
}

.gh-acct-menu-item:hover .gh-acct-menu-icon {
    background: rgba(49, 130, 206, 0.1);
}

.gh-acct-menu-item:hover .gh-acct-menu-icon i {
    color: var(--pc-accent-ink, #3182ce);
}

/* ── Sign out — separated and distinct ── */
.gh-acct-signout {
    padding: 0.35rem 0.55rem 0.55rem;
    border-top: 1px solid var(--pc-border, #e2e8f0);
}

.gh-acct-signout-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    width: 100%;
    padding: 0.45rem 0.65rem;
    font-size: 0.78rem;
    font-weight: 500;
    font-family: inherit;
    color: #dc2626;
    background: none;
    border: 1px solid rgba(220, 38, 38, 0.2);
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s;
}

.gh-acct-signout-btn:hover {
    background: rgba(220, 38, 38, 0.06);
    border-color: rgba(220, 38, 38, 0.35);
}

/* ── Announcement Popover Panel ── */
.gh-announce-backdrop {
    position: fixed;
    inset: 0;
    z-index: 99;
}

.gh-announce-panel {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    width: 340px;
    background: var(--pc-surface-elevated, #fff);
    border: 1px solid var(--pc-border, #e2e8f0);
    border-radius: var(--pc-radius, 12px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    z-index: 100;
    overflow: hidden;
}

.gh-announce-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--pc-border-light, #f1f5f9);
}

.gh-announce-panel-header h4 {
    margin: 0;
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--pc-primary);
}

.gh-announce-close {
    background: none;
    border: none;
    color: var(--pc-text-muted, #718096);
    cursor: pointer;
    font-size: 0.8rem;
    padding: 0.2rem;
    border-radius: 4px;
}

.gh-announce-close:hover {
    color: var(--pc-text, #2d3748);
    background: var(--pc-border-light, #f1f5f9);
}

.gh-announce-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 1.5rem;
    color: var(--pc-text-muted, #718096);
}

.gh-announce-empty i {
    font-size: 1.5rem;
    opacity: 0.3;
    margin-bottom: 0.5rem;
}

.gh-announce-empty p {
    font-size: 0.78rem;
    margin: 0;
    opacity: 0.6;
}

.gh-announce-list {
    max-height: 320px;
    overflow-y: auto;
}

.gh-announce-item {
    display: flex;
    flex-direction: column;
    border-bottom: 1px solid var(--pc-border-light, #f1f5f9);
}

.gh-announce-item:last-child {
    border-bottom: none;
}

.gh-announce-row {
    display: flex;
    gap: 0.65rem;
    padding: 0.65rem 1rem;
    align-items: flex-start;
    cursor: pointer;
    transition: background-color 0.12s;
}

.gh-announce-row:hover {
    background: var(--pc-border-light, #f1f5f9);
}

.gh-announce-icon {
    flex-shrink: 0;
    font-size: 0.9rem;
}

.gh-announce-info .gh-announce-icon { color: #3182ce; }
.gh-announce-warning .gh-announce-icon { color: #dd6b20; }
.gh-announce-danger .gh-announce-icon { color: #e53e3e; }

.gh-announce-body {
    flex: 1;
    min-width: 0;
}

.gh-announce-title {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--pc-text, #2d3748);
    line-height: 1.3;
}

.gh-announce-slot {
    font-size: 0.7rem;
    color: var(--pc-text-muted, #718096);
    margin-top: 0.15rem;
}

.gh-announce-chevron {
    flex-shrink: 0;
    font-size: 0.7rem;
    color: var(--pc-text-muted, #718096);
    margin-top: 2px;
}

.gh-announce-detail {
    padding: 0 1rem 0.75rem 1rem;
    font-size: 0.82rem;
    line-height: 1.55;
    color: var(--pc-text, #2d3748);
    border-top: 1px dashed var(--pc-border-light, #f1f5f9);
    margin: 0 0.5rem;
    padding-top: 0.6rem;
    overflow: hidden;
    max-height: 300px;
    overflow-y: auto;
}

.gh-announce-detail img { max-width: 100%; height: auto; }

.gh-announce-preview {
    font-size: 0.8rem;
    color: var(--pc-text-muted, #718096);
    margin: 0 0 0.5rem;
    line-height: 1.45;
}

.gh-announce-view-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--pc-accent-ink, #3182ce);
    background: none;
    border: 1px solid var(--pc-accent, #3182ce);
    border-radius: 0.3rem;
    padding: 0.3rem 0.65rem;
    cursor: pointer;
    transition: background-color 0.12s, color 0.12s;
}

.gh-announce-view-btn:hover {
    background: var(--pc-accent, #3182ce);
    color: white;
}

/* Announcement detail modal — markup + styles live in <AnnouncementModalView />.
   The bell popup invokes that shared component instead of duplicating the modal. */

/* Inline action row inside an expanded popup item — choices, "Got it",
   dismiss. Sits below the announcement body. Severity inheritance comes
   from the parent .gh-announce-@severity wrapper. */
.gh-announce-detail-body { margin-bottom: 0.5rem; }

.gh-announce-detail-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
    margin-top: 0.5rem;
}

.gh-announce-detail-choice-btn,
.gh-announce-detail-ack-btn,
.gh-announce-detail-dismiss-btn {
    padding: 0.3rem 0.75rem;
    border: 1px solid currentColor;
    border-radius: 0.25rem;
    background: transparent;
    color: inherit;
    font-size: 0.8rem;
    cursor: pointer;
    opacity: 0.85;
    transition: opacity 0.15s, background-color 0.15s;
    white-space: nowrap;
}

.gh-announce-detail-choice-btn:hover,
.gh-announce-detail-ack-btn:hover,
.gh-announce-detail-dismiss-btn:hover {
    opacity: 1;
    background-color: rgba(0, 0, 0, 0.08);
}

.gh-announce-detail-dismiss-link {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 0.78rem;
    color: inherit;
    opacity: 0.65;
    text-decoration: underline;
    padding: 0.15rem 0.25rem;
    transition: opacity 0.15s;
}
.gh-announce-detail-dismiss-link:hover { opacity: 1; }

/* ── Responsive visibility helpers for GlobalHeaderActions ── */
.gh-mobile-only { display: none; }

@media (min-width: 769px) {
    .gh-mobile-only { display: none !important; }
}

@media (max-width: 768px) {
    .gh-desktop-only { display: none !important; }
    .gh-mobile-only { display: flex !important; }
}

/* ═══════════════════════════════════════════════════════════════
   MOBILE: Dark card trigger (matches sidebar CustomerContextSelector)
   ═══════════════════════════════════════════════════════════════ */
.gh-mobile-card-wrap {
    width: 100%;
    position: relative;
}

.gh-mobile-card {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.35rem 0.55rem;
    background: #1e293b;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 10px;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
    font-family: inherit;
    color: white;
    text-align: left;
}

.gh-mobile-card:hover {
    background: #253347;
    border-color: rgba(255, 255, 255, 0.14);
}

.gh-mobile-card-active {
    background: #253347;
    border-color: rgba(99, 179, 237, 0.3);
}

/* Avatar — gradient initials square */
.gh-mobile-avatar {
    width: 26px;
    height: 26px;
    border-radius: 6px;
    background: linear-gradient(135deg, #4299e1, #63b3ed);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.7rem;
    color: #fff;
    flex-shrink: 0;
}

.gh-mobile-card-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.gh-mobile-card-name {
    font-size: 0.78rem;
    font-weight: 600;
    color: #fff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 1.3;
}

.gh-mobile-card-context {
    font-size: 0.62rem;
    color: rgba(255, 255, 255, 0.45);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 1.3;
    display: flex;
    align-items: center;
    gap: 0.3rem;
}

.gh-mobile-card-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: #f59e0b;
    flex-shrink: 0;
}

.gh-mobile-card-chevron {
    font-size: 0.55rem;
    color: rgba(255, 255, 255, 0.35);
    flex-shrink: 0;
    transition: transform 0.2s ease;
}

.gh-mobile-chevron-open {
    transform: rotate(180deg);
    color: rgba(255, 255, 255, 0.6);
}

/* ═══════════════════════════════════════════════════════════════
   MOBILE SHEET — slides down from the card trigger, dark themed.
   Overrides the light-themed gh-ctx-* and gh-acct-* for dark bg.
   ═══════════════════════════════════════════════════════════════ */
.gh-mobile-sheet {
    position: fixed;
    top: 50px;
    left: 0;
    right: 0;
    z-index: 1009;
    background: #1e293b;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 0 0 12px 12px;
    box-shadow: 0 12px 36px rgba(0, 0, 0, 0.4);
    max-height: calc(100vh - 50px - 80px);
    overflow-y: auto;
    animation: gh-sheet-slide 0.2s ease-out;
}

@keyframes gh-sheet-slide {
    from { opacity: 0; transform: translateY(-8px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ── Dark overrides for context sections inside sheet ── */
.gh-mobile-sheet .gh-ctx-section {
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.gh-mobile-sheet .gh-ctx-label {
    color: rgba(255, 255, 255, 0.4);
}

.gh-mobile-sheet .gh-ctx-select-wrap {
    padding: 0 0.65rem 0.35rem;
}

.gh-mobile-sheet .gh-ctx-select-trigger {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 255, 255, 0.12);
    color: white;
}

.gh-mobile-sheet .gh-ctx-select-trigger:hover:not(:disabled) {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.2);
}

.gh-mobile-sheet .gh-ctx-select-id {
    color: rgba(255, 255, 255, 0.4);
}

.gh-mobile-sheet .gh-ctx-select-chevron {
    color: rgba(255, 255, 255, 0.4);
}

.gh-mobile-sheet .gh-ctx-select-dropdown {
    background: #283244;
    border-color: rgba(255, 255, 255, 0.12);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.gh-mobile-sheet .gh-ctx-select-option {
    color: rgba(255, 255, 255, 0.8);
    border-bottom-color: rgba(255, 255, 255, 0.04);
}

.gh-mobile-sheet .gh-ctx-select-option:hover:not(:disabled) {
    background: rgba(255, 255, 255, 0.06);
}

.gh-mobile-sheet .gh-ctx-select-option-active {
    background: rgba(99, 179, 237, 0.12);
    color: #93c5fd;
}

.gh-mobile-sheet .gh-ctx-select-option-active:hover:not(:disabled) {
    background: rgba(99, 179, 237, 0.12);
}

.gh-mobile-sheet .gh-ctx-check {
    color: #63b3ed;
}

.gh-mobile-sheet .gh-ctx-name {
    color: inherit;
}

.gh-mobile-sheet .gh-ctx-id {
    color: rgba(255, 255, 255, 0.4);
}

/* Toggle overrides for dark theme */
.gh-mobile-sheet .gh-ctx-group {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.08);
}

.gh-mobile-sheet .gh-ctx-toggle {
    color: rgba(255, 255, 255, 0.55);
    border-bottom-color: rgba(255, 255, 255, 0.04);
}

.gh-mobile-sheet .gh-ctx-toggle:hover {
    background: rgba(255, 255, 255, 0.06);
}

.gh-mobile-sheet .gh-ctx-toggle-on {
    color: rgba(255, 255, 255, 0.9);
}

.gh-mobile-sheet .gh-ctx-track {
    background: rgba(255, 255, 255, 0.15);
}

/* Restore the green on-state inside the dark mobile sheet — without
   this rule the .gh-mobile-sheet .gh-ctx-track override above wins by
   cascade order and the toggles look identical whether selected or not.
   Higher specificity (0,3,0) beats the override (0,2,0). */
.gh-mobile-sheet .gh-ctx-toggle-on .gh-ctx-track {
    background: #22c55e;
}

.gh-mobile-sheet .gh-ctx-switching {
    color: rgba(255, 255, 255, 0.5);
}

/* ── Dark nav links ── */
.gh-mobile-sheet .gh-acct-nav {
    border-top-color: rgba(255, 255, 255, 0.06);
}

.gh-mobile-sheet .gh-acct-menu-item {
    color: rgba(255, 255, 255, 0.75);
}

.gh-mobile-sheet .gh-acct-menu-item:hover {
    background: rgba(255, 255, 255, 0.06);
    color: #93c5fd;
}

.gh-mobile-sheet .gh-acct-menu-icon {
    background: rgba(255, 255, 255, 0.08);
}

.gh-mobile-sheet .gh-acct-menu-icon i {
    color: rgba(255, 255, 255, 0.5);
}

.gh-mobile-sheet .gh-acct-menu-item:hover .gh-acct-menu-icon {
    background: rgba(99, 179, 237, 0.15);
}

.gh-mobile-sheet .gh-acct-menu-item:hover .gh-acct-menu-icon i {
    color: #93c5fd;
}

/* ── Dark sign out ── */
.gh-mobile-sheet .gh-acct-signout {
    border-top-color: rgba(255, 255, 255, 0.06);
}

.gh-mobile-sheet .gh-acct-signout-btn {
    color: #fca5a5;
    border-color: rgba(252, 165, 165, 0.2);
}

.gh-mobile-sheet .gh-acct-signout-btn:hover {
    background: rgba(252, 165, 165, 0.1);
    border-color: rgba(252, 165, 165, 0.35);
}

/* ── Sheet extras: chat + announcements (mobile-only) ── */
.gh-sheet-extras {
    display: flex;
    flex-direction: column;
    padding: 0.35rem 0;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.gh-sheet-link {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    padding: 0.5rem 0.85rem;
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.75);
    font-size: 0.8rem;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
    transition: background 0.1s, color 0.1s;
}

.gh-sheet-link:hover {
    background: rgba(255, 255, 255, 0.06);
    color: #93c5fd;
}

.gh-sheet-link-icon {
    width: 26px;
    height: 26px;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.08);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.gh-sheet-link-icon i {
    font-size: 0.78rem;
    color: rgba(255, 255, 255, 0.5);
}

.gh-sheet-link:hover .gh-sheet-link-icon {
    background: rgba(99, 179, 237, 0.15);
}

.gh-sheet-link:hover .gh-sheet-link-icon i {
    color: #93c5fd;
}

/* Inline badge for announcement count */
.gh-bell-badge-inline {
    background: #e53e3e;
    color: white;
    font-size: 0.65rem;
    font-weight: 600;
    padding: 0.1rem 0.4rem;
    border-radius: 10px;
    margin-left: auto;
}

/* ================================================================
   DIALOG ACTION BUTTONS — consistent Cancel / Save across every modal
   footer (the Edit Address modal's treatment is the reference):
     - primary (Save/confirm) = dark primary fill
     - secondary (Cancel)     = light gray fill
     - the footer never wraps to a second row
   Danger actions (btn-danger / btn-outline-danger) keep their own color.
   Applies to any dialog using the standard .modal-footer + Bootstrap btns.
   ================================================================ */
.modal-footer {
    /* Match the Edit Address modal's footer chrome so every dialog using the
       standard .modal-footer aligns its buttons identically (right-aligned,
       same horizontal padding as a 1.5rem body, single row). */
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0.75rem;
    padding: 1rem 1.5rem;
    border-top: 1px solid #e2e8f0;
}

.modal-footer .btn-primary {
    background-color: var(--pc-accent, #0046ad);
    border-color: var(--pc-accent, #0046ad);
    color: #fff;
}

.modal-footer .btn-primary:hover:not(:disabled) {
    background-color: var(--pc-primary, #00337d);
    border-color: var(--pc-primary, #00337d);
    color: #fff;
}

/* Brand-aware "soft" primary — blue on PCE, slate on SF (via --pc-accent-soft) —
   for value-setting dialog confirms (ready-time, deliver-by, property string
   input). These read as form controls, not the main order-submit CTA, so SF's
   harsh red accent stays off them while the submit button keeps the brand color.
   Placed after .modal-footer .btn-primary so it wins on source order there too
   (equal specificity); it out-specifies the base .btn-primary everywhere else. */
.btn-primary.btn-soft {
    background-color: var(--pc-accent-soft, var(--pc-accent, #0046ad));
    border-color: var(--pc-accent-soft, var(--pc-accent, #0046ad));
}

.btn-primary.btn-soft:hover:not(:disabled),
.btn-primary.btn-soft:focus:not(:disabled),
.btn-primary.btn-soft:active:not(:disabled) {
    background-color: var(--pc-primary, #00337d);
    border-color: var(--pc-primary, #00337d);
}

.btn-primary.btn-soft:disabled,
.btn-primary.btn-soft.disabled {
    background-color: var(--pc-accent-soft, var(--pc-accent, #0046ad));
    border-color: var(--pc-accent-soft, var(--pc-accent, #0046ad));
}

.modal-footer .btn-secondary {
    background-color: #e2e8f0;
    border-color: #e2e8f0;
    color: #4a5568;
}

.modal-footer .btn-secondary:hover:not(:disabled) {
    background-color: #cbd5e0;
    border-color: #cbd5e0;
    color: #2d3748;
}

/* Mobile adjustments */
@media (max-width: 768px) {
    /* Page header pinned to the top of the viewport on mobile. We use
       position:fixed (not sticky) because the .content-area ancestor sets
       overflow-x:hidden, which per spec forces overflow-y to compute to
       auto — making content-area a scroll container that grows with its
       content while the *window* does the scrolling. A sticky child of a
       scroll container that never itself scrolls has nothing to stick to,
       so it scrolls away. Fixed pins to the viewport regardless. The
       z-index keeps the header (and its Quick Actions / Support / account
       dropdowns) above page content such as the Active Orders map.
       NOTE: .content-area gets a matching padding-top (≈ header height) so
       page content isn't hidden under the now-out-of-flow header. */
    .page-header {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        z-index: 1050;
        /* Solid themed bar (chevrons retired for now). Style A (default): white
           surface + hairline border; B/D override below to match the desktop
           strip. The title keeps its theme colour (base .page-header h1 rule). */
        background: #fff;
        border-bottom: 1px solid #e2e8f0;
    }

    /* Drop shadow below the fixed header so content scrolling under it reads as
       separate (gives the scrollable area depth). Fixed because .page-header is
       fixed; pointer-events:none so it never intercepts taps. */
    .page-header::after {
        content: "";
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        height: 14px;
        background: linear-gradient(to bottom, rgba(15, 23, 42, 0.14), rgba(15, 23, 42, 0));
        pointer-events: none;
    }

    /* Mobile header — brand-blue bar, light text (matches the desktop org strip). */
    .page-header {
        background: var(--pc-accent);
        border-bottom-color: transparent;
        color: #fff;
    }

    .page-header h1 {
        color: #fff;
    }

    .page-header .gh-btn {
        color: rgba(255, 255, 255, 0.9);
        border-color: transparent;
    }

    .page-header .gh-btn:hover {
        background: rgba(255, 255, 255, 0.15);
        color: #fff;
    }

    /* Near-solid white avatar with accent initials on the mobile bar. */
    .page-header .gh-acct-trigger {
        background: rgba(255, 255, 255, 0.92);
        color: var(--pc-accent-ink);
    }

    /* Mobile QA trigger: near-solid white CTA with accent content + soft glow. */
    .page-header-actions .gh-btn {
        background: rgba(255, 255, 255, 0.92);
        color: var(--pc-accent-ink);
        transition: box-shadow 0.15s ease;
    }

    .page-header-actions .gh-btn:hover {
        color: var(--pc-accent-ink);
        box-shadow: 0 0 10px rgba(255, 255, 255, 0.6);
    }

    /* Modal headers: reduce padding on mobile since close buttons are 44px tall */
    .modal-header {
        padding: 0.25rem 0.75rem;
    }

    .page-action-bar {
        padding: 0.35rem 0.75rem;
        gap: 0.35rem;
        flex-wrap: wrap;
    }

    .page-body {
        padding: 0.5rem 0.75rem;
    }

    /* gh-actions (Quick Actions / Support / account icons) flows inline in the
       page header on mobile, same right-aligned layout as desktop — no fixed
       dark top bar. */

    .gh-announce-panel {
        width: min(340px, calc(100vw - 2rem));
        right: -0.5rem;
    }
}

/* Deliver-by modal — shared between PlaceOrder and ContinuationFinalize.
   Lives here (not in either page's <style>) because Blazor inline styles
   only enter the DOM when the host page is rendered; consumers on other
   pages would otherwise inherit no styling. The specificity bump on
   `.modal-overlay > .modal-content.deliver-by-modal` overrides the global
   `.modal-content { overflow: hidden }` rule so the combobox dropdown
   isn't clipped by the modal body. */
.modal-overlay > .modal-content.deliver-by-modal {
    max-width: 400px;
    overflow: visible;
}

.modal-overlay > .modal-content.deliver-by-modal .modal-body {
    overflow: visible;
}

/* overflow: visible on the deliver-by modal (needed so the combobox
   dropdown isn't clipped) lets the gradient header paint over the
   parent's 8px rounded corners, making the top of the modal look
   square. The footer gets its own border-radius: 0 0 8px 8px in
   each page's modal-chrome <style> block; mirror that on the header
   here so the modal looks rounded on all four sides. */
.modal-overlay > .modal-content.deliver-by-modal .modal-header {
    border-top-left-radius: 8px;
    border-top-right-radius: 8px;
}

.deliver-by-header-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.deliver-by-modal .modal-header h3 {
    margin: 0;
}

.deliver-by-date-subtitle {
    font-size: 0.85rem;
    color: rgba(255, 255, 255, 0.85);
    font-weight: 400;
}

.deliver-by-earliest-line {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.4rem;
    font-size: 0.85rem;
    color: #4b5563;
}

.deliver-by-earliest-line strong {
    color: #059669;
    font-weight: 600;
}

.deliver-by-validation-error {
    margin-top: 0.5rem;
    font-size: 0.85rem;
    color: #dc2626;
}

/* ──────────────────────────────────────────────────────────────
   .db-qa-btn — shared "quick action" button style.

   One global definition so every surface that shows quick-action
   buttons (Dashboard toolbar, OrderConfirmation, ContinuationConfirmation)
   inherits the same font size, padding, border, and hover behavior.
   Edit this block to retune the buttons portal-wide; no per-page
   restatement needed.

   Variants:
     .db-qa-btn            — default outline (secondary actions)
     .db-qa-primary        — solid accent (primary action: "Place Order")
     .db-qa-popular        — red-tinged outline (popular-recurring slot)
     .db-qa-chevron        — small chevron icon on dropdown buttons
   ────────────────────────────────────────────────────────────── */
.db-qa-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.85rem;
    border-radius: var(--pc-radius-sm, 8px);
    border: 1px solid var(--pc-border, #e2e8f0);
    background: var(--pc-surface-elevated, #ffffff);
    font-size: 0.8rem;
    color: var(--pc-text-muted, #64748b);
    cursor: pointer;
    transition: all 0.15s;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
    text-decoration: none;
}

.db-qa-btn:hover,
.db-qa-btn:focus {
    /* Themed hover: PCE blue / SF slate via --pc-accent-soft (never harsh red). */
    border-color: var(--pc-accent-soft, var(--pc-accent, #0046ad));
    color: var(--pc-accent-soft, var(--pc-accent, #0046ad));
    background: rgba(100, 116, 139, 0.08);
    text-decoration: none;
}

.db-qa-btn.db-qa-primary {
    background: var(--pc-accent-soft, var(--pc-accent, #0046ad));
    color: #ffffff;
    border-color: var(--pc-accent-soft, var(--pc-accent, #0046ad));
}

.db-qa-btn.db-qa-primary:hover,
.db-qa-btn.db-qa-primary:focus {
    /* Darken toward the themed primary (PCE deep blue / SF charcoal). */
    background: var(--pc-primary, #00337d);
    color: #ffffff;
    border-color: var(--pc-primary, #00337d);
}

/* Popular slot accent — used by the Dashboard's popular-recurring
   button. Confirmation pages don't render this variant. */
.db-qa-btn.db-qa-popular {
    border-color: #fc8181;
    color: #c53030;
}

.db-qa-btn.db-qa-popular:hover,
.db-qa-btn.db-qa-popular:focus {
    background: #fff5f5;
    border-color: #e53e3e;
    color: #c53030;
}

/* Chevron icon on dropdown-style quick-action buttons. */
.db-qa-chevron {
    font-size: 0.6rem;
    margin-left: 0.1rem;
    opacity: 0.5;
}
/* Danger "link" button — a destructive secondary action (Clear Address, Remove,
   etc.) styled as a lighter danger-text link rather than a filled/outlined box,
   so it never competes visually with the primary Save/confirm button. This was
   originally scoped to AddressEditModal's "Clear Address" button; promoted here
   to a global utility so any footer can reuse the exact same treatment.

   Note: this is a NEW class name, not an override of Bootstrap's
   .btn-outline-danger — overriding the Bootstrap class would restyle every
   danger-outline button on the site. Pair with Bootstrap's `me-auto` when you
   want it pushed to the far-left of a flex footer (layout stays the consumer's
   job; this class only carries the visual treatment). */
.btn-danger-link {
    white-space: nowrap;
    background: transparent;
    border-color: transparent;
    color: #c53030;
    padding-left: 0;
}

.btn-danger-link:hover:not(:disabled) {
    background: transparent;
    border-color: transparent;
    color: #9b2c2c;
    text-decoration: underline;
}

/* ================================================================
   PRINT — print just the page content, full width. Hide the app
   chrome (nav, headers, mobile bars) and the Reports page's own
   filter/toolbar/action controls, and drop the table's scroll box so
   the report flows across pages instead of clipping (overflow-x:auto
   otherwise reserves a vertical scrollbar gutter on the right).
   ================================================================ */
@media print {
    .org-strip,
    .sidebar,
    .sidebar-overlay,
    .site-footer,
    .page-header,
    .mobile-menu-btn,
    .mobile-bottom-nav,
    .impersonation-banner,
    .report-search-card,
    .report-toolbar,
    .results-actions {
        display: none !important;
    }

    .main-content,
    .content-area {
        margin: 0 !important;
        padding: 0 !important;
    }

    .results-section {
        margin: 0 !important;
        border: none !important;
    }

    /* Neutralize every scroll container between the root and the table so
       none reserves a scrollbar gutter (which Chrome paints into the PDF as
       a grey bar down the right edge). Includes html/body because a root
       viewport scrollbar can survive into paged output. */
    html,
    body,
    .content-area,
    .page-body,
    .reports-page,
    .results-section,
    .results-table-container {
        overflow: visible !important;
        height: auto !important;
    }
}

/* ── 3D freight size preview ─────────────────────────────────────────────────
   The dimensions header, the sliders/preview two-column row, and the CSS-3D box with
   its person-for-scale watermark. Moved here from PlaceOrder.razor's page-level style
   block, which only exists in the DOM while that page is rendered — CompactFreightSelector
   renders the same preview in its Custom pane on Continuation.

   Unchanged apart from unescaping Razor's @@ back to @. PlaceOrder's own .slider-* rules
   deliberately stayed behind: nothing else uses them, and .slider-label / .slider-number
   are generic enough that globalising them invites a collision. Task #3548. */
/* .section-sep is gone — it had no markup left. It was a spacer that drew nothing
   (visibility: hidden), separating generic freight's pieces/weight half from its
   dimensions half; both halves are labelled preset-spec-blocks now and the margin on
   .generic-freight > .preset-spec-block does the same job honestly. Task #3551. */

/* ══════════════════════════════════════════════
   DIMS + PREVIEW ROW
   ══════════════════════════════════════════════ */
/* Top-aligned, not stretched. Stretching centred the fixed-height scene inside whichever
   column was taller, which put a band of empty card above the box. Both columns now start
   on the same line: the fields column leads with pieces/weight, and the scene sits level
   with it. */
.dims-preview-row {
    display: flex;
    gap: 0px;
    align-items: flex-start;
    justify-content: center;
}

/* Sized to its fields, not grown. flex:1 here made the column eat the whole row and
   pinned the scene to the far right edge; with flex:0 1 auto the leftover width goes to
   .preview-col, which is what centres the scene in it.

   The column holds every numeric field the pane asks for — pieces/weight first, then the
   L/W/H block, each its own .preset-spec-block. The gap separates the two, replacing the
   margin they carried when pieces/weight sat outside this row. */
.dims-col {
    flex: 0 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
    /* No horizontal padding so the L/W/H number boxes justify to the same left/right
       edges as the pieces/weight pair above them. Vertical padding is kept. */
    padding: 8px 0;
    /* Lifted over the 3D box, which is deliberately NOT clipped to its 170px frame and so
       paints across these fields at large dimensions. See .box-scene. */
    position: relative;
    z-index: 2;
}

/* Takes the width the fields don't, and centres the scene in it (align-items on a column
   flexbox is the cross axis = horizontal). The scene is a figure, not a field — it reads
   as one when it has its own space rather than being flush against the last input or
   jammed into the panel's right edge.

   The 84px top is a measured constant, not a guess to round off: it clears the pieces and
   weight block (.dims-col's 8px top padding + the heading + its field row + the 1.1rem
   column gap) so the scene starts level with the SIZE block instead. Which is the point —
   the box illustrates L/W/H, and pieces/weight is just the group it has to clear to get
   there. If that block's height ever changes, this number moves with it.

   .cfs-preset-panel overrides this to 0: its pane leads with pieces/weight in a much
   narrower column, and the scene belongs directly beside the fields there. */
.preview-col {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 84px 10px 10px;
}

/* Fixed height, not flex:1 — with the row top-aligned there is no stretched column to
   fill, and a growing scene would only re-open the gap this closes. */
.preview-col .box-scene {
    flex: 0 0 auto;
    width: 170px;
    min-height: 170px;
}

.dims-header {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #64748b;
    text-align: left;
    margin-bottom: 2px;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    /* Left-anchored so the label + tooltip + preview button stay put. If the
       row were centered, toggling the preview (which widens/narrows the dims
       column) would re-center the group and shift the button horizontally. */
    justify-content: flex-start;
}

.dims-header .hint-icon {
    color: #94a3b8;
    cursor: help;
    font-size: 0.8rem;
}

/* Show/hide-preview button — styled as .box-scene-btn (matches the rotate
   button). Sits inline right after the header text + help tooltip (the
   .dims-header gap spaces it), so its position is fixed whether the preview
   is shown or hidden. Scoped under .dims-header to out-specify .box-scene-btn
   (defined later in the file) — slightly tighter so it reads inline with the
   compact header text rather than towering over it. */
.dims-header .dims-preview-toggle,
.preset-spec-heading .dims-preview-toggle {
    padding: 3px 7px;
    font-size: 0.8rem;
}

/* The preset editor's headings are uppercase 0.78rem label text, so the eye button has
   to come down further still or it sets the line height for the whole row. It sits
   directly after the hint icon rather than being pushed to the trailing edge: the
   heading's width is set by the fields below it, so margin-left:auto parked the eye a
   long way from the label it belongs to. */
.preset-spec-heading .dims-preview-toggle {
    padding: 2px 6px;
    font-size: 0.75rem;
}

/* ══════════════════════════════════════════════
   SLIDER CONTROLS — range + number input pairs
   One-click value selection for pieces, weight, and dimensions.
   ══════════════════════════════════════════════ */

/* Every rule BODY in this section was lost when the block moved out of PlaceOrder's
   page-level <style>: the comments came across but the declarations didn't, and two
   selectors were left dangling with trailing commas. Those two then merged into the
   .person-watermark rule below — so .generic-freight > .slider-group .slider-label was
   being absolutely positioned, which is what threw the Custom pane's sliders and number
   boxes out of alignment. Restored verbatim from the page block. Task #3551. */
.slider-group {
    display: flex;
    flex-direction: row;
    gap: 1rem;
    /* Lets the row shrink to fit a flex parent (.freight-fields).
       Without this the row's intrinsic content size (slider-range
       defaults + number input + label) can overflow the card. */
    min-width: 0;
    max-width: 100%;
}

/* .generic-freight > .preset-spec-block is gone. It styled the pieces/weight block back
   when that block led the pane on its own full-width line above .dims-preview-row — which
   is what left the dead space beside it. The block moved INTO .dims-col, and both of the
   rule's jobs moved with it: the z-index lift over the unclipped 3D box (see .box-scene)
   and the 1.1rem between the two labelled blocks, now .dims-col's gap. */

.slider-unit {
    display: flex;
    align-items: center;
    /* Tight gap so the slider sits close to the label with no
       dead space — leaves more room for the range track. */
    gap: 0.35rem;
    /* Strict 50/50 split between Pieces and Weight in the row.
       flex: 1 1 0 makes each unit take exactly half the row width
       regardless of intrinsic content size. min-width: 0 lets the
       inner range input shrink instead of overflowing. */
    flex: 1 1 0;
    min-width: 0;
}

/* Stack Pieces / Weight back to a column on narrow screens where two
   slider units side-by-side leave no room for the range input. */
@media (max-width: 575px) {
    .slider-group {
        flex-direction: column;
    }
}

.slider-label {
    font-size: 0.75rem;
    font-weight: 600;
    color: #475569;
    /* Drop the wide 65px min-width so the label hugs its text and
       gives the range input more horizontal real estate. The
       slider-unit's gap of 0.35rem provides the visual breathing
       room between label and slider. */
    text-align: right;
    white-space: nowrap;
}

/* .dim-sliders and the shared label-column width that went with it are gone: generic
   freight's L/W/H sliders were replaced by typed preset-spec-* fields, so there is no
   longer a slider track to line up. The .slider-* rules above stay — small freight and
   commercial freight still use them. Task #3551. */

.slider-range {
    flex: 1 1 0;
    height: 6px;
    cursor: pointer;
    accent-color: #3b82f6;
    /* input[type="range"] has a default user-agent min-width that
       prevents it from shrinking below ~150px in some browsers.
       min-width: 0 lets the flex 1 1 0 actually take effect. */
    min-width: 0;
}

.slider-number {
    width: 40px;
    padding: 0.2rem 0.15rem;
    font-size: 0.8rem;
    text-align: center;
    border: 1px solid #cbd5e1;
    border-radius: 4px;
    background: #f8fafc;
    color: #1e293b;
}

.slider-number:focus {
    outline: none;
    border-color: #3b82f6;
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
}

.slider-number.is-invalid {
    border-color: #dc2626;
}

/* Hide number input spinner arrows for cleaner look */
.slider-number::-webkit-inner-spin-button,
.slider-number::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.slider-number[type=number] {
    -moz-appearance: textfield;
}

/* ══════════════════════════════════════════════
   PERSON WATERMARK — behind the 3D box
   ══════════════════════════════════════════════ */
.person-watermark {
    position: absolute;
    left: 0;
    bottom: 0;
    pointer-events: none;
    opacity: 0.5;
    height: 100%;
    width: auto;
    object-fit: contain;
    object-position: bottom;
}


@keyframes clip-fade {
    0%, 70% { opacity: 1; }
    100% { opacity: 0; }
}

/* Bottom-right control stack: rotate on top, show/hide toggle below it. */
.box-scene-controls {
    position: absolute;
    right: 4px;
    bottom: 4px;
    z-index: 5;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.box-scene-btn {
    padding: 5px 10px;
    border: 1px solid #cbd5e1;
    border-radius: 5px;
    background: #fff;
    color: #64748b;
    cursor: pointer;
    font-size: 0.85rem;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: all 0.15s;
    box-shadow: 0 1px 2px rgba(0,0,0,0.06);
}

.box-scene-btn:hover {
    border-color: #3b82f6;
    color: #3b82f6;
    opacity: 1;
}

/* 3D Box Preview */
.box-preview-column {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    min-width: 120px;
}

.box-scene {
    width: 170px;
    height: 170px;
    perspective: 500px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding-left: 40px;
    position: relative;
    /* Intentionally NOT clipped — the box is meant to grow past this 170px
       frame to convey scale against the person silhouette. Because the faces
       are transform:preserve-3d elements they paint ABOVE earlier in-flow
       siblings (freight type / category / pieces+weight), so those controls
       are lifted into a higher stacking level (position:relative + z-index)
       to sit over the overflowing box. See .freight-type-compact /
       .freight-category-selector / .generic-freight .slider-group below. */
}

/* Preview toggled off (eye button in the dims header) — drop the whole
   preview column so the three dimension sliders span the full row width. */
.dims-preview-row.preview-hidden .preview-col {
    display: none;
}

/* ...and stop the row re-centring what's left. The base row is justify-content:center,
   which is inert while the preview is on screen — .preview-col is flex:1 1 auto, so it
   absorbs all the free space and there is nothing left to distribute. Hide that column
   and the free space comes back, so the fields column (flex:0 1 auto) gets centred and
   every label/input slides right as the box disappears. Pack left instead: toggling the
   picture off must not move the controls. */
.dims-preview-row.preview-hidden {
    justify-content: flex-start;
}

.box-3d {
    position: relative;
    transform-style: preserve-3d;
    transform: rotateX(-20deg) rotateY(-30deg);
    animation: box-float 4s ease-in-out infinite;
}

@keyframes box-float {
    0%, 100% { transform: rotateX(-20deg) rotateY(-30deg); }
    50% { transform: rotateX(-25deg) rotateY(-35deg) translateY(-3px); }
}

.box-face {
    position: absolute;
    left: 50%;
    top: 50%;
    border: 1px solid rgba(59, 130, 246, 0.5);
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.15) 0%, rgba(59, 130, 246, 0.05) 100%);
    backface-visibility: visible;
}

/* Front/Back faces: width × height, offset along Z by depth/2 */
.box-face.front {
    width: var(--box-w, 50px);
    height: var(--box-h, 50px);
    transform: translate(-50%, -50%) translateZ(calc(var(--box-d, 50px) / 2));
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.2) 0%, rgba(59, 130, 246, 0.1) 100%);
}

.box-face.back {
    width: var(--box-w, 50px);
    height: var(--box-h, 50px);
    transform: translate(-50%, -50%) rotateY(180deg) translateZ(calc(var(--box-d, 50px) / 2));
}

/* Right/Left faces: depth × height, offset along X by width/2 */
.box-face.right {
    width: var(--box-d, 50px);
    height: var(--box-h, 50px);
    transform: translate(-50%, -50%) rotateY(90deg) translateZ(calc(var(--box-w, 50px) / 2));
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.25) 0%, rgba(59, 130, 246, 0.1) 100%);
}

.box-face.left {
    width: var(--box-d, 50px);
    height: var(--box-h, 50px);
    transform: translate(-50%, -50%) rotateY(-90deg) translateZ(calc(var(--box-w, 50px) / 2));
}

/* Top/Bottom faces: width × depth, offset along Y by height/2 */
.box-face.top {
    width: var(--box-w, 50px);
    height: var(--box-d, 50px);
    transform: translate(-50%, -50%) rotateX(90deg) translateZ(calc(var(--box-h, 50px) / 2));
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.3) 0%, rgba(59, 130, 246, 0.15) 100%);
}

.box-face.bottom {
    width: var(--box-w, 50px);
    height: var(--box-d, 50px);
    transform: translate(-50%, -50%) rotateX(-90deg) translateZ(calc(var(--box-h, 50px) / 2));
}

/* Clipped dimension — cap face turns red when rotation exceeds max */
.box-face.clipped {
    border-color: rgba(220, 38, 38, 0.6) !important;
    transition: background 0.3s, border-color 0.3s;
}

.box-face.top.clipped { background: linear-gradient(135deg, rgba(220,38,38,0.35) 0%, rgba(220,38,38,0.15) 100%) !important; }
.box-face.bottom.clipped { background: linear-gradient(135deg, rgba(220,38,38,0.15) 0%, rgba(220,38,38,0.05) 100%) !important; }
.box-face.right.clipped { background: linear-gradient(135deg, rgba(220,38,38,0.3) 0%, rgba(220,38,38,0.1) 100%) !important; }
.box-face.left.clipped { background: linear-gradient(135deg, rgba(220,38,38,0.15) 0%, rgba(220,38,38,0.05) 100%) !important; }
.box-face.front.clipped { background: linear-gradient(135deg, rgba(220,38,38,0.25) 0%, rgba(220,38,38,0.1) 100%) !important; }
.box-face.back.clipped { background: linear-gradient(135deg, rgba(220,38,38,0.15) 0%, rgba(220,38,38,0.05) 100%) !important; }

/* ============================================================
   Client admin section (Task #3823)
   The CUSTOMER's own admin area — their administrator managing
   their people. Not the staff admin console; it renders in the
   normal portal shell like any other page.
   ============================================================ */

.client-admin-page .ca-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.75rem;
}

.client-admin-page .ca-toolbar-left,
.client-admin-page .ca-toolbar-right {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.client-admin-page .ca-search {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    background: var(--pc-surface-elevated);
    border: 1px solid var(--pc-border);
    border-radius: 6px;
    padding: 0.35rem 0.6rem;
    min-width: 20rem;
}

.client-admin-page .ca-search i {
    color: var(--pc-text-muted);
}

.client-admin-page .ca-search input {
    border: none;
    outline: none;
    background: transparent;
    flex: 1;
    font-size: 0.9rem;
    color: var(--pc-text);
}

.client-admin-page .ca-toggle {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
    color: var(--pc-text-muted);
    cursor: pointer;
    user-select: none;
}

.client-admin-page .ca-count {
    font-size: 0.85rem;
    color: var(--pc-text-muted);
}

.client-admin-page .ca-muted {
    color: var(--pc-text-muted);
}

/* Sortable headers — same affordance as the address book grid. */
.client-admin-page .ca-sortable {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

.client-admin-page .ca-sortable::after {
    content: "";
    display: inline-block;
    width: 0.75rem;
    opacity: 0.4;
}

.client-admin-page .ca-sort-asc::after {
    content: " \2191";
    opacity: 1;
}

.client-admin-page .ca-sort-desc::after {
    content: " \2193";
    opacity: 1;
}

.client-admin-page .ca-row {
    cursor: pointer;
}

.client-admin-page .ca-row:hover {
    background: var(--pc-accent-glow);
}

/* Inactive users are shown (their list hides them) but visibly de-emphasised. */
.client-admin-page .ca-row-inactive td {
    opacity: 0.6;
}

.client-admin-page .ca-name {
    font-weight: 600;
}

.client-admin-page .ca-login {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.82rem;
}

.client-admin-page .ca-badge {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    vertical-align: middle;
}

.client-admin-page .ca-badge-self {
    background: var(--pc-border-light);
    color: var(--pc-text-muted);
}

.client-admin-page .ca-badge-admin {
    background: var(--pc-accent-glow);
    color: var(--pc-accent);
}

.client-admin-page .ca-chip {
    display: inline-block;
    margin: 0 0.2rem 0.2rem 0;
    padding: 0.05rem 0.4rem;
    border-radius: 4px;
    font-size: 0.7rem;
    border: 1px solid transparent;
}

.client-admin-page .ca-chip-on {
    background: var(--pc-success-light);
    color: #065f46;
}

.client-admin-page .ca-chip-off {
    background: transparent;
    color: var(--pc-text-muted);
    border-color: var(--pc-border);
    opacity: 0.55;
}

.client-admin-page .ca-status {
    font-size: 0.78rem;
    font-weight: 600;
}

.client-admin-page .ca-status-active {
    color: #065f46;
}

.client-admin-page .ca-status-inactive {
    color: var(--pc-text-muted);
}

.client-admin-page .ca-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    margin-top: 1rem;
}

.client-admin-page .ca-pager-label {
    font-size: 0.85rem;
    color: var(--pc-text-muted);
}

/* --- Detail view --- */

.client-admin-page .ca-back {
    margin-bottom: 0.75rem;
}

.client-admin-page .ca-back a {
    font-size: 0.85rem;
    color: var(--pc-text-muted);
    text-decoration: none;
}

.client-admin-page .ca-back a:hover {
    color: var(--pc-accent);
}

.client-admin-page .ca-detail-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: 1rem;
}

.client-admin-page .ca-card {
    background: var(--pc-surface-elevated);
    border: 1px solid var(--pc-border);
    border-radius: 8px;
    padding: 1rem 1.15rem;
}

.client-admin-page .ca-card h2 {
    font-size: 0.95rem;
    font-weight: 600;
    margin: 0 0 0.75rem;
    color: var(--pc-primary);
}

.client-admin-page .ca-fields {
    margin: 0;
}

.client-admin-page .ca-field {
    display: grid;
    grid-template-columns: 11rem 1fr;
    gap: 0.5rem;
    padding: 0.3rem 0;
    border-bottom: 1px solid var(--pc-border-light);
}

.client-admin-page .ca-field:last-child {
    border-bottom: none;
}

.client-admin-page .ca-field dt {
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--pc-text-muted);
}

.client-admin-page .ca-field dd {
    margin: 0;
    font-size: 0.88rem;
    color: var(--pc-text);
    overflow-wrap: anywhere;
}

.client-admin-page .ca-permissions {
    margin-top: 1rem;
}

.client-admin-page .ca-permissions-note {
    font-size: 0.82rem;
    margin: -0.4rem 0 1rem;
}

.client-admin-page .ca-perm-group {
    margin-bottom: 1rem;
}

.client-admin-page .ca-perm-group h3 {
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--pc-text-muted);
    margin: 0 0 0.45rem;
}

.client-admin-page .ca-perm-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 0.2rem 1rem;
}

.client-admin-page .ca-perm-grid {
    /* Three columns like the XLCP's own Security grid, collapsing to two then one as the
       card narrows. Explicit rather than auto-fill so the layout is predictable and never a
       single 100%-width column. */
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.3rem 1.5rem;
}

@media (max-width: 720px) {
    .client-admin-page .ca-perm-grid {
        grid-template-columns: 1fr 1fr;
    }
}

@media (max-width: 460px) {
    .client-admin-page .ca-perm-grid {
        grid-template-columns: 1fr;
    }
}

.client-admin-page .ca-perm-list li {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.86rem;
    padding: 0.15rem 0;
}

.client-admin-page .ca-perm-on {
    color: var(--pc-text);
}

.client-admin-page .ca-perm-on i {
    color: var(--pc-success);
}

.client-admin-page .ca-perm-off {
    color: var(--pc-text-muted);
    opacity: 0.7;
}

.client-admin-page .ca-perm-off i {
    color: var(--pc-border);
}

/* ---- Client admin edit mode (Task #3833) ---- */
.client-admin-page .ca-actions {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.client-admin-page .ca-save-banner {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.6rem 0.85rem;
    border-radius: 6px;
    margin-bottom: 1rem;
    font-size: 0.9rem;
}

.client-admin-page .ca-save-ok {
    background: rgba(56, 161, 105, 0.12);
    color: #276749;
}

.client-admin-page .ca-save-error {
    background: rgba(197, 48, 48, 0.10);
    color: #9b2c2c;
}

/* Delete confirmation: an inline danger panel, not a modal — a two-step confirm without
   blocking the render loop. */
.client-admin-page .ca-confirm {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem 1rem;
    padding: 0.85rem 1rem;
    border: 1px solid rgba(197, 48, 48, 0.35);
    background: rgba(197, 48, 48, 0.06);
    border-radius: 6px;
    margin-bottom: 1rem;
}

.client-admin-page .ca-confirm-body {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    color: #9b2c2c;
}

.client-admin-page .ca-confirm-body i {
    font-size: 1.15rem;
    line-height: 1.4;
}

.client-admin-page .ca-confirm-body strong {
    display: block;
    font-size: 0.95rem;
}

.client-admin-page .ca-confirm-body p {
    margin: 0.15rem 0 0;
    font-size: 0.85rem;
    color: #6b4a4a;
}

.client-admin-page .ca-confirm-actions {
    display: flex;
    gap: 0.5rem;
    flex-shrink: 0;
}

.client-admin-page .ca-field-edit dd {
    padding: 0;
}

.client-admin-page .ca-input {
    width: 100%;
    padding: 0.4rem 0.55rem;
    border: 1px solid var(--pc-border);
    border-radius: 5px;
    font-size: 0.9rem;
}

.client-admin-page .ca-perm-edit label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    margin: 0;
}

.client-admin-page .ca-perm-edit input[type="checkbox"] {
    width: 1rem;
    height: 1rem;
    flex: none;
}

@media (max-width: 768px) {
    .client-admin-page .ca-search {
        min-width: 0;
        width: 100%;
    }

    .client-admin-page .ca-toolbar-left {
        width: 100%;
        flex-wrap: wrap;
    }

    .client-admin-page .ca-field {
        grid-template-columns: 1fr;
        gap: 0.1rem;
    }
}
