/* ---------------------------------------------------------------------------
   Invoicing / fulfilment console.
   A thin layer over the bundled Bootstrap 5 - no CDN, because the production
   server serves this behind Apache with no outbound asset fetching.
   --------------------------------------------------------------------------- */

:root {
    --brand:            #1f3a5f;
    --brand-dark:       #16293f;
    --brand-accent:     #2f7fd1;
    --sidebar-width:    16rem;
    --surface:          #f5f7fa;
    --border:           #dfe3e8;
    --text-muted:       #6b7683;
}

/* Typography
   ------------------------------------------------------------------------------
   System fonts, no webfonts: nothing to download, nothing to block first paint, and
   no third-party dependency for an internal tool.

   `system-ui` leads deliberately. Naming 'Segoe UI' first - as this file used to -
   pins Windows to the 2004 face and skips Segoe UI Variable, the current Windows 11
   default; system-ui resolves to whatever the OS actually uses today. The rest is the
   modern fallback chain, matching what Bootstrap itself ships. */
:root {
    --font-sans: system-ui, -apple-system, "Segoe UI Variable Text", "Segoe UI",
                 Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial,
                 sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji";

    /* ui-monospace picks SF Mono / Cascadia where they exist. 'Courier New' is gone:
       it was the one face here that genuinely looked like 1998. */
    --font-mono: ui-monospace, SFMono-Regular, "SF Mono", "Cascadia Mono",
                 "JetBrains Mono", Menlo, Consolas, "Liberation Mono", monospace;
}

html, body {
    font-family: var(--font-sans);
    background: var(--surface);
    color: #212a35;

    /* Smoother stems on dark-on-light text, and the modern text-size default. */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

/* Form controls default to the browser's own UI font, which on Windows is still the
   old Segoe face - so without this the inputs quietly disagree with everything around
   them. Bootstrap sets this for .form-control; these are our own hand-rolled fields. */
input, select, textarea, button {
    font-family: inherit;
}

/* Fields side by side keep their inputs on one line, however their labels wrap.

   A row of columns, each a label over an input, lines everything up by the top edge. So
   when one label runs to two lines - which the Spanish ones often do - only that
   column's input drops, and the row turns into a staircase. Here each such column
   stacks vertically and its label takes up whatever height is spare, which pushes every
   input to the bottom of the row together. The labels still start level at the top.

   Only columns that hold a form label are touched, so layout columns are left alone. This
   relies on nothing sitting under an input in one column but not its neighbours: helper
   text belongs in a column of its own, as the Carriers preview does. */
.row > [class*="col"]:has(> .form-label) {
    display: flex;
    flex-direction: column;
}

.row > [class*="col"] > .form-label {
    flex-grow: 1;
}

/* Headings a touch tighter than body copy - default tracking looks loose at large
   sizes on variable system faces. */
h1, h2, h3, h4, h5, h6 {
    letter-spacing: -0.011em;
    font-weight: 600;
}

/* Overflow containment
   ------------------------------------------------------------------------------
   Data from marketplaces contains long unbroken strings - relay e-mail addresses,
   SKUs, tracking numbers, order references - with no natural break point. Left alone
   they widen their container, which in a flex or grid layout widens the page and
   produces a horizontal scrollbar on the whole site rather than wrapping locally. */

/* Flex and grid children default to min-width:auto, meaning "never shrink below my
   content". That default is what turns one long value into a page-wide scrollbar. */
.panel, .panel-body, .panel-header, .app-content, .card, .col, [class^="col-"] {
    min-width: 0;
}

.panel-body, .kv, .alert, .form-text, td, th, dd, p {
    overflow-wrap: break-word;
}

/* Deliberately NOT `html, body { overflow-x: hidden }`. That hides the scrollbar but
   also clips anything genuinely too wide, with no way to reach it - a worse failure
   than the scrollbar it removes. Wide content gets its own scroll container instead. */

/* Wide tables scroll within the panel rather than stretching it. Bootstrap's
   .table-responsive does this - every table in the app is wrapped in one. */

/* Long values that must stay on one line to remain readable - a tracking number split
   across lines is worse than one that is clipped - get an ellipsis and a tooltip
   instead of breaking the layout. */
.truncate {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

/* Money and counts line up column-to-column. This is the change that actually matters
   in an invoicing app: with proportional digits, 1,234.56 and 987.00 do not align, and
   a column of figures is harder to scan than it should be. */
table, .kv dd, .num, .mono, input[type="number"], input[type="date"] {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

h1, h2, h3, h4 { font-weight: 600; letter-spacing: -0.01em; }
h1 { font-size: 1.55rem; }
h2 { font-size: 1.2rem; }

a { color: var(--brand-accent); }
a:hover { color: var(--brand); }

/* ----- shell ------------------------------------------------------------- */

.app {
    display: flex;
    min-height: 100vh;
}

.app-sidebar {
    width: var(--sidebar-width);
    flex: 0 0 var(--sidebar-width);
    background: var(--brand);
    color: #dce4ee;
    display: flex;
    flex-direction: column;

    /* Stays put while the content scrolls. align-self is required: without it the
       flex item stretches to the full container height and has no room to stick in. */
    align-self: flex-start;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* Only visible if the navigation itself outgrows the viewport. */
.app-sidebar::-webkit-scrollbar { width: 8px; }
.app-sidebar::-webkit-scrollbar-track { background: transparent; }
.app-sidebar::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.16);
    border-radius: 4px;
}
.app-sidebar::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.26); }
.app-sidebar { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.2) transparent; }

.app-brand {
    padding: 1.15rem 1.25rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.app-brand a {
    display: flex;
    align-items: center;
    gap: 0.7rem;
}

.app-brand .brand-mark {
    width: 34px;
    height: 34px;
    flex: 0 0 34px;
    filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.3));
}

/* min-width:0 lets the text truncate instead of pushing the mark out of the bar. */
.app-brand .brand-text { min-width: 0; }

.app-brand .name {
    font-size: 1.05rem;
    font-weight: 600;
    color: #fff;
    line-height: 1.2;
    display: block;
}

.app-brand .sub {
    font-size: 0.75rem;
    color: #9fb3cd;
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-nav { padding: 0.75rem 0; flex: 1 1 auto; }

.app-nav .nav-link {
    color: #c6d3e4;
    padding: 0.55rem 1.25rem;
    border-left: 3px solid transparent;
    font-size: 0.94rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.app-nav .nav-link:hover {
    background: rgba(255, 255, 255, 0.06);
    color: #fff;
}

.app-nav .nav-link.active {
    background: rgba(255, 255, 255, 0.10);
    border-left-color: var(--brand-accent);
    color: #fff;
    font-weight: 600;
}

.app-nav .nav-section {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #7f95b3;
    padding: 1rem 1.25rem 0.35rem;
}

.app-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* Header block - warning bar plus top bar - stays visible while content scrolls,
   so the environment indicator and sign-out are always reachable. */
.app-header {
    position: sticky;
    top: 0;
    z-index: 20;
    box-shadow: 0 1px 3px rgba(20, 40, 70, 0.06);
}

.app-topbar {
    background: #fff;
    border-bottom: 1px solid var(--border);
    padding: 0.55rem 1.5rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.app-content { padding: 1.5rem; flex: 1 1 auto; }

/* The active page caption lives in the header bar rather than on the page, so the
   content area starts with the content itself. */
.page-caption { min-width: 0; }

/* FocusOnNavigate moves focus to the page heading after each render so screen readers
   announce the new page. The heading now lives in the header bar, so that focus was
   drawing a visible rectangle around the caption on every form post.

   FocusOnNavigate gives the heading tabindex="-1", which makes it focusable by script
   but NOT reachable by tabbing. There is therefore no keyboard-focus case to preserve,
   and both :focus and :focus-visible are suppressed - browsers do match :focus-visible
   on programmatic focus, so leaving that rule in place simply drew a different
   rectangle instead of removing it. */
.page-caption h1:focus,
.page-caption h1:focus-visible { outline: none; box-shadow: none; }

.page-caption h1 {
    font-size: 1.15rem;
    font-weight: 650;
    letter-spacing: -0.01em;
    margin: 0;
    color: #16293f;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.page-caption p {
    margin: 0.1rem 0 0;
    font-size: 0.8rem;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The subtitle is the first thing to go when the bar gets tight. */
@media (max-width: 1100px) {
    .page-caption p { display: none; }
}

/* ----- environment banner ------------------------------------------------ */

/* The single most important piece of chrome here: this application can spend
   real money, so which environment it points at must never be ambiguous. */
.env-pill {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 0.25rem 0.6rem;
    border-radius: 999px;
}

.env-sandbox    { background: #e7f3ff; color: #14507f; border: 1px solid #b9d9f5; }
.env-production { background: #fdecea; color: #8c1d13; border: 1px solid #f5c2bd; }

/* Parcel list on a split shipment. */
.parcel-list { display: flex; flex-direction: column; gap: 0.25rem; }
.parcel-list > div { display: flex; align-items: center; gap: 0.5rem; }

/* Sign out. A button element for safety (see MainLayout), styled as the link it reads
   as - the surrounding chip already carries the visual weight. */
.signout-link {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    font-size: 0.8rem;
    color: #6b7684;
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
}

.signout-link:hover  { color: #1f4d74; }
.signout-link:focus-visible { outline: 2px solid #1f4d74; outline-offset: 2px; border-radius: 2px; }

/* Language selector. Deliberately quiet in the header - it is a preference, not an
   action - and given room to breathe on the login page where there is nothing else. */
.lang-selector { display: inline-flex; margin: 0; }

.lang-selector select {
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: 0.2rem 1.4rem 0.2rem 0.5rem;
    border: 1px solid #d5dae1;
    border-radius: 4px;
    background-color: #fff;
    color: #4d5866;
    cursor: pointer;
}

.lang-selector select:hover { border-color: #b6bec9; }

.lang-selector.lang-login {
    justify-content: flex-end;
    width: 100%;
    margin-bottom: 0.75rem;
}

.lang-selector.lang-login select { font-size: 0.82rem; padding-block: 0.3rem; }

/* The health indicator in the top bar. Carries its state in colour AND in a word, so
   it does not depend on a reader distinguishing amber from red at a glance. */
.health-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0.25rem 0.65rem;
    border-radius: 999px;
    text-decoration: none;
    white-space: nowrap;
}

.health-pill:hover { text-decoration: none; filter: brightness(0.97); }

.health-dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: currentColor;
    flex: none;
}

.health-ok   { background: #e8f5ec; color: #1d6b3a; border: 1px solid #b8ddc5; }
.health-warn { background: #fdf3e0; color: #85590d; border: 1px solid #f0d9ac; }
.health-bad  { background: #fdecea; color: #8c1d13; border: 1px solid #f5c2bd; }

/* The list on /problems. */
.problem-list { display: flex; flex-direction: column; gap: 0.75rem; }

/* A problem spread over several marketplaces gets one button each, stacked. */
.problem-action {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.4rem;
}

.problem-action form { margin: 0; }

.problem {
    display: grid;
    grid-template-columns: 4.5rem minmax(0, 1fr) auto;
    gap: 1rem;
    align-items: center;
    padding: 1rem 1.25rem;
    background: #fff;
    border: 1px solid #e3e7ec;
    border-left-width: 4px;
    border-radius: 6px;
}

.problem-bad  { border-left-color: #c0392b; }
.problem-warn { border-left-color: #c98a12; }

.problem-count {
    font-size: 1.6rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: right;
    line-height: 1;
}

.problem-bad .problem-count  { color: #8c1d13; }
.problem-warn .problem-count { color: #85590d; }

.problem-body { min-width: 0; }
.problem-body h2 { font-size: 1rem; margin: 0 0 0.15rem; }
.problem-body p  { margin: 0; font-size: 0.88rem; color: #5b6673; overflow-wrap: anywhere; }

@media (max-width: 720px) {
    .problem { grid-template-columns: 3.25rem minmax(0, 1fr); }
    .problem-action { grid-column: 2; align-items: flex-start; }
    .problem-count { font-size: 1.3rem; }
}

.env-warning-bar {
    background: #8c1d13;
    color: #fff;
    font-size: 0.85rem;
    padding: 0.45rem 1.5rem;
    text-align: center;
}

/* ----- stat tiles -------------------------------------------------------- */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
    gap: 0.85rem;
}

.stat-tile {
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 0.5rem;
    padding: 0.9rem 1rem;
    text-decoration: none;
    color: inherit;
    display: block;
    border-left: 4px solid var(--border);
    transition: box-shadow 0.12s ease, transform 0.12s ease;
}

.stat-tile:hover {
    box-shadow: 0 2px 10px rgba(20, 40, 70, 0.09);
    transform: translateY(-1px);
    color: inherit;
}

.stat-tile.is-active { border-color: var(--brand-accent); }

.stat-tile .value { font-size: 1.6rem; font-weight: 650; line-height: 1.1; }
.stat-tile .label { font-size: 0.78rem; color: var(--text-muted); margin-top: 0.15rem; }

.stat-tile.tone-attention { border-left-color: #d9880a; }
.stat-tile.tone-danger    { border-left-color: #c0392b; }
.stat-tile.tone-ready     { border-left-color: var(--brand-accent); }
.stat-tile.tone-done      { border-left-color: #2e8b57; }
.stat-tile.tone-muted     { border-left-color: #b6bdc7; }

/* ----- cards and tables -------------------------------------------------- */

.panel {
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 0.5rem;
    margin-bottom: 1.25rem;
}

.panel-header {
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.panel-header h2 { margin: 0; font-size: 1rem; }
.panel-body { padding: 1rem; }
.panel-body.flush { padding: 0; }

.table > :not(caption) > * > * { padding: 0.55rem 0.75rem; }
.table thead th {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    font-weight: 600;
    border-bottom-width: 1px;
    white-space: nowrap;
}

.table td { font-size: 0.88rem; vertical-align: middle; }
.mono { font-family: var(--font-mono); font-size: 0.82rem; }

/* The smaller monospace font would make a text field shorter than the fields beside it -
   a height set by its own font size. Once a row's inputs share a bottom line, that
   shows as a field whose top edge sits lower than its neighbours'. These are Bootstrap's
   own heights for each field size, measured in rem so the smaller font cannot shrink them. */
.form-control.mono    { min-height: calc(2.25rem + 2px); }
.form-control-sm.mono { min-height: calc(1.8125rem + 2px); }

/* ----- state badges ------------------------------------------------------ */

.state {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 600;
    padding: 0.2rem 0.55rem;
    border-radius: 0.25rem;
    white-space: nowrap;
    border: 1px solid transparent;
}

.state-review   { background: #fff4e0; color: #8a5a00; border-color: #f2d9a8; }
.state-ready    { background: #e8f1fc; color: #14507f; border-color: #bcd6f2; }
.state-sent     { background: #eef1f5; color: #3c4a5a; border-color: #d3dae3; }
.state-paid     { background: #e9f6ee; color: #1d6b3f; border-color: #bfe3cd; }
.state-shipped  { background: #e3f4ea; color: #14663a; border-color: #b3ddc4; }
.state-done     { background: #2e8b57; color: #fff; border-color: #2e8b57; }
.state-error    { background: #fdecea; color: #8c1d13; border-color: #f5c2bd; }
.state-inactive { background: #f2f4f7; color: #6b7683; border-color: #dfe3e8; }

/* ----- misc -------------------------------------------------------------- */

.empty-state {
    padding: 2.5rem 1rem;
    text-align: center;
    color: var(--text-muted);
}

.field-issue {
    border-left: 3px solid #d9880a;
    background: #fffaf0;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.5rem;
    border-radius: 0.25rem;
}

.field-issue.blocking { border-left-color: #c0392b; background: #fdf3f2; }
.field-issue .field { font-weight: 600; font-size: 0.82rem; }
.field-issue .detail { font-size: 0.85rem; color: #4a5563; }

/* minmax(0, 1fr) rather than 1fr: a plain 1fr track refuses to shrink below its
   content, so one long unbroken string pushes the whole grid past its panel instead of
   wrapping. Marketplace relay e-mail addresses do exactly that - they are 40-odd
   characters with no space or hyphen to break at. */
.kv { display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: 0.35rem 1rem; font-size: 0.9rem; }
.kv dt { color: var(--text-muted); font-weight: 500; overflow-wrap: break-word; }
.kv dd {
    margin: 0;
    min-width: 0;
    /* `anywhere` rather than `break-word`: break-word will not split a single token that
       has no break opportunity at all, which is precisely the case here. */
    overflow-wrap: anywhere;
}

@media (max-width: 900px) {
    .app { flex-direction: column; }
    .app-sidebar {
        width: 100%;
        flex-basis: auto;
        position: static;
        height: auto;
        align-self: auto;
        overflow-y: visible;
    }
    /* On a phone a pinned header costs too much of a short screen. */
    .app-header { position: static; }
    .kv { grid-template-columns: 1fr; }
}

/* ----- marketplace selector --------------------------------------------- */

.marketplace-selector { margin: 0; }

.marketplace-selector select {
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--brand-accent);
    padding: 0.28rem 1.7rem 0.28rem 0.6rem;
    border: 1px solid var(--border);
    border-radius: 0.35rem;
    background-color: #fff;
    background-image:
        linear-gradient(45deg, transparent 50%, #6b7683 50%),
        linear-gradient(135deg, #6b7683 50%, transparent 50%);
    background-position: right 0.72rem center, right 0.45rem center;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
    appearance: none;
    cursor: pointer;
}

.marketplace-selector option { color: var(--brand-accent); }

.marketplace-selector select:hover { border-color: #b9c4d1; }

.marketplace-selector select:focus {
    outline: none;
    border-color: var(--brand-accent);
    box-shadow: 0 0 0 3px rgba(47, 127, 209, 0.16);
}

.marketplace-single {
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--brand-accent);
}

.marketplace-none { font-size: 0.82rem; color: #8c1d13; }

.topbar-divider {
    width: 1px;
    height: 1.35rem;
    background: var(--border);
}

/* ----- sync progress ----------------------------------------------------- */

.sync-panel {
    background: #fff;
    border: 1px solid var(--border);
    border-left: 4px solid var(--brand-accent);
    border-radius: 0.5rem;
    padding: 0.9rem 1rem;
    margin-bottom: 1.25rem;
}

.sync-panel-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    margin-bottom: 0.55rem;
}

.sync-panel-head .label { font-size: 0.9rem; font-weight: 600; color: #16293f; }
.sync-panel-head .detail { font-size: 0.78rem; color: var(--text-muted); white-space: nowrap; }

.sync-progress {
    height: 1.15rem;
    background: #eef1f5;
    border-radius: 0.35rem;
    overflow: hidden;
}

.sync-progress-bar {
    height: 100%;
    width: 0;
    background: linear-gradient(180deg, #2f7fd1 0%, #2569b0 100%);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 600;
    line-height: 1.15rem;
    text-align: center;
    transition: width 0.25s ease;
}

/* No total yet, so show motion rather than a percentage we would be inventing. */
.sync-progress-bar.is-indeterminate {
    background: repeating-linear-gradient(
        45deg, #2f7fd1 0 12px, #2569b0 12px 24px);
    background-size: 34px 34px;
    animation: sync-stripes 0.9s linear infinite;
}

@keyframes sync-stripes {
    from { background-position: 0 0; }
    to   { background-position: 34px 0; }
}

@media (prefers-reduced-motion: reduce) {
    .sync-progress-bar.is-indeterminate { animation: none; }
    .sync-progress-bar { transition: none; }
}

/* ----- pagination -------------------------------------------------------- */

.pager {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 0.7rem 1rem;
    border-top: 1px solid var(--border);
    font-size: 0.85rem;
}

/* At the top of a table the divider belongs on the other edge. */
.pager.is-top {
    border-top: none;
    border-bottom: 1px solid var(--border);
}

.pager-summary { color: var(--text-muted); }

.pager-links { display: flex; align-items: center; gap: 0.25rem; }

.pager-links a,
.pager-links span {
    display: inline-block;
    min-width: 2rem;
    padding: 0.25rem 0.5rem;
    text-align: center;
    border-radius: 0.3rem;
    text-decoration: none;
}

.pager-links a {
    color: var(--brand-accent);
    border: 1px solid var(--border);
    background: #fff;
}

.pager-links a:hover { border-color: var(--brand-accent); background: #f2f7fd; }

.pager-links .current {
    background: var(--brand-accent);
    border: 1px solid var(--brand-accent);
    color: #fff;
    font-weight: 600;
}

.pager-links .disabled { color: #b6bdc7; border: 1px solid transparent; }
.pager-links .gap { min-width: 1rem; color: var(--text-muted); border: none; }

.pager-controls { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }

.pager-size { display: flex; align-items: center; gap: 0.4rem; margin: 0; }
.pager-size label { color: var(--text-muted); font-size: 0.82rem; }

.pager-size select {
    font-size: 0.82rem;
    padding: 0.2rem 1.5rem 0.2rem 0.5rem;
    color: var(--brand-accent);
    background-color: #fff;
    border: 1px solid var(--border);
    border-radius: 0.3rem;
    background-image:
        linear-gradient(45deg, transparent 50%, #6b7683 50%),
        linear-gradient(135deg, #6b7683 50%, transparent 50%);
    background-position: right 0.62rem center, right 0.38rem center;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
    appearance: none;
    cursor: pointer;
}

.pager-size select:hover { border-color: #b9c4d1; }
.pager-size select:focus {
    outline: none;
    border-color: var(--brand-accent);
    box-shadow: 0 0 0 3px rgba(47, 127, 209, 0.16);
}

/* ----- record navigation ------------------------------------------------- */

.record-nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 0.85rem;
}

.record-nav-back { font-size: 0.9rem; }

.record-nav-controls { display: flex; align-items: center; gap: 0.4rem; }

.record-nav-position {
    font-size: 0.8rem;
    color: var(--text-muted);
    margin-right: 0.3rem;
}

.record-nav-controls a,
.record-nav-controls span.disabled {
    font-size: 0.85rem;
    min-width: 2rem;
    text-align: center;
    padding: 0.28rem 0.7rem;
    border-radius: 0.3rem;
    text-decoration: none;
    border: 1px solid var(--border);
    background: #fff;
}

.record-nav-controls a { color: var(--brand-accent); }
.record-nav-controls a:hover { border-color: var(--brand-accent); background: #f2f7fd; }
.record-nav-controls span.disabled { color: #b6bdc7; border-color: transparent; background: transparent; }

/* Purchase-invoice export form: a short row of controls, wrapping on narrow screens. */
.pi-form {
    display: flex;
    align-items: flex-end;
    gap: 1rem;
    flex-wrap: wrap;
}

.pi-field { display: flex; flex-direction: column; gap: 0.25rem; }

.pi-field label { font-size: 0.82rem; color: var(--text-muted); }

.pi-field input[type="date"] {
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--border);
    border-radius: 0.3rem;
    background: #fff;
    font: inherit;
}

.pi-field-check {
    flex-direction: row;
    align-items: center;
    gap: 0.4rem;
    padding-bottom: 0.4rem;
}

.pi-field-check label { font-size: 0.9rem; color: inherit; }

/* Correction panel: a compact two-column grid of short text fields. */
.fix-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.6rem 1rem;
}

.fix-grid label {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    font-size: 0.8rem;
    color: var(--text-muted);
}

/* Same rule as the column rows: the two fields in a grid row keep their inputs level
   even when one label wraps. Grid cells in a row already share a height; this puts each
   input at the bottom of its cell instead of straight under its label. */
.fix-grid label > input {
    margin-top: auto;
}

.fix-grid input {
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--border);
    border-radius: 0.3rem;
    font: inherit;
    font-size: 0.9rem;
    color: var(--text);
    background: #fff;
}

.fix-grid input::placeholder { color: #aab2bd; }

.fix-grid .fix-wide { grid-column: 1 / -1; }

@media (max-width: 640px) {
    .fix-grid { grid-template-columns: 1fr; }
}

/* One row per DropXL account: country, credentials, save. */
.account-row {
    display: grid;
    grid-template-columns: 8rem minmax(0, 1.2fr) minmax(0, 1.2fr) minmax(0, 1fr) auto;
    gap: 0.5rem;
    align-items: center;
}

.account-label { font-size: 0.85rem; line-height: 1.2; }

@media (max-width: 900px) {
    .account-row { grid-template-columns: 1fr; }
}

/* Marketplace note sits under the name in the same row. Capped so a long note cannot
   stretch the first column and squeeze the status badges. */
.marketplace-note { max-width: 22rem; line-height: 1.3; }

/* Carriers screen. Each carrier is one bordered card holding three parts that must read
   as one thing: the fields, the finished link they produce, and the remove button. The
   link sits between them on purpose - it is the point of the screen, and burying it under
   the button would make it look like a footnote. */
.carrier-card {
    border: 1px solid var(--border);
    border-radius: 0.5rem;
    padding: 1rem;
    margin-bottom: 1rem;
    position: relative;
}

.carrier-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.75rem;
}

/* The finished link can be long and has no spaces to break at, so it is allowed to wrap
   mid-word rather than widen the card and push the page into a horizontal scroll. */
.carrier-preview {
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px dashed var(--border);
    font-family: var(--font-mono);
    font-size: 0.8rem;
    overflow-wrap: anywhere;
}

