

:root {
    --bg: #f2f2f259;
    --surface: #ffffff;
    --surface-2: #f3f6fb;
    --border: #d7e1ee;
    --text: #2f4058;
    --text-muted: #70839a;
    --accent: #200f0ae6;
    --accent-strong: #200f0ae6;
    --accent-soft: #f7f4f0;
    --topbar-bg: #ffffff;
    --topbar-border: #d7e1ee;
    --topbar-text: #344861;
    --topbar-muted: #6f8299;
    --topbar-search-bg: var(--bg);
    --topbar-search-border: #d8e2ef;
    --topbar-search-focus: #ffffff;
    --error-bg: #fdecea;
    --error-border: #f5c2c0;
    --error-text: #8e2f2b;
    --info-bg: #eaf3fb;
    --info-border: #bcdcf5;
    --info-text: #1c5480;
    --ok-bg: #e7f4ec;
    --ok-border: #bfe0cb;
    --ok-text: #1d6b3d;
    --warn-bg: #fdf1e0;
    --warn-text: #8a5a12;
    --shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 8px 24px rgba(16, 24, 40, .08);
    --sidebar-bg: #ffffff;
    --sidebar-border: #d7e1ee;
    --sidebar-hover: var(--bg);
    --sidebar-active-bg: var(--bg);
    --sidebar-active-border: #dbe5f2;
    --sidebar-active-text: #223550;
    --sidebar-active-shadow: 0 10px 24px rgba(148, 163, 184, .18);
    --button-bg: #111111;
    --button-hover: #000000;
    --button-border: #111111;
    --button-text: #ffffff;
    --button-disabled: #6b7280;
    --radius: 10px;
    --topbar-h: 56px;
    /* Wide enough for the longest page name, "Search Order-wise Settlements",
       on one line in bold with a few pixels to spare for browser zoom. */
    --sidebar-w: 280px;
    --sidebar-rail: 68px;
    --app-footer-h: 49px;

    /* The grid toolbar's height, as a number the stylesheet can hold space for
       before app.js has built the thing: 14px of padding top and bottom, a 40px
       row of controls between them, and the rule underneath.

       It is a token rather than a measurement because the reservation has to be
       made before there is anything to measure. `.data-grid-toolbar` pins itself
       to it, so the two cannot drift. */
    --grid-toolbar-h: 69px;

    /* The width below which a grid scrolls sideways inside its shell rather than
       squeezing its columns. Per-page overrides sit with those pages. */
    --grid-table-min-w: 760px;

    /* What the finished shell sits below the content above it. */
    --grid-shell-mt: 0px;
}

/* Denser rows mean a denser toolbar; both are set from one place so the space
   reserved for it before app.js runs still matches what turns up. */
:root[data-grid-density="compact"] {
    --grid-toolbar-h: 61px;
}

:root[data-grid-density="comfortable"] {
    --grid-toolbar-h: 73px;
}

[data-theme="dark"] {
    --bg: #12161d;
    --surface: #1a1f28;
    --surface-2: #212734;
    --border: #2b3240;
    --text: #e6e9ee;
    --text-muted: #98a2b3;
    --accent: #6ea2ff;
    --accent-strong: #d5e4ff;
    --accent-soft: #1f2d45;
    --error-bg: #3a2222;
    --error-border: #5c3230;
    --error-text: #f3b0ad;
    --info-bg: #1b2a38;
    --info-border: #2c4459;
    --info-text: #9dcdf0;
    --ok-bg: #1c2f24;
    --ok-border: #2f5540;
    --ok-text: #8fd3ab;
    --warn-bg: #33291a;
    --warn-text: #e2b872;
    --topbar-bg: #172231;
    --topbar-border: #101925;
    --topbar-text: #f1f5fb;
    --topbar-muted: rgba(241, 245, 251, .72);
    --topbar-search-bg: rgba(255, 255, 255, .07);
    --topbar-search-border: rgba(255, 255, 255, .05);
    --topbar-search-focus: rgba(255, 255, 255, .11);
    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 24px rgba(0, 0, 0, .45);
    --sidebar-bg: #161d28;
    --sidebar-border: #293241;
    --sidebar-hover: #202a39;
    --sidebar-active-bg: #1b2535;
    --sidebar-active-border: #32455e;
    --sidebar-active-text: #f1f5fb;
    --sidebar-active-shadow: 0 12px 28px rgba(0, 0, 0, .35);
    --button-bg: #111111;
    --button-hover: #000000;
    --button-border: #111111;
    --button-text: #ffffff;
    --button-disabled: #64748b;
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--bg);
    color: var(--text);
    font-family: "Segoe UI", Roboto, system-ui, -apple-system, sans-serif;
    font-size: 15px;
    line-height: 1.5;
}

[hidden] {
    display: none !important;
}

.icon {
    width: 20px;
    height: 20px;
    flex: 0 0 auto;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.topbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 30;
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 0 16px;
    background: var(--topbar-bg);
    border-bottom: 1px solid var(--topbar-border);
    backdrop-filter: blur(14px);
}

.topbar-left,
.topbar-right {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    padding: 0;
    border: 0;
    border-radius: 9px;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
}

.icon-btn:hover {
    background: var(--surface-2);
    color: var(--text);
}

.topbar .icon-btn {
    border-radius: 10px;
    color: var(--topbar-muted);
}

.topbar .icon-btn:hover {
    background: var(--bg);
    color: var(--text);
}

.brand {
    display: flex;
    align-items: center;
    gap: 9px;
    text-decoration: none;
    color: var(--topbar-text);
    font-weight: 700;
}

.brand-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1px solid rgba(54, 109, 240, .16);
    background: linear-gradient(135deg, rgba(54, 109, 240, .18), rgba(54, 109, 240, .08));
    color: var(--accent-strong);
    font-size: 11px;
    letter-spacing: .5px;
}

.brand-name {
    letter-spacing: .01em;
    max-width: min(24vw, 260px);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.search {
    position: relative;
    display: flex;
    align-items: center;
    margin-left: 10px;
}

.search .icon {
    position: absolute;
    left: 12px;
    color: var(--topbar-muted);
    width: 18px;
    height: 18px;
}

.search input {
    width: 340px;
    max-width: 34vw;
    padding: 9px 14px 9px 38px;
    border: 1px solid var(--topbar-search-border);    
    background: var(--topbar-search-bg);
    color: var(--topbar-text);
    font: inherit;
    font-size: 14px;
}

.search input::placeholder {
    color: var(--topbar-muted);
}

.search input:focus {
    outline: none;
    border-color: var(--accent);
    background: var(--topbar-search-focus);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.theme-icon-light {
    display: none;
}

[data-theme="dark"] .theme-icon-dark {
    display: none;
}

[data-theme="dark"] .theme-icon-light {
    display: inline-flex;
}

.user-menu {
    position: relative;
}

.user-trigger {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 5px 8px 5px 5px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--topbar-text);
    font: inherit;
    cursor: pointer;
}

.user-trigger:hover,
.user-trigger.open {
    background: var(--bg);
}

.user-trigger .chevron {
    width: 16px;
    height: 16px;
    color: var(--topbar-muted);
    transform: rotate(90deg);
    transition: transform .15s ease;
}

.user-trigger.open .chevron {
    transform: rotate(-90deg);
}

.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--button-bg);
    color: var(--button-text);
    font-size: 13px;
    font-weight: 700;
}

.avatar-lg {
    width: 44px;
    height: 44px;
    font-size: 15px;
}

.user-text {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    line-height: 1.2;
}

.user-name {
    font-size: 14px;
    font-weight: 600;
}

.user-role {
    font-size: 12px;
    color: var(--topbar-muted);
}

.dropdown {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    min-width: 250px;
    padding: 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    z-index: 40;
}

.dropdown-head {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 8px 10px 12px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 6px;
}

.dropdown-name {
    margin: 0;
    font-weight: 600;
    font-size: 14px;
}

.dropdown-meta {
    margin: 0;
    font-size: 12px;
    color: var(--text-muted);
}

/* The account menu takes the width of the email address under the name, up to a
   point: positioned inside the narrow trigger, it otherwise stayed at its minimum
   and broke an ordinary address in the middle. Past that point it wraps. */
.user-menu .dropdown {
    width: max-content;
    max-width: min(360px, calc(100vw - 32px));
}

/* Name, email and vendor code. */
.dropdown-who {
    display: grid;
    gap: 2px;
    min-width: 0;
}

.dropdown-who .dropdown-meta {
    overflow-wrap: anywhere;
}

.dropdown-code {
    color: var(--text);
    font-weight: 600;
    letter-spacing: .04em;
}

.dropdown-item {
    display: flex;
    align-items: center;
    gap: 11px;
    width: 100%;
    padding: 9px 10px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 14px;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.dropdown-item:hover {
    background: var(--surface-2);
    color: var(--accent-strong);
}

.dropdown-item .icon {
    width: 18px;
    height: 18px;
    color: var(--text-muted);
}

.dropdown-danger:hover {
    background: var(--error-bg);
    color: var(--error-text);
}

.dropdown-sep {
    height: 1px;
    margin: 6px 0;
    background: var(--border);
}

.dropdown form {
    margin: 0;
}


.app-body {
    flex: 1 0 auto;
    display: flex;
    align-items: stretch;
    padding-top: var(--topbar-h);
    padding-bottom: var(--app-footer-h);
    min-height: 0;
}

.sidebar {
    position: fixed;
    top: var(--topbar-h);
    bottom: 0;
    left: 0;
    z-index: 20;
    width: var(--sidebar-w);
    padding: 14px 10px;
    overflow-y: auto;
    background: var(--sidebar-bg);
    border-right: 1px solid var(--sidebar-border);
    box-shadow: none;
    transition: width .18s ease, transform .18s ease;
}

.app-body .page {
    flex: 1 1 auto;
    min-width: 0;
    width: calc(100% - var(--sidebar-w));
    max-width: none;
    margin-left: var(--sidebar-w);
    padding: 0px;
    overflow-x: hidden;
    transition: margin-left .18s ease;
}

.sidebar-collapsed .sidebar {
    width: var(--sidebar-rail);
}

.sidebar-collapsed .app-body .page {
    width: calc(100% - var(--sidebar-rail));
    margin-left: var(--sidebar-rail);
}

.app-shell-end {
    flex: 0 0 auto;
}

.app-footer {
    position: fixed;
    left: var(--sidebar-w);
    bottom: 0;
    z-index: 25;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: var(--app-footer-h);
    width: calc(100% - var(--sidebar-w));
    padding: 12px 18px;
    border-top: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-muted);
    text-align: center;
    transition: left .18s ease, width .18s ease;
}

.sidebar-collapsed .app-footer {
    left: var(--sidebar-rail);
    width: calc(100% - var(--sidebar-rail));
}

.app-footer-copy {
    margin: 0;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
}

/*
  Moving between screens. Each screen is a page of its own, so a click loads a
  new one, and the whole window used to be drawn afresh each time. The browser
  now makes it a transition instead (Chrome and Edge; others load as before):
  the top bar, the sidebar and the footer, the same on both pages, stay exactly
  where they are, and only the screen's content changes, in a quick fade.
*/
@view-transition {
    navigation: auto;
}

.topbar {
    view-transition-name: app-topbar;
}

.sidebar {
    view-transition-name: app-sidebar;
}

.app-footer {
    view-transition-name: app-footer;
}

/* The frame does not animate: the new page's, at once, with no cross-fade. */
::view-transition-group(app-topbar),
::view-transition-group(app-sidebar),
::view-transition-group(app-footer),
::view-transition-new(app-topbar),
::view-transition-new(app-sidebar),
::view-transition-new(app-footer) {
    animation: none;
}

::view-transition-old(app-topbar),
::view-transition-old(app-sidebar),
::view-transition-old(app-footer) {
    display: none;
}

::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: .12s;
}

@media (prefers-reduced-motion: reduce) {
    @view-transition {
        navigation: none;
    }
}

/*
  Moving between screens without a reload (app.js). The next screen is usually
  fetched before the click, from the pointer resting on the link; when it is
  still on its way after a moment, a thin bar runs under the top bar so the
  click visibly took.
*/
html.is-navigating {
    cursor: progress;
}

html.is-navigating body::before {
    content: "";
    position: fixed;
    top: var(--topbar-h);
    left: 0;
    z-index: 60;
    width: 40%;
    height: 2px;
    background: var(--accent-strong);
    pointer-events: none;
    animation: nav-progress 1.1s ease-in-out infinite;
}

@keyframes nav-progress {
    from {
        transform: translateX(-100%);
    }

    to {
        transform: translateX(250%);
    }
}

@media (prefers-reduced-motion: reduce) {
    html.is-navigating body::before {
        width: 100%;
        opacity: .5;
        animation: none;
    }
}

/* Focused after a screen is swapped in, for a screen reader to start there; no ring for that. */
main.page:focus {
    outline: none;
}

.sidebar-collapsed .menu-group-name,
.sidebar-collapsed .menu-item-name {
    display: none;
}

.sidebar-collapsed .menu-group-toggle .icon {
    display: block;
}

.sidebar-collapsed .menu-group-toggle,
.sidebar-collapsed .menu-item-top {
    justify-content: center;
    padding: 11px 0;
}

.sidebar-collapsed .menu-item-top .menu-item-name {
    display: none;
}

.sidebar-collapsed .sidebar {
    overflow: visible;
}

.sidebar-collapsed .menu-group .menu-items {
    display: none;
}

.sidebar-collapsed .menu-group.flyout-open .menu-items {
    display: block;
    position: absolute;
    top: 0;
    left: calc(100% + 6px);
    z-index: 25;
    /* As wide as its longest page name, so every page takes one line. Positioned
       inside the narrow rail, it would otherwise shrink to its minimum and wrap
       "Search Order-wise Settlements" onto two. No cap: the flyout only opens on
       a window wider than app.js's 900px mobile breakpoint, which it always fits. */
    width: max-content;
    min-width: 216px;
    padding: 8px;
    background: var(--surface);
    border: 1px solid var(--sidebar-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.sidebar-collapsed .menu-group.flyout-open .menu-items::before {
    content: '';
    position: absolute;
    top: -6px;
    left: -10px;
    width: 10px;
    height: calc(100% + 12px);
}

.sidebar-collapsed .menu-group.flyout-open .menu-items::after {
    content: '';
    position: absolute;
    top: 16px;
    left: -6px;
    width: 10px;
    height: 10px;
    background: var(--surface);
    border-left: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    transform: rotate(45deg);
}

.sidebar-collapsed .menu-group.flyout-open .menu-group-toggle {
    background: var(--sidebar-hover);
    color: var(--text);
}

.sidebar-collapsed .menu-group.flyout-open .flyout-title {
    display: block;
    padding: 4px 14px 8px;
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 700;
}

/* Unclipped: the flyout is exactly as wide as its longest name, so clipping
   could turn a fraction of a pixel of zoom rounding into a "…". */
.sidebar-collapsed .menu-group.flyout-open .menu-item-name {
    display: inline;
    overflow: visible;
}

.menu-group {
    position: relative;
}

.menu-group + .menu-group {
    margin-top: 6px;
    padding-top: 6px;    
}

.menu-group-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 7px 10px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--text-muted);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background .16s ease, color .16s ease;
}

.menu-group-toggle:hover {
    background: var(--sidebar-hover);
    color: var(--text);
}

.menu-group-name {
    margin-right: auto;
}

.menu-group-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
}

.menu-group-icon .icon {
    width: 18px;
    height: 18px;
}

.menu-items {
    display: none;
    padding: 2px 0 4px;
}

.menu-group.open .menu-items {
    display: block;
}

.sidebar-collapsed .menu-group.open .menu-items {
    display: none;
}

.sidebar-collapsed .menu-group.flyout-open .menu-items {
    display: block;
}

.menu-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 14px 8px 16px;
    border: 1px solid transparent;
    border-radius: 999px;
    color: var(--text);
    text-decoration: none;
    font-size: 14px;
    transition: background .16s ease, border-color .16s ease, box-shadow .16s ease, color .16s ease;
}

.menu-item:hover {
    background: var(--sidebar-hover);
}

/* One line per page, sidebar and flyout alike. The sidebar is sized to the
   longest name and the flyout to its own, but at a browser zoom such as 125%
   the bold name of the open page can draw a fraction of a pixel wider than it
   was measured, and would break onto a second line. A longer name added later
   ends in "…" rather than wrapping. */
.menu-item-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/*
  The two kinds of top-level sidebar row: a standalone page such as Home, which
  is a link, and a group header such as Orders, which is a button that expands. They
  are different elements for good reason and they are meant to look different --
  a header is smaller and muted, a page is full size -- but they must agree on
  exactly where the icon and the label sit, or the column reads as ragged.

  Three things had them disagreeing. The link carried a transparent 1px border
  and the button carried none, putting their icons a pixel apart; the link
  inherited the 12px gap meant for indented child items while the button used
  8px, putting their labels 4px apart; and their vertical padding differed by a
  pixel, making the rows different heights.
*/
.menu-group-toggle,
.menu-item-top {
    gap: 8px;
    padding: 7px 10px;
    border: 1px solid transparent;
}

.menu-item .icon {
    width: 18px;
    height: 18px;
    color: var(--text-muted);
}

/*
  Pages inside a group carry no icon of their own, so their labels are indented
  to start where the group header's label starts: 1px border + 10px padding +
  18px icon + 8px gap = 37px. Section headings take the same indent.
*/
.menu-items .menu-item {
    padding-left: 36px;
}

.menu-items .menu-section {
    padding-left: 31px;
}

/* In the flyout there is no header icon to line up with; align to its title. */
.sidebar-collapsed .menu-group.flyout-open .menu-items .menu-item {
    padding-left: 13px;
}

.sidebar-collapsed .menu-group.flyout-open .menu-items .menu-section {
    padding-left: 10px;
}

.menu-item.active {
    background: var(--sidebar-active-bg);
    border-color: var(--sidebar-active-border);
    box-shadow: var(--sidebar-active-shadow);
    color: var(--sidebar-active-text);
    font-weight: 700;
}

.menu-item.active .icon {
    color: var(--accent);
}

.flyout-title {
    display: none;
}

/* A heading inside a group, ruled off from the pages above it. */
.menu-section {
    display: block;
    margin: 8px 6px 4px;
    padding: 10px 10px 4px;
    border-top: 1px solid var(--sidebar-border);
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    line-height: 1.4;    
}

/* The flyout grows to fit its rows; the expanded sidebar is a fixed width, so
   there the heading wraps rather than running under the edge. */
.sidebar-collapsed .menu-group.flyout-open .menu-section {
    white-space: nowrap;
}

.menu-empty {
    padding: 12px;
    color: var(--text-muted);
    font-size: 13px;
}

/* The rail is an icon wide: the sentence only spilled across the page beside it. */
.sidebar-collapsed .menu-empty {
    display: none;
}

.filtered-out {
    display: none !important;
}

.sidebar-scrim {
    position: fixed;
    inset: var(--topbar-h) 0 0 0;
    z-index: 19;
    background: rgba(9, 13, 20, .45);
}


@media (max-width: 900px) {
    .sidebar {
        transform: translateX(-100%);
        box-shadow: var(--shadow);
    }

    .sidebar-open .sidebar {
        transform: translateX(0);
    }

    .app-body .page,
    .sidebar-collapsed .app-body .page {
        width: 100%;
        margin-left: 0;
        padding: 18px 16px;
    }

    .app-footer,
    .sidebar-collapsed .app-footer {
        left: 0;
        width: 100%;
        padding: 12px 16px;
    }

    .search input {
        width: 180px;
    }

    .user-text {
        display: none;
    }

    .brand-name {
        display: none;
    }


}




/* --- settings pages ---
   Same two-column arrangement as the profile page: the form on the left, the
   things you can only look at on the right. Its own class rather than reusing
   .profile-* so neither can be restyled by accident on behalf of the other. */

.settings-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
    align-items: start;
    gap: 16px;
    padding: 18px;
}

.settings-main,
.settings-aside {
    display: grid;
    gap: 16px;
    min-width: 0;
}

.settings-card {
    padding: 20px;
}

/* One form spanning several cards, so the connection and the wording save
   together. Without the grid the form becomes .settings-main's only child and
   swallows the gap between the cards inside it. */
.settings-form {
    display: grid;
    gap: 16px;
    min-width: 0;
}

.settings-card-head {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 18px;
}

.settings-card-icon {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: var(--accent-soft);
    color: var(--accent);
}

.settings-card-icon .icon {
    width: 18px;
    height: 18px;
}

.settings-card-copy {
    min-width: 0;
}

.settings-card-copy h2 {
    margin: 0;
    font-size: 16px;
    line-height: 1.25;
}

.settings-card-copy p {
    margin: 3px 0 0;
    color: var(--text-muted);
    font-size: 13px;
}

.settings-field-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 14px;
}

.settings-note {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin: 16px 0 0;
    padding: 12px 14px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--text-muted);
    font-size: 13px;
}

.settings-note .icon {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    margin-top: 1px;
}

.settings-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}

.settings-facts {
    display: grid;
    gap: 12px;
    margin: 0 0 16px;
}

.settings-fact dt {
    margin-bottom: 3px;
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

.settings-fact dd {
    margin: 0;
    font-size: 13.5px;
    overflow-wrap: anywhere;
}

.settings-preview + .settings-preview {
    margin-top: 12px;
}

.settings-preview-label {
    display: block;
    margin-bottom: 6px;
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    cursor: default;
}

details.settings-preview .settings-preview-label {
    cursor: pointer;
}

/* Pre-formatted and scrolling: the plain-text part is written to a fixed width
   and rewrapping it here would hide where the real line breaks fall. */
.settings-preview-body {
    margin: 0;
    max-height: 260px;
    padding: 14px;
    overflow: auto;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--text);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12.5px;
    line-height: 1.55;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* --- email preview switch ---
   One preview card, two emails, a segmented control to choose between them.
   Radios and labels rather than a script: the CSP allows no inline script, and
   :checked is all it takes. The radios precede the switch and both panels in the
   markup, because ~ only reaches forward. */
.mail-preview-radio {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.mail-preview-switch {
    display: inline-flex;
    flex-wrap: wrap;
    max-width: 100%;
    margin-bottom: 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface);
    overflow: hidden;
}

.mail-preview-option {
    display: inline-flex;
    align-items: center;
    min-height: 36px;
    padding: 0 16px;
    color: var(--text);
    font-size: 13.5px;
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
}

.mail-preview-option + .mail-preview-option {
    border-left: 1px solid var(--border);
}

.mail-preview-option:hover {
    background: var(--surface-2);
}

#mailPreviewActivation:checked ~ .mail-preview-switch [for="mailPreviewActivation"],
#mailPreviewVerification:checked ~ .mail-preview-switch [for="mailPreviewVerification"] {
    background: var(--accent-soft);
    color: var(--accent-strong);
    font-weight: 600;
}

/* The radio has the focus; its label is what a keyboard user sees, so it wears
   the ring. Arrow keys move between the two, as in any radio group. */
#mailPreviewActivation:focus-visible ~ .mail-preview-switch [for="mailPreviewActivation"],
#mailPreviewVerification:focus-visible ~ .mail-preview-switch [for="mailPreviewVerification"] {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

.mail-preview-verification,
#mailPreviewVerification:checked ~ .mail-preview-activation {
    display: none;
}

#mailPreviewVerification:checked ~ .mail-preview-verification {
    display: block;
}

.mail-preview-intro {
    margin: 0 0 16px;
}

@media (max-width: 1080px) {
    .settings-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 560px) {
    .settings-grid {
        padding: 14px;
        gap: 14px;
    }

    .settings-card {
        padding: 16px;
    }

    .settings-actions {
        justify-content: stretch;
    }

    .settings-actions .btn-primary,
    .settings-actions .btn-ghost {
        flex: 1 1 auto;
        justify-content: center;
    }
}

/* --- activation page ---
   Reuses the sign-in card and the profile page's strength meter, so it needs only
   the two things neither already provides. */

.auth-strength {
    margin: 2px 0 4px;
}

.auth-hint {
    margin: 0 0 4px;
    color: var(--text-muted);
    font-size: 12.5px;
}

/* --- profile page ---
   Identity down the left, the two things a user may change on the right. Two
   cards rather than one long form because they fail independently: a rejected
   password must not look as though it also lost the name you typed.

   The header is the shared one, so nothing about it is repeated here. */

.profile-header-user {
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 600;
}

/* The gutter round the content. `.app-body .page` is padding: 0 for every page
   in the application, so each one insets its own body; the header above is
   full-bleed for every screen. */
.profile-grid {
    display: grid;
    grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
    align-items: start;
    gap: 16px;
    padding: 18px;
}

.profile-aside,
.profile-main {
    display: grid;
    gap: 16px;
    min-width: 0;
}

/* --- identity card --- */

/* The tinted sweep behind the avatar. A gradient on a pseudo-element rather than
   an image: it is two colours and a curve, and an asset would be one more file to
   ship and to keep in step with the palette. */
.profile-hero {
    position: relative;
    overflow: hidden;
    padding: 74px 22px 24px;
    text-align: center;
}

.profile-hero::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 120px;
    background: linear-gradient(155deg,
                var(--accent-soft) 0%,
                var(--accent-soft) 46%,
                transparent 88%);
    border-radius: 0 0 60% 40% / 0 0 24% 20%;
    pointer-events: none;
}

.profile-hero > * {
    position: relative;
}

.profile-hero-edit {
    position: absolute;
    top: 14px;
    right: 14px;
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    padding: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-muted);
    cursor: pointer;
    transition: color .14s ease, border-color .14s ease;
}

.profile-hero-edit:hover {
    color: var(--text);
    border-color: var(--text-muted);
}

.profile-hero-edit .icon {
    width: 15px;
    height: 15px;
}

.profile-avatar {
    display: grid;
    place-items: center;
    width: 78px;
    height: 78px;
    margin: 0 auto 14px;
    border-radius: 999px;
    background: var(--accent);
    border: 3px solid var(--surface);
    box-shadow: 0 6px 18px rgba(15, 20, 28, .16);
    color: var(--surface);
    font-size: 25px;
    font-weight: 700;
    letter-spacing: .04em;
}

.profile-hero-name {
    margin: 0;
    font-size: 17px;
    line-height: 1.25;
}

.profile-hero-handle {
    margin: 3px 0 0;
    color: var(--text-muted);
    font-size: 13px;
}

.profile-hero-roles {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
    margin-top: 12px;
}

.profile-role-chip {
    padding: 4px 12px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent-strong);
    font-size: 12px;
    font-weight: 600;
}

.profile-role-chip.is-muted {
    background: var(--surface-2);
    color: var(--text-muted);
}

/* --- account summary --- */

.profile-summary {
    padding: 18px 20px 20px;
}

.profile-summary-title {
    margin: 0 0 4px;
    font-size: 14px;
    line-height: 1.2;
}

.profile-summary-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.profile-summary-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
}

.profile-summary-row:last-child {
    border-bottom: 0;
    padding-bottom: 0;
}

.profile-summary-icon {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border-radius: 9px;
    background: var(--surface-2);
    color: var(--text-muted);
}

.profile-summary-icon .icon {
    width: 16px;
    height: 16px;
}

.profile-summary-icon.is-ok {
    background: var(--ok-bg);
    color: var(--ok-text);
}

.profile-summary-icon.is-bad {
    background: var(--warn-bg);
    color: var(--warn-text);
}

.profile-summary-copy {
    display: grid;
    gap: 2px;
    min-width: 0;
}

.profile-summary-label {
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.profile-summary-value {
    font-size: 13.5px;
    font-weight: 600;
    overflow-wrap: anywhere;
}

.profile-summary-value.is-accent {
    color: var(--accent-strong);
}

/* --- the two forms --- */

.profile-card {
    padding: 20px;
}

.profile-card-head {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 18px;
}

.profile-card-icon {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: var(--accent-soft);
    color: var(--accent);
}

.profile-card-icon .icon {
    width: 18px;
    height: 18px;
}

.profile-card-copy {
    min-width: 0;
}

.profile-card-copy h2 {
    margin: 0;
    font-size: 16px;
    line-height: 1.25;
}

.profile-card-copy p {
    margin: 3px 0 0;
    color: var(--text-muted);
    font-size: 13px;
}

.profile-field-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 14px;
}

.profile-optional {
    color: var(--text-muted);
    font-weight: 400;
}

/* The input and its ornaments share one bordered box, so the focus ring lands
   around the whole control rather than around the text field inside it. */
.profile-input {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--text-muted);
}

.profile-input:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.profile-input.has-error {
    border-color: var(--error-border);
}

.profile-input > .icon {
    flex: 0 0 auto;
    width: 17px;
    height: 17px;
}

/* The field inside the wrapper must bring nothing of its own -- no border, no
   background, no radius -- or the two draw a box inside a box.

   Spelled out per input type on purpose. The application-wide rule is
   `.form-field input[type="text"]`, specificity (0,2,1), and a plain
   `.profile-input input` is (0,1,1): it loses on specificity, not on order, so
   moving this block would not have helped. Matching the same attribute
   selectors under one more class puts it at (0,3,1) and makes the override
   deliberate rather than accidental. */
.profile-page .profile-input input[type="text"],
.profile-page .profile-input input[type="email"],
.profile-page .profile-input input[type="password"] {
    flex: 1 1 auto;
    width: 100%;
    min-width: 0;
    padding: 11px 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 14px;
}

/* The ring belongs to the wrapper, which is what a user sees as the control.
   Left alone, `.form-field input:focus` would draw a second one round the text. */
.profile-page .profile-input input:focus {
    outline: 0;
    border-color: transparent;
    box-shadow: none;
}

/* Chrome and Safari tint an autofilled box, which reinstates the inner
   rectangle the moment a password manager fills the form. */
.profile-page .profile-input input:-webkit-autofill {
    -webkit-text-fill-color: var(--text);
    box-shadow: 0 0 0 40px var(--surface) inset;
}

.profile-reveal {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
}

.profile-reveal:hover {
    color: var(--text);
    background: var(--surface-2);
}

.profile-reveal .icon {
    width: 17px;
    height: 17px;
}

.profile-note {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin: 16px 0 0;
    padding: 12px 14px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--text-muted);
    font-size: 13px;
}

.profile-note .icon {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    margin-top: 1px;
}

.profile-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}

/* --- strength meter ---
   Advisory only. The server accepts anything past the length rule, so the wording
   is a description of the password and never a verdict on the request. */

.profile-strength {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 14px;
}

.profile-strength-label {
    color: var(--text-muted);
    font-size: 12.5px;
}

.profile-strength-track {
    display: flex;
    gap: 5px;
}

.profile-strength-seg {
    width: 34px;
    height: 4px;
    border-radius: 999px;
    background: var(--border);
    transition: background .16s ease;
}

.profile-strength-word {
    font-size: 12.5px;
    font-weight: 700;
}

/* Filled segments and the word take their colour from the level, which the script
   puts on the container. Empty is the resting state, with nothing said. */
.profile-strength[data-level="1"] .profile-strength-seg:nth-child(-n+1),
.profile-strength[data-level="2"] .profile-strength-seg:nth-child(-n+2),
.profile-strength[data-level="3"] .profile-strength-seg:nth-child(-n+3),
.profile-strength[data-level="4"] .profile-strength-seg:nth-child(-n+4) {
    background: currentColor;
}

.profile-strength[data-level="1"] {
    color: var(--error-text);
}

.profile-strength[data-level="2"] {
    color: var(--warn-text);
}

.profile-strength[data-level="3"] {
    color: var(--accent);
}

.profile-strength[data-level="4"] {
    color: var(--ok-text);
}

.profile-strength[data-empty="true"] .profile-strength-word {
    display: none;
}

/* --- black actions ---
   The buttons on this page are black rather than the application accent. Scoped to
   the page so nothing else shifts, and written against the same tokens the rest of
   the sheet uses so both themes stay legible: on a dark theme "black" has to become
   the light end of the scale or the label disappears into the button. */

.profile-page .btn-primary {
    background: #111827;
    border-color: #111827;
    color: #ffffff;
}

.profile-page .btn-primary:hover {
    background: #000000;
    border-color: #000000;
}

.profile-page .btn-primary:focus-visible {
    outline: 0;
    box-shadow: 0 0 0 3px rgba(17, 24, 39, .28);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .profile-page .btn-primary {
        background: #f4f5f7;
        border-color: #f4f5f7;
        color: #111827;
    }

    :root:not([data-theme="light"]) .profile-page .btn-primary:hover {
        background: #ffffff;
        border-color: #ffffff;
    }

    :root:not([data-theme="light"]) .profile-page .btn-primary:focus-visible {
        box-shadow: 0 0 0 3px rgba(244, 245, 247, .3);
    }
}

:root[data-theme="dark"] .profile-page .btn-primary {
    background: #f4f5f7;
    border-color: #f4f5f7;
    color: #111827;
}

:root[data-theme="dark"] .profile-page .btn-primary:hover {
    background: #ffffff;
    border-color: #ffffff;
}

:root[data-theme="dark"] .profile-page .btn-primary:focus-visible {
    box-shadow: 0 0 0 3px rgba(244, 245, 247, .3);
}

/* One column once the identity card can no longer sit beside the forms without
   squeezing both. */
@media (max-width: 960px) {
    .profile-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 560px) {
    .profile-grid {
        padding: 14px;
        gap: 14px;
    }

    .profile-card,
    .profile-summary {
        padding: 16px;
    }

    .profile-hero {
        padding: 68px 16px 20px;
    }

    .profile-actions {
        justify-content: stretch;
    }

    .profile-actions .btn-primary {
        flex: 1 1 auto;
        justify-content: center;
    }

    /* The @username beside the breadcrumb is the one thing here worth dropping
       before the buttons are: it repeats what the card below already says. */
    .profile-header-user {
        display: none;
    }
}

/* --- create launcher ---
   The quick-create section, revealed by the topbar's plus button.

   It slides down from behind the topbar rather than appearing as a dialog over a
   dimmed page. That is why the z-index sits between the two fixed elements it has
   to negotiate: below the topbar at 30, so the closed panel is genuinely hidden
   behind it rather than merely translated off somewhere, and above the sidebar at
   20, so the open panel reads as one band across the application.

   The closed state is a transform, not the hidden attribute, because a hidden
   element cannot animate out -- it would vanish. visibility carries the part
   hidden used to do, keeping the panel out of the tab order and away from screen
   readers, and its transition is delayed by the length of the slide so it only
   takes effect once the panel has finished leaving. */

.launcher-panel {
    position: fixed;
    top: var(--topbar-h);
    left: 0;
    right: 0;
    z-index: 29;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    box-shadow: 0 18px 40px rgba(15, 20, 28, .16);
    transform: translateY(-100%);
    visibility: hidden;
    transition: transform .3s cubic-bezier(.22, .7, .3, 1), visibility 0s .3s;
}

.launcher-panel.is-open {
    transform: translateY(0);
    visibility: visible;
    transition: transform .3s cubic-bezier(.22, .7, .3, 1), visibility 0s;
}

/* Height comes from the content, capped so a long list scrolls inside the band
   instead of pushing it past the bottom of the window. */
.launcher-inner {
    display: flex;
    flex-direction: column;
    max-height: min(calc(100vh - var(--topbar-h) - 24px), 560px);
    padding: 0 clamp(16px, 3vw, 40px);
}

.launcher-header {
    display: flex;
    align-items: center;
    gap: 16px;
    flex: 0 0 auto;
    padding: 16px 0 14px;
}

.launcher-heading {
    min-width: 0;
}

.launcher-title {
    margin: 0;
    font-size: 17px;
    line-height: 1.2;
}

.launcher-subtitle {
    margin: 2px 0 0;
    color: var(--text-muted);
    font-size: 12.5px;
}

/* Takes the middle of the header and gives way first when the row runs out of
   room, since the heading and the close button both have fixed jobs. */
.launcher-search {
    display: flex;
    align-items: center;
    gap: 9px;
    flex: 1 1 auto;
    min-width: 0;
    max-width: 340px;
    margin-left: auto;
    padding: 0 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--text-muted);
}

.launcher-search:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.launcher-search .icon {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
}

.launcher-search-input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 9px 0;
    border: 0;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 14px;
}

.launcher-search-input:focus {
    outline: 0;
}

/* The native clear affordance sits badly against the flat field, and Escape
   already closes the panel. */
.launcher-search-input::-webkit-search-cancel-button {
    display: none;
}

.launcher-close {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border-radius: 9px;
}

.launcher-body {
    flex: 1 1 auto;
    padding-bottom: 20px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.launcher-section + .launcher-section {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}

.launcher-section-title {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 0 0 8px;
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.launcher-section-title .icon {
    width: 14px;
    height: 14px;
}

/* auto-fill across the full band: several columns on a desktop, one on a phone,
   without a breakpoint spelling either out. */
.launcher-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 6px;
}

.launcher-item {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    padding: 9px 10px;
    border: 1px solid transparent;
    border-radius: 10px;
    color: var(--text);
    text-decoration: none;
    font-size: 14px;
    transition: background .14s ease, border-color .14s ease;
}

.launcher-item:hover {
    background: var(--surface-2);
    border-color: var(--border);
}

/* Keyboard users get what the pointer gets, plus a ring. is-active is the row the
   arrow keys have moved to, which Enter will open. */
.launcher-item:focus-visible,
.launcher-item.is-active {
    background: var(--surface-2);
    border-color: var(--accent);
    outline: 0;
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.launcher-item-icon {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: var(--accent-soft);
    color: var(--accent);
}

.launcher-item-icon .icon {
    width: 16px;
    height: 16px;
}

.launcher-item-name {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Points the way without taking space when it is not wanted. */
.launcher-item-go {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    color: var(--text-muted);
    opacity: 0;
    transition: opacity .14s ease;
}

.launcher-item-go .icon {
    width: 15px;
    height: 15px;
}

.launcher-item:hover .launcher-item-go,
.launcher-item:focus-visible .launcher-item-go,
.launcher-item.is-active .launcher-item-go {
    opacity: 1;
}

.launcher-no-results {
    margin: 4px 0 0;
    padding: 16px;
    border: 1px dashed var(--border);
    border-radius: 12px;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 13.5px;
    text-align: center;
}

/* On a phone the heading and the search field cannot share a row. */
@media (max-width: 620px) {
    .launcher-header {
        flex-wrap: wrap;
        gap: 10px;
    }

    .launcher-search {
        order: 3;
        flex-basis: 100%;
        max-width: none;
        margin-left: 0;
    }

    .launcher-inner {
        max-height: calc(100vh - var(--topbar-h));
    }

    .launcher-item {
        padding: 11px 10px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .launcher-panel,
    .launcher-panel.is-open {
        transition: visibility 0s;
    }
}

.page h1 {
    margin: 0 0 4px;
    font-size: 22px;
}

.muted {
    color: var(--text-muted);
    font-size: 14px;
}

/* Shared page header — one definition for every screen: a bar across the top of
   the page with the breadcrumb taking the width and the screen's primary action
   at the far end. Square corners, because `.app-body .page` has no gutter for a
   rounded card to float in.

   Six screens used to carry a copy of this laid out by a wrapper class of their
   own, all six identical to each other and to what follows. Pages should not
   restyle it; adjust the sizes here so all pages stay in step. */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: nowrap;
    padding: 14px 18px;
    background: var(--surface);    
    border-radius: 0;
    border-bottom: 1px solid var(--border);
}

.page-header > * {
    min-width: 0;
}

.page-header .breadcrumb {
    flex: 1 1 auto;
}

/* Breadcrumb above, the screen's title large beneath it. */
.page-header-heading {
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1 1 auto;
}

.page-header-heading .breadcrumb {
    flex: 0 0 auto;
}

/* The title, with a back arrow before it on a screen opened from another. */
.page-header-titlebar {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}

.page-header-back {
    display: inline-grid;
    place-items: center;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    margin-left: -6px;
    border-radius: 50%;
    color: var(--text);
}

.page-header-back:hover {
    background: var(--surface-2);
    color: var(--accent);
}

.page-header-back .icon {
    width: 22px;
    height: 22px;
}

.page-header-title {
    margin: 0;
    font-size: 22px;
    font-weight: 600;
    line-height: 1.25;
    color: var(--text);
    overflow-wrap: anywhere;
}

/* A sub page's one line: the trail, then the title in the same size type as the
   steps before it, set apart by weight alone. The trail takes only the room its
   steps need, so the title follows it rather than being pushed to the far end. */
.page-header-heading.is-inline .page-header-titlebar {
    flex-wrap: wrap;
    gap: 8px;
}

.page-header-heading.is-inline .breadcrumb {
    flex: 0 1 auto;
    font-size: 15px;
}

/* Margin restated: `.page h1` would otherwise lift the title off the trail's line. */
.page-header-title.is-inline {
    margin: 0;
    font-size: 15px;
    line-height: 1.5;
}

/* The header's actions slot. Screens that passed ~{} leave it empty, which costs
   nothing: a flex item with no children is zero wide and the breadcrumb keeps
   the whole bar. */
.page-header-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-left: auto;
    flex: 0 0 auto;
}

.page-header-actions .btn-primary,
.page-header-actions .btn-ghost {
    white-space: nowrap;
}

/* Nothing passed in: on a narrow screen the slot would still take a row of its own. */
.page-header-actions:not(:has(*)) {
    display: none;
}

/* Tabbed screens put their per-tab buttons in a group of their own, because the
   tab script hides the group whole when the open tab has nothing to create. */
.page-header-tab-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
}

.page-header-tab-actions[hidden] {
    display: none;
}

.breadcrumb {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 8px;
    min-width: 0;
    font-size: 13px;
}

.breadcrumb a {
    color: var(--accent-strong);
    text-decoration: none;
    font-weight: 500;
}

.breadcrumb a:hover {
    text-decoration: underline;
}

.breadcrumb .breadcrumb-home {
    display: inline-flex;
    color: var(--text);
}

.breadcrumb-home .icon {
    width: 20px;
    height: 20px;
}

.breadcrumb-current {
    color: var(--text-muted);
}

.breadcrumb-sep {
    display: inline-flex;
    color: var(--text-muted);
}

.breadcrumb-sep .icon {
    width: 14px;
    height: 14px;
}

/* A search box for the header's actions slot: the field and its button drawn as
   one control, the magnifier at the far end. */
.header-search {
    display: flex;
    align-items: center;
    width: 380px;
    max-width: 100%;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    transition: border-color .16s ease, box-shadow .16s ease;
}

.header-search:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.header-search input {
    flex: 1 1 auto;
    min-width: 0;
    height: 40px;
    padding: 0 4px 0 14px;
    border: 0;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 14px;
    outline: none;
}

.header-search button {
    display: grid;
    place-items: center;
    width: 42px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 0 8px 8px 0;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
}

.header-search button:hover,
.header-search button:focus-visible {
    color: var(--text);
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Intro line + primary action, sitting between the header and the content. */
.page-toolbar {
    display: flex;
    align-items: flex-start;
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: 12px 16px;
    margin: 0 0 4px;
}

.page-toolbar p {
    margin: 0;
    min-width: 0;
    flex: 1 1 100%;
    max-width: none;
}

.page-toolbar-end {
    justify-content: flex-end;
}

.page-toolbar > a,
.page-toolbar > form {
    margin-left: auto;
}

.page-toolbar-end > a,
.page-toolbar-end > form {
    margin-left: 0;
}

/* Shared surface: every card-like block on every page uses this treatment.
   Keep .panel, .data-table and .form-card in step. */
.panel {      
    background: var(--surface);    
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.panel h2 {
    margin: 0 0 6px;
    font-size: 16px;
}

.link-row {
    display: flex;
    gap: 16px;
    margin: 8px 0 0;
}

.link-row a {
    color: var(--accent-strong);
    font-weight: 600;
}

.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 12px 0 0;
    padding: 0;
    list-style: none;
}

.chips li {
    padding: 3px 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
    font-size: 12px;
    font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
}

.auth-body {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 24px;
}

.auth-card {
    width: 100%;
    max-width: 380px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 32px;
    box-shadow: var(--shadow);
}

.auth-header {
    text-align: center;
    margin-bottom: 24px;
}

.auth-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    margin-bottom: 12px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    font-weight: 700;
    letter-spacing: .5px;
    font-size: 14px;
}

.auth-header h1 {
    margin: 0;
    font-size: 20px;
    font-weight: 600;
}

.auth-sub {
    margin: 4px 0 0;
    color: var(--text-muted);
    font-size: 14px;
}

.auth-form {
    display: flex;
    flex-direction: column;
}

.auth-form label {
    margin-bottom: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
}

.auth-form input {
    margin-bottom: 16px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 15px;
    font-family: inherit;
    background: var(--surface);
    color: var(--text);
}

.auth-form input:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
}

.auth-footer {
    margin-top: 20px;
    text-align: center;
}

.auth-footer p {
    margin: 0;
    font-size: 12px;
    color: var(--text-muted);
}

.alert {
    margin-bottom: 18px;
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid transparent;
    font-size: 14px;
}

.alert-error {
    background: var(--error-bg);
    border-color: var(--error-border);
    color: var(--error-text);
}

.alert-info {
    background: var(--info-bg);
    border-color: var(--info-border);
    color: var(--info-text);
}

.alert-success {
    background: var(--ok-bg);
    border-color: var(--ok-border);
    color: var(--ok-text);
}

.flash-toast-region {
    position: fixed;
    left: 50%;
    z-index: 1200;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    width: calc(100vw - 32px);
    transform: translateX(-50%);
    pointer-events: none;
}

.flash-toast-region-interactive {
    bottom: 24px;
}

.flash-toast-region-status {
    bottom: 24px;
}

.flash-toast {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    margin: 0;
    max-width: min(100%, 460px);
    padding: 10px 14px;
    border-width: 1px;
    border-style: solid;
    border-radius: 18px;
    box-shadow: var(--shadow);
    font-size: 14px;
    font-weight: 600;
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0) scale(1);
    transition: opacity .32s ease, transform .32s ease;
}

.flash-toast.alert-success {
    background: #111111;
    border-color: #111111;
    color: #ffffff;
}

.flash-toast.alert-error {
    background: #5b171b;
    border-color: #5b171b;
    color: #ffffff;
}

.flash-toast.alert-confirm {
    background: #111111;
    border-color: #111111;
    color: #ffffff;
}

.flash-toast-content {
    min-width: 0;
    flex: 1 1 auto;
}

.flash-toast-message {
    display: block;
}

.flash-toast[data-toast-kind="delete-selection"] {
    gap: 10px;
    padding: 8px 12px;
}

.flash-toast-actions {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
}

.flash-toast-button {
    min-height: 34px;
    padding: 0 12px;
    border: 1px solid rgba(255, 255, 255, .28);
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
}

.flash-toast-button:hover {
    background: rgba(255, 255, 255, .08);
}

.flash-toast-button.is-danger {
    border-color: #ffffff;
    background: #ffffff;
    color: #5b171b;
}

.flash-toast-button.is-danger:hover {
    background: rgba(255, 255, 255, .9);
}

.flash-toast-button:disabled {
    opacity: .6;
    cursor: not-allowed;
}

.flash-toast[data-toast-kind="delete-selection"] .flash-toast-button {
    min-height: 30px;
    padding: 0 10px;
    font-size: 12px;
}

.flash-toast.is-hiding {
    opacity: 0;
    transform: translateY(-8px) scale(.98);
}

.confirm-modal-scrim {
    position: fixed;
    inset: 0;
    z-index: 1250;
    border: 0;
    background: rgba(15, 20, 28, .46);
    animation: scrim-in .18s ease-out both;
}

.confirm-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    z-index: 1251;
    width: min(calc(100vw - 32px), 380px);
    padding: 22px 22px 18px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 0;
    box-shadow: 0 18px 44px rgba(15, 20, 28, .24);
    transform: translate(-50%, -50%);
    animation: confirm-modal-in .18s cubic-bezier(.24, .72, .32, 1) both;
}

.confirm-modal-title {
    margin: 0 0 10px;
    font-size: 20px;
    line-height: 1.15;
    color: var(--text);
}

.confirm-modal-message {
    margin: 0 0 18px;
    color: var(--text-muted);
    font-size: 14px;
    line-height: 1.5;
}

.confirm-modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    flex-wrap: wrap;
}

.confirm-modal-actions .btn-primary,
.confirm-modal-actions .btn-ghost {
    border-radius: 0;
}

.confirm-modal-delete {
    background: #5b171b;
    border-color: #5b171b;
}

.confirm-modal-delete:hover {
    background: #4a1216;
    border-color: #4a1216;
}

@keyframes confirm-modal-in {
    from {
        opacity: 0;
        transform: translate(-50%, calc(-50% + 10px));
    }
    to {
        opacity: 1;
        transform: translate(-50%, -50%);
    }
}

.data-table-shell {
    margin-top: var(--grid-shell-mt);
    /* Stated rather than left to overflow: hidden, which also implied it, so the
       shell keeps its width when that is lifted below. */
    min-width: 0;
    overflow: hidden;
    background: var(--surface);
    border-radius: 0;
}

/* The Columns and Density menus open down from the toolbar, inside the shell. A
   table of a row or two ends before the menu does, and the shell cut the menu
   off there, hiding half of its columns. Lifted only while a menu is open, so the
   shell clips everything else as before. */
.data-table-shell:has(.data-grid-menu[open]) {
    overflow: visible;
}

.data-table-shell[data-grid-ready="true"] {
    display: flex;
    flex-direction: column;
}

.data-grid-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
    min-height: var(--grid-toolbar-h);
    padding: 14px 16px;
    border-bottom: 1px solid rgba(215, 225, 238, .92);   
}

.data-grid-summary {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    min-width: 0;
}

.data-grid-title {
    margin: 0;
    font-size: 14px;
    font-weight: 700;
    color: var(--text);
}

.data-grid-chips {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.data-grid-chip {
    display: inline-flex;
    align-items: center;
    min-height: 28px;
    padding: 0 10px;
    border-radius: 0;
    background: var(--accent-soft);
    color: var(--accent-strong);
    font-size: 12px;
    font-weight: 700;
    white-space: nowrap;
}

.data-grid-chip-muted {
    background: var(--surface-2);
    color: var(--text-muted);
}

.data-grid-controls {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    flex: 1 1 320px;
    flex-wrap: wrap;
}

.data-grid-bulk-actions {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.data-grid-bulk-actions .data-grid-action-button {
    border: 1px solid var(--border);
    background: var(--surface);
}

.data-grid-actions {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0;
    border: 1px solid var(--border);
    background: var(--surface);
}

.data-grid-menu {
    position: relative;
}

.data-grid-menu summary {
    list-style: none;
}

.data-grid-menu summary::-webkit-details-marker {
    display: none;
}

.data-grid-action-button {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 38px;
    padding: 0 14px;
    border: 0;
    border-right: 1px solid var(--border);
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}

.data-grid-actions > .data-grid-action-button:last-child,
.data-grid-menu:last-child .data-grid-action-button {
    border-right: 0;
}

.data-grid-action-button:hover,
.data-grid-menu[open] .data-grid-action-button {
    background: var(--surface-2);
}

.data-grid-action-danger {
    color: var(--error-text);
}

.data-grid-action-button:disabled {
    opacity: .45;
    cursor: not-allowed;
}

.data-grid-action-button::after {
    content: '';
    width: 7px;
    height: 7px;
    border-right: 1.4px solid currentColor;
    border-bottom: 1.4px solid currentColor;
    transform: rotate(45deg) translateY(-1px);
    opacity: .7;
    transition: transform .16s ease, opacity .16s ease;
}

.data-grid-menu[open] .data-grid-action-button::after {
    transform: rotate(-135deg) translateY(1px);
    opacity: .92;
}

.data-grid-action-button[data-grid-action="export"]::after,
.data-grid-action-button[data-grid-action="reset"]::after,
.data-grid-action-button[data-grid-action="bulk-delete"]::after,
.data-grid-action-button[data-grid-action="clear-selection"]::after {
    display: none;
}

.data-grid-menu-panel {
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    z-index: 5;
    min-width: 220px;
    padding: 10px;
    border: 1px solid var(--border);
    background: var(--surface);
    box-shadow: var(--shadow);
}

.data-grid-menu-panel-header {
    margin: 0 0 8px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.data-grid-column-list,
.data-grid-density-list {
    display: grid;
    gap: 4px;
}

.data-grid-column-option,
.data-grid-density-option {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 34px;
    padding: 0 10px;
    background: transparent;
    border: 1px solid transparent;
    color: var(--text);
    font: inherit;
    font-size: 13px;
}

.data-grid-column-option:hover,
.data-grid-density-option:hover {
    background: var(--surface-2);
}

.data-grid-column-option input {
    margin: 0;
}

.data-grid-density-option {
    width: 100%;
    text-align: left;
    cursor: pointer;
}

.data-grid-search {
    position: relative;
    flex: 1 1 220px;
    max-width: 260px;
}

.data-grid-search::after {
    content: '';
    position: absolute;
    top: 50%;
    right: 12px;
    width: 8px;
    height: 8px;
    border: 2px solid currentColor;
    border-radius: 50%;
    color: var(--text-muted);
    transform: translateY(-60%);
    opacity: .6;
}

.data-grid-search::before {
    content: '';
    position: absolute;
    top: calc(50% + 5px);
    right: 8px;
    width: 7px;
    height: 2px;
    border-radius: 999px;
    background: currentColor;
    color: var(--text-muted);
    transform: rotate(45deg);
    opacity: .6;
}

.data-grid-search.is-active::after,
.data-grid-search.is-active::before {
    color: var(--accent);
}

.data-grid-search-input {
    width: 100%;
    min-height: 38px;
    padding: 0 38px 0 12px;
    border: 1px solid var(--border);
    border-radius: 0;
    background: var(--surface-2);
    color: var(--text);
    font: inherit;
    font-size: 13px;
}

.data-grid-search-input::placeholder {
    color: var(--text-muted);
}

.data-grid-search-input:focus {
    outline: none;
    border-color: var(--accent);
    background: var(--surface);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.data-grid-density-button {
    min-height: 34px;
    padding: 0 10px;
    border: 1px solid transparent;
    border-radius: 0;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    transition: background .16s ease, color .16s ease, border-color .16s ease;
}

.data-grid-density-button:hover {
    background: var(--surface-2);
}

.data-grid-density-button.is-active {
    border-color: var(--border);
    background: var(--accent-soft);
    color: var(--accent-strong);
}

.panel .data-table-shell {    
    border: 0;
}

.panel .data-table-shell:first-child {
    margin-top: 0;
}

.data-table-scroll {
    position: relative;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: thin;
    scrollbar-color: rgba(112, 131, 154, .55) transparent;
}

.data-table-scroll::-webkit-scrollbar {
    height: 10px;
}

.data-table-scroll::-webkit-scrollbar-thumb {
    background: rgba(112, 131, 154, .42);
    border-radius: 999px;
}

.data-table-scroll::-webkit-scrollbar-track {
    background: transparent;
}

.data-table {
    width: 100%;
    /* separate + zero spacing so the card corners actually round;
       `collapse` silently cancels border-radius on tables. */
    border-collapse: separate;
    border-spacing: 0;
    margin-top: 16px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 0;
    overflow: hidden;
    font-size: 14px;
    line-height: 1.35;
}

/* Inside a panel the table is part of that card, not a second one. */
.panel .data-table {
    border: 0;
    border-radius: 0;
    box-shadow: none;
}

.panel .data-table:first-child {
    margin-top: 0;
}

/* Before app.js runs, the table is the plain markup the server sent: no shell
   around it, no toolbar above it, no selection column beside it. Left alone the
   browser paints that, then app.js rearranges it and the rows slide down and
   across -- the jump you see a beat after any page with a table opens.

   So for the length of that boot the table keeps its place in the flow but not
   its pixels. It holds the height the toolbar is about to take, and the width it
   will have once it can scroll sideways inside the shell, so nothing below it
   moves; and it waits to be shown rather than being painted somewhere it is
   about to leave. theme.js sets the mark in the head, app.js clears it.

   Matrix tables are excluded: they are never made into grids, so no chrome is
   coming and there is nothing to hold space for. */
html.grids-booting .data-table:not(.matrix-table) {
    margin-top: calc(var(--grid-shell-mt) + var(--grid-toolbar-h));
    min-width: var(--grid-table-min-w);
    /* The shell carries the frame once it exists; two pixels of border here
       would be two pixels of movement there. */
    border: 0;
    visibility: hidden;
}

.data-table-shell .data-table {
    margin-top: 0;
    min-width: var(--grid-table-min-w);
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: transparent;
}

.data-table th,
.data-table td {
    padding: 14px 16px;
    text-align: left;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
}

.data-table thead th {
    background: linear-gradient(180deg, rgba(243, 246, 251, .92), rgba(238, 243, 250, .98));
    font-size: 13px;
    font-weight: 700;
    text-transform: none;
    letter-spacing: 0;
    color: var(--text);
    white-space: nowrap;
}

.data-table-shell[data-grid-ready="true"] .data-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    backdrop-filter: blur(10px);
}

.data-grid-sort {
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    width: 100%;
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    font-weight: inherit;
    text-align: inherit;
    cursor: pointer;
}

.data-grid-sort:hover {
    color: var(--accent-strong);
}

.data-grid-sort-label {
    display: inline-flex;
    align-items: center;
    min-width: 0;
}

.data-grid-sort-indicator {
    width: 8px;
    height: 8px;
    flex: 0 0 auto;
    border-right: 1.6px solid currentColor;
    border-bottom: 1.6px solid currentColor;
    opacity: .3;
    transform: rotate(45deg);
    transition: transform .16s ease, opacity .16s ease, color .16s ease;
}

.data-table thead th[data-grid-sort-state="asc"] .data-grid-sort-indicator {
    opacity: .82;
    transform: rotate(-135deg);
}

.data-table thead th[data-grid-sort-state="desc"] .data-grid-sort-indicator {
    opacity: .82;
    transform: rotate(45deg);
}

.data-table .check-col {
    width: 52px;
    min-width: 52px;
    padding: 12px 10px;
    text-align: center;
    vertical-align: middle;
}

.data-table .check-col input {
    width: 16px;
    height: 16px;
    margin: 0;
    accent-color: var(--accent);
    cursor: pointer;
}

.data-table thead th.num .data-grid-sort,
.data-table .num .data-grid-sort {
    justify-content: flex-end;
}

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

.data-table-shell[data-grid-ready="true"] .data-table tbody tr:nth-child(even) td {
    background: rgba(17, 24, 39, .015);
}

.data-table tbody tr:hover td {
    background: rgba(54, 109, 240, .035);
}

.data-table a {
    color: var(--text);
    font-weight: 600;
    text-decoration: none;
}

.data-table a:hover {
    color: var(--accent-strong);
}

.data-table code {
    font-size: 12px;
    font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
}

.data-table .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.data-table td .muted {
    display: block;
    margin-top: 4px;
    font-size: 12px;
    line-height: 1.4;
}

.data-table .status,
.data-table .tag {
    white-space: nowrap;
}

.row-actions {
    white-space: nowrap;
}

.row-actions form {
    margin: 0;
}

.data-grid-empty {
    padding: 14px 16px 16px;
    border-top: 1px solid rgba(215, 225, 238, .92);
    color: var(--text-muted);
    font-size: 13px;
    background: linear-gradient(180deg, rgba(247, 250, 255, .7), rgba(255, 255, 255, .92));
}

/* Density hangs off the root element, not off each shell: theme.js has to set it
   in the head, before a shell exists, or every row resizes just after it is
   painted. That is also why these reach the table directly rather than through
   .data-table-shell -- during boot there is no shell yet. */
:root[data-grid-density="compact"] .data-grid-toolbar {
    padding: 10px 12px;
}

:root[data-grid-density="compact"] .data-table th,
:root[data-grid-density="compact"] .data-table td {
    padding: 10px 12px;
}

:root[data-grid-density="comfortable"] .data-grid-toolbar {
    padding: 16px 18px;
}

:root[data-grid-density="comfortable"] .data-table th,
:root[data-grid-density="comfortable"] .data-table td {
    padding: 16px 18px;
}

[data-theme="dark"] .data-grid-toolbar {
    border-bottom-color: rgba(43, 50, 64, .94);
    background: linear-gradient(180deg, rgba(26, 31, 40, .98), rgba(22, 27, 35, .96));
}

[data-theme="dark"] .data-grid-actions,
[data-theme="dark"] .data-grid-menu-panel,
[data-theme="dark"] .data-grid-action-button {
    border-color: var(--border);
}

[data-theme="dark"] .data-grid-action-button:hover,
[data-theme="dark"] .data-grid-menu[open] .data-grid-action-button,
[data-theme="dark"] .data-grid-column-option:hover,
[data-theme="dark"] .data-grid-density-option:hover,
[data-theme="dark"] .data-grid-density-button:hover {
    background: rgba(255, 255, 255, .05);
}

[data-theme="dark"] .data-table thead th {
    background: linear-gradient(180deg, rgba(33, 39, 52, .96), rgba(26, 31, 40, .98));
}

[data-theme="dark"] .data-table-shell[data-grid-ready="true"] .data-table tbody tr:nth-child(even) td {
    background: rgba(255, 255, 255, .02);
}

[data-theme="dark"] .data-grid-empty {
    border-top-color: rgba(43, 50, 64, .94);
    background: linear-gradient(180deg, rgba(22, 27, 35, .8), rgba(26, 31, 40, .96));
}

[data-theme="dark"] .data-table-shell > .pager {
    background: linear-gradient(180deg, rgba(22, 27, 35, .86), rgba(26, 31, 40, .98));
}

@media (max-width: 640px) {
    .flash-toast {
        flex-direction: column;
        align-items: stretch;
    }

    .flash-toast-actions {
        width: 100%;
        justify-content: flex-end;
    }

    /* Stacked, the toolbar is the summary row, the three actions in a column and
       the search field, inside its own padding: 28 + 28 + 14 + 118 + 10 + 40 + 1.
       An estimate, unlike the single-row height above, so it only reserves space
       -- min-height is dropped below so nothing is forced to it. The density
       selector is matched, not just :root, or the denser settings would keep the
       one-row height they set at the top of the file. */
    :root,
    :root[data-grid-density] {
        --grid-toolbar-h: 239px;
    }

    .data-grid-toolbar {
        align-items: stretch;
        min-height: 0;
    }

    .data-grid-summary,
    .data-grid-controls,
    .data-grid-search {
        width: 100%;
        max-width: none;
    }

    .data-grid-controls {
        justify-content: stretch;
    }

    .data-grid-bulk-actions {
        width: 100%;
        justify-content: space-between;
    }

    .data-grid-actions {
        width: 100%;
        flex-direction: column;
    }

    .data-grid-menu,
    .data-grid-action-button {
        width: 100%;
    }

    .data-grid-action-button {
        justify-content: space-between;
        border-right: 0;
        border-bottom: 1px solid var(--border);
    }

    .data-grid-actions > .data-grid-action-button:last-child,
    .data-grid-menu:last-child .data-grid-action-button {
        border-bottom: 0;
    }

    .data-grid-menu-panel {
        position: static;
        margin-top: -1px;
        border-width: 1px 0 0;
        box-shadow: none;
    }
}

.tag {
    display: inline-block;
    margin-right: 4px;
    padding: 1px 8px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
    font-size: 11px;
    color: var(--text-muted);
}

.status {
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
}

.status-on {
    background: var(--ok-bg);
    color: var(--ok-text);
}

.status-off {
    background: var(--surface-2);
    color: var(--text-muted);
}

.status-warn {
    background: var(--warn-bg);
    color: var(--warn-text);
}

.btn-primary {
    padding: 10px 16px;
    border: 1px solid var(--button-border);    
    background: var(--button-bg);
    color: var(--button-text);
    font-size: 15px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    text-decoration: none;
    transition: background .16s ease, border-color .16s ease, color .16s ease, box-shadow .16s ease;
}

.btn-primary:hover {
    background: var(--button-hover);
    border-color: var(--button-hover);
    color: var(--button-text);
    box-shadow: 0 10px 20px rgba(15, 23, 42, .12);
}

.btn-inline {
    display: inline-block;
    padding: 9px 15px;
    text-decoration: none;
    font-size: 14px;
}

.btn-link {
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent-strong);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    text-decoration: underline;
}

.btn-link.danger {
    color: var(--error-text);
}

.logout-form {
    margin: 0;
}

/* A drawer is modal: while one is open the page under it does not scroll, so the
   page's scrollbar is not left showing in a strip beside the drawer. */
:root:has(.drawer) {
    overflow: hidden;
}

.drawer-scrim {
    position: fixed;
    inset: 0;
    z-index: 60;
    background: rgba(15, 20, 28, .45);
    animation: scrim-in .18s ease-out both;
}

.drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 61;
    display: flex;
    flex-direction: column;
    width: min(780px, 64vw);
    min-width: 0;
    background: var(--surface);
    border-left: 1px solid var(--border);
    box-shadow: -14px 0 40px rgba(15, 20, 28, .18);
    animation: drawer-in .22s cubic-bezier(.32, .72, .35, 1) both;
}

@keyframes drawer-in {
    from { transform: translateX(100%); }
    to   { transform: translateX(0); }
}

@keyframes scrim-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .confirm-modal,
    .confirm-modal-scrim,
    .drawer,
    .drawer-scrim {
        animation: none;
    }
}

.drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex: 0 0 auto;
    padding: 20px 28px;
    border-bottom: 1px solid var(--border);
}

.drawer-header h2 {
    margin: 0;
    font-size: 21px;
    font-weight: 700;
    color: var(--accent-strong);
}

.drawer-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--text-muted);
    text-decoration: none;
    cursor: pointer;
}

.drawer-close:hover {
    background: var(--surface-2);
    color: var(--text);
}

.drawer-form {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.drawer-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 26px 28px;
}

.drawer-footer {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 0 0 auto;
    padding: 16px 28px;
    border-top: 1px solid var(--border);
    background: var(--surface);
}

@media (max-width: 760px) {
    .drawer {
        width: 100%;
        border-left: 0;
    }

    .drawer-header,
    .drawer-body,
    .drawer-footer {
        padding-left: 16px;
        padding-right: 16px;
    }
}

.form-card {
    margin-top: 16px;
    padding: 28px 32px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.form-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px 24px;
    align-items: start;
}

.form-field {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* An author `display` outranks the browser's rule for [hidden], so a field the
   form has switched off would otherwise stay on screen. */
.form-field[hidden] {
    display: none;
}

.form-field > label,
.form-field > .form-label {
    margin-bottom: 7px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
}

.form-field input[type="text"],
.form-field input[type="email"],
.form-field input[type="password"],
.form-field input[type="number"],
.form-field select,
.form-field textarea {
    width: 100%;
    padding: 11px 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 15px;
    font-family: inherit;
    background: var(--surface);
    color: var(--text);
}

.form-field input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.form-field select,
.form-field textarea {
    appearance: none;
}

.form-field textarea {
    min-height: 92px;
    resize: vertical;
}

.form-field input[readonly] {
    background: var(--surface-2);
    color: var(--text-muted);
}

.form-field > .field-help,
.form-field > .field-error {
    margin: 7px 0 0;
}

.form-field-full {
    grid-column: 1 / -1;
}

.form-field-full > .form-label {
    font-size: 16px;
}

.form-card .form-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 4px 0 0;
    padding-top: 22px;
    border-top: 1px solid var(--border);
}

.btn-ghost {
    padding: 10px 22px;
    border: 1px solid var(--button-border);
    border-radius: 8px;
    background: var(--button-bg);
    color: var(--button-text);
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background .16s ease, border-color .16s ease, color .16s ease, box-shadow .16s ease;
}

.btn-ghost:hover {
    background: var(--button-hover);
    border-color: var(--button-hover);
    color: var(--button-text);
    box-shadow: 0 10px 20px rgba(15, 23, 42, .12);
}

.btn-primary:disabled,
.btn-ghost:disabled {
    border-color: var(--button-disabled);
    background: var(--button-disabled);
    color: #ffffff;
    box-shadow: none;
    cursor: not-allowed;
    opacity: .78;
}

.form-card .btn-primary {
    padding: 10px 28px;
}

@media (max-width: 760px) {
    .form-card {
        padding: 20px 18px;
    }

    .form-grid {
        grid-template-columns: minmax(0, 1fr);
        gap: 16px;
    }
}

.stacked-form {
    max-width: 900px;
}

.field-row {
    display: flex;
    gap: 16px;
}

.field-row .field {
    flex: 1 1 0;
}

.field {
    margin-bottom: 16px;
}

.field > label {
    display: block;
    margin-bottom: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
}

.field input[type="text"],
.field input[type="email"],
.field input[type="password"],
.field input[type="number"],
.field select,
.field textarea {
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 15px;
    font-family: inherit;
    background: var(--surface);
    color: var(--text);
}

.field input:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

.field input[readonly] {
    background: var(--surface-2);
    color: var(--text-muted);
}

.field-help {
    margin: 6px 0 0;
    font-size: 12px;
    color: var(--text-muted);
}

.field-error {
    margin: 6px 0 0;
    font-size: 13px;
    color: var(--error-text);
}

.section-title {
    margin: 26px 0 4px;
    font-size: 16px;
}

.check-list {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 20px;
    padding: 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.check-item {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 14px;
    cursor: pointer;
}

.check-item + .check-item {
    margin-top: 8px;
}

.check-item code {
    font-size: 11px;
    color: var(--text-muted);
}

.form-actions {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-top: 24px;
}

.matrix {
    margin-top: 14px;
}

.matrix-table .check-col {
    width: 78px;
    text-align: center;
}

.matrix-table tbody td:first-child {
    font-weight: 500;
}

.matrix-table input[type="checkbox"] {
    width: 16px;
    height: 16px;
    cursor: pointer;
}

.cell-empty {
    color: var(--border);
}

/* ============================================================================
   Pager for paged admin lists (fragments/pagination.html).
   ========================================================================= */

.pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 12px 4px 2px;
    border-top: 1px solid var(--border);
    margin-top: 4px;
}

.pager-meta {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}

.pager-count {
    margin: 0;
    font-size: 13px;
    color: var(--text-muted);
    /* Digits in a count that changes as you page should not make the row jump. */
    font-variant-numeric: tabular-nums;
}

.pager-total,
.pager-size {
    margin: 0;
    font-size: 12px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.pager-count strong {
    color: var(--text);
}

.pager-total strong,
.pager-size strong {
    color: var(--text);
}

.pager-controls {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.pager-position {
    font-size: 13px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    padding: 0 4px;
}

.pager-position strong {
    color: var(--text);
}

.pager-btn {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border: 1px solid var(--border);
    border-radius: 0;
    background: var(--surface);
    color: var(--text);
    font-size: 17px;
    line-height: 1;
    text-decoration: none;
}

.pager-btn:hover {
    background: var(--surface-2);
}

/* Kept visible but inert at the ends, so the control does not move under the
   cursor as you reach the first or last page. */
.pager-btn.is-disabled {
    opacity: .38;
    pointer-events: none;
}

.pager-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

.data-table-shell > .pager,
.data-table-shell > [data-live-pagination] {
    border-top: 1px solid var(--border);
}

.data-table-shell > .pager {
    margin-top: 0;
    padding: 12px 16px 14px;
    border-top-width: 1px;
    background: linear-gradient(180deg, rgba(247, 250, 255, .82), rgba(255, 255, 255, .96));
}

.data-table-shell > [data-live-pagination] {
    padding: 0 16px;
}

.data-table-shell > [data-live-pagination] .pager {
    margin-top: 0;
    padding: 12px 0 14px;
    border-top: 0;
}

.empty-state {
    padding: 22px 24px;
    margin-bottom: 16px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.empty-state p {
    margin: 0 0 6px;
}

.empty-state p:last-child {
    margin-bottom: 0;
}

/*
  A picture for an empty screen, from fragments/illustrations. Its colours are
  tokens scoped to it, so dark mode only has to restate them.
*/
.empty-illustration {
    --ill-blob: #eaf2fb;
    --ill-line: #d6dfeb;
    --ill-frame: #ffffff;
    --ill-pane: #f2f6fb;
    --ill-cat: #4a4b50;
    --ill-leaf: #5bbd8b;
    --ill-leaf-soft: #a8dcc0;
    --ill-pot: #bcdcf5;

    display: block;
    width: 100%;
    max-width: 340px;
    height: auto;
    margin: 0 auto 18px;
}

[data-theme="dark"] .empty-illustration {
    --ill-blob: #1b2535;
    --ill-line: #2f3a4b;
    --ill-frame: #1a1f28;
    --ill-pane: #212734;
    --ill-cat: #aab4c3;
    --ill-leaf: #4fa57a;
    --ill-leaf-soft: #2f6b4d;
    --ill-pot: #2c4459;
}

.empty-illustration .ill-blob { fill: var(--ill-blob); }
.empty-illustration .ill-line { stroke: var(--ill-line); stroke-width: 2; stroke-linecap: round; }
.empty-illustration .ill-frame { fill: var(--ill-frame); stroke: var(--ill-line); stroke-width: 5; }
.empty-illustration .ill-pane { fill: var(--ill-pane); }
.empty-illustration .ill-bars { fill: none; stroke: var(--ill-line); stroke-width: 4; }
.empty-illustration .ill-dots { fill: var(--ill-line); }
.empty-illustration .ill-cat { fill: var(--ill-cat); }
.empty-illustration .ill-tail { fill: none; stroke: var(--ill-cat); stroke-width: 7; stroke-linecap: round; }
.empty-illustration .ill-neck { fill: none; stroke: var(--ill-cat); stroke-width: 18; stroke-linecap: round; }
.empty-illustration .ill-leaf { fill: var(--ill-leaf); }
.empty-illustration .ill-leaf-soft { fill: var(--ill-leaf-soft); }
.empty-illustration .ill-pot { fill: var(--ill-pot); }


/* ============================================================================
   Services Transaction History: status chips over a plain table, which shows
   one centred row with a picture when there is nothing in it. A table of its
   own rather than .data-table, which app.js would give a grid toolbar.
   ========================================================================= */

.svc-title {
    margin: 18px;
    font-size: 20px;
    font-weight: 400;
}

.svc-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 24px;
}

.svc-chips .ri-chip {
    text-decoration: none;
}

.svc-table-wrap {
    overflow-x: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
}

.svc-table {
    width: 100%;
    min-width: 900px;
    border-collapse: collapse;
    font-size: 14px;
}

.svc-table th {
    padding: 14px 12px;
    border-bottom: 1px solid var(--border);
    color: var(--text-muted);
    font-weight: 600;
    text-align: left;
    white-space: nowrap;
}

.svc-empty td {
    padding: 40px 16px 48px;
    text-align: center;
}

.svc-empty .empty-illustration {
    max-width: 300px;
    margin-bottom: 22px;
}

.svc-empty p {
    margin: 0;
    font-weight: 500;
}

/* ============================================================================
   Icon buttons and the inline search field.
   ========================================================================= */

.btn-icon {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.btn-icon .icon {
    width: 16px;
    height: 16px;
}

/* The magnifier sits inside the field, so the search box reads as a search box
   before anyone reads its placeholder. */
.filter-search {
    position: relative;
    display: flex;
    align-items: center;
}

.filter-search input {
    width: 100%;
    padding-right: 60px;
}

.filter-search > .icon {
    position: absolute;
    right: 11px;
    width: 16px;
    height: 16px;
    color: var(--text-muted);
    pointer-events: none;
}

@media (max-width: 960px) {
    /* Breadcrumb on its own line, the actions filling the one below it. Buttons
       share that line rather than each taking it, so the two-button screens do
       not push the page down by a row apiece. */
    .page-header {
        flex-wrap: wrap;
    }

    .page-header .breadcrumb,
    .page-header-heading {
        flex-basis: 100%;
    }

    .page-header-actions {
        width: 100%;
        margin-left: 0;
    }

    .header-search {
        flex: 1 1 auto;
        width: auto;
    }

    .page-header-actions .btn-primary,
    .page-header-actions .btn-ghost {
        flex: 1 1 auto;
        justify-content: center;
    }

    /* A button that posts something sits in a form of its own; the form is the
       flex item, so it has to stretch and pass the width on. */
    .page-header-actions > form {
        display: flex;
        flex: 1 1 auto;
    }

    .page-header-tab-actions {
        flex: 1 1 auto;
    }

    :root {
        --grid-shell-mt: 14px;
        --grid-table-min-w: 700px;
    }
}

@media (max-width: 640px) {

    .data-table th,
    .data-table td {
        padding: 12px 14px;
    }

    .data-table thead th {
        font-size: 12px;
    }

    .data-table-shell .data-table {
        min-width: 640px;
    }

    .data-table-shell > .pager {
        padding-left: 14px;
        padding-right: 14px;
    }

    .data-table-shell > [data-live-pagination] {
        padding-left: 14px;
        padding-right: 14px;
    }
}

/* ============================================================================
   Desktop density tune.

   The shell and admin lists were comfortable only after browser zoom-out,
   which is a sign the desktop defaults are oversized. Tighten the shared
   desktop scale here so 100% browser zoom feels like the intended layout while
   keeping tablet and mobile untouched.
   ========================================================================= */

@media (min-width: 1100px) {
    :root {
        --radius: 9px;
        --topbar-h: 52px;
        /* Not as tight as the rest: below this the longest page name wraps. */
        --sidebar-w: 256px;
        --sidebar-rail: 60px;
    }

    body {
        font-size: 14px;
    }

    .icon {
        width: 18px;
        height: 18px;
    }

    .topbar {
        gap: 12px;
        padding: 0 12px;
    }

    .topbar-left,
    .topbar-right {
        gap: 6px;
    }

    .icon-btn {
        width: 34px;
        height: 34px;
        border-radius: 8px;
    }

    .brand {
        gap: 8px;
    }

    .brand-mark {
        width: 30px;
        height: 30px;
        font-size: 10px;
    }

    .search {
        margin-left: 8px;
    }

    .search .icon {
        left: 11px;
        width: 16px;
        height: 16px;
    }

    .search input {
        width: 270px;
        max-width: 24vw;
        padding: 8px 12px 8px 34px;        
        font-size: 13px;
    }

    .user-trigger {
        gap: 8px;
        padding: 4px 7px 4px 4px;
    }

    .sidebar {
        padding: 12px 8px;
    }

    .menu-group + .menu-group {
        margin-top: 4px;
        padding-top: 4px;
    }

    .menu-group-toggle {
        padding: 6px 8px;
        font-size: 12px;
    }

    .menu-group-icon .icon,
    .menu-item .icon {
        width: 16px;
        height: 16px;
    }

    .menu-item {
        gap: 10px;
        padding: 7px 12px 7px 14px;
        font-size: 13px;
    }

    /* 1px border + 8px padding + 16px icon + 8px gap = 33px. */
    .menu-items .menu-item {
        padding-left: 32px;
    }

    .menu-items .menu-section {
        padding-left: 27px;
    }

    .page h1 {
        font-size: 20px;
    }

    .muted {
        font-size: 13px;
    }

    .page-header {
        gap: 12px;
        padding: 12px 14px;
    }

    .page-header-title {
        font-size: 20px;
    }

    .breadcrumb {
        gap: 6px;
        font-size: 13px;
    }

    .page-toolbar {
        gap: 10px 14px;
        margin-bottom: 2px;
    }


    .panel h2 {
        font-size: 15px;
    }

    .flash-toast-region {
        width: calc(100vw - 24px);
    }

    .flash-toast-region-interactive {
        bottom: 16px;
    }

    .flash-toast-region-status {
        bottom: 16px;
    }

    .flash-toast {
        max-width: min(100%, 420px);
        font-size: 14px;
    }

    .data-table {
        margin-top: 12px;
        font-size: 13px;
    }

    .data-table th,
    .data-table td {
        padding: 8px 10px;
    }

    .data-table thead th {
        font-size: 11px;
    }

    .data-table code {
        font-size: 11px;
    }

    .tag,
.status {
        font-size: 11px;
    }

    .tag {
        padding: 1px 7px;
    }

    .status {
        padding: 2px 8px;
    }

    .btn-primary,
    .btn-ghost {
        padding: 9px 14px;
        font-size: 14px;
    }

    .btn-inline {
        padding: 7px 12px;
        font-size: 13px;
    }

    .form-card {
        margin-top: 12px;
        padding: 22px 24px;
    }

    .form-grid {
        gap: 16px 20px;
    }

    .form-field > label,
    .form-field > .form-label {
        margin-bottom: 6px;
        font-size: 13px;
    }

    .form-field input[type="text"],
    .form-field input[type="email"],
    .form-field input[type="password"],
    .form-field input[type="number"],
    .form-field select,
    .form-field textarea,
    .field input[type="text"],
    .field input[type="email"],
    .field input[type="password"],
    .field input[type="number"],
    .field select,
    .field textarea {
        font-size: 14px;
    }

    .form-field input[type="text"],
    .form-field input[type="email"],
    .form-field input[type="password"],
    .form-field input[type="number"],
    .form-field select,
    .form-field textarea {
        padding: 9px 12px;
    }

    .field input[type="text"],
    .field input[type="email"],
    .field input[type="password"],
    .field input[type="number"],
    .field select,
    .field textarea {
        padding: 8px 10px;
    }

    .filter-search input {
        padding-right: 54px;
    }

    .filter-search > .icon {
        right: 10px;
        width: 14px;
        height: 14px;
    }

    .pager {
        gap: 8px;
        padding: 10px 4px 2px;
    }

    .pager-count,
    .pager-position {
        font-size: 12px;
    }

    .pager-btn {
        width: 30px;
        height: 30px;
        font-size: 15px;
    }

    .empty-state {
        padding: 18px 20px;
        margin-bottom: 14px;
    }
}

@media (max-width: 1500px) and (min-width: 901px) {
    .search input {
        width: 240px;
        max-width: 22vw;
    }

    .user-role {
        display: none;
    }
}

@media (max-width: 1280px) and (min-width: 901px) {
    .user-name {
        max-width: 180px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}

/* ============================================================================
   Order detail.

   One catalogue order read back from its stored snapshot, laid out like a
   catalogue listing: for each piece its photo on the left and, stacked on the
   right, its price, what it is and its papers; then how the order was paid and
   its history. How far the order has come is in the page header.

   The page has an accent of its own, a jeweller's gold, held as tokens on the
   page so the dark theme can redefine it in one place. Everything else is the
   shared palette.

   Last in the sheet, and headings scoped under .od, so the density tune's
   `.panel h2` above does not resize them.
   ========================================================================= */

.order-detail-page {
    --od-gold: #b8862b;
    --od-gold-strong: #8a6118;
    --od-gold-soft: #fbf3e2;
    --od-gold-line: #ecdcbb;
    --od-cream: #fdf8ec;
    --od-ink: #0f1b33;
    --od-ink-hover: #050c1c;
    --od-ink-text: #ffffff;
    --od-on-gold: #ffffff;
}

:root[data-theme="dark"] .order-detail-page {
    --od-gold: #deb466;
    --od-gold-strong: #f0cd86;
    --od-gold-soft: #2b2416;
    --od-gold-line: #4a3d22;
    --od-cream: #241f15;
    --od-ink: #e6e9ee;
    --od-ink-hover: #ffffff;
    --od-ink-text: #111827;
    --od-on-gold: #1a1408;
}

/* The page's frame: the container its layout queries measure. The breakpoints
   further down are container queries on this, not media queries, so they
   measure the room the order actually has, after the sidebar.

   It is drawn at full size on every screen, the same type size as the rest of
   the application. It used to be scaled down on high-density laptop screens to
   fit a summary band and three cards abreast; with the items and one side
   column there is room without it. */
.od-frame {
    container: od / inline-size;
}

.od {
    display: grid;
    gap: 16px;
    padding: 18px;
}

.od-muted {
    color: var(--text-muted);
}

/* ---- masked customer details ----
   The rest of a name, email or phone is not in the page at all (see Masked);
   this blurs the fixed stand-in drawn where it would be. Used by the order list
   too. Not selectable, so a copy takes only what is shown. */

.masked-tail {
    display: inline-block;
    margin-left: 1px;
    filter: blur(4px);
    opacity: .75;
    user-select: none;
    pointer-events: none;
}

/* ---- pills ---- */

.od-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
}

.od-pill::before {
    content: "";
    flex: 0 0 auto;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}

.od-pill.is-ok {
    background: var(--ok-bg);
    color: var(--ok-text);
}

.od-pill.is-info {
    background: var(--info-bg);
    color: var(--info-text);
}

.od-pill.is-warn {
    background: var(--warn-bg);
    color: var(--warn-text);
}

.od-pill.is-bad {
    background: var(--error-bg);
    color: var(--error-text);
}

/* ---- progress strip ---- */

/* The progress strip, at the right-hand end of the page header: a dashed rule
   runs between the stage marks and turns gold up to the furthest stage reached. */
.od-steps {
    display: flex;
    margin: 0;
    padding: 0;
    list-style: none;
}

.od-step {
    position: relative;
    display: grid;
    justify-items: center;
    gap: 7px;
    min-width: 80px;
    color: var(--text-muted);
    font-size: 12.5px;
    text-align: center;
}

.od-step + .od-step::before {
    content: "";
    position: absolute;
    top: 21px;
    right: calc(50% + 26px);
    left: calc(-50% + 26px);
    border-top: 1.5px dashed var(--border);
}

.od-step.is-done + .od-step::before,
.od-step.is-done + .od-step.is-current::before,
.od-step.is-done + .od-step.is-done::before {
    border-top-color: var(--od-gold);
}

.od-step-icon {
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    border: 1.5px solid var(--border);
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-muted);
}

.od-step-icon .icon {
    width: 18px;
    height: 18px;
}

.od-step-label {
    padding: 3px 10px;
    border-radius: 999px;
    white-space: nowrap;
}

.od-step.is-done .od-step-icon {
    border-color: var(--od-gold-line);
    background: var(--od-gold-soft);
    color: var(--od-gold);
}

.od-step.is-done {
    color: var(--text);
}

.od-step.is-current .od-step-icon {
    border-color: var(--od-gold);
    background: var(--od-gold);
    color: var(--od-on-gold);
    box-shadow: 0 0 0 4px var(--od-gold-soft);
}

.od-step.is-current .od-step-label {
    background: var(--od-gold-soft);
    color: var(--od-gold-strong);
    font-weight: 700;
}

.od-step.is-bad .od-step-icon {
    border-color: var(--error-border);
    background: var(--error-bg);
    color: var(--error-text);
}

.od-step.is-bad .od-step-label {
    background: var(--error-bg);
    color: var(--error-text);
    font-weight: 700;
}

/* The strip is in the page header, outside the order's container, so these are
   media queries. Narrow, the header's actions take a row of their own and the
   stages spread across it; on a phone they come down a size to fit. */
@media (max-width: 960px) {
    .page-header .od-steps {
        width: 100%;
        justify-content: space-between;
    }

    .page-header .od-step {
        flex: 1 1 0;
        min-width: 0;
    }
}

@media (max-width: 640px) {
    .page-header .od-step {
        font-size: 11px;
    }

    .page-header .od-step-label {
        padding: 2px 6px;
    }

    .page-header .od-step-icon {
        width: 34px;
        height: 34px;
    }

    .page-header .od-step + .od-step::before {
        top: 17px;
        right: calc(50% + 21px);
        left: calc(-50% + 21px);
    }
}

/* ---- listing: one row per piece ---- */

/* The photo on the left, the cards that describe the piece stacked on the
   right. The photo column stretches to the height of the stack. */
.od-listing {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    align-items: stretch;
    gap: 14px;
}

.od-listing-photos {
    display: flex;
    flex-direction: column;
    gap: 14px;
    min-width: 0;
}

.od-listing-details {
    display: grid;
    align-content: start;   
    min-width: 0;
}

/* With more than one piece, a ruled line names each one: "Item 2 of 3". The
   space above it is extra to the page's gap, so pieces read as apart rather
   than as one long stack of cards. */
.od-item-divider {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 0;
    color: var(--text-muted);
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

.od-item-divider::before,
.od-item-divider::after {
    content: "";
    flex: 1 1 auto;
    border-top: 2px solid var(--border);
}

.od-item-divider::before {
    flex: 0 0 24px;
}

.od-listing + .od-item-divider {
    margin-top: 14px;
}

/* Payment and history, side by side under the pieces. */
.od-below {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
    gap: 14px;
}

/* ---- cards ----
   Flat white cards with a hairline edge: a check that turns green once the
   card has anything in it, then the title. */

.od-box {
    min-width: 0;
    padding: 18px 20px;    
    background: var(--surface);
}

.od-box-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 10px;
    margin: 0 0 14px;
}

.od-box-check {
    display: inline-flex;
    flex: 0 0 auto;
    color: var(--text-muted);
}

.od-box-check .icon {
    width: 18px;
    height: 18px;
}

.od-box-check.is-done {
    color: var(--ok-text);
}

.od .od-box-title {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
    line-height: 1.3;
}

.od-box-empty {
    margin: 0;
    color: var(--text-muted);
    font-size: 13.5px;
}

.od-empty {
    margin: 0;
    padding: 14px 16px;
    border: 1px dashed var(--border);
    border-radius: 6px;
    color: var(--text-muted);
    font-size: 13px;
}

/* Label and value pairs, two to a row: the label muted, the value beside it. */
.od-fields {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px 28px;
    margin: 0;
    font-size: 14px;
}

.od-fields > div {
    display: grid;
    grid-template-columns: minmax(0, 120px) minmax(0, 1fr);
    align-items: baseline;
    gap: 4px 12px;
    min-width: 0;
}

.od-fields dt {
    color: var(--text-muted);
}

.od-fields dd {
    margin: 0;
    color: var(--text);
    font-weight: 500;
    overflow-wrap: anywhere;
}

.od-fields dd s {
    margin-left: 6px;
    font-weight: 400;
}

/* ---- photo ---- */

.od-photo-box {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}

.od-photo {
    display: grid;
    place-items: center;
    flex: 1 1 auto;
    min-height: 240px;
    padding: 12px;
    border-radius: 6px;    
}

.od-photo img {
    display: block;
    width: 100%;
    max-width: 360px;
    max-height: 360px;
    object-fit: contain;
}

.od-photo.is-empty .icon {
    width: 56px;
    height: 56px;
    color: var(--text-muted);
    opacity: .6;
}

/* Where the piece has got to, at the far end of the piece's name. */
.od-photo-status {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 6px;
    margin-left: auto;
}

/* The badge carries an edge in its own colour, so it holds its shape on white. */
.od-photo-status .od-pill {
    border: 1px solid transparent;
    font-size: 13px;
}

.od-photo-status .od-pill.is-ok {
    border-color: var(--ok-border);
}

.od-photo-status .od-pill.is-bad {
    border-color: var(--error-border);
}

/* ---- returns ---- */

.od-return + .od-return {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}

.od-shipment-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    font-size: 14px;
}

.od-shipment-head .od-muted {
    margin-left: 4px;
    font-weight: 500;
}

/* A shipment's steps, top to bottom, each dot in the colour of what it means. */
.od-ministeps {
    display: grid;
    gap: 6px;
    margin: 12px 0 0;
    padding: 0;
    list-style: none;
    font-size: 12.5px;
}

.od-ministeps li {
    position: relative;
    display: flex;
    justify-content: space-between;
    gap: 10px;
    padding-left: 16px;
}

.od-ministeps li::before {
    content: "";
    position: absolute;
    top: 5px;
    left: 0;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--od-gold);
}

.od-ministeps li.is-ok::before {
    background: var(--ok-text);
}

.od-ministeps li.is-bad::before {
    background: var(--error-text);
}

.od-ministeps span {
    font-weight: 600;
}

.od-ministeps time {
    color: var(--text-muted);
    white-space: nowrap;
}

.od-pieces {
    display: grid;
    gap: 6px;
    margin: 12px 0 0;
    padding: 10px 12px;
    list-style: none;
    border-radius: 10px;
    background: var(--surface-2);
    font-size: 13px;
}

.od-pieces li {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 8px;
}

.od-piece-qty {
    color: var(--text-muted);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.od-piece-title {
    font-weight: 600;
}

.od-piece-detail {
    color: var(--text-muted);
    font-size: 12px;
}

.od-returns {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 16px;
}

.od-returns .od-return + .od-return {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

/* ---- activity timeline ---- */

.od-timeline {
    display: grid;
    margin: 0;
    padding: 0;
    list-style: none;
}

.od-timeline li {
    position: relative;
    display: grid;
    grid-template-columns: 20px minmax(0, 1fr) auto;
    gap: 2px 12px;
    padding: 0 0 18px;
    font-size: 13px;
}

.od-timeline li:last-child {
    padding-bottom: 0;
}

/* The rule joining one dot to the next. */
.od-timeline li:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 18px;
    bottom: 0;
    left: 9px;
    border-left: 1.5px solid var(--border);
}

.od-tl-dot {
    width: 14px;
    height: 14px;
    margin: 2px 0 0 3px;
    border: 3px solid var(--surface-2);
    border-radius: 50%;
    background: var(--text-muted);
    box-shadow: 0 0 0 1px var(--border);
}

.od-timeline li.is-accent .od-tl-dot {
    background: var(--od-gold);
    border-color: var(--od-gold-soft);
    box-shadow: 0 0 0 1px var(--od-gold-line);
}

.od-timeline li.is-ok .od-tl-dot {
    background: var(--ok-text);
    border-color: var(--ok-bg);
}

.od-timeline li.is-info .od-tl-dot {
    background: var(--info-text);
    border-color: var(--info-bg);
}

.od-timeline li.is-warn .od-tl-dot {
    background: var(--warn-text);
    border-color: var(--warn-bg);
}

.od-timeline li.is-bad .od-tl-dot {
    background: var(--error-text);
    border-color: var(--error-bg);
}

.od-tl-copy {
    display: grid;
    gap: 1px;
    min-width: 0;
}

.od-tl-copy .od-muted {
    font-size: 12px;
    overflow-wrap: anywhere;
}

.od-tl-time {
    color: var(--text-muted);
    font-size: 12.5px;
    white-space: nowrap;
}

/* ---- narrower screens ---- */

/* Too narrow for the photo beside its cards: the photo goes above them, and
   payment and history stack. */
@container od (max-width: 980px) {
    .od-listing,
    .od-below {
        grid-template-columns: minmax(0, 1fr);
    }

    .od-photo {
        min-height: 200px;
    }
}

/* A phone: one field to a row. */
@container od (max-width: 608px) {
    .od {
        gap: 14px;
        padding: 14px;
    }

    .od-box {
        padding: 16px;
    }

    .od-fields {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ---- print ----
   Printing prints the order, not the application around it: no chrome, and
   the cards in one column. */

@media print {
    .topbar,
    .sidebar,
    .app-footer,
    .page-header,
    .flash-toast-region {
        display: none !important;
    }

    .app-body .page {
        width: auto;
        margin: 0;
    }

    .od {
        padding: 0;
    }

    .od-listing,
    .od-below {
        grid-template-columns: minmax(0, 1fr);
    }

    .od-box {
        border-color: #d0d7e2;
        break-inside: avoid;
    }

    /* The header carries the order's number and its progress strip: print both,
       but not the breadcrumb. */
    .order-detail-page .page-header {
        display: block !important;
        padding: 0 0 12px;
        border: 0;
    }

    .order-detail-page .page-header .breadcrumb {
        display: none !important;
    }

    .order-detail-page .page-header .od-steps {
        margin-top: 12px;
    }
}

/* ============================================================================
   Returns Insights.

   Laid out like a seller portal's: the sales period and filters in a row of
   segmented controls, a strip for anything worth a look, the overview table
   with its slanted band of colour behind each metric, and the reasons. Flat:
   hairline borders and grey table heads, no shadows.
   ========================================================================= */

.returns-insights-page {
    --ri-band: #f7f4f0;
    --ri-head: #f1f3f6;
    --ri-line: var(--border);
}

:root[data-theme="dark"] .returns-insights-page {
    --ri-band: #1f2d45;
    --ri-head: #212734;
}

.ri {
    display: grid;
    gap: 22px;
    padding: 18px;
}

/* ---- period and filters ---- */

.ri-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 16px 28px;
}

.ri-filter {
    display: grid;
    gap: 6px;
    min-width: 0;
}

.ri-filter-end {
    margin-left: auto;
    justify-items: end;
}

.ri-filter-label {
    display: flex;
    align-items: center;
    gap: 4px;
    margin: 0;
    color: var(--text-muted);
    font-size: 12.5px;
}

.ri-filter-label .icon {
    width: 14px;
    height: 14px;
    color: var(--accent);
}

/* Buttons joined into one control, a hairline between each. */
.ri-seg {
    display: flex;
    flex-wrap: wrap;
    border: 1px solid var(--ri-line);
    border-radius: 6px;
    background: var(--surface);
}

.ri-seg > * + * {
    border-left: 1px solid var(--ri-line);
}

.ri-seg-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 40px;
    padding: 0 18px;
    color: var(--text);
    font-size: 14px;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    list-style: none;
}

.ri-seg-btn::-webkit-details-marker {
    display: none;
}

.ri-seg-btn .icon {
    width: 16px;
    height: 16px;
}

.ri-seg-btn:hover {
    background: var(--surface-2);
}

.ri-seg-btn.is-active {
    background: var(--accent-soft);
    color: var(--accent-strong);
    font-weight: 600;
}

.ri-seg-icon {
    padding: 0 14px;
    color: var(--text-muted);
    cursor: default;
}

.ri-seg-icon:hover {
    background: transparent;
}

/* A dropdown that opens without script: a details element and its panel. */
.ri-drop {
    position: relative;
}

.ri-drop[open] > summary .icon {
    transform: rotate(180deg);
}

.ri-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 20;
    display: grid;
    min-width: 200px;
    max-height: 320px;
    overflow-y: auto;
    padding: 6px;
    border: 1px solid var(--ri-line);
    border-radius: 8px;
    background: var(--surface);
    box-shadow: var(--shadow);
}

.ri-menu-item {
    padding: 8px 12px;
    border-radius: 6px;
    color: var(--text);
    font-size: 14px;
    text-decoration: none;
}

.ri-menu-item:hover {
    background: var(--surface-2);
}

.ri-menu-item.is-active {
    background: var(--accent-soft);
    color: var(--accent-strong);
    font-weight: 600;
}

.ri-dates {
    gap: 10px;
    padding: 12px;
}

.ri-dates label {
    display: grid;
    gap: 4px;
    color: var(--text-muted);
    font-size: 12.5px;
}

.ri-dates input {
    min-height: 36px;
    padding: 0 10px;
    border: 1px solid var(--ri-line);
    border-radius: 6px;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: 14px;
}

.ri-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 38px;
    padding: 0 18px;
    border: 1px solid var(--accent);
    border-radius: 6px;
    background: var(--accent);
    color: #ffffff;
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
}

.ri-btn:hover {
    border-color: var(--accent-strong);
    background: var(--accent-strong);
}

.ri-btn-outline {
    background: var(--surface);
    color: var(--accent);
}

.ri-btn-outline:hover {
    background: var(--accent-soft);
    color: var(--accent-strong);
}

/* ---- worth a look ---- */

.ri-insights {
    display: flex;
    align-items: center;
    gap: 20px;
}

.ri-art {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 76px;
    height: 76px;
    border-radius: 50%;
    background: radial-gradient(circle at 30% 30%, var(--ok-bg), var(--accent-soft));
    color: var(--ok-text);
}

.ri-art .icon {
    width: 32px;
    height: 32px;
}

.ri-insights-copy h2 {
    margin: 0 0 4px;
    font-size: 20px;
    font-weight: 600;
}

.ri-insights-copy p {
    margin: 0;
    color: var(--text);
    font-size: 14px;
}

.ri-insight-list {
    display: grid;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 14px;
}

.ri-insight-list li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.ri-insight-list .icon {
    width: 17px;
    height: 17px;
    color: var(--warn-text);
}

.ri-insight-list a {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
}

/* ---- overview and reasons ---- */

.ri-section {
    display: grid;
    gap: 12px;
}

.ri-section-title {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    font-size: 17px;
    font-weight: 600;
}

.ri-section-title .icon {
    width: 20px;
    height: 20px;
}

.ri-subtitle {
    margin: 0;
    color: var(--text);
    font-size: 15px;
    font-weight: 500;
}

.ri-note {
    margin: 0;
    color: var(--text-muted);
    font-size: 13.5px;
}

.ri-tabs {
    display: inline-flex;
    justify-self: start;
    border: 1px solid var(--ri-line);
    border-radius: 6px;
    overflow: hidden;
}

.ri-tab {
    padding: 8px 16px;
    color: var(--text);
    font-size: 14px;
    text-decoration: none;
}

.ri-tab + .ri-tab {
    border-left: 1px solid var(--ri-line);
}

.ri-tab.is-active {
    background: var(--accent-soft);
    color: var(--accent-strong);
}

.ri-table-wrap {
    min-width: 0;
    overflow-x: auto;
    border: 1px solid var(--ri-line);
    background: var(--surface);
}

.ri-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

.ri-table th,
.ri-table td {
    padding: 14px 16px;
    border-bottom: 1px solid var(--ri-line);
    text-align: left;
    vertical-align: middle;
    font-weight: 400;
}

.ri-table thead th {
    background: var(--ri-head);
    color: var(--text);
    font-size: 13.5px;
}

.ri-table tbody tr:last-child > * {
    border-bottom: 0;
}

.ri-table tbody th {
    color: var(--text);
}

.ri-table .ri-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.ri-table .ri-empty {
    color: var(--text-muted);
    text-align: center;
}

/* The summary: the figure's icon in a cell of its own, then a band of colour
   slanting off behind its name, its counts and rate in columns, and a ruled
   line before what changed. No minimum width: the tables fit the column they
   are in, the name and the sentence wrapping, rather than scrolling sideways. */

.ri-table .ri-period-head {
    text-align: center;
}

.ri-table .ri-divide {
    border-left: 1px solid var(--ri-line);
}

.ri-summary tbody td,
.ri-summary tbody th,
.ri-trend-metrics tbody td,
.ri-trend-metrics tbody th {
    height: 90px;
}

.ri-table .ri-icon-cell {
    width: 56px;
    padding: 0 6px 0 16px;
    color: var(--text-muted);
}

.ri-icon-cell .icon {
    display: block;
    width: 24px;
    height: 24px;
}

.ri-table .ri-metric {
    padding-left: 16px;
    background: linear-gradient(100deg, var(--ri-band) 0 82%, transparent 82%);
}

.ri-metric-name {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
}

.ri-metric-name strong {
    font-size: 15px;
    font-weight: 600;
}

.ri-metric > small {
    display: block;
    margin-top: 4px;
    color: var(--text-muted);
    font-size: 13.5px;
}

.ri-info {
    display: inline-flex;
    color: var(--accent);
    cursor: help;
}

.ri-info .icon {
    width: 16px;
    height: 16px;
}

.ri-ongoing {
    padding: 2px 8px;
    border-radius: 3px;
    background: #5a6472;
    color: #ffffff;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
}

.ri-table .ri-count,
.ri-table .ri-rate {
    width: 1%;
    padding-left: 14px;
    padding-right: 14px;
    text-align: center;
    white-space: nowrap;
}

.ri-value {
    display: inline-grid;
    justify-items: center;
    gap: 6px;
}

.ri-value strong {
    color: var(--accent-strong);
    font-size: 16px;
    font-weight: 700;
}

.ri-value small {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text-muted);
    font-size: 13.5px;
}

.ri-table .ri-change {
    color: var(--text-muted);
    font-size: 14px;
}

.ri-change strong {
    margin-right: 4px;
    font-weight: 600;
}

.ri-change strong.is-good {
    color: var(--ok-text);
}

.ri-change strong.is-bad {
    color: var(--error-text);
}

.ri-change strong.is-flat {
    color: var(--text);
}

.ri-table .ri-spark-head {
    text-align: center;
}

.ri-table .ri-spark {
    width: 22%;
}

.ri-sparkline {
    display: block;
    width: 100%;
    max-width: 220px;
    height: 40px;
    margin: 0 auto;
}

/* Beside the Trend chart the figures have a narrower column: tighter cells. */
.ri-trend-metrics th,
.ri-trend-metrics td {
    padding-left: 10px;
    padding-right: 10px;
}

.ri-trend-metrics .ri-icon-cell {
    width: 40px;
    padding: 0 2px 0 12px;
}

/* Too narrow for a trend line beside the sentence: the line goes, the
   Trend tab still draws it in full. */
@media (max-width: 900px) {
    .ri-table .ri-spark,
    .ri-table .ri-spark-head {
        display: none;
    }
}

.ri-sparkline polyline {
    fill: none;
    stroke: var(--accent);
    stroke-width: 1.6;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

.ri-reasons-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

/* Reasons and sub-reasons side by side, one under the other when narrow. */
.ri-reason-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.ri-reason-grid > .ri-table-wrap + .ri-table-wrap {
    border-left: 0;
}

@media (max-width: 1100px) {
    .ri-reason-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .ri-reason-grid > .ri-table-wrap + .ri-table-wrap {
        border-top: 0;
        border-left: 1px solid var(--ri-line);
    }
}

@media (max-width: 640px) {
    .ri {
        padding: 14px;
    }

    .ri-filter-end {
        margin-left: 0;
        justify-items: start;
    }

    .ri-insights {
        align-items: flex-start;
    }

    .ri-art {
        width: 56px;
        height: 56px;
    }
}

/* The tab not open. Both are in the page; returns-insights.js switches them,
   and .ri-trend's grid would otherwise override the hidden attribute. */
[data-ri-panel][hidden] {
    display: none;
}

/* ---- trend: the figures, and a chart of one of them ---- */

.ri-trend {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    align-items: start;
    gap: 28px;
}

.ri-chart {
    position: relative;
    min-width: 0;
    border: 1px solid var(--ri-line);
    background: var(--surface);
}

/* The radio buttons themselves are out of sight; their labels are drawn as the
   buttons, and which one is checked decides which chart shows. They stay
   focusable, so the arrow keys move between the figures. */
.ri-series-input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.ri-chart-head {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px 48px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--ri-line);
    background: var(--ri-head);
}

.ri-series-option {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    color: var(--text);
    font-size: 14px;
    cursor: pointer;
}

.ri-series-option::before {
    content: "";
    box-sizing: border-box;
    width: 18px;
    height: 18px;
    border: 2px solid var(--border);
    border-radius: 50%;
    background: var(--surface);
}

/* The options are numbered by position, so any three figures can be charted. */
#ri-series-0:checked ~ .ri-chart-head [for="ri-series-0"]::before,
#ri-series-1:checked ~ .ri-chart-head [for="ri-series-1"]::before,
#ri-series-2:checked ~ .ri-chart-head [for="ri-series-2"]::before {
    border-color: var(--accent);
    background: radial-gradient(circle, var(--accent) 0 38%, var(--surface) 44%);
}

#ri-series-0:focus-visible ~ .ri-chart-head [for="ri-series-0"],
#ri-series-1:focus-visible ~ .ri-chart-head [for="ri-series-1"],
#ri-series-2:focus-visible ~ .ri-chart-head [for="ri-series-2"] {
    outline: 2px solid var(--accent);
    outline-offset: 4px;
    border-radius: 4px;
}

.ri-chart-body {
    padding: 12px 16px 8px;
}

.ri-chart-svg {
    display: none;
    width: 100%;
    height: auto;
}

#ri-series-0:checked ~ .ri-chart-body .is-series-0,
#ri-series-1:checked ~ .ri-chart-body .is-series-1,
#ri-series-2:checked ~ .ri-chart-body .is-series-2 {
    display: block;
}

.ri-grid line {
    stroke: var(--border);
    stroke-dasharray: 4 4;
}

.ri-axis,
.ri-ticks line {
    stroke: var(--text-muted);
    stroke-width: 1;
}

/* In the chart's own units: the SVG scales with its column, so these come out
   at about 12 to 16 pixels across the usual laptop and desktop widths. */
.ri-axis-labels text {
    fill: var(--text-muted);
    font-family: inherit;
    font-size: 19px;
}

.ri-chart-line {
    fill: none;
    stroke: var(--accent);
    stroke-width: 2.5;
    stroke-linejoin: round;
    stroke-linecap: round;
}

@media (max-width: 1100px) {
    .ri-trend {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ---- custom dates: a two-month calendar (date-range.js) ----
   Once the script has drawn the calendar, the date inputs and their Apply
   button give way to it; it fills the inputs in, and Done submits them. */

.ri-dates.is-calendar {
    width: max-content;
    max-width: calc(100vw - 32px);
    max-height: none;
    overflow: visible;
    padding: 16px 20px 12px;
    border-radius: 16px;
}

.ri-dates.is-calendar > label,
.ri-dates.is-calendar > .ri-btn {
    display: none;
}

.ri-cal {
    position: relative;
}

.ri-cal-head {
    position: absolute;
    top: -2px;
    right: 0;
    display: flex;
    gap: 4px;
}

.ri-cal-nav {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--text);
    cursor: pointer;
}

.ri-cal-nav:hover:not(:disabled) {
    background: var(--surface-2);
}

.ri-cal-nav:disabled {
    opacity: .3;
    cursor: default;
}

.ri-cal-nav .icon {
    width: 18px;
    height: 18px;
}

.ri-cal-months {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 32px;
}

.ri-cal-month {
    display: grid;
    grid-template-columns: repeat(7, 40px);
    row-gap: 4px;
}

.ri-cal-title {
    grid-column: 1 / -1;
    margin: 4px 0 12px;
    color: var(--text-muted);
    font-size: 15px;
    font-weight: 600;
}

.ri-cal-wd {
    padding: 4px 0 8px;
    color: var(--accent);
    font-size: 13px;
    font-weight: 700;
    text-align: center;
}

.ri-cal-wd.is-weekend {
    color: var(--error-text);
}

.ri-cal-day {
    display: grid;
    place-items: center;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--text);
    font: inherit;
    font-size: 14px;
    cursor: pointer;
}

.ri-cal-day:hover:not(:disabled):not(.is-start):not(.is-end) {
    background: var(--surface-2);
}

/* The neighbouring months' days, and days still to come: shown, not pickable. */
.ri-cal-day.is-other,
.ri-cal-day:disabled {
    color: var(--border);
    cursor: default;
}

.ri-cal-day.is-in-range {
    border-radius: 0;
    background: var(--accent-soft);
    color: var(--accent-strong);
}

.ri-cal-day.is-start,
.ri-cal-day.is-end {
    background: var(--accent);
    color: #ffffff;
    font-weight: 600;
}

.ri-cal-day:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

.ri-cal-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-top: 10px;
}

.ri-cal-range {
    color: var(--text-muted);
    font-size: 13px;
}

.ri-cal-done {
    padding: 6px 4px;
    border: 0;
    background: none;
    color: var(--accent);
    font: inherit;
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
}

.ri-cal-done:disabled {
    opacity: .4;
    cursor: default;
}

@media (max-width: 640px) {
    .ri-cal-month {
        grid-template-columns: repeat(7, 36px);
    }

    .ri-cal-day {
        height: 36px;
    }
}

/* ---- reason wise breakup ----
   The reasons tables, on Returns Insights (top five) and on their own page
   (every one, in tall panels however few the rows). */

.ri-reason-block {
    display: grid;
    gap: 12px;
}

.ri-table thead .ri-info {
    margin-left: 4px;
    vertical-align: -3px;
}

.ri-table .ri-yay {
    color: var(--ok-text);
    font-size: 15px;
}

.ri-reason-grid.is-full > .ri-table-wrap {
    min-height: 460px;
}

.ri-reason-grid.is-full .ri-yay {
    height: 380px;
}

/* ---- Cancellation Insights: its tabs along the top, the units card ---- */

.ri-page-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 28px;
    margin-top: -6px;
    border-bottom: 1px solid var(--ri-line);
}

.ri-page-tab {
    margin-bottom: -1px;
    padding: 10px 2px 11px;
    border-bottom: 3px solid transparent;
    color: var(--text-muted);
    font-size: 15px;
    font-weight: 500;
    text-decoration: none;
}

.ri-page-tab:hover {
    color: var(--text);
}

.ri-page-tab.is-active {
    border-bottom-color: var(--accent);
    color: var(--accent-strong);
}

.ri-units {
    display: inline-flex;
    flex-wrap: wrap;
    justify-self: start;
    max-width: 100%;
    margin: 0;
    border: 1px solid var(--ri-line);
    border-radius: 6px;
    background: var(--surface);
}

.ri-units > div {
    display: grid;
    gap: 4px;
    padding: 12px 22px;
}

.ri-units > div + div {
    border-left: 1px solid var(--ri-line);
}

.ri-units dt {
    color: var(--text-muted);
    font-size: 13px;
}

.ri-units dd {
    margin: 0;
    color: var(--text);
    font-size: 16px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.ri-table .ri-tall {
    height: 220px;
}

.ri-shipments .od-pill {
    white-space: nowrap;
}

.ri-shipments a {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
}

.ri-shipments a:hover {
    text-decoration: underline;
}

/* ---- Cancellation Insights: the breakdown by product, category, collection ---- */

.ri-bd-tabs {
    margin-top: 8px;
}

.ri-bd-tabs .ri-page-tab {
    border-top: 0;
    border-right: 0;
    border-left: 0;
    background: none;
    font: inherit;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
}

.ri-bd-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px 24px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--ri-line);
}

.ri-bd-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.ri-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 32px;
    padding: 0 14px;
    border: 1px solid var(--ri-line);
    border-radius: 999px;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
}

.ri-chip:hover {
    border-color: var(--accent);
}

.ri-chip .icon {
    display: none;
    width: 15px;
    height: 15px;
}

.ri-chip.is-active {
    border-color: transparent;
    background: var(--accent-soft);
    color: var(--accent-strong);
}

.ri-chip.is-active .icon {
    display: inline-block;
}

.ri-bd-search {
    position: relative;
    display: block;
    width: 280px;
    max-width: 100%;
    margin-left: auto;
}

.ri-bd-search input {
    width: 100%;
    min-height: 36px;
    padding: 0 34px 0 12px;
    border: 1px solid var(--ri-line);
    border-radius: 4px;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: 13px;
}

.ri-bd-search input:focus {
    border-color: var(--accent);
    outline: none;
}

.ri-bd-search .icon {
    position: absolute;
    top: 50%;
    right: 10px;
    width: 17px;
    height: 17px;
    color: var(--text-muted);
    transform: translateY(-50%);
    pointer-events: none;
}

/* The Actions menus open out of the table, so it does not clip them; it fits
   its column, the headings wrapping, rather than scrolling sideways. */
.ri-bd-wrap {
    overflow: visible;
}

.ri-bd-table thead th {
    font-size: 13px;
    vertical-align: middle;
}

.ri-bd-table th,
.ri-bd-table td {
    padding: 12px 14px;
}

.ri-sort {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: right;
    cursor: pointer;
}

.ri-sort .icon {
    flex: none;
    width: 15px;
    height: 15px;
}

.ri-sort .icon path {
    opacity: .35;
}

.ri-sort.is-desc .icon-sort-down,
.ri-sort.is-asc .icon-sort-up {
    opacity: 1;
}

/* Whole words: the product column takes the room its longest word needs. */
.ri-bd-table tbody th {
    min-width: 130px;
}

.ri-bd-name {
    display: block;
    font-weight: 500;
    overflow-wrap: break-word;
}

.ri-bd-sku {
    display: block;
    margin-top: 2px;
    color: var(--text-muted);
    font-size: 12.5px;
    overflow-wrap: break-word;
}

.ri-bd-table .ri-bd-actions-head,
.ri-bd-table .ri-bd-actions {
    text-align: center;
}

.ri-bd-drop {
    display: inline-block;
}

.ri-bd-view {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--accent);
    font-size: 13.5px;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    list-style: none;
}

.ri-bd-view::-webkit-details-marker {
    display: none;
}

.ri-bd-view .icon {
    width: 15px;
    height: 15px;
}

.ri-bd-menu {
    right: 0;
    left: auto;
    min-width: 250px;
    text-align: left;
}

.ri-bd-order {
    display: grid;
    gap: 1px;
}

.ri-bd-order-no {
    color: var(--accent);
    font-weight: 600;
}

.ri-bd-order small {
    color: var(--text-muted);
    font-size: 12.5px;
}

.ri-bd-more {
    margin: 4px 12px 6px;
    color: var(--text-muted);
    font-size: 12.5px;
}

.ri-bd-none {
    color: var(--text-muted);
}

.ri-table .ri-bd-empty {
    padding: 18px 16px;
}

/* The app's pager, at the foot of the table, driven in place by the script. */
.ri-bd-wrap > .ri-bd-pager {
    margin: 0;
    padding: 10px 16px;
    border-top: 1px solid var(--ri-line);
    background: var(--surface);
}

.ri-bd-pager .pager-count {
    font-size: 13.5px;
}

.ri-bd-pager .pager-btn {
    padding: 0;
    font-family: inherit;
    cursor: pointer;
}

.ri-bd-pager .ri-bd-all {
    min-height: 34px;
    padding: 0 14px;
    font-size: 13px;
}

@media (max-width: 1200px) {
    .ri-bd-table th,
    .ri-bd-table td {
        padding: 12px 8px;
    }
}

@media (max-width: 720px) {
    .ri-bd-wrap {
        overflow-x: auto;
    }

    .ri-bd-search {
        width: 100%;
    }
}

/* Cancellation Insights' overview tab: its sections stay items of the page's
   grid, spaced like the rest, while the tab can be hidden as one. */
.ri-page-panel {
    display: contents;
}

/* A new period or category on its way (insights-live.js): the figures dim
   under a thin running bar at the top; the filters stay as they are. */
.ri {
    position: relative;
}

.ri.is-loading > :not(.ri-filters):not(.ri-page-tabs),
.ri.is-loading > .ri-page-panel > * {
    opacity: .45;
    pointer-events: none;
    transition: opacity .15s ease;
}

.ri.is-loading::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    z-index: 5;
    width: 30%;
    height: 3px;
    border-radius: 3px;
    background: var(--accent);
    animation: ri-loading 1s ease-in-out infinite;
}

@keyframes ri-loading {
    from {
        left: 0;
    }

    to {
        left: 70%;
    }
}

@media (prefers-reduced-motion: reduce) {
    .ri.is-loading::before {
        width: 100%;
        animation: none;
    }
}

/* ============================================================================
   Payments Overview.

   Laid out like a seller portal's, across the full width: the figures in four
   equal bordered cards, each with its split pinned along the foot so the row
   lines up, then Previous Payments in a panel of its own, a chip for each
   recent day over a table that spans the panel. Flat, like the insights
   screens. The cards fall to two a row, then one, as the screen narrows.
   ========================================================================= */

.pay {
    display: grid;
    gap: 28px;
    padding: 18px;
}

.pay-section {
    display: grid;
    gap: 14px;
    min-width: 0;
}

.pay-section-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 14px;
}

.pay-section-title {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    font-size: 17px;
    font-weight: 600;
}

.pay-section-title .icon {
    width: 20px;
    height: 20px;
}

.pay-cards {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px;
}

.pay-card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
    padding: 16px 18px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
}

.pay-card-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 4px 10px;
}

.pay-card-title {
    margin: 0;
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 500;
}

.pay-card-when {
    color: var(--accent-strong);
    font-size: 12.5px;
    font-weight: 500;
    white-space: nowrap;
}

.pay-card-total {
    margin: 0 0 4px;
    color: var(--text);
    font-size: 22px;
    font-weight: 600;
    line-height: 1.3;
    font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
}

/* The split, or the note, sits along the foot of every card alike. */
.pay-card-foot {
    margin: auto 0 0;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}

.pay-card-split {
    display: flex;
    justify-content: space-between;
    gap: 12px;
}

.pay-card-split > div {
    min-width: 0;
}

.pay-card-split > div:last-child {
    text-align: right;
}

.pay-card-split dt {
    color: var(--text-muted);
    font-size: 12.5px;
}

.pay-card-split dd {
    margin: 2px 0 0;
    font-size: 13.5px;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
}

.pay-card-note {
    color: var(--text-muted);
    font-size: 13px;
}

.pay-see-all {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    color: var(--accent);
    font-size: 13.5px;
    font-weight: 600;
    text-decoration: none;
}

.pay-see-all:hover {
    text-decoration: underline;
}

.pay-see-all .icon {
    width: 15px;
    height: 15px;
}

.pay-panel {
    display: grid;
    gap: 16px;
    min-width: 0;
    padding: 18px 20px 8px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
}

.pay-day-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.pay-day {
    display: grid;
    gap: 12px;
    min-width: 0;
}

.pay-day-summary {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    margin: 0;
    color: var(--ok-text);
    font-size: 13.5px;
}

.pay-day-summary .icon {
    width: 16px;
    height: 16px;
}

.pay-table-wrap {
    min-width: 0;
    overflow-x: auto;
}

.pay-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

.pay-table th,
.pay-table td {
    padding: 13px 14px;
    border-bottom: 1px solid var(--border);
    font-weight: 400;
    text-align: left;
    vertical-align: top;
}

.pay-table thead th {
    padding-top: 10px;
    padding-bottom: 10px;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 500;
}

.pay-table thead th:first-child,
.pay-table thead th:nth-child(2) {
    width: 22%;
}

.pay-table tbody th {
    font-weight: 600;
}

.pay-table .pay-num,
.pay-settlements .pay-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.pay-table tr.is-total > * {
    border-bottom: 0;
    font-weight: 600;
}

.pay-type {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.pay-info {
    display: inline-flex;
    color: var(--text-muted);
}

.pay-info .icon {
    width: 15px;
    height: 15px;
}

.pay-line {
    display: block;
}

.pay-line + .pay-line {
    margin-top: 6px;
}

.pay-settlements .pay-net {
    font-weight: 600;
}

@media (max-width: 1100px) {
    .pay-cards {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 600px) {
    .pay {
        padding: 16px 0;
    }

    .pay-cards {
        grid-template-columns: minmax(0, 1fr);
    }

    .pay-panel {
        padding: 14px 14px 6px;
    }
}

/* ============================================================================
   Earnings Summary.

   Built on Returns Insights' parts -- the tabs along the top, the segmented
   controls, the dropdowns and the calendar, the tables -- with Payments
   Overview's cards. Its own: the toolbar holding the SKU search, the period,
   the views and the download in one row; the charts; the guide; and the
   picture shown while there is nothing to show.

   The charts are SVG sized by attribute, not by style: the page's
   Content-Security-Policy allows no inline style, so a bar's height cannot be
   set in one. A light bar is a sale amount, the dark bar over it what of it
   was kept.
   ========================================================================= */

.earnings-page {
    --es-sale: #e4dace;
    --es-net: var(--accent);
    --es-cat: #4f5157;
}

:root[data-theme="dark"] .earnings-page {
    --es-sale: #2e3f5c;
    --es-cat: #a3abb9;
}

/* ---- toolbar ---- */

.es-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 16px 28px;
}

.es-search {
    display: grid;
    gap: 6px;
}

.es-search-box {
    position: relative;
    display: block;
    width: 300px;
    max-width: 100%;
}

.es-search-box input {
    width: 100%;
    min-height: 42px;
    padding: 0 42px 0 14px;
    border: 1px solid var(--ri-line);
    border-radius: 4px;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: 14px;
}

.es-search-box input:focus {
    border-color: var(--accent);
    outline: none;
}

.es-search-box button {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    display: grid;
    place-items: center;
    width: 42px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
}

.es-search-box button:hover {
    color: var(--accent);
}

.es-search-box .icon {
    width: 18px;
    height: 18px;
}

.es-period .ri-seg-btn,
.es-views .ri-seg-btn {
    min-height: 42px;
}

/* The days the period covers, beside the month or Custom Dates. */
.es-chip {
    padding: 1px 8px;
    border-radius: 4px;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 12.5px;
    font-weight: 500;
}

.ri-seg-btn.is-active .es-chip {
    background: var(--surface);
}

.es-views {
    overflow: hidden;
}

.es-download {
    gap: 6px;
    min-height: 42px;
    margin-left: auto;
}

.es-download .icon {
    width: 17px;
    height: 17px;
}

/* A new period or SKU on its way (insights-live.js): the controls stay lit. */
.ri.es.is-loading > .es-toolbar {
    opacity: 1;
    pointer-events: auto;
}

/* ---- the guide, from the page header ---- */

.es-learn-btn {
    gap: 8px;
    list-style: none;
}

.es-learn-btn::-webkit-details-marker {
    display: none;
}

.es-learn-btn .icon {
    width: 16px;
    height: 16px;
}

.es-learn[open] > summary .icon {
    transform: none;
}

.es-learn-panel {
    right: 0;
    left: auto;
    gap: 12px;
    width: 440px;
    max-width: calc(100vw - 32px);
    max-height: min(80vh, 720px);
    padding: 18px 20px;
    color: var(--text);
    font-size: 14px;
}

.es-learn-panel h2 {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
}

.es-learn-panel ol {
    display: grid;
    gap: 6px;
    margin: 0;
    padding-left: 20px;
}

.es-learn-panel dl {
    display: grid;
    gap: 6px;
    margin: 0;
    padding-top: 12px;
    border-top: 1px solid var(--ri-line);
}

.es-learn-panel dt {
    font-weight: 600;
}

.es-learn-panel dd {
    margin: 0;
    color: var(--text-muted);
}

.es-learn-foot {
    margin: 0;
    color: var(--text-muted);
    font-size: 13px;
}

/* ---- panels, cards and tables ---- */

.es-panel {
    display: grid;
    gap: 18px;
    min-width: 0;
}

/* Three deductions, one to a line: side by side, a large amount would break
   mid-number. */
.es-card-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 4px;
}

.es-card-split > div {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.es-card-split dd {
    margin: 0;
    overflow-wrap: normal;
    text-align: right;
}

.es-card-net {
    border-color: var(--accent);
}

.es-table th,
.es-table td {
    white-space: nowrap;
}

.es-table tfoot th,
.es-table tfoot td {
    border-top: 1px solid var(--ri-line);
    border-bottom: 0;
    background: var(--ri-head);
    font-weight: 600;
}

.ri-table .es-minus {
    color: var(--text-muted);
}

.ri-table .es-net {
    font-weight: 600;
}

.es-product {
    display: flex;
    align-items: center;
    gap: 14px;
}

.es-product-art {
    display: grid;
    place-items: center;
    flex: none;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent-strong);
}

.es-product-art .icon {
    width: 24px;
    height: 24px;
}

.es-product-title {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
}

.es-product-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 2px 0;
    margin: 2px 0 0;
    color: var(--text-muted);
    font-size: 13.5px;
}

.es-product-meta > span + span::before {
    content: "·";
    margin: 0 8px;
}

.es-choose {
    display: grid;
    gap: 14px;
    padding: 20px;
    border: 1px solid var(--ri-line);
    background: var(--surface);
}

.es-choose p {
    margin: 0;
}

.es-choices {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.es-choices a {
    text-decoration: none;
}

/* ---- charts ---- */

.es-chart {
    display: grid;
    gap: 16px;
    min-width: 0;
    margin: 0;
    padding: 16px 18px 18px;
    border: 1px solid var(--ri-line);
    background: var(--surface);
}

.es-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 24px;
    color: var(--text);
    font-size: 13.5px;
}

.es-key {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.es-key::before {
    content: "";
    width: 14px;
    height: 14px;
    border-radius: 3px;
    background: var(--es-sale);
}

.es-key.is-net::before {
    background: var(--es-net);
}

.es-legend-note {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 12.5px;
}

.es-chart-empty {
    margin: 0;
    padding: 40px 0;
    color: var(--text-muted);
    text-align: center;
}

.es-rect-sale {
    fill: var(--es-sale);
}

.es-rect-net {
    fill: var(--es-net);
}

/* Columns over time: the scale down the left, a column for every day or week,
   and dates under every few. The scale is in quarters, so its labels are
   spread evenly against gridlines a quarter of the plot apart. */
.es-columns {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: 240px auto;
    column-gap: 10px;
}

.es-yaxis {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    margin: -8px 0;
    color: var(--text-muted);
    font-size: 12px;
    line-height: 16px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.es-plot {
    display: flex;
    min-width: 0;
    border-bottom: 1px solid var(--text-muted);
    background: repeating-linear-gradient(to top,
            transparent 0, transparent calc(25% - 1px),
            var(--border) calc(25% - 1px), var(--border) 25%);
}

.es-col {
    display: flex;
    justify-content: center;
    flex: 1 1 0;
    min-width: 0;
}

.es-col:hover {
    background: var(--surface-2);
}

.es-col svg {
    display: block;
    width: 100%;
    max-width: 56px;
    height: 100%;
}

.es-xaxis {
    grid-column: 2;
    display: flex;
    padding-top: 8px;
    color: var(--text-muted);
    font-size: 12px;
}

/* A date wider than its column spills evenly either side of it. */
.es-xaxis > span {
    display: flex;
    justify-content: center;
    flex: 1 1 0;
    min-width: 0;
    white-space: nowrap;
}

/* Bars by vertical or brand: the name, the bar, and what it came to. */
.es-bars {
    display: grid;
    gap: 12px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.es-bar-row {
    display: grid;
    grid-template-columns: minmax(90px, 200px) minmax(0, 1fr) auto;
    align-items: center;
    gap: 14px;
    font-size: 14px;
}

.es-bar-label {
    overflow: hidden;
    font-weight: 500;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.es-bar-track {
    display: block;
    width: 100%;
    height: 22px;
    border-radius: 3px;
    background: var(--surface-2);
}

.es-bar-value {
    min-width: 170px;
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}

.es-bar-value small {
    color: var(--text-muted);
    font-size: 12.5px;
}

/* ---- nothing to show ---- */

.es-nothing {
    display: grid;
    justify-items: center;
    gap: 8px;
    padding: 32px 16px 48px;
    text-align: center;
}

.es-art {
    width: 300px;
    max-width: 80%;
    height: auto;
}

.es-nothing-text {
    margin: 18px 0 0;
    color: var(--text);
    font-size: 17px;
    font-weight: 600;
}

.es-nothing-hint {
    margin: 0;
    color: var(--text-muted);
    font-size: 14px;
}

.es-art-blob {
    fill: var(--info-bg);
}

.es-art-frame {
    fill: var(--surface);
    stroke: var(--border);
    stroke-width: 3;
}

.es-art-pane {
    fill: var(--surface-2);
}

.es-art-mullion {
    fill: none;
    stroke: var(--border);
    stroke-width: 3;
}

.es-art-light {
    fill: var(--border);
}

.es-art-floor {
    fill: none;
    stroke: var(--border);
    stroke-width: 2;
    stroke-linecap: round;
}

.es-art-pot {
    fill: var(--info-border);
}

.es-art-leaf {
    fill: #5fb98a;
}

.es-art-leaf.is-pale {
    fill: #a6dcbf;
}

.es-art-cat {
    fill: var(--es-cat);
}

.es-art-tail {
    fill: none;
    stroke: var(--es-cat);
    stroke-width: 5;
    stroke-linecap: round;
}

@media (max-width: 720px) {
    .es-toolbar {
        align-items: stretch;
    }

    .es-search,
    .es-search-box {
        width: 100%;
    }

    .es-download {
        margin-left: 0;
    }

    .es-columns {
        grid-template-rows: 200px auto;
    }

    .es-bar-row {
        grid-template-columns: minmax(0, 1fr) auto;
    }

    .es-bar-track {
        grid-row: 2;
        grid-column: 1 / -1;
    }

    .es-bar-value {
        min-width: 0;
    }

    .es-legend-note {
        margin-left: 0;
    }
}

/* ============================================================================
   Search Order-wise Settlements: the filter bar.

   The created dates or a search by ID, side by side with an OR between them,
   as a seller portal lays them out. The date box opens the two-month calendar
   (date-range.js). While a search is on, the dates are set aside, so they dim.
   ========================================================================= */

.st-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px 16px;
    padding: 14px 18px 12px;
}

.st-field {
    display: grid;
    gap: 6px;
    min-width: 0;
    margin: 0;
}

.st-label {
    margin: 0;
    color: var(--text-muted);
    font-size: 12.5px;
    font-weight: 400;
}

/* The date box and the search box: one look for both. */
.st-box {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 280px;
    max-width: 100%;
    min-height: 38px;
    padding: 0 10px 0 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    color: var(--text);
    font-size: 14px;
    transition: border-color .16s ease, box-shadow .16s ease;
}

.st-box .icon {
    flex: none;
    width: 17px;
    height: 17px;
    color: var(--text-muted);
}

summary.st-box {
    justify-content: space-between;
    list-style: none;
    cursor: pointer;
}

summary.st-box::-webkit-details-marker {
    display: none;
}

.st-dates[open] > .st-box,
summary.st-box:focus-visible,
.st-box:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
    outline: none;
}

/* A calendar, not a chevron: it stays the right way up when open. */
.st-dates[open] > summary .icon {
    transform: none;
}

.st-box.is-idle {
    color: var(--text-muted);
}

.st-or {
    padding-bottom: 10px;
    color: var(--text-muted);
    font-size: 12.5px;
    font-weight: 600;
}

.st-search {
    padding-right: 6px;
}

.st-search input {
    flex: 1 1 auto;
    min-width: 0;
    height: 36px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--text);
    font: inherit;
    outline: none;
}

.st-search button {
    display: grid;
    place-items: center;
    padding: 2px;
    border: 0;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
}

.st-search button:hover,
.st-search button:focus-visible {
    color: var(--text);
}

.st-result {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    margin: 0;
    padding: 0 18px 12px;
    color: var(--text-muted);
    font-size: 13px;
}

.st-result a {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
}

.st-result a:hover {
    text-decoration: underline;
}

@media (max-width: 720px) {
    .st-filters {
        flex-direction: column;
        align-items: stretch;
    }

    .st-box {
        width: 100%;
    }

    .st-or {
        padding: 0;
        text-align: center;
    }
}
/* ============================================================================
   SPF Claims.

   Built from Returns Insights' and Earnings' parts: the tabs along the top, the
   chips, the search box, the download, the flat table and the guide in the
   page header. Its own: the counts in the tabs and chips, the toolbar row, the
   table's columns, the empty row, and the insides of its two drawers -- the
   choice of issue on a new claim, and a claim's details.
   ========================================================================= */

.spf-page .ri-page-tab {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.spf-tab-code {
    padding: 0 6px;
    border: 1px solid var(--ri-line);
    border-radius: 4px;
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 600;
    line-height: 18px;
    letter-spacing: .04em;
}

.ri-page-tab.is-active .spf-tab-code {
    border-color: currentColor;
    color: var(--accent-strong);
}

.spf-count {
    min-width: 22px;
    padding: 0 7px;
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 600;
    line-height: 20px;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.ri-page-tab.is-active .spf-count,
.ri-chip.is-active .spf-count {
    background: var(--accent);
    color: var(--surface);
}

.spf-new {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.spf-new .icon {
    width: 16px;
    height: 16px;
    stroke-width: 2;
}

/* ---- toolbar: the chips, then the search and the download at the far end ---- */

.spf-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px 24px;
}

.spf-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    min-width: 0;
}

.spf-chips .ri-chip {
    text-decoration: none;
}

.spf-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-left: auto;
}

.spf-search {
    margin: 0;
}

.spf-search .es-search-box {
    width: 300px;
}

.spf-tools .es-download {
    margin-left: 0;
}

.spf-result {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    margin: -8px 0 0;
    color: var(--text-muted);
    font-size: 13px;
}

.spf-result a {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
}

.spf-result a:hover {
    text-decoration: underline;
}

/* ---- table ---- */

.spf-table-wrap {
    border-radius: 6px;
}

.spf-table {
    min-width: 940px;
}

/* Nothing to scroll sideways to when the only row is the picture. */
.spf-table.is-empty {
    min-width: 0;
}

.spf-table thead th {
    font-weight: 600;
    white-space: nowrap;
}

.spf-table small {
    display: block;
    margin-top: 3px;
    color: var(--text-muted);
    font-size: 12.5px;
}

.spf-id {
    font-weight: 600;
    white-space: nowrap;
}

/* IDs are long and unbroken; they wrap anywhere rather than widen the column. */
.spf-code {
    overflow-wrap: anywhere;
    font-variant-numeric: tabular-nums;
}

/* Tracking IDs are short enough to keep whole; the order IDs beside them give way. */
.spf-tracking {
    white-space: nowrap;
}

.spf-qty {
    margin-right: 2px;
    font-weight: 600;
    white-space: nowrap;
}

.spf-when {
    white-space: nowrap;
}

.spf-sort {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: inherit;
    text-decoration: none;
}

.spf-sort .icon {
    width: 14px;
    height: 14px;
    color: var(--text-muted);
}

.spf-sort:hover,
.spf-sort:hover .icon {
    color: var(--accent-strong);
}

.spf-action {
    width: 1%;
    text-align: right;
    white-space: nowrap;
}

.spf-row-btn {
    min-height: 32px;
    padding: 0 14px;
    font-size: 13px;
}

.spf-table .spf-empty td {
    padding: 40px 16px 48px;
    text-align: center;
}

.spf-empty .empty-illustration {
    max-width: 260px;
}

.spf-empty-title {
    margin: 0;
    color: var(--text);
    font-size: 16px;
    font-weight: 600;
}

.spf-empty-hint {
    max-width: 440px;
    margin: 6px auto 0;
    color: var(--text-muted);
    font-size: 14px;
}

.spf-empty .ri-btn {
    margin-top: 16px;
}

/* ---- drawers ---- */

.spf-drawer {
    width: min(720px, 100vw);
}

/* Tighter than the shared drawer, so a whole claim fits a laptop screen
   without scrolling. */
.spf-drawer .drawer-body {
    padding-top: 20px;
    padding-bottom: 20px;
}

.spf-drawer .form-grid {
    gap: 16px 20px;
}

.spf-drawer-title {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    min-width: 0;
}

.spf-drawer .form-field textarea:focus,
.spf-drawer .form-field select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

/* The two kinds of claim, as cards side by side: the one picked takes the accent. */
.spf-issues {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px 12px;
    min-width: 0;
    margin: 0 0 18px;
    padding: 0;
    border: 0;
}

.spf-issues .field-error {
    grid-column: 1 / -1;
}

.spf-issues legend {
    margin-bottom: 10px;
    padding: 0;
    color: var(--text);
    font-size: 14px;
    font-weight: 600;
}

.spf-issue {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface);
    cursor: pointer;
    transition: border-color .16s ease, background .16s ease;
}

.spf-issue:hover,
.spf-issue:has(input:checked) {
    border-color: var(--accent);
}

.spf-issue:has(input:checked) {
    background: var(--accent-soft);
}

.spf-issue:has(input:focus-visible) {
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.spf-issue input {
    flex: none;
    width: 18px;
    height: 18px;
    margin: 1px 0 0;
    accent-color: var(--accent);
}

.spf-issue strong {
    display: block;
    color: var(--text);
    font-size: 14px;
    font-weight: 600;
}

.spf-issue small {
    display: block;
    margin-top: 2px;
    color: var(--text-muted);
    font-size: 13px;
}

.spf-drawer .drawer-footer {
    flex-wrap: wrap;
}

/* Beside the buttons, so it costs the form no height of its own. */
.spf-drawer-note {
    flex: 1 1 200px;
    margin: 0;
    color: var(--text-muted);
    font-size: 13px;
    text-align: right;
}

/* A claim's details: label over value, two to a row. */
.spf-facts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px 24px;
    margin: 0 0 22px;
    padding: 18px 20px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 14px;
}

.spf-facts > div {
    display: grid;
    gap: 3px;
    min-width: 0;
}

.spf-facts > .is-wide {
    grid-column: 1 / -1;
}

.spf-facts dt {
    color: var(--text-muted);
    font-size: 12.5px;
}

.spf-facts dd {
    margin: 0;
    color: var(--text);
    font-weight: 500;
    overflow-wrap: anywhere;
}

.spf-note {
    margin: 0 0 18px;
}

.spf-note h3 {
    margin: 0 0 6px;
    color: var(--text);
    font-size: 14px;
    font-weight: 600;
}

.spf-note p {
    margin: 0;
    padding: 12px 14px;
    border-radius: 8px;
    background: var(--surface-2);
    color: var(--text);
    font-size: 14px;
    white-space: pre-line;
    overflow-wrap: anywhere;
}

.spf-reply {
    margin-top: 6px;
}

@media (max-width: 900px) {
    .spf-tools {
        width: 100%;
        margin-left: 0;
    }

    .spf-search {
        flex: 1 1 240px;
    }

    .spf-search .es-search-box {
        width: 100%;
    }
}

@media (max-width: 720px) {
    /* The column heads would hold the empty row as wide as the table, its
       picture scrolled out of sight; there is nothing to label, so they go. */
    .spf-table.is-empty thead {
        display: none;
    }
}

@media (max-width: 560px) {
    .spf-page .ri-page-tabs {
        gap: 4px 18px;
    }

    /* Both tabs on one line: the names say enough without the codes. */
    .spf-tab-code {
        display: none;
    }

    .spf-tools {
        flex-direction: column;
        align-items: stretch;
    }

    .spf-search {
        flex: none;
    }

    .spf-facts,
    .spf-issues {
        grid-template-columns: minmax(0, 1fr);
    }

    .spf-drawer-note {
        text-align: left;
    }
}

/* ============================================================================
   Seller sign-up and onboarding.

   Sign-up is the sign-in card, a little wider. Onboarding stands alone, as the
   only screen a seller can reach until it is done: a bar with the name and
   Sign out, the completion status and checklist on the left, the steps on the
   right in the same order. Amber marks what is still to do, green what is done.
   ========================================================================= */

.auth-card-wide {
    max-width: 440px;
}

.auth-form input.is-invalid,
.auth-prefixed.is-invalid {
    border-color: var(--error-text);
}

.auth-error {
    margin: -10px 0 14px;
    color: var(--error-text);
    font-size: 12.5px;
}

/* +91 and the number, drawn as one field. */
.auth-prefixed {
    display: flex;
    align-items: stretch;
    margin-bottom: 16px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    overflow: hidden;
}

.auth-prefixed:focus-within {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
}

.auth-prefix {
    display: grid;
    place-items: center;
    padding: 0 10px;
    border-right: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 14px;
}

.auth-prefixed input,
.auth-form .auth-prefixed input {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    border: 0;
    border-radius: 0;
    outline: none;
}

.auth-footer p + p {
    margin-top: 6px;
}

.auth-footer a {
    color: var(--accent-strong);
    font-weight: 600;
}

/* ---- onboarding wizard ----
   Laid out like the application's other screens: the top bar, a white page
   header holding the title and a one-line stepper, and the stage in a card.
   Each stage's two halves sit side by side, so a whole stage fits a laptop
   screen without scrolling; below 860px they stack. Green marks a stage done,
   the accent the one open now; a stage ahead is grey and not a link. */

.ob-body {
    --ob-amber: #e59a1f;
    --ob-amber-soft: #fdf3e1;

    min-height: 100vh;
    background: var(--bg);
}

:root[data-theme="dark"] .ob-body {
    --ob-amber: #e8a93f;
    --ob-amber-soft: #33291a;
}

.ob-topbar {
    position: sticky;
    top: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    height: var(--topbar-h);
    padding: 0 24px;
    border-bottom: 1px solid var(--topbar-border);
    background: var(--topbar-bg);
    color: var(--topbar-text);
}

.ob-brand {
    font-size: 17px;
    font-weight: 700;
}

.ob-topbar form {
    margin: 0;
}

.ob-signout {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: transparent;
    color: var(--topbar-text);
    font: inherit;
    font-size: 14px;
    cursor: pointer;
}

.ob-signout:hover {
    background: var(--surface-2);
}

.ob-signout .icon {
    width: 16px;
    height: 16px;
}

/* ---- page header: title and stepper ---- */

.wz-header {
    border-bottom: 1px solid var(--border);
    background: var(--surface);
}

.wz-header-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px 32px;
    max-width: 1080px;
    margin: 0 auto;
    padding: 14px 24px;
}

.wz-heading h1 {
    margin: 0;
    color: var(--text);
    font-size: 21px;
    font-weight: 600;
    line-height: 1.25;
}

.wz-heading p {
    margin: 3px 0 0;
    color: var(--text-muted);
    font-size: 13.5px;
}

.wz-steps {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

.wz-step {
    display: flex;
    align-items: center;
}

/* The rule from the stage before, green once this stage is reached. */
.wz-step + .wz-step::before {
    content: "";
    flex: none;
    width: 28px;
    height: 2px;
    margin: 0 10px;
    border-radius: 2px;
    background: var(--border);
}

.wz-step.is-done::before,
.wz-step.is-current::before {
    background: var(--ok-text);
}

.wz-step-link {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}

a.wz-step-link:hover .wz-step-label {
    color: var(--text);
    text-decoration: underline;
}

.wz-step-dot {
    display: grid;
    place-items: center;
    flex: none;
    width: 26px;
    height: 26px;
    border: 2px solid var(--border);
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-muted);
    font-size: 12.5px;
    font-weight: 700;
}

.wz-step-dot .icon {
    width: 14px;
    height: 14px;
    stroke-width: 2.8;
}

.wz-step.is-done .wz-step-dot {
    border-color: var(--ok-text);
    background: var(--ok-text);
    color: var(--surface);
}

.wz-step.is-done .wz-step-label {
    color: var(--text);
}

.wz-step.is-current .wz-step-dot {
    border-color: var(--accent);
    background: var(--accent);
    color: var(--surface);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.wz-step.is-current .wz-step-label {
    color: var(--text);
    font-weight: 700;
}

/* Done and open at once: back on a finished stage, or on Done itself. Green, ringed. */
.wz-step.is-done.is-current .wz-step-dot {
    border-color: var(--ok-text);
    background: var(--ok-text);
    box-shadow: 0 0 0 3px var(--ok-bg);
}

/* ---- the stage card ---- */

/* Full width up to the cap: the body is a flex column, where auto margins
   alone would shrink each stage to its own content. */
.wz {
    display: grid;
    gap: 14px;
    width: 100%;
    max-width: 1080px;
    margin: 0 auto;
    padding: 18px 24px 20px;
}

.wz-alert {
    margin: 0;
}

.wz-card {
    margin: 0;
    overflow: hidden;   
    border-radius: var(--radius);
    background: var(--surface);
   
}

.wz-card-head {
    padding: 18px 24px 0;
}

.wz-kicker {
    display: inline-block;
    margin-bottom: 4px;
    color: var(--accent-strong);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

.wz-card-head h2 {
    margin: 0;
    color: var(--text);
    font-size: 18px;
    font-weight: 700;
}

.wz-card-head p {
    margin: 4px 0 0;
    color: var(--text-muted);
    font-size: 13.5px;
}

.wz-card-body {
    display: grid;
    gap: 14px;
    padding: 16px 24px 20px;
}

.wz-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 24px;    
    background: var(--surface-2);
}

.wz-next,
.wz-back {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    border-radius: 8px;
    text-decoration: none;
}

.wz-next .icon,
.wz-back .icon {
    width: 17px;
    height: 17px;
}

/* Back is the lesser way: an outline, not the solid button. */
.wz-back,
.wz-back:hover {
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    box-shadow: none;
}

.wz-back:hover {
    border-color: var(--text-muted);
}

.wz-wait {
    color: var(--text-muted);
    font-size: 13.5px;
}

.wz-question {
    margin: 0 0 8px;
    padding: 0;
    color: var(--text);
    font-size: 14.5px;
    font-weight: 600;
}

/* A stage's two halves, side by side. */
.wz-pair,
.wz-columns {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
}

.wz-pair {
    gap: 16px;
}

.wz-columns {
    gap: 32px;
}

.wz-col {
    display: grid;
    gap: 14px;
    min-width: 0;
}

.wz-col .wz-question {
    margin: 0 0 8px;
}

.wz .form-field select {
    appearance: auto;
}

.wz .form-field select:focus,
.wz .form-field textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.wz-form-grid {
    gap: 14px 20px;
}

.wz-taxid {
    letter-spacing: .04em;
    text-transform: uppercase;
}

.wz-taxid::placeholder {
    letter-spacing: normal;
    text-transform: none;
}

.ob-dev-note {
    margin: 0;
    padding: 9px 12px;
    border: 1px dashed var(--ob-amber);
    border-radius: 8px;
    background: var(--ob-amber-soft);
    color: var(--text);
    font-size: 13px;
}

.ob-fieldset {
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
}

.ob-required {
    color: var(--error-text);
}

.ob-optional {
    color: var(--text-muted);
    font-weight: 400;
}

/* ---- step 1: the two contacts ---- */

.wz-contact {
    display: grid;
    align-content: start;
    gap: 10px;
    min-width: 0;
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
}

.wz-contact-top {
    display: flex;
    align-items: center;
    gap: 10px;
}

.wz-contact-top .od-pill {
    margin-left: auto;
}

.wz-contact-icon {
    display: grid;
    place-items: center;
    flex: none;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--surface-2);
    color: var(--text-muted);
}

.wz-contact-icon .icon {
    width: 17px;
    height: 17px;
}

.wz-contact-label {
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 600;
}

.wz-contact-value {
    color: var(--text);
    font-size: 16px;
    font-weight: 600;
    overflow-wrap: anywhere;
}

.wz-contact-done {
    margin: 0;
    color: var(--ok-text);
    font-size: 13px;
}

.ob-code {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 8px;
    margin: 0;
}

.ob-code > input {
    width: 150px;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: 15px;
    letter-spacing: .2em;
    font-variant-numeric: tabular-nums;
}

.ob-code > input::placeholder {
    letter-spacing: normal;
}

.ob-code > input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.ob-code .auth-prefixed {
    margin: 0;
    border-radius: 8px;
}

.ob-code .auth-prefixed input {
    width: 130px;
    padding: 8px 12px;
    background: transparent;
    color: var(--text);
    font: inherit;
}

.ob-contact-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 6px 18px;
}

.ob-contact-actions form {
    margin: 0;
}

.ob-change[open] {
    flex-basis: 100%;
}

.ob-change summary {
    list-style: none;
}

.ob-change summary::-webkit-details-marker {
    display: none;
}

.ob-change .ob-code {
    margin-top: 8px;
}

.ob-feedback {
    margin: 0;
    font-size: 13px;
}

.ob-feedback.is-error {
    color: var(--error-text);
}

.ob-feedback.is-ok {
    color: var(--ok-text);
}

.ob-feedback.is-info {
    color: var(--info-text);
}

/* A text button, for the lesser actions. */
.ob-link {
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent-strong);
    font: inherit;
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
}

.ob-link:hover:not(:disabled) {
    text-decoration: underline;
}

.ob-link:disabled {
    color: var(--text-muted);
    cursor: default;
}

/* As a real link, such as the bank stage's "Find your IFSC": underlined on hover
   like the buttons, and the size of the help line it sits in. */
a.ob-link {
    text-decoration: none;
}

.field-help .ob-link {
    font-size: inherit;
}

/* ---- step 2: the signature ---- */

.wz-signature {
    gap: 10px;
}

.wz-signature .wz-question {
    margin: 0;
}

.ob-sig-options {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 12px;
}

.ob-option {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 42px;
    padding: 8px 16px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface);
    color: var(--accent-strong);
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}

.ob-option:hover {
    border-color: var(--accent);
}

.ob-option:focus-within {
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.ob-option .icon {
    width: 18px;
    height: 18px;
}

.ob-or {
    color: var(--text-muted);
    font-size: 13.5px;
}

.ob-pad-wrap,
.ob-file-preview {
    display: grid;
    gap: 6px;
}

.ob-pad-wrap[hidden],
.ob-file-preview[hidden] {
    display: none;
}

/* Light in both themes: a signature is dark ink on paper. */
.ob-pad {
    width: 100%;
    height: auto;
    aspect-ratio: 3 / 1;
    border: 1px dashed var(--border);
    border-radius: 10px;
    background: #ffffff;
    cursor: crosshair;
    touch-action: none;
}

.ob-pad-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.ob-pad-actions .field-help {
    margin: 0;
}

.ob-file-preview {
    justify-items: start;
}

.ob-file-preview img,
.ob-signature-saved img {
    width: 240px;
    max-width: 100%;
    height: auto;
    padding: 6px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: #ffffff;
    object-fit: contain;
}

.ob-signature-saved {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
}

/* ---- done ---- */

.wz-done .wz-card-body {
    justify-items: center;
    gap: 10px;
    padding: 36px 24px;
    text-align: center;
}

.wz-done-mark {
    display: grid;
    place-items: center;
    width: 60px;
    height: 60px;
    border-radius: 50%;
    background: var(--ok-bg);
    color: var(--ok-text);
}

.wz-done-mark .icon {
    width: 28px;
    height: 28px;
    stroke-width: 2.4;
}

.wz-done h2 {
    margin: 6px 0 0;
    font-size: 21px;
}

.wz-done p {
    max-width: 440px;
    margin: 0 0 8px;
    color: var(--text-muted);
}

/* A stage's confirmation: shown for a few seconds, then gone; it stays put for
   anyone who asked for less motion. */
.ob-toast {
    position: fixed;
    bottom: 24px;
    left: 50%;
    z-index: 20;
    max-width: calc(100vw - 32px);
    margin: 0;
    padding: 12px 18px;
    border: 1px solid var(--ok-border);
    border-radius: 10px;
    background: var(--ok-bg);
    color: var(--ok-text);
    box-shadow: var(--shadow);
    font-size: 14px;
    font-weight: 600;
    transform: translateX(-50%);
    animation: ob-toast-out 5s ease forwards;
    pointer-events: none;
}

@keyframes ob-toast-out {
    0%, 85% {
        opacity: 1;
        visibility: visible;
    }

    100% {
        opacity: 0;
        visibility: hidden;
    }
}

@media (prefers-reduced-motion: reduce) {
    .ob-toast {
        animation: none;
    }
}

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

    .wz-columns {
        gap: 20px;
    }
}

@media (max-width: 600px) {
    .ob-topbar {
        padding: 0 16px;
    }

    .wz-header-inner {
        padding: 12px 16px;
    }

    .wz-step-label {
        display: none;
    }

    .wz-step.is-current .wz-step-label {
        display: inline;
    }

    .wz {
        padding: 16px 12px 48px;
    }

    .wz-card-head {
        padding: 16px 16px 0;
    }

    .wz-card-body {
        padding: 14px 16px 18px;
    }

    .wz-actions {
        padding: 12px 16px;
    }

    .wz-form-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .ob-option {
        flex: 1 1 100%;
    }

    .ob-or {
        flex-basis: 100%;
        text-align: center;
    }
}

/* ============================================================================
   Notifications.

   The bell in the top bar, for the super admin only, with a count of what is
   unread and a list of the latest under it; and the same counts in the sidebar,
   beside the screen each is about and on its group. Red for unread, the one
   place it is used for something other than an error, so it is never missed.
   ========================================================================= */

:root {
    --nt-badge: #dc2626;
}

.nt {
    position: relative;
}

.nt-toggle {
    position: relative;
}

.nt-count {
    position: absolute;
    top: 2px;
    right: 1px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border: 2px solid var(--topbar-bg);
    border-radius: 999px;
    background: var(--nt-badge);
    color: #ffffff;
    font-size: 10.5px;
    font-weight: 700;
    line-height: 14px;
    text-align: center;
    box-sizing: border-box;
}

.nt-panel {
    width: 360px;
    max-width: calc(100vw - 24px);
    padding: 0;
    overflow: hidden;
}

.nt-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
}

.nt-head form {
    margin: 0;
}

.nt-heading {
    color: var(--text);
    font-size: 15px;
    font-weight: 700;
}

.nt-mark {
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent-strong);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.nt-mark:hover {
    text-decoration: underline;
}

.nt-empty {
    margin: 0;
    padding: 24px 16px;
    color: var(--text-muted);
    font-size: 13.5px;
    text-align: center;
}

.nt-list {
    max-height: 380px;
    margin: 0;
    padding: 6px;
    overflow-y: auto;
    list-style: none;
}

.nt-list form {
    margin: 0;
}

.nt-item {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    width: 100%;
    padding: 10px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.nt-item:hover {
    background: var(--surface-2);
}

.nt-icon {
    display: grid;
    place-items: center;
    flex: none;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--ok-bg);
    color: var(--ok-text);
}

.nt-icon .icon {
    width: 18px;
    height: 18px;
}

.nt-text {
    display: grid;
    flex: 1 1 auto;
    gap: 2px;
    min-width: 0;
}

.nt-title {
    font-size: 14px;
    font-weight: 500;
}

.nt-item.is-unread .nt-title {
    font-weight: 700;
}

.nt-body {
    color: var(--text-muted);
    font-size: 13px;
    overflow-wrap: anywhere;
}

.nt-time {
    color: var(--text-muted);
    font-size: 12px;
}

.nt-dot {
    flex: none;
    width: 8px;
    height: 8px;
    margin-top: 6px;
    border-radius: 50%;
    background: var(--nt-badge);
}

.nt-footer {
    display: block;
    padding: 11px 14px;
    border-top: 1px solid var(--border);
    color: var(--accent-strong);
    font-size: 13.5px;
    font-weight: 600;
    text-align: center;
    text-decoration: none;
}

.nt-footer:hover {
    background: var(--surface-2);
}

/* ---- the counts in the sidebar ---- */

.menu-badge,
.menu-group-badge {
    flex: none;
    min-width: 20px;
    margin-left: auto;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--nt-badge);
    color: #ffffff;
    font-size: 11.5px;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
}

.menu-group-toggle {
    position: relative;
}

/* Down to the rail, a group's count becomes a dot on its icon. */
.sidebar-collapsed .menu-group-badge {
    position: absolute;
    top: 7px;
    right: calc(50% - 15px);
    width: 10px;
    min-width: 0;
    height: 10px;
    padding: 0;
    border: 2px solid var(--sidebar-bg);
    font-size: 0;
}

/* The flyout lists the pages, each with its own count; the dot on the icon has said enough. */
.sidebar-collapsed .menu-group.flyout-open .menu-badge {
    margin-left: 12px;
}

@media (max-width: 560px) {
    .nt-panel {
        position: fixed;
        top: calc(var(--topbar-h) + 6px);
        right: 12px;
        left: 12px;
        width: auto;
    }
}
