/* ==========================================================================
   OMi Partners Portal - components (docs/DESIGN-SYSTEM.md)
   1. Bootstrap 5.3 bridge: --bs-* variables mapped onto tokens.css
   2. Base (body, headings, focus, icons)
   3. Bootstrap components themed to the mockup (btn, form, badge, table,
      alert, dropdown, modal, offcanvas, nav-underline, progress, tooltip)
   4. Custom components, op- prefix (never collide with Bootstrap)
   Source of truth for the look: dev/design-preview/ (approved mockup).
   ========================================================================== */

/* ---------- 1. Bootstrap bridge ------------------------------------------- */
:root, [data-bs-theme="light"], [data-bs-theme="dark"] {
  --bs-font-sans-serif: var(--font-sans);
  --bs-font-monospace: var(--font-code);
  --bs-body-font-family: var(--font-sans);
  --bs-body-font-size: var(--fs-md);
  --bs-body-font-weight: var(--fw-regular);
  --bs-body-line-height: var(--lh-body);
  --bs-body-color: var(--text);
  --bs-body-color-rgb: var(--text-rgb);
  --bs-body-bg: var(--bg);
  --bs-body-bg-rgb: var(--bg-rgb);
  --bs-emphasis-color: var(--text);
  --bs-emphasis-color-rgb: var(--text-rgb);
  --bs-secondary-color: var(--text-muted);
  --bs-secondary-color-rgb: var(--text-muted-rgb);
  --bs-secondary-bg: var(--surface-3);
  --bs-tertiary-color: var(--text-muted);
  --bs-tertiary-bg: var(--surface-2);
  --bs-tertiary-bg-rgb: var(--surface-2-rgb);
  --bs-heading-color: var(--text);
  --bs-link-color: var(--link);
  --bs-link-color-rgb: var(--link-rgb);
  --bs-link-hover-color: var(--primary-hover);
  --bs-link-hover-color-rgb: var(--link-hover-rgb);
  --bs-link-decoration: underline;
  --bs-border-color: var(--line);
  --bs-border-color-translucent: var(--line);
  --bs-border-radius: var(--r-sm);
  --bs-border-radius-sm: var(--r-xs);
  --bs-border-radius-lg: var(--r-md);
  --bs-border-radius-xl: var(--r-lg);
  --bs-border-radius-xxl: var(--r-lg);
  --bs-border-radius-pill: var(--r-pill);
  --bs-box-shadow: var(--shadow-2);
  --bs-box-shadow-sm: var(--shadow-1);
  --bs-box-shadow-lg: var(--shadow-3);
  --bs-focus-ring-color: color-mix(in srgb, var(--focus) 25%, transparent);
  --bs-highlight-bg: color-mix(in srgb, var(--spectrum-yellow) 40%, transparent);
  --bs-highlight-color: inherit;

  --bs-primary: var(--primary);             --bs-primary-rgb: var(--primary-rgb);
  --bs-primary-text-emphasis: var(--primary-hover);
  --bs-primary-bg-subtle: var(--primary-soft);  --bs-primary-border-subtle: var(--primary-soft-2);
  --bs-secondary: var(--text-muted);        --bs-secondary-rgb: var(--text-muted-rgb);
  --bs-secondary-text-emphasis: var(--text-2);
  --bs-secondary-bg-subtle: var(--surface-3);   --bs-secondary-border-subtle: var(--line-strong);
  --bs-success: var(--success);             --bs-success-rgb: var(--success-rgb);
  --bs-success-text-emphasis: var(--success);
  --bs-success-bg-subtle: var(--success-soft);  --bs-success-border-subtle: color-mix(in srgb, var(--success) 30%, transparent);
  --bs-warning: var(--warning);             --bs-warning-rgb: var(--warning-rgb);
  --bs-warning-text-emphasis: var(--warning);
  --bs-warning-bg-subtle: var(--warning-soft);  --bs-warning-border-subtle: var(--warning-line);
  --bs-danger: var(--danger);               --bs-danger-rgb: var(--danger-rgb);
  --bs-danger-text-emphasis: var(--danger);
  --bs-danger-bg-subtle: var(--danger-soft);    --bs-danger-border-subtle: color-mix(in srgb, var(--danger) 35%, transparent);
  --bs-info: var(--info);                   --bs-info-rgb: var(--info-rgb);
  --bs-info-text-emphasis: var(--info);
  --bs-info-bg-subtle: var(--info-soft);        --bs-info-border-subtle: color-mix(in srgb, var(--info) 30%, transparent);
  --bs-light-rgb: var(--surface-2-rgb);
  --bs-dark-rgb: var(--text-rgb);

  --bs-form-valid-color: var(--success);     --bs-form-valid-border-color: var(--success);
  --bs-form-invalid-color: var(--danger);    --bs-form-invalid-border-color: var(--danger);
}

/* ---------- 2. Base --------------------------------------------------------- */
html { -webkit-text-size-adjust: 100%; }
body {
  background: var(--bg); color: var(--text);
  font: var(--fw-regular) var(--fs-md)/var(--lh-body) var(--font-sans);
  font-feature-settings: "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4, .h1, .h2, .h3, .h4 { line-height: var(--lh-tight); font-weight: var(--fw-semibold); color: var(--text); }
h1, .h1 { font-size: var(--fs-2xl); letter-spacing: var(--tracking-tight); font-weight: var(--fw-bold); }
h2, .h2 { font-size: var(--fs-xl); letter-spacing: var(--tracking-tight); }
h3, .h3 { font-size: var(--fs-lg); }
h4, .h4 { font-size: var(--fs-md); }
a { color: var(--link); text-underline-offset: 2px; }
a:hover { color: var(--primary-hover); }
::selection { background: color-mix(in srgb, var(--primary) 28%, transparent); }
mark, .mark { background: color-mix(in srgb, var(--spectrum-yellow) 40%, transparent); color: inherit; border-radius: 2px; padding: 0 1px; }
.text-muted, .text-body-secondary { color: var(--text-muted) !important; }

/* Focus: one ring everywhere, visible on any surface */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.btn:focus-visible, .form-control:focus-visible, .form-select:focus-visible, .form-check-input:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; box-shadow: none; }

/* Icons from the sprite: <svg class="op-i"><use href="#i-name"></use></svg> (ui_icon() / OP.icon()) */
.op-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
svg.op-i { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; vertical-align: -0.3em; }
svg.op-i.sm { width: 16px; height: 16px; vertical-align: -0.2em; }
svg.op-i.lg { width: 24px; height: 24px; }

.op-num { font-variant-numeric: tabular-nums; }
.op-muted { color: var(--text-muted); }
.op-sr-only, .visually-hidden { position: absolute !important; width: 1px !important; height: 1px !important; overflow: hidden !important; clip: rect(0 0 0 0) !important; white-space: nowrap !important; margin: -1px !important; padding: 0 !important; border: 0 !important; }
.op-spectrum-line { height: 3px; background: var(--spectrum); }
.op-kbd { display: inline-block; font-size: 11px; font-weight: var(--fw-semibold); color: var(--text-muted); border: 1px solid var(--line-strong); border-bottom-width: 2px; border-radius: 4px; padding: 0 5px; line-height: 17px; background: var(--surface); font-family: var(--font-sans); }
.op-small-link { font-size: 13px; font-weight: var(--fw-medium); text-decoration: none; }
.op-small-link:hover { text-decoration: underline; }
.op-danger-text { color: var(--danger); }

/* ---------- 3. Bootstrap components, themed --------------------------------- */

/* Buttons (.btn .btn-primary | -secondary | -ghost | -danger | -link | -on-dark, sizes -sm / -lg) */
.btn {
  --bs-btn-padding-x: 14px; --bs-btn-padding-y: 0; --bs-btn-font-size: 14px; --bs-btn-font-weight: var(--fw-semibold);
  --bs-btn-line-height: 1.25; --bs-btn-border-radius: var(--r-sm); --bs-btn-border-width: 1px;
  --bs-btn-focus-box-shadow: none; --bs-btn-disabled-opacity: .5;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 36px; white-space: nowrap; text-decoration: none;
  transition: background-color var(--dur-1), border-color var(--dur-1), color var(--dur-1), box-shadow var(--dur-1);
}
.btn svg.op-i { width: 18px; height: 18px; }
.btn-sm { --bs-btn-padding-x: 10px; --bs-btn-font-size: 13px; --bs-btn-border-radius: var(--r-sm); min-height: 30px; }
.btn-lg { --bs-btn-padding-x: 20px; --bs-btn-font-size: 15px; --bs-btn-border-radius: var(--r-sm); min-height: 44px; }
.btn .btn-meta { font-weight: var(--fw-regular); opacity: .8; }
.btn-primary {
  --bs-btn-color: var(--on-primary); --bs-btn-bg: var(--primary); --bs-btn-border-color: var(--primary);
  --bs-btn-hover-color: var(--on-primary); --bs-btn-hover-bg: var(--primary-hover); --bs-btn-hover-border-color: var(--primary-hover);
  --bs-btn-active-color: var(--on-primary); --bs-btn-active-bg: var(--primary-hover); --bs-btn-active-border-color: var(--primary-hover);
  --bs-btn-disabled-color: var(--on-primary); --bs-btn-disabled-bg: var(--primary); --bs-btn-disabled-border-color: var(--primary);
}
.btn-secondary, .btn-light, .btn-outline-secondary, .btn-outline-primary, .btn-outline-dark {
  --bs-btn-color: var(--text); --bs-btn-bg: var(--surface); --bs-btn-border-color: var(--line-strong);
  --bs-btn-hover-color: var(--text); --bs-btn-hover-bg: var(--surface-2); --bs-btn-hover-border-color: var(--ink-400);
  --bs-btn-active-color: var(--text); --bs-btn-active-bg: var(--surface-3); --bs-btn-active-border-color: var(--ink-400);
  --bs-btn-disabled-color: var(--text); --bs-btn-disabled-bg: var(--surface); --bs-btn-disabled-border-color: var(--line-strong);
  box-shadow: var(--shadow-1);
}
.btn-outline-primary { --bs-btn-color: var(--primary); --bs-btn-hover-color: var(--primary); --bs-btn-active-color: var(--primary); --bs-btn-disabled-color: var(--primary); }
.btn-ghost {
  --bs-btn-color: var(--text-2); --bs-btn-bg: transparent; --bs-btn-border-color: transparent;
  --bs-btn-hover-color: var(--text); --bs-btn-hover-bg: var(--surface-3); --bs-btn-hover-border-color: transparent;
  --bs-btn-active-color: var(--text); --bs-btn-active-bg: var(--surface-3); --bs-btn-active-border-color: transparent;
  --bs-btn-disabled-color: var(--text-2); --bs-btn-disabled-bg: transparent; --bs-btn-disabled-border-color: transparent;
}
.btn-danger {
  --bs-btn-color: var(--on-danger); --bs-btn-bg: var(--danger); --bs-btn-border-color: var(--danger);
  --bs-btn-hover-color: var(--on-danger); --bs-btn-hover-bg: color-mix(in srgb, var(--danger) 88%, #000); --bs-btn-hover-border-color: color-mix(in srgb, var(--danger) 88%, #000);
  --bs-btn-active-color: var(--on-danger); --bs-btn-active-bg: color-mix(in srgb, var(--danger) 80%, #000); --bs-btn-active-border-color: color-mix(in srgb, var(--danger) 80%, #000);
  --bs-btn-disabled-color: var(--on-danger); --bs-btn-disabled-bg: var(--danger); --bs-btn-disabled-border-color: var(--danger);
}
.btn-outline-danger {
  --bs-btn-color: var(--danger); --bs-btn-bg: var(--surface); --bs-btn-border-color: var(--line-strong);
  --bs-btn-hover-color: var(--danger); --bs-btn-hover-bg: var(--danger-soft); --bs-btn-hover-border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  --bs-btn-active-color: var(--danger); --bs-btn-active-bg: var(--danger-soft); --bs-btn-active-border-color: var(--danger);
  --bs-btn-disabled-color: var(--danger); --bs-btn-disabled-bg: var(--surface); --bs-btn-disabled-border-color: var(--line-strong);
  box-shadow: var(--shadow-1);
}
.btn-success {
  --bs-btn-color: var(--on-primary); --bs-btn-bg: var(--success); --bs-btn-border-color: var(--success);
  --bs-btn-hover-color: var(--on-primary); --bs-btn-hover-bg: color-mix(in srgb, var(--success) 85%, #000); --bs-btn-hover-border-color: color-mix(in srgb, var(--success) 85%, #000);
}
.btn-link {
  --bs-btn-color: var(--link); --bs-btn-hover-color: var(--primary-hover); --bs-btn-active-color: var(--primary-hover);
  --bs-btn-padding-x: 0; --bs-btn-font-weight: var(--fw-medium); --bs-btn-disabled-color: var(--text-muted);
  min-height: 0; text-decoration: none; border: 0;
}
.btn-link:hover { text-decoration: underline; }
.btn-on-dark {
  --bs-btn-color: var(--on-inverse); --bs-btn-bg: rgba(255, 255, 255, .1); --bs-btn-border-color: rgba(255, 255, 255, .14);
  --bs-btn-hover-color: var(--on-inverse); --bs-btn-hover-bg: rgba(255, 255, 255, .18); --bs-btn-hover-border-color: rgba(255, 255, 255, .2);
  --bs-btn-active-color: var(--on-inverse); --bs-btn-active-bg: rgba(255, 255, 255, .22); --bs-btn-active-border-color: rgba(255, 255, 255, .2);
}
.btn-on-dark.is-danger { --bs-btn-color: #FFB4AE; --bs-btn-hover-color: #FFC9C4; }
.btn-on-dark.is-primary { --bs-btn-color: var(--ink-900); --bs-btn-bg: #fff; --bs-btn-border-color: #fff; --bs-btn-hover-color: var(--ink-900); --bs-btn-hover-bg: var(--omi-blue-100); --bs-btn-hover-border-color: var(--omi-blue-100); }
.btn-close { --bs-btn-close-focus-shadow: none; }

/* Forms: .form-control (= mockup .input), .form-select, .form-label, .form-text, .form-check-input, .form-switch */
.form-control, .form-select {
  min-height: 40px; padding: 8px 12px; border-radius: var(--r-sm); border: 1px solid var(--line-strong);
  background-color: var(--surface); color: var(--text); font-size: var(--fs-md); line-height: 1.4;
  transition: border-color var(--dur-1), box-shadow var(--dur-1);
}
.form-select { padding-right: 34px; background-position: right 10px center; background-size: 16px 12px; }
.form-control::placeholder { color: var(--icon); opacity: 1; }
.form-control:hover, .form-select:hover { border-color: var(--ink-400); }
.form-control:focus, .form-select:focus { border-color: var(--focus); box-shadow: var(--focus-ring); background-color: var(--surface); color: var(--text); outline: none; }
.form-control:disabled, .form-select:disabled { background-color: var(--surface-2); color: var(--text-muted); }
.form-control-sm, .form-select-sm { min-height: 34px; font-size: 14px; padding-top: 5px; padding-bottom: 5px; }
.form-select-sm { min-height: 32px; font-size: 13px; }
.form-control-lg { min-height: 44px; font-size: var(--fs-md); }
textarea.form-control { min-height: 120px; resize: vertical; padding: 10px 12px; }
.form-control.is-invalid, .form-select.is-invalid { border-color: var(--danger); }
.form-label, .op-label { font-size: 14px; font-weight: var(--fw-medium); color: var(--text); margin-bottom: 6px; }
.form-text, .op-help { font-size: var(--fs-sm); color: var(--text-muted); }
.invalid-feedback { font-size: var(--fs-sm); color: var(--danger); }
.form-check-input {
  --bs-form-check-bg: var(--surface);
  width: 18px; height: 18px; margin-top: .15em; border: 1.5px solid var(--line-strong); border-radius: var(--r-xs);
  background-color: var(--surface); cursor: pointer; transition: background-color var(--dur-1), border-color var(--dur-1);
}
.form-check-input[type="radio"] { border-radius: 50%; }
.form-check-input:hover { border-color: var(--primary); }
.form-check-input:focus { border-color: var(--primary); box-shadow: none; }
.form-check-input:checked, .form-check-input:indeterminate { background-color: var(--primary); border-color: var(--primary); }
.form-check-label { font-size: 14px; }
.form-switch .form-check-input { width: 34px; height: 20px; border-radius: var(--r-pill); border-width: 1px; margin-top: .1em; background-color: var(--line-strong); border-color: var(--line-strong);
  --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); }
.form-switch .form-check-input:focus { --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); }
.form-switch .form-check-input:checked { background-color: var(--primary); border-color: var(--primary); }
.input-group-text { background: var(--surface-2); border-color: var(--line-strong); color: var(--text-muted); }

/* Badges: .badge + .badge-new | -new-soft | -lock | -everyone | -neutral | -role-admin | -role-moderator | -role-partner | -danger | -success */
.badge {
  --bs-badge-padding-x: 7px; --bs-badge-padding-y: 0; --bs-badge-font-size: var(--fs-xs); --bs-badge-font-weight: var(--fw-semibold);
  --bs-badge-border-radius: var(--r-xs);
  display: inline-flex; align-items: center; gap: 4px; height: 20px; line-height: 1; vertical-align: middle; white-space: nowrap;
}
.badge svg.op-i { width: 13px; height: 13px; stroke-width: 2; }
.badge-new { color: #fff; background: var(--spectrum-teal); }
.badge-new-soft { color: #0B6E8F; background: color-mix(in srgb, var(--spectrum-teal) 14%, var(--surface)); }
.badge-lock { color: var(--acl-restricted); background: var(--acl-restricted-soft); }
.badge-everyone { color: var(--acl-everyone); background: var(--success-soft); }
.badge-neutral { color: var(--text-2); background: var(--surface-3); }
.badge-role-admin { color: #fff; background: var(--spectrum-navy); }
.badge-role-moderator { color: var(--omi-blue-800); background: var(--omi-blue-100); }
.badge-role-partner { color: var(--text-2); background: var(--surface-3); }
.badge-danger { color: var(--danger); background: var(--danger-soft); }
.badge-success { color: var(--success); background: var(--success-soft); }
:root[data-theme="dark"] .badge-new { color: #062330; }
:root[data-theme="dark"] .badge-new-soft { color: #7FD0EC; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .badge-new { color: #062330; }
  :root:not([data-theme="light"]) .badge-new-soft { color: #7FD0EC; }
}

/* Tables: .table inside .op-table-wrap (rounded panel) */
.table {
  --bs-table-color: var(--text); --bs-table-bg: var(--surface); --bs-table-border-color: var(--line);
  --bs-table-striped-color: var(--text); --bs-table-striped-bg: var(--surface-2);
  --bs-table-hover-color: var(--text); --bs-table-hover-bg: var(--surface-2);
  --bs-table-active-color: var(--text); --bs-table-active-bg: var(--selected);
  font-size: 14px; border-collapse: separate; border-spacing: 0;
}
.table > :not(caption) > * > * { padding: 10px 12px; border-bottom-color: var(--line); }
.table > thead > tr > th, .table > thead > tr > td {
  font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--text-muted); background: var(--surface-2); white-space: nowrap; text-align: left;
}
.table td { vertical-align: middle; }
.table > tbody > tr:last-child > * { border-bottom: 0; }
.table-hover > tbody > tr:hover > * { --bs-table-bg-state: var(--surface-2); }
.op-table-wrap { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
.op-table-wrap > .table, .op-table-wrap > .table-responsive > .table { margin: 0; }
.op-table-wrap.is-scroll { overflow: auto; }
.op-table-foot { padding: 10px 14px; border-top: 1px solid var(--line); }

/* Alerts: Bootstrap .alert coloured from tokens (legacy and simple messages). New UI uses .op-notice. */
.alert { --bs-alert-border-radius: var(--r-sm); --bs-alert-padding-x: 14px; --bs-alert-padding-y: 12px; font-size: 14px; }
.alert-info, .alert-primary { --bs-alert-color: var(--text); --bs-alert-bg: var(--info-soft); --bs-alert-border-color: color-mix(in srgb, var(--info) 30%, transparent); --bs-alert-link-color: var(--link); }
.alert-success { --bs-alert-color: var(--text); --bs-alert-bg: var(--success-soft); --bs-alert-border-color: color-mix(in srgb, var(--success) 30%, transparent); --bs-alert-link-color: var(--link); }
.alert-warning { --bs-alert-color: var(--text); --bs-alert-bg: var(--warning-soft); --bs-alert-border-color: var(--warning-line); --bs-alert-link-color: var(--link); }
.alert-danger { --bs-alert-color: var(--text); --bs-alert-bg: var(--danger-soft); --bs-alert-border-color: color-mix(in srgb, var(--danger) 35%, transparent); --bs-alert-link-color: var(--link); }
.alert-secondary, .alert-light { --bs-alert-color: var(--text); --bs-alert-bg: var(--surface-2); --bs-alert-border-color: var(--line); --bs-alert-link-color: var(--link); }

/* Cards (legacy pages); new UI uses .op-panel */
.card { --bs-card-bg: var(--surface); --bs-card-border-color: var(--line); --bs-card-border-radius: var(--r-md); --bs-card-inner-border-radius: calc(var(--r-md) - 1px); --bs-card-cap-bg: var(--surface-2); --bs-card-color: var(--text); }
.list-group { --bs-list-group-bg: var(--surface); --bs-list-group-color: var(--text); --bs-list-group-border-color: var(--line); --bs-list-group-action-hover-bg: var(--surface-2); --bs-list-group-active-bg: var(--primary); --bs-list-group-active-border-color: var(--primary); --bs-list-group-active-color: var(--on-primary); }
.pagination { --bs-pagination-color: var(--link); --bs-pagination-bg: var(--surface); --bs-pagination-border-color: var(--line); --bs-pagination-hover-bg: var(--surface-2); --bs-pagination-hover-border-color: var(--line); --bs-pagination-active-bg: var(--primary); --bs-pagination-active-border-color: var(--primary); --bs-pagination-active-color: var(--on-primary); --bs-pagination-disabled-bg: var(--surface); --bs-pagination-disabled-color: var(--text-muted); --bs-pagination-focus-box-shadow: var(--focus-ring); }

/* Menus: Bootstrap dropdown styled as the mockup .menu */
.dropdown-menu {
  --bs-dropdown-bg: var(--surface); --bs-dropdown-color: var(--text); --bs-dropdown-border-color: var(--line);
  --bs-dropdown-border-radius: var(--r-md); --bs-dropdown-padding-x: 6px; --bs-dropdown-padding-y: 6px; --bs-dropdown-min-width: 200px;
  --bs-dropdown-box-shadow: var(--shadow-2); --bs-dropdown-font-size: 14px;
  --bs-dropdown-link-color: var(--text); --bs-dropdown-link-hover-color: var(--text); --bs-dropdown-link-hover-bg: var(--surface-3);
  --bs-dropdown-link-active-color: var(--text); --bs-dropdown-link-active-bg: var(--surface-3);
  --bs-dropdown-item-padding-x: 10px; --bs-dropdown-item-padding-y: 8px; --bs-dropdown-item-border-radius: 6px;
  --bs-dropdown-divider-bg: var(--line); --bs-dropdown-divider-margin-y: 6px; --bs-dropdown-header-color: var(--text-muted);
  box-shadow: var(--bs-dropdown-box-shadow);
}
.dropdown-menu.show { animation: op-pop var(--dur-2) var(--ease-out); }
.dropdown-item { display: flex; align-items: center; gap: 10px; }
.dropdown-item svg.op-i { color: var(--icon); width: 18px; height: 18px; }
.dropdown-item:focus-visible { outline: none; background: var(--surface-3); }
.dropdown-item.is-danger, .dropdown-item.is-danger svg.op-i { color: var(--danger); }
.dropdown-divider { margin-left: 4px; margin-right: 4px; }
.op-menu-head { padding: 8px 10px 10px; display: grid; font-size: 13px; border-bottom: 1px solid var(--line); margin-bottom: 6px; line-height: 1.35; }
.op-menu-head span { color: var(--text-muted); }
@keyframes op-pop { from { opacity: 0; transform: translateY(-4px) scale(.98); } }

/* Dialogs: Bootstrap .modal styled as the mockup .dialog (OP.confirmDialog / OP.dialog build these) */
.modal {
  --bs-modal-bg: var(--surface); --bs-modal-color: var(--text); --bs-modal-border-width: 0; --bs-modal-border-radius: var(--r-lg);
  --bs-modal-box-shadow: var(--shadow-3); --bs-modal-width: 520px; --bs-modal-padding: 16px 20px;
  --bs-modal-header-padding: 20px 20px 4px; --bs-modal-header-border-width: 0; --bs-modal-footer-border-width: 0; --bs-modal-footer-gap: 8px;
  --bs-modal-inner-border-radius: var(--r-lg);
}
.modal-lg, .modal-xl { --bs-modal-width: 720px; }
.modal-header { align-items: flex-start; gap: 12px; }
.modal-title { font-size: var(--fs-xl); font-weight: var(--fw-semibold); letter-spacing: var(--tracking-tight); }
.modal-header p, .modal-sub { margin: 4px 0 0; color: var(--text-muted); font-size: 14px; }
.modal-footer { padding: 12px 20px 20px; }
.modal-footer > * { margin: 0; }
.modal-backdrop, .offcanvas-backdrop { --bs-backdrop-bg: var(--scrim); --bs-backdrop-opacity: 1; background-color: var(--scrim); }
.modal-backdrop.fade, .offcanvas-backdrop.fade { opacity: 0; }
.modal-backdrop.show, .offcanvas-backdrop.show { opacity: 1; }
.modal.fade .modal-dialog { transition: transform var(--dur-3) var(--ease-out), opacity var(--dur-3) var(--ease-out); transform: translateY(12px) scale(.98); opacity: 0; }
.modal.show .modal-dialog { transform: none; opacity: 1; }

/* Drawers: Bootstrap .offcanvas styled as the mockup .drawer */
.offcanvas, .offcanvas-lg, .offcanvas-md, .offcanvas-sm {
  --bs-offcanvas-width: min(var(--drawer-w), 100vw); --bs-offcanvas-bg: var(--surface); --bs-offcanvas-color: var(--text);
  --bs-offcanvas-border-width: 0; --bs-offcanvas-box-shadow: var(--shadow-3); --bs-offcanvas-padding-x: 20px; --bs-offcanvas-padding-y: 16px;
  --bs-offcanvas-transition: transform var(--dur-3) var(--ease-out);
}
.offcanvas.show, .offcanvas.showing { box-shadow: var(--shadow-3); }
.offcanvas-header { gap: 12px; border-bottom: 1px solid var(--line); }
.offcanvas-title { font-size: var(--fs-xl); font-weight: var(--fw-semibold); letter-spacing: var(--tracking-tight); }
.offcanvas-header p { margin: 2px 0 0; font-size: 13px; color: var(--text-muted); }
.offcanvas-body { padding: 8px 20px 20px; }
.op-drawer-foot { padding: 16px 20px 20px; border-top: 1px solid var(--line); background: var(--surface-2); }
.offcanvas-start.op-drawer-nav { --bs-offcanvas-width: min(300px, 86vw); }

/* Tabs: .nav-underline styled as the mockup .tabs */
.nav-underline { --bs-nav-underline-gap: var(--sp-6); --bs-nav-underline-border-width: 2px; --bs-nav-underline-link-active-color: var(--text); --bs-nav-link-color: var(--text-muted); --bs-nav-link-hover-color: var(--text); --bs-nav-link-font-weight: var(--fw-semibold); --bs-nav-link-font-size: 14px; --bs-nav-link-padding-y: 10px; border-bottom: 1px solid var(--line); }
.nav-underline .nav-link { padding-bottom: 12px; margin-bottom: -1px; display: inline-flex; gap: 8px; align-items: center; }
.nav-underline .nav-link.active, .nav-underline .show > .nav-link { border-bottom-color: var(--primary); font-weight: var(--fw-semibold); }
.nav-tabs { --bs-nav-tabs-border-color: var(--line); --bs-nav-tabs-link-active-bg: var(--surface); --bs-nav-tabs-link-active-color: var(--text); --bs-nav-tabs-link-active-border-color: var(--line) var(--line) var(--surface); --bs-nav-link-color: var(--text-muted); --bs-nav-link-hover-color: var(--text); }

/* Progress */
.progress { --bs-progress-height: 6px; --bs-progress-bg: var(--surface-3); --bs-progress-border-radius: var(--r-pill); --bs-progress-bar-bg: var(--primary); --bs-progress-bar-transition: width var(--dur-3) linear; }
.progress.op-spectrum .progress-bar { background: var(--spectrum); }

/* Tooltips (Bootstrap) and OP data-tip tooltips (.op-tip) */
.tooltip { --bs-tooltip-bg: var(--inverse); --bs-tooltip-color: var(--on-inverse); --bs-tooltip-border-radius: 6px; --bs-tooltip-font-size: 13px; --bs-tooltip-padding-x: 10px; --bs-tooltip-padding-y: 7px; --bs-tooltip-opacity: 1; }
.op-tip { position: fixed; z-index: 1090; max-width: 280px; padding: 7px 10px; border-radius: 6px; background: var(--inverse); color: var(--on-inverse); font-size: 13px; line-height: 1.4; pointer-events: none; box-shadow: var(--shadow-2); }

/* ---------- 4. Custom components (op-) ------------------------------------- */

/* Icon button: 34px square, ghost */
.op-icon-btn {
  display: inline-grid; place-items: center; width: 34px; height: 34px; padding: 0; border-radius: var(--r-sm);
  border: 0; background: transparent; color: var(--text-muted); cursor: pointer; position: relative; text-decoration: none;
  transition: background-color var(--dur-1), color var(--dur-1);
}
.op-icon-btn:hover { background: var(--surface-3); color: var(--text); }
.op-icon-btn[aria-pressed="true"] { color: var(--primary); background: var(--primary-soft); }
.op-icon-btn.sm { width: 30px; height: 30px; }
.op-icon-btn[disabled] { opacity: .5; cursor: not-allowed; }
.op-count-dot {
  position: absolute; top: 1px; right: 0; min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--r-pill);
  background: var(--primary); color: var(--on-primary); font-size: 11px; font-weight: var(--fw-bold); line-height: 18px; text-align: center;
  box-shadow: 0 0 0 2px var(--surface);
}

/* Field layout */
.op-field { display: grid; gap: 6px; }
.op-field > .form-label { margin: 0; }
.op-label-row { display: flex; justify-content: space-between; align-items: baseline; }
.op-input-icon { position: relative; }
.op-input-icon > svg.op-i { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--icon); pointer-events: none; width: 18px; height: 18px; }
.op-input-icon > .form-control { padding-left: 36px; }
.op-input-icon > .op-kbd { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); }
.op-form-stack { display: grid; gap: 18px; }
.op-two { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.op-fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.op-filters { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 16px; }
.op-filters .op-grow { flex: 1; min-width: 240px; }
.op-filters .form-select { width: auto; min-width: 140px; }

/* Segmented control */
.op-segmented { display: inline-flex; padding: 3px; gap: 2px; border-radius: 8px; background: var(--surface-3); }
.op-segmented button, .op-segmented a { border: 0; background: transparent; height: 30px; padding: 0 10px; border-radius: 6px; color: var(--text-muted); font-size: 13px; font-weight: var(--fw-semibold); display: inline-flex; align-items: center; gap: 6px; cursor: pointer; text-decoration: none; }
.op-segmented button:hover, .op-segmented a:hover { color: var(--text); }
.op-segmented [aria-pressed="true"], .op-segmented [aria-selected="true"], .op-segmented [aria-current="true"] { background: var(--surface); color: var(--text); box-shadow: var(--shadow-1); }
.op-segmented svg.op-i { width: 16px; height: 16px; }

/* Chips */
.op-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.op-chip {
  display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: var(--r-pill);
  border: 1px solid var(--line-strong); background: var(--surface); font-size: 13px; font-weight: var(--fw-medium); cursor: pointer; color: var(--text-2); text-decoration: none;
}
.op-chip:hover { border-color: var(--ink-400); color: var(--text); }
.op-chip[aria-pressed="true"] { background: var(--primary-soft); border-color: var(--primary); color: var(--primary); }
.op-chip[aria-disabled="true"] { opacity: .5; cursor: not-allowed; text-decoration: line-through; }
.op-chip .op-chip-x { display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; margin-right: -4px; border: 0; background: none; color: inherit; padding: 0; }
.op-chip .op-chip-x:hover { background: var(--surface-3); }
.op-chip.is-group { color: var(--acl-restricted); background: var(--acl-restricted-soft); border-color: color-mix(in srgb, var(--acl-restricted) 30%, transparent); }

/* File-type tile: the swoosh colours encode the type. <span class="op-ft op-ft-pdf"><svg class="op-i">…</svg></span> */
.op-ft {
  --c: var(--ft-doc);
  width: 36px; height: 36px; border-radius: 9px; display: inline-grid; place-items: center; flex: none;
  color: var(--c); background: color-mix(in srgb, var(--c) 13%, var(--surface));
}
.op-ft svg.op-i { width: 20px; height: 20px; }
.op-ft.sm { width: 28px; height: 28px; border-radius: 7px; }
.op-ft.sm svg.op-i { width: 16px; height: 16px; }
.op-ft.lg { width: 56px; height: 56px; border-radius: 14px; }
.op-ft.lg svg.op-i { width: 30px; height: 30px; }
.op-ft-folder { --c: var(--ft-folder); background: var(--ft-folder-bg); }
.op-ft-folder svg.op-i { fill: color-mix(in srgb, var(--c) 30%, transparent); }
.op-ft-omiapp { --c: var(--ft-omiapp); }
.op-ft-installer { --c: var(--ft-installer); }
.op-ft-pdf { --c: var(--ft-pdf); }
.op-ft-video { --c: var(--ft-video); }
.op-ft-image { --c: var(--ft-image); }
.op-ft-zip { --c: var(--ft-zip); }
.op-ext { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0; color: var(--text-muted); }

/* Panels */
.op-panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); }
.op-panel-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--line); }
.op-panel-head h2 { font-size: 15px; letter-spacing: 0; }
.op-panel-body { padding: var(--sp-5); }
.op-panel > .op-table-wrap { border: 0; }

/* Inline notice: .op-notice .op-notice-info | -warning | -danger | -success | -restricted, icon + <div> text */
.op-notice { display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; border-radius: var(--r-sm); font-size: 14px; border: 1px solid; color: var(--text); }
.op-notice > svg.op-i { margin-top: 1px; }
.op-notice > div { flex: 1; min-width: 0; }
.op-notice-info { background: var(--info-soft); border-color: color-mix(in srgb, var(--info) 30%, transparent); }
.op-notice-info > svg.op-i { color: var(--info); }
.op-notice-success { background: var(--success-soft); border-color: color-mix(in srgb, var(--success) 30%, transparent); }
.op-notice-success > svg.op-i { color: var(--success); }
.op-notice-warning { background: var(--warning-soft); border-color: var(--warning-line); }
.op-notice-warning > svg.op-i { color: var(--warning); }
.op-notice-danger { background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 35%, transparent); }
.op-notice-danger > svg.op-i { color: var(--danger); }
.op-notice-restricted { background: var(--acl-restricted-soft); border-color: color-mix(in srgb, var(--acl-restricted) 30%, transparent); }
.op-notice-restricted > svg.op-i { color: var(--acl-restricted); }

/* Toasts (OP.toast): bottom centre, dark in light mode and light in dark mode */
#op-toast-root { position: fixed; z-index: 1095; left: 50%; bottom: 24px; transform: translateX(-50%); display: grid; gap: 8px; justify-items: center; pointer-events: none; width: max-content; max-width: calc(100vw - 32px); }
.op-toast {
  pointer-events: auto; display: flex; align-items: center; gap: 12px; min-height: 44px; padding: 8px 8px 8px 14px; border-radius: var(--r-md);
  background: var(--inverse); color: var(--on-inverse); font-size: 14px; box-shadow: var(--shadow-3); animation: op-toast-in var(--dur-3) var(--ease-out); max-width: calc(100vw - 32px);
}
.op-toast > span { padding: 4px 0; }
.op-toast.no-actions { padding-right: 14px; }
.op-toast { --t-ok: #9BCB5E; --t-err: #FF8A80; --t-info: #A9CBF0; }
.op-toast > svg.op-i { color: var(--t-ok); }
.op-toast.is-error > svg.op-i { color: var(--t-err); }
.op-toast.is-info > svg.op-i { color: var(--t-info); }
.op-toast .btn-link { --bs-btn-color: var(--on-inverse-link); --bs-btn-hover-color: var(--on-inverse-link); padding: 6px 8px; font-weight: var(--fw-semibold); }
.op-toast .op-icon-btn { color: var(--on-inverse-muted); width: 30px; height: 30px; }
.op-toast .op-icon-btn:hover { background: rgba(127, 137, 163, .2); color: var(--on-inverse); }
:root[data-theme="dark"] .op-toast { --t-ok: #3F7A12; --t-err: #C21D15; --t-info: #2C5B90; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .op-toast { --t-ok: #3F7A12; --t-err: #C21D15; --t-info: #2C5B90; } }
@keyframes op-toast-in { from { opacity: 0; transform: translateY(12px); } }
@keyframes op-fade { from { opacity: 0; } }

/* Floating bars: selection bar and pending-changes bar (always dark, white text) */
.op-selbar {
  position: sticky; bottom: 20px; z-index: 30; margin: 20px auto 0; width: fit-content; max-width: 100%;
  display: flex; align-items: center; gap: 16px; padding: 8px 8px 8px 18px; border-radius: var(--r-md);
  background: var(--bar-bg); color: #fff; box-shadow: var(--shadow-3); animation: op-toast-in var(--dur-3) var(--ease-out);
}
.op-selbar-count { white-space: nowrap; font-size: 14px; }
.op-selbar-count .op-num { color: #B4BBCA; }
.op-selbar-actions { display: flex; gap: 6px; }
.op-selbar .op-icon-btn { color: #B4BBCA; }
.op-selbar .op-icon-btn:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.op-savebar { position: fixed; left: 16px; right: 16px; bottom: 20px; margin: 0 auto; z-index: 46; max-width: 720px; animation: op-toast-in var(--dur-3) var(--ease-out); }
.op-savebar-main { display: flex; align-items: center; gap: 12px; padding: 10px 10px 10px 18px; border-radius: var(--r-md); background: var(--bar-bg); color: #fff; box-shadow: var(--shadow-3); font-size: 14px; }
.op-savebar-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--spectrum-orange); flex: none; }
.op-savebar-sp { flex: 1; }
.op-savebar .btn-link { --bs-btn-color: #A9CBF0; --bs-btn-hover-color: #C8DDF5; }

/* Breadcrumbs: <ol class="op-crumbs"><li><a>…</a></li>…<li aria-current="page"><span>…</span></li></ol> */
.op-crumbs { list-style: none; display: flex; flex-wrap: wrap; align-items: center; gap: 2px; margin: 0 0 10px; padding: 0; font-size: 14px; }
.op-crumbs li { display: flex; align-items: center; gap: 2px; color: var(--text-muted); }
.op-crumbs li + li::before { content: ""; width: 16px; height: 16px; background: currentColor; opacity: .5; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m9.5 6 6 6-6 6'/%3E%3C/svg%3E") center/16px no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m9.5 6 6 6-6 6'/%3E%3C/svg%3E") center/16px no-repeat; }
.op-crumbs a { color: var(--text-muted); text-decoration: none; padding: 2px 4px; border-radius: 4px; }
.op-crumbs a:hover { color: var(--text); background: var(--surface-3); }
.op-crumbs [aria-current] span { color: var(--text); font-weight: var(--fw-medium); padding: 2px 4px; }
.op-crumbs .op-crumb-ellipsis { display: none; }

/* Radio cards */
.op-radio-cards { display: grid; gap: 8px; }
.op-radio-card { display: flex; gap: 12px; align-items: flex-start; padding: 12px 14px; border: 1px solid var(--line-strong); border-radius: var(--r-md); cursor: pointer; }
.op-radio-card input { margin-top: 3px; accent-color: var(--primary); width: 16px; height: 16px; }
.op-radio-card:has(input:checked) { border-color: var(--primary); background: var(--primary-soft); }

/* Avatar */
.op-avatar { width: 32px; height: 32px; border-radius: 50%; display: inline-grid; place-items: center; flex: none; font-size: 12px; font-weight: var(--fw-bold); color: var(--omi-blue-800); background: var(--omi-blue-100); }
.op-avatar.sm { width: 26px; height: 26px; font-size: 11px; }
:root[data-theme="dark"] .op-avatar { color: var(--omi-blue-100); background: var(--omi-blue-800); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .op-avatar { color: var(--omi-blue-100); background: var(--omi-blue-800); } }

/* Empty state: icon badge + short spectrum bar (OP.emptyArc('search') in JS, ui_empty_visual('search') in PHP) */
.op-empty { display: grid; justify-items: center; text-align: center; gap: 8px; padding: 56px 24px; }
.op-empty-visual { display: grid; justify-items: center; gap: 12px; margin-bottom: 8px; }
.op-empty-badge {
  width: 64px; height: 64px; border-radius: 50%; display: grid; place-items: center; color: var(--primary);
  background: var(--primary-soft); box-shadow: 0 0 0 8px color-mix(in srgb, var(--primary-soft) 45%, transparent);
}
.op-empty-badge svg.op-i { width: 28px; height: 28px; stroke-width: 1.6; }
.op-empty-bar { width: 40px; height: 3px; border-radius: var(--r-pill); background: var(--spectrum); }

/* Logo (ui_logo()): colour letters on light surfaces, white letters on dark ones */
.op-logo { display: block; height: auto; max-width: 100%; }
.op-logo.op-logo-dark { display: none; }
:root[data-theme="dark"] .op-logo.op-logo-light { display: none; }
:root[data-theme="dark"] .op-logo.op-logo-dark { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .op-logo.op-logo-light { display: none; }
  :root:not([data-theme="light"]) .op-logo.op-logo-dark { display: block; }
}
.op-empty h2, .op-empty h3 { font-size: var(--fs-lg); letter-spacing: 0; }
.op-empty p { color: var(--text-muted); max-width: 42ch; margin: 0; }
.op-empty .op-empty-actions { margin-top: 12px; display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }

/* KPI tiles (dashboard, reports) */
.op-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 16px; }
.op-kpi { padding: 16px 18px; display: grid; gap: 6px; align-content: start; }
.op-kpi-l { font-size: 13px; color: var(--text-muted); font-weight: var(--fw-medium); }
.op-kpi b { font-size: 26px; font-weight: var(--fw-bold); letter-spacing: var(--tracking-tight); font-variant-numeric: tabular-nums; }
.op-kpi b small { font-size: 14px; font-weight: var(--fw-regular); letter-spacing: 0; }
.op-kpi-d { font-size: 13px; color: var(--text-muted); }
.op-kpi-d.is-up { color: var(--success); }

/* Spinner (inline loading) */
.op-spinner { width: 18px; height: 18px; border-radius: 50%; border: 2px solid color-mix(in srgb, currentColor 25%, transparent); border-top-color: currentColor; animation: op-spin .8s linear infinite; display: inline-block; flex: none; }
@keyframes op-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .op-spinner { animation-duration: 2.4s; } }

@media (max-width: 1180px) { .op-kpis { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 700px) {
  .op-two { grid-template-columns: 1fr; }
  .op-filters .form-select { flex: 1; }
  .op-crumbs .op-crumb-mid { display: none; }
  .op-crumbs .op-crumb-ellipsis { display: flex; }
  .op-selbar { bottom: 12px; gap: 8px; padding-left: 12px; width: 100%; }
  .op-selbar-count { flex: 1; }
  .op-selbar-actions .btn .op-btn-label { display: none; }
  .op-savebar-main { flex-wrap: wrap; }
  .op-kpis { gap: 10px; }
  .op-kpi b { font-size: 21px; }
}

/* ---------- 5. Touch and phones ------------------------------------------------
   Coarse pointers (phones, tablets): every control is at least 44x44px; small chips and links
   keep their look and get a bigger invisible hit area (::after). Inputs use 16px text on touch
   and narrow screens, so iOS Safari does not zoom in when they get focus. Fixed bars, toasts
   and trays keep clear of the iOS home indicator (env(safe-area-inset-*), viewport-fit=cover). */
@media (pointer: coarse) {
  .btn, .btn-sm { min-height: 44px; min-width: 44px; }
  .btn-sm { --bs-btn-font-size: 14px; }
  .btn-link { min-height: 44px; }
  .op-icon-btn, .op-icon-btn.sm { width: 44px; height: 44px; }
  .form-control, .form-select, .form-control-sm, .form-select-sm, .form-control-lg { min-height: 44px; font-size: 16px; }
  .dropdown-menu { --bs-dropdown-item-padding-y: 12px; }
  .dropdown-item { min-height: 44px; }
  .op-segmented button, .op-segmented a { height: 44px; padding: 0 12px; }
  .op-segmented { padding: 2px; }
  .op-chip, .op-crumbs a, .op-small-link, .op-chip .op-chip-x { position: relative; }
  .op-chip::after, .op-crumbs a::after, .op-small-link::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 44px; transform: translateY(-50%); }
  .op-chip .op-chip-x::after { content: ""; position: absolute; inset: -13px; }
  .form-check-input { width: 22px; height: 22px; }
  .form-check { min-height: 44px; display: flex; align-items: center; gap: 10px; padding-left: 0; }
  .form-check .form-check-input { float: none; margin: 0; flex: none; }
  .form-check-label { padding: 10px 0; }
  .form-switch .form-check-input { width: 44px; height: 26px; }
  .op-toast .op-icon-btn { width: 44px; height: 44px; }
  .op-toast .btn-link { min-height: 44px; }
}
@media (max-width: 700px) {
  .form-control, .form-select, textarea.form-control { font-size: 16px; }
}
#op-toast-root { bottom: calc(24px + env(safe-area-inset-bottom, 0px)); }
.op-selbar { bottom: calc(20px + env(safe-area-inset-bottom, 0px)); }
.op-savebar { bottom: calc(20px + env(safe-area-inset-bottom, 0px)); }
.op-drawer-foot { padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px)); }
.modal-footer { padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px)); }
/* A toast never covers the selection bar, the pending-changes bar or the upload tray: it moves above them */
body:has(.op-selbar) #op-toast-root, body:has(.op-savebar) #op-toast-root { bottom: calc(92px + env(safe-area-inset-bottom, 0px)); }
@media (max-width: 700px) {
  .op-selbar { bottom: calc(12px + env(safe-area-inset-bottom, 0px)); }
  #op-toast-root { width: calc(100vw - 32px); }
  .op-toast { width: 100%; }
  .op-toast > span { flex: 1; min-width: 0; overflow-wrap: anywhere; }
  body:has(.op-upload-tray) #op-toast-root { bottom: auto; top: calc(var(--topbar-h) + 12px); }
  /* Dialogs: full width with a small margin, body scrolls, footer buttons stay reachable */
  .modal-dialog { margin: 8px; max-width: none; }
  .modal-dialog:not(.modal-dialog-scrollable) .modal-content { max-height: calc(100dvh - 16px); }
  .modal-content { display: flex; flex-direction: column; max-height: calc(100dvh - 16px); }
  .modal-body { overflow-y: auto; min-height: 0; overscroll-behavior: contain; }
  .modal-header { padding: 16px 16px 4px; }
  .modal-body { --bs-modal-padding: 12px 16px; }
  .modal-footer { padding-left: 16px; padding-right: 16px; flex-wrap: wrap; }
  .modal-footer > .btn { flex: 1 1 auto; }
  .modal-title { font-size: var(--fs-lg); overflow-wrap: anywhere; }
  .offcanvas-end { --bs-offcanvas-width: 100vw; }
  .offcanvas-body { padding-left: 16px; padding-right: 16px; }
  .op-empty { padding: 40px 16px; }
}
@media (orientation: landscape) and (max-height: 500px) {
  .modal-dialog { margin: 6px auto; }
  .modal-content { max-height: calc(100dvh - 12px); display: flex; flex-direction: column; }
  .modal-body { overflow-y: auto; min-height: 0; }
  .op-empty { padding: 24px 16px; }
}

/* Close buttons in dialog / drawer headers never shrink (long titles wrap instead) */
.modal-header > .op-icon-btn, .offcanvas-header > .op-icon-btn, .modal-header > .btn-close, .offcanvas-header > .btn-close { flex: none; }
.modal-header > div, .offcanvas-header > div { min-width: 0; }
