/* ============================================================
   New look components.
   Part 1: v-* components used by v2 views.
   Part 2: refinements to legacy components (ui.css.php) that v2
   pages still render through shared partials and dialogs. These
   are scoped to body.v2 so the current look is untouched.
   ============================================================ */

/* ============ Part 1: v2 components ============ */

/* ---- Page header ---- */
.v-page-head {display: flex; align-items: flex-end; flex-wrap: wrap; gap: 10px 12px; margin: 0 0 18px;}
.v-page-head__text {min-width: 0; flex: 1 1 260px;}
.v-page-head h1 {margin: 0; font-size: var(--fs-page-title); font-weight: 600; letter-spacing: -.01em; color: var(--ink); line-height: 1.25;}
.v-page-head__sub {margin-top: 2px; color: var(--muted);}
.v-page-head__actions {display: flex; flex-wrap: wrap; gap: 8px; align-items: center;}

/* ---- Buttons ---- */
.v-btn {display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: var(--btn-h); padding: 0 12px; box-sizing: border-box; border: var(--border-default); border-radius: var(--radius-md); background: var(--white); color: var(--ink); font: 500 13px/1 var(--font); white-space: nowrap; text-decoration: none; cursor: pointer; transition: background var(--transition-default), border-color var(--transition-default);}
body.v2 a.v-btn {color: var(--ink);}
.v-btn:hover {background: var(--surface); border-color: var(--lighter);}
.v-btn i {font-size: 16px;}
.v-btn.is-primary, body.v2 a.v-btn.is-primary {background: var(--brand); border-color: var(--brand); color: #fff;}
.v-btn.is-primary:hover {background: var(--brand-hover); border-color: var(--brand-hover);}
.v-btn.is-ghost, body.v2 a.v-btn.is-ghost {border-color: transparent; background: transparent; color: var(--mid);}
.v-btn.is-ghost:hover {background: var(--hover);}
.v-btn.is-danger, body.v2 a.v-btn.is-danger {color: var(--danger);}
.v-btn.is-sm {height: 28px; padding: 0 9px; font-size: 12px;}
.v-btn.is-icon {width: var(--btn-h); padding: 0;}
.v-btn.is-sm.is-icon {width: 28px;}
.v-btn[disabled], .v-btn.is-disabled {opacity: .5; pointer-events: none;}

/* ---- Card ---- */
.v-card {background: var(--white); border: var(--border-default); border-radius: var(--radius-card); box-shadow: var(--shadow-sm); min-width: 0;}
.v-card + .v-card {margin-top: var(--card-gap);}
.v-card__head {display: flex; align-items: center; gap: 8px; min-height: 46px; padding: 0 14px; border-bottom: var(--border-pale-line); box-sizing: border-box;}
.v-card__head h2 {margin: 0; font-size: var(--fs-section-h2); font-weight: 600; color: var(--ink);}
.v-card__head .v-card__meta {color: var(--muted); font-size: var(--fs-small);}
.v-card__head .v-card__actions {margin-left: auto; display: flex; gap: 6px; align-items: center;}
.v-card__body {padding: 14px;}
.v-card__body.is-flush {padding: 0;}
.v-card__foot {padding: 10px 14px; border-top: var(--border-pale-line); color: var(--muted); font-size: var(--fs-small);}
button.v-card__head {width: 100%; border: 0; background: none; font: inherit; cursor: pointer; text-align: left; border-radius: var(--radius-card) var(--radius-card) 0 0;}
.v-card__toggle {display: flex; align-items: center; gap: 8px; align-self: stretch; padding: 0; border: 0; background: none; font: inherit; color: inherit; cursor: pointer;}
/* collapsed: set by page JS (dashboard uses .collapsed) */
.v-card.is-collapsed > .v-card__head, .v-card.collapsed > .v-card__head {border-bottom: 0;}
.v-card.is-collapsed .v-card__collapsible {display: none;}
.v-card__chev {color: var(--muted); font-size: 18px; transition: transform var(--transition-default);}
.v-card.is-collapsed .v-card__chev, .v-card.collapsed .v-card__chev {transform: rotate(-90deg);}

/* ---- Grid helpers ---- */
.v-grid {display: grid; gap: var(--card-gap); grid-template-columns: repeat(var(--cols, 2), minmax(0, 1fr)); margin-bottom: var(--card-gap);}
.v-grid > .v-card + .v-card {margin-top: 0;}
.v-stack > * + * {margin-top: var(--card-gap);}
@media (max-width: 900px){ .v-grid {grid-template-columns: minmax(0, 1fr);} }

/* ---- Stat strip ---- */
.v-stats {display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); background: var(--white); border: var(--border-default); border-radius: var(--radius-card); box-shadow: var(--shadow-sm); margin-bottom: var(--card-gap); overflow: hidden;}
.v-stat {padding: 13px 16px; border-right: var(--border-pale-line); min-width: 0;}
.v-stat:last-child {border-right: 0;}
.v-stat small {display: block; color: var(--muted); font-size: var(--fs-small);}
.v-stat b {display: block; margin-top: 2px; font-size: var(--fs-stat-value); font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;}
.v-stat .v-stat__note {font-size: var(--fs-caption); color: var(--muted);}

/* ---- Tables ---- */
.v-table-wrap {container-type: inline-size; min-width: 0;}
/* Pages render in quirks mode, where tables do not inherit font size */
body.v2 table {font-size: inherit;}
.v-table {width: 100%; border-collapse: collapse; font-size: var(--fs-body);}
.v-table th {font-size: var(--fs-small); font-weight: 500; color: var(--muted); text-align: left; padding: 9px var(--cell-padding-x); border-bottom: var(--border-default); white-space: nowrap; background: var(--white);}
.v-table td {padding: var(--cell-padding-y) var(--cell-padding-x); border-bottom: var(--border-faint-line); vertical-align: middle;}
.v-table tbody tr:last-child td {border-bottom: 0;}
.v-table tbody tr.is-link {cursor: pointer;}
.v-table tbody tr.is-link:hover td {background: var(--surface);}
.v-table .is-num {text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap;}
.v-table .is-muted {color: var(--muted);}
.v-table .is-nowrap {white-space: nowrap;}
.v-table .is-actions {text-align: right; white-space: nowrap; width: 1%;}
.v-table a.v-row-link {color: var(--ink); text-decoration: none; font-weight: 500;}
.v-table a.v-row-link:hover {color: var(--brand-ink);}
.v-table tr.is-hidden, .v-table tr.is-seg-hidden, .v-table tr.is-more {display: none !important;}
/* Stacked rows (v2/tables.js adds .is-stack when a table is cramped):
   each row becomes a compact card - first value as the title, the rest side
   by side with their column label, actions on the same line pushed right */
body.v2 table.is-stack, body.v2 table.is-stack > tbody {display: block; width: auto;}
body.v2 table.is-stack > thead {display: none;}
body.v2 table.is-stack > tbody > tr {display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 18px; padding: 10px 14px; border-bottom: var(--border-faint-line);}
body.v2 table.is-stack > tbody > tr:last-child {border-bottom: 0;}
body.v2 table.is-stack > tbody > tr > td {display: block; width: auto !important; padding: 0; border: 0; text-align: left;}
body.v2 table.is-stack > tbody > tr > td:first-child {flex: 1 0 100%; font-weight: 500;}
body.v2 table.is-stack > tbody > tr > td:empty {display: none;}
body.v2 table.is-stack > tbody > tr > td[data-label]:not(:first-child):not(.actions):not(.is-actions)::before,
body.v2 .ui-table.is-stack .ui-table-row > .ui-table-cell[data-label]:not(:first-child):not(.actions)::before {content: attr(data-label); display: block; font-size: 10px; font-weight: 500; color: var(--muted);}
body.v2 table.is-stack > tbody > tr > td.actions, body.v2 table.is-stack > tbody > tr > td.is-actions {display: flex; gap: 4px; margin-left: auto; white-space: nowrap;}
body.v2 .ui-table.is-stack > .ui-table-head {display: none;}
body.v2 .ui-table.is-stack .ui-table-row {display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 18px; padding: 10px 14px; height: auto;}
body.v2 .ui-table.is-stack .ui-table-row > .ui-table-cell {display: block; width: auto !important; min-width: 0; max-width: none; flex: 0 1 auto; order: 0; font-size: 13px; line-height: 18px; color: inherit; padding: 0; text-align: left; white-space: normal;}
body.v2 .ui-table.is-stack .ui-table-row > .ui-table-cell:first-child {flex: 1 0 100%; font-weight: 500;}
body.v2 .ui-table.is-stack .ui-table-row > .ui-table-cell:empty {display: none;}
body.v2 .ui-table.is-stack .ui-table-row > .ui-table-cell.actions {margin-left: auto;}

/* ---- Status pill ---- */
.v-pill {display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; border-radius: 10px; font-size: var(--fs-small); font-weight: 500; line-height: 1.5; white-space: nowrap; background: var(--border-faint); color: var(--mid);}
.v-pill::before {content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor;}
.v-pill.is-plain::before {display: none;}
.v-pill.is-success {background: var(--success-pale); color: var(--brand-ink);}
.v-pill.is-warning {background: var(--warning-pale); color: var(--warning);}
.v-pill.is-danger {background: var(--danger-pale); color: var(--danger);}
.v-pill.is-info {background: var(--info-pale); color: var(--info);}

/* ---- Count badge ---- */
.v-count {display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 5px; box-sizing: border-box; border-radius: 9px; background: var(--border-faint); color: var(--mid); font-size: 11px; font-weight: 600;}
.v-count.is-alert {background: var(--danger); color: #fff;}

/* ---- Segmented control + filter bar ---- */
.v-filters {display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 12px;}
.v-filters .v-filters__grow {flex: 1 1 200px; min-width: 0;}
/* one row, one line: legacy form/label margins never push a control off it */
:is(.v-filters, .v-page-head__actions, .v-card__actions) > :is(form, label, nav, div, select, input, a, button) {margin: 0;}
:is(.v-filters, .v-page-head__actions, .v-card__actions) > form {display: flex; align-items: center; gap: 8px;}
.v-seg {display: inline-flex; max-width: 100%; overflow-x: auto; border: var(--border-default); border-radius: var(--radius-md); background: var(--white); scrollbar-width: none;}
.v-seg::-webkit-scrollbar {display: none;}
.v-seg > a, .v-seg > button {display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 11px; border: 0; border-right: var(--border-pale-line); background: none; color: var(--mid); font: 500 13px var(--font); text-decoration: none; white-space: nowrap; cursor: pointer;}
body.v2 .v-seg > a {color: var(--mid);}
.v-seg > :last-child {border-right: 0;}
.v-seg > a:hover, .v-seg > button:hover {background: var(--hover);}
body.v2 .v-seg > .is-active {background: var(--ink); color: #fff;}
.v-seg .v-seg__swatch {width: 8px; height: 8px; border-radius: 50%; background: var(--swatch, var(--light));}
.v-seg .v-seg__n {font-size: 11px; color: var(--muted);}
.v-seg > .is-active .v-seg__n {color: rgba(255,255,255,.7);}
.v-seg > .is-empty {color: var(--light);}

.v-search {display: flex; align-items: center; gap: 6px; height: 32px; padding: 0 10px; box-sizing: border-box; border: var(--border-default); border-radius: var(--radius-md); background: var(--white); color: var(--muted);}
.v-search input {flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; font: inherit; color: var(--ink); height: 30px;}
.v-search:focus-within {border-color: var(--brand); box-shadow: var(--focus-ring);}

.v-select {width: auto; height: 32px; padding: 0 30px 0 10px; border: var(--border-default); border-radius: var(--radius-md); background: var(--white) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23858B87' stroke-width='1.5' fill='none'/%3E%3C/svg%3E") no-repeat right 10px center; -webkit-appearance: none; appearance: none; font: inherit; color: var(--ink); max-width: 100%;}

/* ---- Tabs ---- */
.v-tabs {display: flex; gap: 2px; border-bottom: var(--border-default); margin-bottom: 16px; overflow-x: auto; scrollbar-width: none;}
.v-tabs::-webkit-scrollbar {display: none;}
.v-tabs a {padding: 9px 12px; color: var(--muted); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap;}
body.v2 .v-tabs a {color: var(--muted);}
body.v2 .v-tabs a.is-active {color: var(--ink); border-color: var(--ink); font-weight: 500;}

/* ---- Key / value list ---- */
.v-kv {margin: 0;}
.v-kv > div {display: flex; justify-content: space-between; gap: 12px; padding: 8px 14px; border-bottom: var(--border-faint-line);}
.v-kv > div:last-child {border-bottom: 0;}
.v-kv dt {color: var(--muted);}
.v-kv dd {margin: 0; text-align: right; color: var(--ink);}

/* ---- Empty state ---- */
.v-empty {padding: 28px 16px; text-align: center; color: var(--muted);}
.v-empty i {display: block; font-size: 26px; color: var(--lighter); margin-bottom: 6px;}

/* ---- Inline panel (a former dialog opened in place) ---- */
.v-inline {border: var(--border-default); border-radius: var(--radius-card); background: var(--white); box-shadow: var(--shadow-sm);}
.v-inline__head {display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-bottom: var(--border-pale-line); font-weight: 600;}
.v-inline__body {padding: 14px;}
.v-inline__foot {display: flex; justify-content: flex-end; gap: 8px; padding: 10px 14px; border-top: var(--border-pale-line);}

/* ---- Misc ---- */
.v-dev-banner {position: fixed; top: 0; left: 50%; transform: translateX(-50%); z-index: 10100; background: var(--danger); color: #fff; font-size: 9px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; padding: 1px 10px; border-radius: 0 0 4px 4px; pointer-events: none;}
.v-muted {color: var(--muted);}
.v-num {font-variant-numeric: tabular-nums;}
.v-swatch {display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--swatch, var(--light)); vertical-align: middle;}
.v-note {padding: 10px 14px; border-radius: var(--radius-md); background: var(--surface); border: var(--border-pale-line); color: var(--mid); font-size: var(--fs-small);}


/* ============ Part 2: legacy components inside the new look ============ */

/* Breadcrumbs: quiet trail above the page header */
body.v2 #ui-breadcrumbs {margin: 0 0 6px; padding: 0; font-size: var(--fs-small); color: var(--muted); background: none; border: 0;}
body.v2 #ui-breadcrumbs a {color: var(--muted); text-decoration: none;}
body.v2 #ui-breadcrumbs a:hover {color: var(--ink);}
body.v2 #ui-breadcrumbs .current {color: var(--mid);}
body.v2 #ui-breadcrumbs .separator {margin: 0 5px; color: var(--lighter);}

/* Page header from ui/page-header */
body.v2 .ui-page-header {display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; margin: 0 0 16px; padding: 0; background: none; border: 0;}
body.v2 .ui-page-header h1 {margin: 0; font-size: var(--fs-page-title); font-weight: 600; letter-spacing: -.01em; color: var(--ink);}
body.v2 .ui-page-header h2 {margin: 0; font-size: var(--fs-body); font-weight: 400; color: var(--muted); flex-basis: 100%;}
body.v2 .ui-page-header .actions {position: static; margin-left: auto; display: flex; flex-wrap: wrap; gap: 8px;}

/* Section header from ui/section-header: keeps its .actions markup for page JS */
body.v2 .ui-section-header {display: flex; align-items: center; flex-wrap: wrap; gap: 8px; min-height: 44px; margin: 0; padding: 6px 14px; box-sizing: border-box; background: var(--white); border: var(--border-default); border-bottom: var(--border-pale-line); border-radius: var(--radius-card) var(--radius-card) 0 0;}
body.v2 .ui-section-header h2 {margin: 0; font-size: var(--fs-section-h2); font-weight: 600; color: var(--ink);}
body.v2 .ui-section-header > .actions, body.v2 .ui-section-header > .links {margin-left: auto; display: flex; flex-wrap: wrap; gap: 6px; float: none;}
body.v2 .ui-section-header > .actions > a, body.v2 .ui-section-header > .actions > div,
body.v2 .ui-section-header > .links > a, body.v2 .ui-section-header > .links > div {display: inline-flex; align-items: center; gap: 5px; height: 28px; padding: 0 9px; border: var(--border-default); border-radius: var(--radius-md); background: var(--white); color: var(--ink); font-size: 12px; font-weight: 500; text-decoration: none; cursor: pointer; margin: 0; line-height: 1;}
body.v2 .ui-section-header > .actions > a:hover, body.v2 .ui-section-header > .actions > div:hover,
body.v2 .ui-section-header > .links > a:hover, body.v2 .ui-section-header > .links > div:hover {background: var(--surface);}
body.v2 .ui-section-header .mdi {font-size: 15px; color: var(--mid);}
body.v2 .ui-section-header .no-actions {display: none;}

/* Buttons */
body.v2 .ui-btn {display: inline-flex; align-items: center; gap: 6px; height: var(--btn-h); padding: 0 12px; border: var(--border-default); border-radius: var(--radius-md); background: var(--white); color: var(--ink); font: 500 13px/1 var(--font); text-transform: none; letter-spacing: 0; box-shadow: none; text-decoration: none;}
body.v2 .ui-btn:hover {background: var(--surface);}
body.v2 .ui-btn:is(.cta, .primary) {background: var(--brand); border-color: var(--brand); color: #fff;}
body.v2 .ui-btn:is(.cta, .primary):hover {background: var(--brand-hover); border-color: var(--brand-hover);}
body.v2 .ui-btn.delete {color: var(--danger);}

/* Forms */
body.v2 .form-group > label, body.v2 .ui-modal label {font-size: var(--fs-small); font-weight: 500; color: var(--mid); text-transform: none; letter-spacing: 0;}
body.v2 .form-control, body.v2 .ui-modal input[type=text], body.v2 .ui-modal input[type=email], body.v2 .ui-modal input[type=tel], body.v2 .ui-modal input[type=number], body.v2 .ui-modal input[type=date], body.v2 .ui-modal input[type=time], body.v2 .ui-modal select, body.v2 .ui-modal textarea {border: var(--border-default); border-radius: var(--radius-md); font-family: var(--font); font-size: 13px; color: var(--ink); background-color: var(--white); box-shadow: none;}
body.v2 .form-control:focus, body.v2 .ui-modal input:focus, body.v2 .ui-modal select:focus, body.v2 .ui-modal textarea:focus {border-color: var(--brand); box-shadow: var(--focus-ring); outline: 0;}

/* Div tables (ui/table_head + ui-table rows) */
body.v2 .ui-table {background: var(--white); border: var(--border-default); border-top: 0; border-radius: 0 0 var(--radius-card) var(--radius-card);}
body.v2 .ui-table .ui-table-head {background: var(--white); border-bottom: var(--border-default);}
body.v2 .ui-table .ui-table-head .ui-table-cell {font-size: var(--fs-small); font-weight: 500; color: var(--muted); text-transform: none; letter-spacing: 0;}
body.v2 .ui-table .ui-table-row {border-bottom: var(--border-faint-line); background: var(--white);}
body.v2 .ui-table .ui-table-row:hover {background: var(--surface);}
body.v2 .ui-table .ui-table-cell {color: var(--slate);}

/* Row action menu */
body.v2 .ui-actions-menu {border: var(--border-default); border-radius: var(--radius-lg); box-shadow: var(--shadow-pop); padding: 4px; background: var(--white);}
body.v2 .ui-actions-menu li {border-radius: var(--radius-sm); font-size: 13px; color: var(--slate);}
body.v2 .ui-actions-menu li:hover {background: var(--hover);}

/* Dialogs: white header with a left title, real buttons in the footer.
   Dialogs never close on backdrop click (modals.js has no backdrop handler). */
body.v2 .ui-modal .container {border-radius: var(--radius-shell); box-shadow: var(--shadow-pop); border: 0;}
body.v2 .ui-modal-inner > .header {background: var(--white); color: var(--ink); text-align: left; font-size: 16px; font-weight: 600; padding: 16px 52px 14px 22px; border-bottom: var(--border-pale-line); letter-spacing: -.005em;}
body.v2 .ui-modal .close-modal {top: 12px; right: 12px; width: 30px; height: 30px; border-radius: var(--radius-md); color: var(--muted);}
body.v2 .ui-modal .close-modal:hover {background: var(--hover);}
body.v2 .ui-modal-inner > .content {padding: 18px 22px 8px;}
body.v2 .ui-modal-inner > .header:has(+ .uim-tabs) {border-bottom: 0; padding-bottom: 4px;}
body.v2 .uim-tabs {padding: 0 10px; border-bottom: var(--border-pale-line);}
body.v2 .uim-tabs button.is-active {color: var(--brand-ink); border-bottom-color: var(--brand);}
body.v2 .ui-modal-inner > .footer {background: var(--surface); border-top: var(--border-pale-line);}
body.v2 .ui-modal-inner > .footer .right button, body.v2 .ui-modal-inner > .footer .left button {height: 32px; line-height: 30px; padding: 0 14px; border: var(--border-default); background: var(--white); color: var(--ink); font: 500 13px var(--font); text-transform: none; letter-spacing: 0;}
body.v2 .ui-modal-inner > .footer .right button:last-child:not([name=cancel]), body.v2 .ui-modal-inner > .footer .right button.filled {background: var(--brand); border-color: var(--brand); color: #fff;}
body.v2 .ui-modal-inner > .footer .right button:last-child:not([name=cancel]):not(.disabled):hover, body.v2 .ui-modal-inner > .footer .right button.filled:not(.disabled):hover {background: var(--brand-hover);}
body.v2 .ui-modal-inner > .footer button[name=delete] {color: var(--danger);}
body.v2 .ui-modal-backdrop {background: rgba(20, 24, 22, .35);}

/* Notification toast (App::displayNotification -> ui/notification) */
body.v2 .ui-notification {position: fixed; z-index: 10200; left: 50%; right: auto; bottom: calc(20px + env(safe-area-inset-bottom)); transform: translateX(-50%); width: auto; max-width: min(560px, calc(100vw - 32px)); box-sizing: border-box; display: flex; align-items: center; gap: 12px; padding: 11px 14px 11px 16px; border-radius: var(--radius-lg); background: var(--ink); color: #fff; font: 500 13px/1.4 var(--font); text-align: left; box-shadow: var(--shadow-pop); border-left: 4px solid var(--muted);}
body.v2 .ui-notification.success {background: var(--ink); border-left-color: var(--brand);}
body.v2 .ui-notification.fail, body.v2 .ui-notification.error {background: var(--ink); border-left-color: var(--danger);}
body.v2 .ui-notification.info {background: var(--ink); border-left-color: var(--warning);}
body.v2 .ui-notification .dismiss {cursor: pointer; opacity: .6; font-size: 16px; margin-left: auto;}
body.v2 .ui-notification .dismiss:hover {opacity: 1;}

/* info_subtle notices */
body.v2 .info-subtle, body.v2 .ui-info-subtle {border-radius: var(--radius-md);}
body.v2 .info-subtle-blue {border-radius: var(--radius-md); background: var(--info-pale);}
body.v2 .info-subtle-blue .message {color: var(--info);}
body.v2 .warn-subtle {border-radius: var(--radius-md); background: var(--warning-pale); color: var(--warning);}
body.v2 .warn-subtle .message, body.v2 .warn-subtle a {color: inherit;}
body.v2 .warn-subtle .message form {display: inline-flex; margin-left: 10px; vertical-align: middle;}

/* Sections with a section header and a table read as one card */
body.v2 #ui-page-content section {margin-bottom: var(--card-gap);}

/* A .ui-section-header that only exists so page JS finds its .actions */
body.v2 .ui-section-header.is-bare {display: flex; min-height: 0; padding: 0; border: 0; background: none; border-radius: 0; box-shadow: none;}
body.v2 .ui-section-header.is-bare > .actions {margin: 0;}
body.v2 .ui-section-header.is-bare > .actions > .v-btn {height: var(--btn-h); padding: 0 12px; font-size: 13px;}
body.v2 .ui-section-header.is-bare > .actions > .v-btn.is-primary {background: var(--brand); border-color: var(--brand); color: #fff;}
body.v2 .ui-section-header.is-bare > .actions > .v-btn.is-primary .mdi {color: #fff;}

/* Title-bar actions in dialogs (e.g. booking print) on the white header */
body.v2 .ui-modal-inner > .header {position: relative;}
body.v2 .ui-modal-inner .header .ui-modal-actions {right: 52px;}
body.v2 .ui-modal-inner .header .ui-modal-actions a, body.v2 .ui-modal-inner .header .ui-modal-actions a:link, body.v2 .ui-modal-inner .header .ui-modal-actions a:visited {border-color: var(--border); color: var(--mid); background: var(--white);}
body.v2 .ui-modal-inner .header .ui-modal-actions a:hover {color: var(--brand-ink); border-color: var(--brand);}

/* In-app confirm / alert / prompt (dialog.js) */
body.v2 .app-dialog {width: 400px; border-radius: var(--radius-shell); box-shadow: var(--shadow-pop);}
body.v2 .app-dialog-body {padding: 20px 22px 14px; font-size: 14px; color: var(--ink);}
body.v2 .app-dialog-footer {padding: 10px 14px; background: var(--surface); border-top: var(--border-pale-line);}
body.v2 .app-dialog-btn {height: 32px; padding: 0 14px; border: var(--border-default); border-radius: var(--radius-md); background: var(--white); color: var(--ink); font: 500 13px var(--font); text-transform: none; letter-spacing: 0;}
body.v2 .app-dialog-btn.confirm {background: var(--brand); border-color: var(--brand); color: #fff;}
body.v2 .app-dialog-btn.confirm.danger {background: var(--danger); border-color: var(--danger);}

/* Global vertical rhythm: blocks stacked in the page (or a stack container)
   always get the card gap, so no two cards ever touch. A section header and
   the table it heads stay joined. */
body.v2 .v-wrap > * + *, body.v2 .v-dash > * + *, body.v2 .v-stack > * + * {margin-top: var(--card-gap);}
body.v2 .ui-section-header + .ui-table, body.v2 .ui-section-header + form + .ui-table {margin-top: 0;}

/* Legacy "Select store..." filters (a form with one auto-submitting select,
   used across many list pages) become a compact filter control */
body.v2 section > form > .form-group:only-child {display: inline-flex; margin: 10px 14px 0; padding: 0;}
body.v2 section > form > .form-group:only-child > select {width: auto; min-width: 220px; max-width: 100%; height: var(--btn-h); padding: 0 30px 0 10px; border: var(--border-default); border-radius: var(--radius-md); background: var(--white) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23858B87' stroke-width='1.5' fill='none'/%3E%3C/svg%3E") no-repeat right 10px center; -webkit-appearance: none; appearance: none; font: 13px var(--font); color: var(--ink);}
body.v2 section > .ui-section-header + form {background: var(--white); border-left: var(--border-default); border-right: var(--border-default); padding-bottom: 10px; margin: 0;}

/* Legacy full-page forms (.ui-form-group of dl > dt label + dd field): a
   responsive grid of fields in a card, normal-case labels */
body.v2 .ui-form-group {display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px 20px; max-width: 1040px; padding: 0; margin: 0;}
/* Same grid when the form sits inside the group (.ui-form-group > form > dl) */
body.v2 .ui-form-group:has(> form) {display: block; padding: 20px 22px; box-sizing: border-box;}
body.v2 .ui-form-group > form {display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px 20px;}
body.v2 :is(.ui-form-group, .ui-form-group > form) > dl {margin: 0; padding: 0; border: 0; display: block; min-width: 0;}
body.v2 :is(.ui-form-group, .ui-form-group > form) > dl > dt {margin: 0 0 5px; padding: 0; width: auto; float: none;}
body.v2 :is(.ui-form-group, .ui-form-group > form) > dl > dt label {font-size: var(--fs-small); font-weight: 500; color: var(--mid); text-transform: none; letter-spacing: 0;}
body.v2 :is(.ui-form-group, .ui-form-group > form) > dl > dd {margin: 0; padding: 0; width: auto; float: none;}
body.v2 :is(.ui-form-group, .ui-form-group > form) > dl > dd :is(input[type=text], input[type=email], input[type=tel], input[type=number], input[type=date], input[type=time], input[type=url], input[type=password], select, textarea) {width: 100%; max-width: none; box-sizing: border-box; min-height: var(--input-h); padding: 6px 10px; border: var(--border-default); border-radius: var(--radius-md); background-color: var(--white); font: 13px var(--font); color: var(--ink);}
body.v2 :is(.ui-form-group, .ui-form-group > form) > dl > dd :is(input, select, textarea):focus {border-color: var(--brand); box-shadow: var(--focus-ring); outline: 0;}
body.v2 :is(.ui-form-group, .ui-form-group > form) > dl:has(textarea) {grid-column: 1 / -1;}
/* The submit row always ends the form: full width, button on the right,
   same place on every page (and the same side as dialog buttons) */
body.v2 :is(.ui-form-group, .ui-form-group > form) > dl.submit {grid-column: 1 / -1; display: flex; justify-content: flex-end; margin-top: 4px; padding-top: 14px; border-top: var(--border-faint-line);}
body.v2 :is(.ui-form-group, .ui-form-group > form) > dl.submit > dt {display: none;}
body.v2 :is(.ui-form-group, .ui-form-group > form) > dl.submit > dd {display: flex; gap: 8px;}
/* Main action always last (right), as in dialogs */
body.v2 :is(.ui-form-group, .ui-form-group > form) > dl.submit > dd > .cta {order: 9;}
body.v2 :is(.ui-form-group, .ui-form-group > form) > hr.form-divider {grid-column: 1 / -1; margin: 4px 0; border: 0; border-top: var(--border-faint-line);}

/* Tabbed settings sheets: tabs as v-tabs, the active tab as a card */
body.v2 .ui-tabbed-sheet {background: none; border: 0; box-shadow: none; padding: 0; margin: 0 0 14px;}
body.v2 .ui-tabbed-sheet > nav {display: flex; gap: 2px; border-bottom: var(--border-default); overflow-x: auto; scrollbar-width: none; background: none; padding: 0;}
body.v2 .ui-tabbed-sheet > nav a {padding: 9px 12px; margin-bottom: -1px; border: 0; border-bottom: 2px solid transparent; border-radius: 0; background: none; color: var(--muted); font-size: 13px; font-weight: 400; text-transform: none; letter-spacing: 0; white-space: nowrap;}
body.v2 .ui-tabbed-sheet > nav a.active {color: var(--ink); border-bottom-color: var(--ink); font-weight: 500; background: none;}
body.v2 .ui-tabbed-sheet + .tab, body.v2 .ui-tabbed-sheet ~ .tab.active {background: var(--white); border: var(--border-default); border-radius: var(--radius-card); box-shadow: var(--shadow-sm); padding: 18px;}
body.v2 .settings-container-info {display: none;}

/* Inputs used as filter controls never stretch (legacy rules set width:100%) */
body.v2 input.v-select, body.v2 select.v-select {width: auto; flex: 0 0 auto;}

/* Top-level legacy sections are already cards (ui.css.php): their header
   becomes the card's head row and inner tables drop their own frame */
body.v2 #ui-page-content > .wrap > section {padding: 14px; box-shadow: var(--shadow-sm);}
body.v2 #ui-page-content > .wrap > section > .ui-section-header {margin: -14px -14px 12px; padding: 6px 14px; min-height: 46px; height: auto; border: 0; border-bottom: var(--border-pale-line); border-radius: 0; background: none;}
body.v2 #ui-page-content > .wrap > section > .ui-section-header:has(> .actions > .no-actions:only-child):not(:has(h2)) {display: none;}
body.v2 #ui-page-content > .wrap > section .ui-table, body.v2 #ui-page-content > .wrap > section > form + .ui-table {border: 0; border-radius: 0; margin-left: -14px; margin-right: -14px;}
body.v2 #ui-page-content > .wrap > section > .ui-section-header + form {border: 0; padding: 0 0 10px; background: none;}
body.v2 #ui-page-content > .wrap > section > form > .form-group:only-child {margin: 0;}

/* Record details (.ui-details-list of dl > dt label + dd value, 21 pages):
   a grid of pairs, muted labels left-aligned beside their values */
body.v2 .ui-details-list {display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 0 28px; padding: 2px 0;}
/* Headings, messages and tables inside a details list (e.g. rota days) take the full row */
body.v2 .ui-details-list > :not(dl) {grid-column: 1 / -1;}
body.v2 .ui-details-list > dl {display: flex; align-items: baseline; gap: 12px; margin: 0; padding: 7px 0; border-bottom: var(--border-faint-line); min-width: 0;}
body.v2 .ui-details-list > dl > dt {flex: 0 0 110px; width: auto; float: none; margin: 0; padding: 0; text-align: left; font-size: var(--fs-small); font-weight: 500; color: var(--muted);}
body.v2 .ui-details-list > dl > dd {flex: 1 1 auto; min-width: 0; width: auto; float: none; margin: 0; padding: 0; color: var(--ink); overflow-wrap: anywhere;}

/* Tables keep every row on one line: ids, dates, money, pills and names never
   break. One flexible text column (.is-flex, the name / supplier / description
   one, picked by v2/tables.js) takes the spare width and truncates with an
   ellipsis. When a row still can't fit, tables.js stacks the table into cards
   (.is-stack), where text wraps again. .no-stack tables scroll sideways;
   .wrap-text and input cells keep wrapping. */
body.v2 .ui-table .ui-table-row > .ui-table-cell {white-space: normal; overflow-wrap: break-word;}
body.v2 #ui-page-content :is(.ui-table, table):not(.is-stack) :is(.ui-table-row > .ui-table-cell, tr > td, tr > th):not(.has-input):not(.wrap-text) {white-space: nowrap; overflow-wrap: normal;}
/* Anything still too long clips with an ellipsis instead of spilling past the card */
body.v2 #ui-page-content :is(.ui-table, table):not(.is-stack) :is(.ui-table-row > .ui-table-cell, tr > td):not(.has-input):not(.wrap-text):not(.actions):not(.view):not(.overflow):not(:has(select, .ui-actions-menu, .dropdown)) {overflow: hidden; text-overflow: ellipsis;}
body.v2 #ui-page-content .ui-table:not(.is-stack) .ui-table-cell.u-flex > div:not([class*="avatar"]) {min-width: 0; overflow: hidden; text-overflow: ellipsis;}
body.v2 #ui-page-content :is(.ui-table, table):not(.is-stack) :is(.ui-table-row > .ui-table-cell, tr > td, tr > th).is-flex {width: 100%; max-width: 0; overflow: hidden; text-overflow: ellipsis;}
body.v2 #ui-page-content :is(.ui-table, table).has-flex:not(.is-stack) :is(.ui-table-row > .ui-table-cell, tr > td, tr > th).is-flex:not(.is-flex2) {width: 60% !important;}
body.v2 #ui-page-content :is(.ui-table, table).has-flex:not(.is-stack) :is(.ui-table-row > .ui-table-cell, tr > td, tr > th).is-flex2 {width: 40% !important;}
body.v2 #ui-page-content :is(.ui-table, table):not(.is-stack) .is-flex > :not(.ui-actions-menu) {overflow: hidden; text-overflow: ellipsis;}
/* With a flexible column the others shrink to their content (their old % widths left gaps) */
body.v2 #ui-page-content :is(.ui-table, table).has-flex:not(.is-stack) :is(.ui-table-row > .ui-table-cell, tr > td, tr > th):not(.is-flex) {width: 1% !important;}
/* text inside a one-line cell stays on that line (legacy span rules reset it) */
body.v2 #ui-page-content :is(.ui-table, table):not(.is-stack) :is(.ui-table-row > .ui-table-cell, tr > td):not(.has-input):not(.wrap-text) > :is(span, a, b, strong, small) {white-space: inherit;}
/* no single fixed column may starve the flexible one: long values truncate */
body.v2 #ui-page-content :is(.ui-table, table).has-flex:not(.is-stack) :is(.ui-table-row > .ui-table-cell, tr > td):not(.is-flex):not(.actions):not(.has-input) {max-width: 260px;}

/* Standard list card: when the section header has no title (actions only)
   and a filter/search form follows, they share one toolbar row - search or
   filters left, actions right - and the table fills the card below */
body.v2 #ui-page-content > .wrap > section:has(> .ui-section-header.is-untitled + :is(form, input)) {display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px 12px; align-items: center;}
/* the search under the store picker: the grid gap spaces it, not its own margin */
body.v2 #ui-page-content > .wrap > section > .ui-section-header.is-untitled + form ~ input#searchInput, body.v2 #ui-page-content > .wrap > section > .ui-section-header.is-untitled + form ~ form > input#searchInput {margin-top: 0;}
body.v2 #ui-page-content > .wrap > section:has(> .ui-section-header.is-untitled + :is(form, input)) > * {grid-column: 1 / -1;}
body.v2 #ui-page-content > .wrap > section:has(> .ui-section-header.is-untitled + :is(form, input)) > .ui-section-header {grid-column: 2; grid-row: 1; margin: 0; padding: 0; min-height: 0; border: 0;}
body.v2 #ui-page-content > .wrap > section:has(> .ui-section-header.is-untitled + :is(form, input)) > .ui-section-header + :is(form, input) {grid-column: 1; grid-row: 1; padding: 0; margin: 0; min-width: 0;}
/* the store picker / search shares the row with the add button: it never runs under it */
body.v2 #ui-page-content > .wrap > section > .ui-section-header.is-untitled + form :is(select, input:not([type=hidden])) {width: 100%; max-width: 100%; min-width: 0; box-sizing: border-box;}
body.v2 #ui-page-content > .wrap > section > .ui-section-header.is-untitled + form .form-group {display: block; width: 100%; max-width: 420px; margin: 0; min-width: 0;}
body.v2 #ui-page-content > .wrap > section > .ui-section-header + form #searchInput {margin: 0 !important;}
body.v2 #ui-page-content > .wrap > section > .ui-section-header + form ~ .ui-table, body.v2 #ui-page-content > .wrap > section > .ui-section-header + form ~ form + .ui-table {margin-top: 12px;}
body.v2 #ui-page-content > .wrap > section :is(#searchInput, .ui-table-controls input) {height: var(--btn-h); border-radius: var(--radius-md);}

/* Section header actions are buttons everywhere (the legacy section-card
   rule strips them to plain text); "add" actions are the primary button */
body.v2 #ui-page-content .ui-section-header > .actions > :is(a, div):not(.no-actions),
body.v2 #ui-page-content .ui-section-header > .links > :is(a, div) {display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 11px; border: var(--border-default); border-radius: var(--radius-md); background: var(--white); color: var(--ink); font-size: 12.5px; font-weight: 500; text-decoration: none; cursor: pointer;}
body.v2 #ui-page-content .ui-section-header > .actions > :is(a, div):not(.no-actions):hover,
body.v2 #ui-page-content .ui-section-header > .links > :is(a, div):hover {background: var(--surface); border-color: var(--lighter);}
body.v2 #ui-page-content .ui-section-header > .actions > :is(a, div).add {background: var(--brand); border-color: var(--brand); color: #fff;}
body.v2 #ui-page-content .ui-section-header > .actions > :is(a, div).add .mdi {color: #fff;}
body.v2 #ui-page-content .ui-section-header > .actions > :is(a, div).add:hover {background: var(--brand-hover); border-color: var(--brand-hover);}

/* Stacked card title: the name-like column, first in the card, no label */
body.v2 table.is-stack > tbody > tr > td.is-title, body.v2 .ui-table.is-stack .ui-table-row > .ui-table-cell.is-title {order: -1; flex: 1 0 100%; font-weight: 500; color: var(--ink);}
body.v2 table.is-stack > tbody > tr > td.is-title::before, body.v2 .ui-table.is-stack .ui-table-row > .ui-table-cell.is-title::before {display: none !important;}
body.v2 table.is-stack > tbody > tr > td:first-child:not(.is-title), body.v2 .ui-table.is-stack .ui-table-row > .ui-table-cell:first-child:not(.is-title) {flex: 0 1 auto; font-weight: 400;}
body.v2 table.is-stack > tbody > tr > td:first-child:not(.is-title)[data-label]::before, body.v2 .ui-table.is-stack .ui-table-row > .ui-table-cell:first-child:not(.is-title)[data-label]::before {content: attr(data-label); display: block; font-size: 10px; font-weight: 500; color: var(--muted);}

/* Store totals widget (purchasing): the date range wraps on narrow screens */
body.v2 .store-totals-widget .ui-section-header, body.v2 section.store-totals .ui-section-header {flex-wrap: wrap;}
@media (max-width: 640px){ body.v2 #ui-page-content input[type=date] {max-width: 100%; min-width: 0;} }
body.v2 .store-totals-header {flex-wrap: wrap; gap: 8px;}
body.v2 .store-totals-form {flex-wrap: wrap; max-width: 100%;}

/* Report date stepper (.forwards-backwards-nav): one compact bar, the date
   in the middle, previous / next as small buttons either side */
body.v2 .forwards-backwards-nav {display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 0 0 16px; padding: 8px 10px; background: var(--white); border: var(--border-default); border-radius: var(--radius-card); box-shadow: var(--shadow-sm);}
body.v2 .forwards-backwards-nav > a {text-decoration: none;}
body.v2 .forwards-backwards-nav .left, body.v2 .forwards-backwards-nav .right {display: inline-flex; align-items: center; gap: 4px; height: 30px; padding: 0 10px; border: var(--border-default); border-radius: var(--radius-md); background: var(--white); color: var(--ink); font-size: 12.5px; font-weight: 500; float: none; width: auto; line-height: 1;}
body.v2 .forwards-backwards-nav .left:hover, body.v2 .forwards-backwards-nav .right:hover {background: var(--surface);}
body.v2 .forwards-backwards-nav .middle {text-align: center; font-size: 13px; color: var(--mid); line-height: 1.3; float: none; width: auto;}
body.v2 .forwards-backwards-nav .middle b {color: var(--ink); font-size: 14px;}
body.v2 .forwards-backwards-nav .fake-link {cursor: pointer;}

/* Inline filter forms keep their controls compact (legacy rules make
   inputs and selects full width) */
body.v2 :is(form.u-flex, .report-filter-bar, .report-filters, .finza-filters form, .finza-rep-filter, .statement-filters, .finza-adj-add, .finza-stock-weeks, .finza-stock-add, .finza-toolbar, .finza-cleanup-row, .mc-row, .mc-merge, .mc-fillall) :is(input[type=date], input[type=text], input[type=search], input[type=month], input[type=number], select) {width: auto; min-width: 140px; max-width: 100%; height: var(--btn-h); padding: 0 10px; border: var(--border-default); border-radius: var(--radius-md); font: 13px var(--font); color: var(--ink); background-color: var(--white); box-sizing: border-box;}
body.v2 :is(form.u-flex, .report-filter-bar, .report-filters, .finza-filters form, .finza-rep-filter, .finza-adj-add) :is(input[type=text], input[type=search]) {flex: 1 1 220px;}
/* legacy .btn in the same rows: the controls' height, not its own */
body.v2 :is(form.u-flex, .report-filter-bar, .report-filters, .finza-filters form, .finza-rep-filter, .statement-filters, .finza-adj-add, .finza-stock-weeks, .finza-stock-add, .finza-toolbar) .btn {display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: var(--btn-h); min-height: 0; margin: 0; padding: 0 14px; box-sizing: border-box; line-height: 1; vertical-align: middle;}
body.v2 .finza-adj-amt input[type=number] {min-width: 0; width: 100px; border: 0; height: calc(var(--btn-h) - 2px);}
body.v2 .finza-adj-amt {height: var(--btn-h); box-sizing: border-box; border-right: var(--border-default); border-radius: var(--radius-md); overflow: hidden;}
body.v2 .report-filter-bar {display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 10px;}
body.v2 .report-filter-bar label {font-size: var(--fs-small); color: var(--mid); font-weight: 500;}
body.v2 .report-filter-bar {align-items: center;}
body.v2 :is(.report-filter-bar, form.u-flex) > button[type=submit], body.v2 :is(.report-filter-bar, form.u-flex) > input[type=submit] {height: var(--btn-h); padding: 0 14px; border: 0; border-radius: var(--radius-md); background: var(--brand); color: #fff; font: 500 13px var(--font); cursor: pointer; width: auto;}

/* Legacy filter panel (.form-group-filter, e.g. reports/invoices): a white
   card with the selects in a wrapping row, checkboxes in a line, submit right */
body.v2 .form-group-filter {display: flex; flex-wrap: wrap; align-items: center; gap: 8px; width: auto; margin: 0 0 14px; padding: 12px 14px; background: var(--white); border: var(--border-default); border-radius: var(--radius-card); box-shadow: var(--shadow-sm);}
body.v2 .form-group-filter .form-group {width: auto; margin: 0;}
body.v2 .form-group-filter select {height: var(--btn-h); min-width: 180px;}
body.v2 .form-group-filter hr {flex-basis: 100%; margin: 2px 0; border: 0; border-top: var(--border-default);}
body.v2 .form-group-filter .form-group-filter__check {color: var(--ink);}
body.v2 .form-group-filter .form-group-filter__check label {display: inline-flex; align-items: center; gap: 6px; margin: 0 8px 0 0; font-size: 13px;}
body.v2 .form-group-filter .form-group-filter__submit {float: none; margin-left: auto;}
body.v2 .form-group-filter__submit input[type=submit] {width: auto; height: var(--btn-h); padding: 0 16px; border: 0; border-radius: var(--radius-md); background: var(--brand); color: #fff; font: 500 13px var(--font); cursor: pointer;}
body.v2 .report-copy-btn {height: var(--btn-h); padding: 0 14px; border: var(--border-default); border-radius: var(--radius-md); background: var(--white); font: 500 13px var(--font); cursor: pointer;}

/* Times, numbers and money (centred / right cells) never wrap in a table row;
   if that makes the table too wide, tables.js stacks it instead */
body.v2 .ui-table:not(.is-stack) .ui-table-row > .ui-table-cell:is(.center, .right):not(.has-input) {white-space: nowrap;}

/* A stacked row keeps a cell's own flex layout (avatar beside name) */
body.v2 .ui-table.is-stack .ui-table-row > .ui-table-cell.u-flex {display: flex;}

/* Switches and checkboxes in the brand colour */
body.v2 .toggle-switch input:checked + .toggle-slider {background-color: var(--brand);}
body.v2 input[type=checkbox], body.v2 input[type=radio] {accent-color: var(--brand);}

/* "Show older" under a list that loads its recent rows first */
body.v2 .ui-table-more {display: flex; justify-content: center; padding: 12px 0 2px;}

/* List rows never go heavier than medium (500): names, b/strong and the
   legacy .bold class included. Headings, badges and totals keep their own. */
body.v2 :is(.ui-table-body, .v-table tbody, .view-rows) :is(b, strong, .bold, .cd-name, .rcp-name, .scc-name) {font-weight: 500;}

/* Users list: EPOS PIN / rota / contractor flags before the role */
body.v2 .user-flags i {margin-right: 6px; font-size: 14px; color: var(--light); vertical-align: -1px;}
body.v2 .ui-table-row.is-off-account {color: var(--muted);}
@media (max-width: 900px){
  body.v2 .v-ios-list .user-flags {display: none;}
  body.v2 .v-ios-list .user-role {display: inline-block; padding: 0 8px; border-radius: 10px; background: var(--border-faint); font-size: 11px; line-height: 18px; font-weight: 500; color: var(--mid);}
}

/* Purchase invoices list: the supplier's own reference follows the name on the same line */
body.v2 .purchase-invoice-reference {display: inline; margin-left: 8px; font-size: var(--fs-small); color: var(--muted); white-space: nowrap;}
/* iOS-list tables as a desktop table: the title column takes the spare width, one line, ellipsis */
@media (min-width: 901px){
  body.v2 #ui-page-content .ui-table.v-ios-list .ui-table-row > .ui-table-cell.ios-title {width: 100%; max-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
  body.v2 #ui-page-content .ui-table.v-ios-list .ui-table-row > .ui-table-cell:not(.ios-title) {width: 1% !important;}
}
/* Purchase invoices list on narrow screens */
@media (max-width: 900px){
  body.v2 .v-ios-list .purchase-invoice-reference {display: none;}
  body.v2 .v-ios-list .ios-title .ui-details-list-blue {margin-left: 6px; font-size: 12px; font-weight: 400;}
}

/* Stacked cards: the actions / chevron sit on the title line, pushed right,
   and a zero-height break starts the values on the next line */
body.v2 table.is-stack > tbody > tr > td.is-title, body.v2 .ui-table.is-stack .ui-table-row > .ui-table-cell.is-title {order: -3; flex: 1 1 0; min-width: 0;}
body.v2 table.is-stack > tbody > tr > td:is(.actions, .is-actions, .view), body.v2 .ui-table.is-stack .ui-table-row > .ui-table-cell:is(.actions, .view) {order: -2; margin-left: auto; align-self: center;}
body.v2 table.is-stack > tbody > tr::after, body.v2 .ui-table.is-stack .ui-table-row::after {content: ""; order: -1; flex: 0 0 100%; height: 0;}
body.v2 table.is-stack > tbody > tr > td.is-blank, body.v2 .ui-table.is-stack .ui-table-row > .ui-table-cell.is-blank {display: none;}
/* Values sit in equal columns (4 across, 3 on phones) so labels line up from
   card to card; each value stays on one line */
body.v2 table.is-stack:not(.v-ios-list) > tbody > tr:has(> .is-title) > td:not(.is-title):not(.actions):not(.is-actions):not(.view),
body.v2 table.is-stack:not(.v-ios-list) > tbody > tr:not(:has(> .is-title)) > td:not(:first-child):not(.actions):not(.is-actions):not(.view),
body.v2 .ui-table.is-stack:not(.v-ios-list) .ui-table-row:has(> .is-title) > .ui-table-cell:not(.is-title):not(.actions):not(.view),
body.v2 .ui-table.is-stack:not(.v-ios-list) .ui-table-row:not(:has(> .is-title)) > .ui-table-cell:not(:first-child):not(.actions):not(.view) {flex: 1 0 calc((100% - 54px) / 4); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
@media (max-width: 640px){
  body.v2 table.is-stack:not(.v-ios-list) > tbody > tr:has(> .is-title) > td:not(.is-title):not(.actions):not(.is-actions):not(.view),
  body.v2 table.is-stack:not(.v-ios-list) > tbody > tr:not(:has(> .is-title)) > td:not(:first-child):not(.actions):not(.is-actions):not(.view),
  body.v2 .ui-table.is-stack:not(.v-ios-list) .ui-table-row:has(> .is-title) > .ui-table-cell:not(.is-title):not(.actions):not(.view),
  body.v2 .ui-table.is-stack:not(.v-ios-list) .ui-table-row:not(:has(> .is-title)) > .ui-table-cell:not(:first-child):not(.actions):not(.view) {flex-basis: calc((100% - 36px) / 3);}
}

body.v2 .v-pill {white-space: nowrap;}

/* Call log: its legacy layout forces the heading row visible; stacked cards hide it */

/* Stacked cards beat the legacy phone list layout (.view-rows used order,
   min-width: 60% and tiny fonts to fake two lines): one card style everywhere */
body.v2 .ui-table.is-stack:not(.v-ios-list) .ui-table-row > .ui-table-cell {order: 0 !important; min-width: 0 !important; margin-left: 0; font-size: 13px !important; line-height: 18px !important; color: var(--ink); text-align: left !important; font-weight: 400;}
body.v2 .ui-table.is-stack:not(.v-ios-list) .ui-table-row > .ui-table-cell.is-title {order: -3 !important; font-size: 14px !important; font-weight: 500;}
body.v2 .ui-table.is-stack:not(.v-ios-list) .ui-table-row > .ui-table-cell:is(.actions, .view) {order: -2 !important; position: static; margin-left: auto;}
body.v2 .ui-table.is-stack:not(.v-ios-list) .ui-table-row > .ui-table-cell:not(.is-title)[data-label]::before {font-size: 10px !important; line-height: 14px; color: var(--muted);}

/* A destructive button in a dialog footer */
body.v2 .ui-modal-inner > .footer button.is-danger {color: var(--danger);}
body.v2 table.is-stack:not(.v-ios-list) > tbody > tr > td {text-align: left !important; font-size: 13px; line-height: 18px;}
body.v2 table.is-stack:not(.v-ios-list) > tbody > tr > td.is-title {font-size: 14px; font-weight: 500;}

/* A section whose header is only an add button (no title, nothing beside it):
   the button sits beside the page title instead of on a bar of its own */
body.v2 #ui-page-content > .wrap > .ui-page-header:not(:has(.actions)) + section:has(> .ui-section-header.is-untitled:first-child > .actions > :only-child):not(:has(> .ui-section-header.is-untitled + :is(form, input))) {position: relative; overflow: visible !important;}
body.v2 #ui-page-content > .wrap > .ui-page-header:not(:has(.actions)) + section:has(> .ui-section-header.is-untitled:first-child > .actions > :only-child):not(:has(> .ui-section-header.is-untitled + :is(form, input))) > .ui-section-header.is-untitled:first-child {position: absolute; right: 0; top: -50px; margin: 0; padding: 0; border: 0; min-height: 0; background: none;}

/* Phones: info pills in a card title (Featured...) are dropped rather than wrapped under the name; status pills stay */
@media (max-width: 640px){
  body.v2 :is(.ui-table, table).is-stack .is-title :is(.v-pill.is-info, .badge-info, .ui-details-list-blue) {display: none;}
}

/* A totals line under a stacked table: one line, label and amount pushed right */
body.v2 .ui-table.is-stack .ui-table-row.is-total {justify-content: flex-end; gap: 12px; background: var(--surface);}
body.v2 .ui-table.is-stack .ui-table-row.is-total::after {display: none;}
body.v2 .ui-table.is-stack .ui-table-row.is-total > .ui-table-cell {flex: 0 0 auto !important; font-weight: 600 !important;}
body.v2 .ui-table.is-stack .ui-table-row.is-total > .ui-table-cell:empty {display: none;}

/* Labels that only make sense once a list collapses to iOS rows
   (Interview 08/07, 4 payments); the table's column heading says it otherwise */
body.v2 .ios-label {display: none;}
@media (max-width: 900px){
  body.v2 .v-ios-list .ios-label {display: inline;}
  body.v2 .v-ios-list .holiday-actions {display: flex !important; gap: 6px;}
  body.v2 .v-ios-list .holiday-actions .btn {min-height: 30px; padding: 0 12px; font-size: 13px; line-height: 28px;}
  body.v2 .v-ios-list.holidays-list .ui-table-row {padding-right: 16px;}
}
@media (max-width: 900px){
  body.v2 #ui-page-content .ui-table.v-ios-list .ui-table-row > .ui-table-cell.ios-hide {display: none !important;}
}

/* Day / month / year pickers sit on one row with a gap (new look form rules
   stretched each to full width and stacked them touching) */
body.v2 .date-group {display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) minmax(0, 1.3fr); gap: 8px; height: auto;}
body.v2 .date-group > select {float: none; width: 100% !important; margin: 0 !important;}
/* Hour / minute pickers (App::htmlTimePicker): two equal columns, each wide enough to show "23" and its arrow */
body.v2 .date-group:has(> select.hour) {grid-template-columns: repeat(2, minmax(64px, 1fr));}
/* Fields stacked one under another in a form row always have a gap */
body.v2 :is(dd, .form-group > [class*="col-"], .form-group, .field) > :is(input:not([type=hidden]):not([type=checkbox]):not([type=radio]), select, textarea) + :is(input:not([type=hidden]):not([type=checkbox]):not([type=radio]), select, textarea) {margin-top: 8px;}
