/* ==========================================================================
   Flyins base + shared components
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; } /* components set display:flex; keep the hidden attribute authoritative */
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font-family);
  color: var(--text-primary);
  background: var(--background-canvas);
  -webkit-font-smoothing: antialiased;
  font-size: 14px; line-height: 20px; letter-spacing: -0.05px;
}
img, svg { display: block; }
a { color: inherit; text-decoration: none; }
button, input { font: inherit; color: inherit; letter-spacing: inherit; }

/* ---- Text styles (Figma) --------------------------------------------- */
.t-heading-24   { font-size: 24px; line-height: 32px; font-weight: var(--fw-semibold); letter-spacing: -0.47px; color: var(--text-heading); margin: 0; }
.t-body-14      { font-size: 14px; line-height: 20px; font-weight: var(--fw-regular); letter-spacing: -0.05px; }
.t-body-14-md   { font-size: 14px; line-height: 20px; font-weight: var(--fw-medium);  letter-spacing: -0.05px; }
.t-body-14-sb   { font-size: 14px; line-height: 20px; font-weight: var(--fw-semibold); letter-spacing: -0.05px; }
.t-body-13      { font-size: 13px; line-height: 18px; font-weight: var(--fw-regular); letter-spacing: -0.04px; }
.t-body-13-md   { font-size: 13px; line-height: 18px; font-weight: var(--fw-medium);  letter-spacing: -0.04px; }

.link { color: var(--brand-fg); font-weight: var(--fw-medium); }
.link:hover { color: var(--brand-fg-hover); text-decoration: underline; }
/* Text button (Button "link" treatment): brand label, no container — e.g. Settings › Change Password */
.btn-text {
  display: inline-flex; align-items: center; gap: var(--space-6); padding: 2px 0; border: 0; background: none;
  font: inherit; font-size: 14px; line-height: 20px; font-weight: var(--fw-semibold); letter-spacing: -0.05px;
  color: var(--brand-fg); cursor: pointer; border-radius: var(--r-xs);
}
.btn-text:hover { color: var(--brand-fg-hover); text-decoration: underline; text-underline-offset: 2px; }
.btn-text:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.btn-text--danger { color: var(--danger-fg); }
.btn-text--danger:hover { color: var(--danger-fg-hover); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---- Button (Figma component set 31:120) -----------------------------
   Styles: primary · secondary · ghost · danger.  Sizes: medium (42px, default) · small (28px).
   Icon: <svg class="btn__icon"> with fill="currentColor" (16px medium / 14px small).
   ------------------------------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-8);
  height: var(--control-lg);
  padding: var(--space-4) var(--space-12);
  border-radius: var(--r-sm);
  border: var(--border-1) solid transparent;
  font-size: 14px; line-height: 20px; font-weight: var(--fw-semibold); letter-spacing: -0.05px;
  cursor: pointer; white-space: nowrap; text-decoration: none;
  transition: background-color .12s, border-color .12s, color .12s;
}
.btn__icon { width: 16px; height: 16px; flex-shrink: 0; }
.btn--sm { height: var(--control-sm); padding: 0 var(--space-10); gap: var(--space-6); font-size: 13px; line-height: 18px; letter-spacing: -0.04px; }
.btn--sm .btn__icon { width: 14px; height: 14px; }
.btn--lg { height: var(--control-lg); } /* legacy alias — medium is 42px */
.btn--block { width: 100%; }
.btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--brand-border); }

.btn--primary { background: var(--brand-default); color: var(--brand-on-brand); }
.btn--primary:hover { background: var(--brand-hover); }
.btn--primary:active { background: var(--brand-active); }

.btn--secondary { background: var(--background-surface); border-color: var(--border-control); color: var(--text-primary); }
.btn--secondary:hover { background: var(--secondary-hover-bg); border-color: var(--secondary-hover-border); }

.btn--ghost { background: transparent; color: var(--text-secondary); }
.btn--ghost:hover { background: var(--background-hover); color: var(--text-primary); }

.btn--danger { background: var(--status-danger); color: var(--on-danger); }
.btn--danger:hover { background: var(--status-danger-hover); }

.btn:disabled, .btn[aria-disabled="true"] {
  background: var(--background-disabled); border-color: transparent; color: var(--text-disabled);
  cursor: not-allowed; box-shadow: none;
}
.btn--secondary:disabled, .btn--secondary[aria-disabled="true"] { border-color: var(--border-disabled); }
.btn--ghost:disabled, .btn--ghost[aria-disabled="true"] { background: transparent; }

/* ---- Icon Button (Figma 107:1235) — brand-purple icon, no container ----- */
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 20px; height: 20px; padding: 0; border: 0; background: none;
  color: var(--brand-fg); cursor: pointer; border-radius: var(--r-xs);
  transition: color .12s;
}
.icon-btn svg { width: 20px; height: 20px; }
.icon-btn--16, .icon-btn--16 svg { width: 16px; height: 16px; }
.icon-btn--24 { width: 24px; height: 24px; }
.icon-btn:hover { color: var(--brand-fg-strong); }
.icon-btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.icon-btn:disabled { color: var(--text-disabled); cursor: not-allowed; }
.icon-group { display: inline-flex; align-items: center; gap: var(--space-12); }
/* Destructive icon action (e.g. Reject) — Danger-700 per Figma User Requests */
.icon-btn--danger { color: var(--danger-fg); }
.icon-btn--danger:hover { color: var(--danger-fg-hover); }

/* ---- Checkbox (Figma 32:101) -------------------------------------------
   <label class="checkbox"><input type="checkbox"><span class="checkbox__box"></span>
     <span class="checkbox__label">Label</span></label>   (label optional)
   ------------------------------------------------------------------------ */
.checkbox { position: relative; display: inline-flex; align-items: center; gap: var(--space-8); cursor: pointer; font-size: 14px; line-height: 20px; color: var(--text-primary); }
.checkbox input { position: absolute; opacity: 0; width: 16px; height: 16px; margin: 0; cursor: pointer; }
.checkbox__box {
  position: relative; flex-shrink: 0; width: 16px; height: 16px;
  background: var(--background-surface) no-repeat center / 12px 12px;
  border: var(--border-1) solid var(--border-control); border-radius: var(--r-xs);
  transition: background-color .12s, border-color .12s;
}
.checkbox:hover .checkbox__box { border-color: var(--brand-fg); }
.checkbox input:focus-visible + .checkbox__box { box-shadow: 0 0 0 3px var(--brand-border); }
.checkbox input:checked + .checkbox__box {
  background-color: var(--brand-default); border-color: var(--brand-fill-border);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M9.6025 2.60231C9.82218 2.38277 10.1783 2.38268 10.3979 2.60231C10.6174 2.82195 10.6174 3.17808 10.3979 3.39772L4.89742 8.89748C4.67775 9.11715 4.32168 9.11715 4.10201 8.89748L1.60225 6.39772C1.38258 6.17805 1.38258 5.82198 1.60225 5.60231C1.82192 5.38264 2.17799 5.38264 2.39766 5.60231L4.49971 7.70436L9.6025 2.60231Z' fill='white'/%3E%3C/svg%3E");
}
.checkbox input:indeterminate + .checkbox__box { background-color: var(--brand-default); border-color: var(--brand-fill-border); background-image: none; }
.checkbox input:indeterminate + .checkbox__box::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 8px; height: 2px; border-radius: 1px;
  background: var(--brand-on-brand); transform: translate(-50%, -50%);
}
.checkbox:hover input:checked + .checkbox__box,
.checkbox:hover input:indeterminate + .checkbox__box { background-color: var(--brand-hover); border-color: var(--brand-hover); }
.checkbox input:disabled ~ * { cursor: not-allowed; }
.checkbox input:disabled + .checkbox__box { background-color: var(--background-disabled); border-color: var(--border-disabled); }
.checkbox input:disabled:checked + .checkbox__box {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M9.6025 2.60231C9.82218 2.38277 10.1783 2.38268 10.3979 2.60231C10.6174 2.82195 10.6174 3.17808 10.3979 3.39772L4.89742 8.89748C4.67775 9.11715 4.32168 9.11715 4.10201 8.89748L1.60225 6.39772C1.38258 6.17805 1.38258 5.82198 1.60225 5.60231C1.82192 5.38264 2.17799 5.38264 2.39766 5.60231L4.49971 7.70436L9.6025 2.60231Z' fill='%2394A3B8'/%3E%3C/svg%3E");
}
.checkbox input:disabled:indeterminate + .checkbox__box::after { background: var(--text-disabled); }
.checkbox input:disabled ~ .checkbox__label { color: var(--text-disabled); }

/* ---- Tabs (Figma 87:5854) ----------------------------------------------
   <div class="tabs" role="tablist"><button class="tab" role="tab" aria-selected="true">…</button>…</div>
   ------------------------------------------------------------------------ */
.tabs {
  display: inline-flex; align-items: flex-start; max-width: 100%;
  padding: var(--space-8); background: var(--background-sunken); border-radius: var(--r-sm);
  overflow-x: auto; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  flex-shrink: 0; padding: 7px 15px; /* 8/16 incl. the 1px border (Figma strokes sit inside) → 36px tall */
  border: var(--border-1) solid transparent; border-radius: var(--r-sm); background: transparent;
  font-size: 14px; line-height: 20px; font-weight: var(--fw-medium); letter-spacing: -0.05px;
  color: var(--text-muted); white-space: nowrap; cursor: pointer;
  transition: color .12s, background-color .12s, border-color .12s, box-shadow .12s;
}
.tab:hover { color: var(--text-heading); }
.tab[aria-selected="true"] {
  background: var(--background-selected); border-color: var(--border-control); color: var(--text-heading);
  box-shadow: var(--shadow-tab);
}
.tab:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.tab-panel[hidden] { display: none; }
/* Tabs + their panels: 8px between the tab bar and the content (Retail Shipments spacing, used on every tabbed page) */
.tab-group { display: flex; flex-direction: column; gap: var(--space-8); }
.tab-group > .tabs { align-self: flex-start; }
/* Segmented control = Tabs styling used as a radio group (e.g. Settings › Theme) */
.tab[role="radio"][aria-checked="true"] {
  background: var(--background-selected); border-color: var(--border-control); color: var(--text-heading);
  box-shadow: var(--shadow-tab);
}
.segmented { padding: var(--space-4); }
.segmented .tab { min-width: 88px; }

/* ---- Alert (Figma 310:3863) — Info · Warning · Danger -------------------
   <div class="alert alert--info" role="status"><img class="alert__icon" …>
     <div class="alert__body"><p class="alert__title">…</p><p class="alert__desc">…</p></div></div>
   ------------------------------------------------------------------------ */
.alert {
  display: flex; align-items: flex-start; gap: var(--space-10); width: 100%;
  padding: var(--space-12) var(--space-14);
  border: var(--border-1) solid; border-radius: var(--r-md);
  font-size: 14px; line-height: 20px; letter-spacing: -0.05px;
}
.alert__icon { width: 20px; height: 20px; flex-shrink: 0; }
.alert__body { display: flex; flex-direction: column; gap: 2px; flex: 1 0 0; min-width: 0; }
.alert__title, .alert__desc { margin: 0; }
.alert__title { font-weight: var(--fw-semibold); }
.alert__desc { font-weight: var(--fw-regular); color: var(--text-secondary); }
.alert__desc b { font-weight: var(--fw-semibold); }
.alert__desc small { font-size: 12px; }
.alert--info { background: var(--status-info-subtle); border-color: var(--status-info); }
.alert--info .alert__title { color: var(--status-info-text); }
.alert--warning { background: var(--status-warning-subtle); border-color: var(--status-warning); }
.alert--warning .alert__title { color: var(--status-warning-text); }
.alert--danger { background: var(--status-danger-subtle); border-color: var(--status-danger); }
.alert--danger .alert__title { color: var(--status-danger-text); }

/* ---- Section Header (Figma 70:503) -------------------------------------- */
.section-header { display: flex; align-items: flex-start; gap: var(--space-10); width: 100%; }
.section-header__icon { display: flex; align-items: center; justify-content: center; flex-shrink: 0; width: 20px; height: 28px; }
.section-header__icon img { width: 20px; height: 20px; }
.section-header__text { display: flex; flex-direction: column; gap: 2px; flex: 1 0 0; min-width: 0; }
.section-header__title { margin: 0; font-size: 20px; line-height: 28px; font-weight: var(--fw-semibold); letter-spacing: -0.33px; color: var(--text-heading); }
.section-header__subtitle { margin: 0; font-size: 14px; line-height: 20px; letter-spacing: -0.05px; color: var(--text-muted); }

/* ---- Panel (content card used on app pages) ------------------------------ */
.panel {
  display: flex; flex-direction: column; gap: var(--space-24); width: 100%;
  padding: var(--space-24);
  background: var(--background-surface); border: var(--border-1) solid var(--border-default); border-radius: var(--r-md);
}
.panel__head { display: flex; align-items: center; gap: var(--space-24); }
.panel__head > .section-header { flex: 1 0 0; min-width: 0; }
.panel__title { flex: 1 0 0; min-width: 0; margin: 0; font-size: 20px; line-height: 28px; font-weight: var(--fw-semibold); letter-spacing: -0.33px; color: var(--text-heading); }

/* ---- Input (Figma component set 28:12) --------------------------------
   States: Default · Hover · Focus · Error · Disabled
   Markup:
   <div class="field [is-error] [is-disabled]">
     <label class="field__label" for="x">Label</label>
     <div class="input">
       [<img class="input__icon" src="assets/icon-search.svg" alt="">]
       <input id="x" placeholder="Value" aria-describedby="x-hint">
       [<button class="input__icon-btn">…</button> | <img class="input__icon">]
     </div>
     <p class="field__hint" id="x-hint">Hint</p>
   </div>
   Focus is 2px purple ring (drawn as border + 1px inset so nothing shifts).
   ------------------------------------------------------------------------ */
.field { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-6); width: 100%; }
.field__label {
  font-size: 14px; line-height: 20px; font-weight: var(--fw-medium); letter-spacing: -0.05px;
  color: var(--text-primary);
}
/* Required marker: <span class="field__required" aria-hidden="true">*</span> after the label text (+ aria-required on the control) */
.field__required { margin-left: 2px; color: var(--required-color); }
.field__hint {
  margin: 0; width: 100%;
  font-size: 13px; line-height: 18px; font-weight: var(--fw-regular); letter-spacing: -0.04px;
  color: var(--text-muted);
}
.field__hint:empty { display: none; }

.input {
  display: flex; align-items: center; gap: var(--space-8);
  width: 100%; height: var(--control-lg);
  padding: var(--space-4) var(--space-14);
  background: var(--background-surface);
  border: var(--border-1) solid var(--border-input);
  border-radius: var(--r-sm);
  overflow: hidden;
  transition: border-color .12s, box-shadow .12s;
}
.input--lg { height: var(--control-lg); } /* legacy alias — Input is always 42px */
.input:hover { border-color: var(--border-control-hover); }
.input:focus-within,
.input.is-focus { border-color: var(--focus-ring); box-shadow: inset 0 0 0 1px var(--focus-ring); }

.input input {
  flex: 1 0 0; min-width: 0; height: 100%;
  border: 0; outline: 0; background: transparent; padding: 0;
  font-size: 14px; line-height: 20px; font-weight: var(--fw-regular); letter-spacing: -0.05px;
  color: var(--text-primary);
}
.input input::placeholder { color: var(--text-placeholder); opacity: 1; }
.input__icon { flex-shrink: 0; width: 16px; height: 16px; }
.input__icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; width: 16px; height: 16px;
  padding: 0; border: 0; background: none; cursor: pointer; border-radius: var(--r-xs);
}
.input__icon-btn img { width: 16px; height: 16px; }
.input__icon-btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.input__icon-btn[aria-pressed="true"] img { opacity: .55; }

/* Error */
.field.is-error .input,
.field.is-error .input:hover { border-color: var(--status-danger); box-shadow: none; }
.field.is-error .input:focus-within { border-color: var(--status-danger); box-shadow: inset 0 0 0 1px var(--status-danger); }
.field.is-error .field__hint { color: var(--status-danger-text); }

/* Disabled */
.field.is-disabled .field__label,
.field.is-disabled .field__hint { color: var(--text-disabled); }
.field.is-disabled .input,
.input:has(input:disabled) {
  background: var(--background-disabled);
  border-color: var(--border-disabled);
  box-shadow: none; cursor: not-allowed;
}
.field.is-disabled .input input,
.input input:disabled { color: var(--text-disabled); cursor: not-allowed; }
.field.is-disabled .input input::placeholder,
.input input:disabled::placeholder { color: var(--text-disabled); }
.field.is-disabled .input__icon,
.field.is-disabled .input__icon-btn img,
.input:has(input:disabled) .input__icon { opacity: .6; }
.field.is-disabled .input__icon-btn { pointer-events: none; }

/* ---- Dropdown Menu + Item (Figma 231:4252 / 231:4244) --------------------
   Panel: surface, 1px Slate-300 border, radius 10, padding 6, gap 2.
   Item: padding 8/12, gap 8, radius 6, 16px check slot always present.
   States: Default · Hover (Background/Hover) · Active (Background/Sunken + check)
   Markup (built by js/dropdown.js — use Flyins.dropdown / data-dropdown):
   <div class="menu" role="menu|listbox">
     <button class="menu__item" role="menuitemradio|option|menuitem" aria-checked|aria-selected="true">
       <span class="menu__check"><img src="assets/icon-check.svg" alt=""></span>
       <span class="menu__label">Item</span>
     </button>
   </div>
   ------------------------------------------------------------------------ */
.menu {
  position: absolute; top: calc(100% + 8px); left: auto; z-index: 40;
  display: flex; flex-direction: column; gap: var(--space-2);
  min-width: 200px; max-width: min(320px, calc(100vw - 32px));
  max-height: min(420px, calc(100vh - 120px)); overflow-y: auto;
  padding: var(--space-6);
  background: var(--background-surface);
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--r-lg);
  filter: drop-shadow(var(--shadow-menu));
}
.menu[hidden] { display: none; }
.menu--wide { min-width: 264px; }

.menu__item {
  display: flex; align-items: center; gap: var(--space-8);
  width: 100%; margin: 0;
  padding: var(--space-8) var(--space-12);
  border: 0; border-radius: var(--r-sm); background: transparent;
  font-size: 14px; line-height: 20px; font-weight: var(--fw-regular); letter-spacing: -0.05px;
  color: var(--text-primary); text-align: left; text-decoration: none;
  cursor: pointer; white-space: nowrap;
}
.menu__item:hover,
.menu__item:focus-visible { background: var(--background-hover); outline: none; }
.menu__item:focus-visible { box-shadow: inset 0 0 0 2px var(--focus-ring); }
.menu__item[aria-checked="true"],
.menu__item[aria-selected="true"],
.menu__item.is-active { background: var(--background-sunken); }
.menu__item[aria-disabled="true"] { color: var(--text-disabled); cursor: not-allowed; background: transparent; }

.menu__checkbox {
  position: relative; flex-shrink: 0; width: 16px; height: 16px;
  background: var(--background-surface) no-repeat center / 12px 12px;
  border: var(--border-1) solid var(--border-control); border-radius: var(--r-xs);
  transition: background-color .12s, border-color .12s;
}
.menu__item--check:hover .menu__checkbox { border-color: var(--brand-fg); }
.menu__item--check[aria-selected="true"] .menu__checkbox {
  background-color: var(--brand-default); border-color: var(--brand-fill-border);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M9.6 2.6a.55.55 0 0 1 .8.78L5.1 9.4a.55.55 0 0 1-.79 0L1.6 6.68a.55.55 0 0 1 .79-.78l2.32 2.32z' fill='%23fff'/%3E%3C/svg%3E");
}
.menu__item--check[aria-selected="true"] { background: transparent; }        /* the box carries the state, not a row fill */
.menu__item--check[aria-selected="true"]:hover,
.menu__item--check:hover { background: var(--background-hover); }
.menu__check { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 16px; height: 16px; overflow: hidden; }
.menu__check img { width: 16px; height: 16px; visibility: hidden; }
.menu__item[aria-checked="true"] .menu__check img,
.menu__item[aria-selected="true"] .menu__check img,
.menu__item.is-active .menu__check img { visibility: visible; }
.menu__label { flex: 1 0 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* Trigger used by data-dropdown selects */
.dropdown { position: relative; display: inline-flex; }
.dropdown-trigger {
  display: inline-flex; align-items: center; gap: var(--space-6);
  padding: 0; border: 0; background: none; cursor: pointer; border-radius: var(--r-xs);
  font: inherit; color: inherit; white-space: nowrap;
}
.dropdown-trigger:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.dropdown-trigger img { width: 16px; height: 16px; flex-shrink: 0; }

/* Chevron — every dropdown trigger's chevron flips when its menu is open.
   Add class="chevron" to the chevron <img> inside any button that sets aria-expanded. */
.chevron { transition: transform .15s ease; }
[aria-expanded="true"] .chevron { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .chevron { transition: none; } }
.dropdown-trigger__label { overflow: hidden; text-overflow: ellipsis; }
.dropdown select { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

/* ---- Dropdown form control (Figma "Dropdown" 29:59) ---------------------
   <div class="field"><label class="field__label" for="x">Label</label>
     <select id="x" data-dropdown="field"><option value="">Select option</option>…</select>
     [<p class="field__hint">…</p>]</div>
   Same chrome and states as Input; menu matches the trigger width.
   ------------------------------------------------------------------------ */
.dropdown--field { display: flex; width: 100%; }
.dropdown-trigger--field {
  width: 100%; height: var(--control-lg); gap: var(--space-8);
  padding: var(--space-4) var(--space-12) var(--space-4) var(--space-14);
  background: var(--background-surface);
  border: var(--border-1) solid var(--border-input); border-radius: var(--r-sm);
  font-size: 14px; line-height: 20px; font-weight: var(--fw-regular); letter-spacing: -0.05px;
  color: var(--text-primary); text-align: left;
  transition: border-color .12s, box-shadow .12s;
}
.dropdown-trigger--field .dropdown-trigger__label { flex: 1 0 0; min-width: 0; }
.dropdown-trigger--field.is-placeholder .dropdown-trigger__label { color: var(--text-placeholder); }
.dropdown-trigger--field:hover { border-color: var(--border-control-hover); }
.dropdown--multi .dropdown-trigger { height: auto; min-height: var(--control-lg); padding-top: var(--space-6); padding-bottom: var(--space-6); }
.dropdown-trigger__label--tags { display: flex; flex-wrap: wrap; gap: var(--space-6); text-align: left; }
.dropdown-trigger--field:focus-visible,
.dropdown-trigger--field[aria-expanded="true"] { outline: none; border-color: var(--focus-ring); box-shadow: inset 0 0 0 1px var(--focus-ring); }
.dropdown--field .menu { left: 0; right: 0; min-width: 100%; max-width: none; top: calc(100% + 6px); }
.field.is-error .dropdown-trigger--field { border-color: var(--status-danger); }
.field.is-disabled .dropdown-trigger--field,
.dropdown-trigger--field:disabled { background: var(--background-disabled); border-color: var(--border-disabled); color: var(--text-disabled); cursor: not-allowed; box-shadow: none; }

/* Compact variant — pagination page-size picker */
.dropdown-trigger--compact {
  gap: var(--space-8); padding: var(--space-8) var(--space-10);
  border: var(--border-1) solid var(--border-input); border-radius: var(--r-xs); background: var(--background-surface);
  font-size: 14px; line-height: 20px; font-weight: var(--fw-medium); letter-spacing: -0.05px; color: var(--text-label);
}
.dropdown-trigger--compact:hover { border-color: var(--border-control-hover); }
.dropdown--compact .menu { left: 0; min-width: 96px; }
.dropdown--up .menu { top: auto; bottom: calc(100% + 6px); }

/* ---- Pagination (Retail Shipments 102:6392) ------------------------------ */
.pagination { display: flex; align-items: center; gap: var(--space-32); width: 100%; flex-wrap: wrap; row-gap: var(--space-12); }
.pagination__summary { display: flex; align-items: center; gap: var(--space-6); flex: 1 0 auto; font-size: 14px; line-height: 20px; font-weight: var(--fw-medium); letter-spacing: -0.05px; color: var(--text-label); }
.pagination__pages { display: flex; align-items: center; gap: var(--space-8); }
.pagination__nav {
  display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px;
  padding: 0; border: 0; background: none; cursor: pointer; border-radius: var(--r-xs);
}
.pagination__nav img { width: 20px; height: 20px; }
.pagination__nav:disabled { opacity: .35; cursor: not-allowed; }
.pagination__nav:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.pagination__page {
  width: 32px; height: 32px; padding: 0;
  background: var(--background-surface); border: 1px solid var(--border-control); border-radius: var(--r-xs);
  font-size: 14px; line-height: 20px; font-weight: var(--fw-regular); letter-spacing: -0.05px; color: var(--text-pagination);
  cursor: pointer; transition: border-color .12s, color .12s;
}
.pagination__page:hover { border-color: var(--border-control-hover); color: var(--text-label); }
.pagination__page[aria-current="page"] { border-color: var(--brand-selected); color: var(--brand-selected); }
.pagination__page:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--brand-border); }
.pagination__gap { width: 16px; text-align: center; color: var(--text-pagination); }

/* ---- Textarea (Figma 30:12) — same chrome/states as Input, 88px tall ----
   <div class="field"><label class="field__label" for="x">Label</label>
     <textarea class="textarea" id="x" maxlength="250"></textarea>
     <div class="field__hint-row"><p class="field__hint">…</p><span class="field__counter">0 / 250</span></div></div>
   ------------------------------------------------------------------------ */
.textarea {
  display: block; width: 100%; height: 88px; min-height: 88px; resize: vertical;
  padding: var(--space-8) var(--space-14); margin: 0;
  background: var(--background-surface);
  border: var(--border-1) solid var(--border-input); border-radius: var(--r-sm);
  font: inherit; font-size: 14px; line-height: 20px; letter-spacing: -0.05px; color: var(--text-primary);
  outline: none; transition: border-color .12s, box-shadow .12s;
}
.textarea::placeholder { color: var(--text-placeholder); opacity: 1; }
.textarea:hover { border-color: var(--border-control-hover); }
.textarea:focus { border-color: var(--focus-ring); box-shadow: inset 0 0 0 1px var(--focus-ring); }
.field.is-error .textarea { border-color: var(--status-danger); }
.textarea:disabled { background: var(--background-disabled); border-color: var(--border-disabled); color: var(--text-disabled); cursor: not-allowed; }
.field__hint-row { display: flex; align-items: flex-start; gap: var(--space-8); width: 100%; }
.field__hint-row .field__hint { flex: 1 0 0; width: auto; }
.field__counter { margin-left: auto; font-size: 13px; line-height: 18px; letter-spacing: -0.04px; color: var(--text-muted); white-space: nowrap; }
.field.is-disabled .field__counter { color: var(--text-disabled); }

/* ---- Date Picker (Figma 255:4463) + custom calendar ----------------------
   <div class="datepicker" data-datepicker data-label-id="lbl" data-min="2026-09-16">
     <input type="hidden" id="x" name="x" value="2026-09-18"></div>
   js/components.js builds the trigger (Date Picker control: calendar icon + value)
   and the calendar panel (Dropdown Menu chrome, Item states).
   Trigger: default border Slate-200 · hover Slate-300 · focus/open 2px ring · error · disabled.
   ------------------------------------------------------------------------ */
.datepicker { position: relative; width: 100%; }
.datepicker__trigger {
  display: flex; align-items: center; gap: var(--space-8);
  width: 100%; height: var(--control-lg);
  padding: var(--space-4) var(--space-14);
  background: var(--background-surface);
  border: var(--border-1) solid var(--border-input); border-radius: var(--r-sm);
  font: inherit; font-size: 14px; line-height: 20px; letter-spacing: -0.05px; color: var(--text-primary);
  text-align: left; cursor: pointer;
  transition: border-color .12s, box-shadow .12s;
}
.datepicker__trigger img { width: 16px; height: 16px; flex-shrink: 0; }
.datepicker__value { flex: 1 0 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.datepicker__trigger.is-placeholder .datepicker__value { color: var(--text-placeholder); }
.datepicker__trigger:hover { border-color: var(--border-control-hover); }
.datepicker__trigger:focus-visible,
.datepicker__trigger[aria-expanded="true"] { outline: none; border-color: var(--focus-ring); box-shadow: inset 0 0 0 1px var(--focus-ring); }
.field.is-error .datepicker__trigger { border-color: var(--status-danger); }
.field.is-error .datepicker__trigger:focus-visible,
.field.is-error .datepicker__trigger[aria-expanded="true"] { border-color: var(--status-danger); box-shadow: inset 0 0 0 1px var(--status-danger); }
.datepicker__trigger:disabled { background: var(--background-disabled); border-color: var(--border-disabled); color: var(--text-disabled); cursor: not-allowed; }
.datepicker__trigger:disabled img { opacity: .6; }

/* Calendar panel — same chrome as Dropdown Menu (231:4252) */
.datepicker__panel {
  position: fixed; z-index: 1100; left: 0; top: 0;
  width: 296px; max-width: calc(100vw - 16px);
  display: flex; flex-direction: column; gap: var(--space-8);
  padding: var(--space-12);
  background: var(--background-surface);
  border: var(--border-1) solid var(--border-strong); border-radius: var(--r-lg);
  box-shadow: var(--shadow-popover);
}
.datepicker__panel[hidden] { display: none; }
.datepicker__head { display: flex; align-items: center; gap: var(--space-8); padding: 0 0 var(--space-4); }
.datepicker__title { flex: 1 0 0; margin: 0; text-align: center; font-size: 14px; line-height: 20px; font-weight: var(--fw-semibold); letter-spacing: -0.05px; color: var(--text-primary); }
.datepicker__nav {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--r-sm);
  background: transparent; cursor: pointer; transition: background-color .12s;
}
.datepicker__nav img { width: 20px; height: 20px; }
.datepicker__nav:hover { background: var(--background-hover); }
.datepicker__nav:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--focus-ring); }
.datepicker__nav:disabled { opacity: .35; cursor: not-allowed; background: transparent; }
.datepicker__grid { width: 100%; border-collapse: separate; border-spacing: 2px; table-layout: fixed; }
.datepicker__grid th {
  height: 28px; padding: 0; text-align: center;
  font-size: 12px; line-height: 16px; font-weight: var(--fw-medium); letter-spacing: 0.01px; color: var(--text-muted);
}
.datepicker__grid td { padding: 0; text-align: center; }
.datepicker__day {
  width: 100%; height: 36px; padding: 0;
  border: 0; border-radius: var(--r-sm); background: transparent;
  font: inherit; font-size: 14px; line-height: 20px; font-weight: var(--fw-regular); letter-spacing: -0.05px;
  color: var(--text-primary); cursor: pointer;
  transition: background-color .12s, color .12s;
}
.datepicker__day:hover { background: var(--background-hover); }
.datepicker__day:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--focus-ring); }
.datepicker__day.is-outside { color: var(--text-muted); } /* still selectable → must meet 4.5:1 */
.datepicker__day.is-today { color: var(--brand-fg); font-weight: var(--fw-semibold); box-shadow: inset 0 0 0 1px var(--brand-border); }
.datepicker__day.is-today:focus-visible { box-shadow: inset 0 0 0 2px var(--focus-ring); }
.datepicker__day[aria-selected="true"] { background: var(--brand-default); color: var(--brand-on-brand); font-weight: var(--fw-semibold); box-shadow: none; }
.datepicker__day[aria-selected="true"]:hover { background: var(--brand-hover); }
.datepicker__day[aria-selected="true"]:focus-visible { box-shadow: 0 0 0 2px var(--background-surface), 0 0 0 4px var(--focus-ring); }
.datepicker__day:disabled { color: var(--text-disabled); background: transparent; cursor: not-allowed; text-decoration: line-through; text-decoration-color: var(--border-control); font-weight: var(--fw-regular); box-shadow: none; }
.datepicker__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-8); padding-top: var(--space-8); border-top: var(--border-1) solid var(--border-default); }
.datepicker__foot-hint { font-size: 12px; line-height: 16px; color: var(--text-muted); }

/* ---- Tooltip (Figma 321:3789) — Top · Bottom · Left · Right ---------------
   Add data-tooltip="Label" (and optional data-tooltip-pos="top|bottom|left|right",
   default bottom) to any control; js/components.js renders it on hover/focus.
   ------------------------------------------------------------------------ */
.tooltip {
  position: fixed; z-index: 1000; left: 0; top: 0;
  display: flex; align-items: center; pointer-events: none;
  opacity: 0; transition: opacity .12s ease;
}
.tooltip.is-visible { opacity: 1; }
.tooltip__bubble {
  padding: var(--space-6); border-radius: var(--r-sm);
  background: var(--background-inverse); color: var(--text-inverse);
  font-size: 12px; line-height: 16px; font-weight: var(--fw-regular); letter-spacing: 0.01px;
  white-space: nowrap; max-width: 280px; overflow: hidden; text-overflow: ellipsis;
}
.tooltip__arrow { flex-shrink: 0; background: var(--background-inverse); }
.tooltip--bottom { flex-direction: column; }
.tooltip--top { flex-direction: column-reverse; }
.tooltip--right { flex-direction: row; }
.tooltip--left { flex-direction: row-reverse; }
.tooltip--bottom .tooltip__arrow { width: 10px; height: 5px; clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.tooltip--top .tooltip__arrow { width: 10px; height: 5px; clip-path: polygon(0 0, 100% 0, 50% 100%); }
.tooltip--right .tooltip__arrow { width: 5px; height: 10px; clip-path: polygon(100% 0, 100% 100%, 0 50%); }
.tooltip--left .tooltip__arrow { width: 5px; height: 10px; clip-path: polygon(0 0, 100% 50%, 0 100%); }
@media (prefers-reduced-motion: reduce) { .tooltip { transition: none; } }

/* ---- Modal (Create Shipment 257:3307) --------------------------------------
   <dialog class="modal" aria-labelledby="t">
     <div class="modal__header"><h2 class="modal__title" id="t">…</h2>
       <button class="modal__close" data-modal-close aria-label="Close"><img src="assets/icon-close.svg" alt=""></button></div>
     <div class="modal__body">…</div>
     <div class="modal__footer">…buttons…</div></dialog>
   Open with FlyinsUI.modal(dialog).open(); Esc, ✕, Cancel and backdrop click close it.
   ------------------------------------------------------------------------ */
.modal {
  width: 800px; max-width: calc(100vw - 32px);
  /* A percentage, not a viewport unit. An open <dialog> lives in the top
     layer, so its containing block IS the viewport and `%` resolves against
     it — this is exactly what the UA stylesheet does. It also sidesteps every
     viewport-unit quirk: `dvh` shrinks when the on-screen keyboard opens, and
     `svh`/`vh` each behave differently again across engines. */
  max-height: calc(100% - 32px);
  padding: 0; margin: auto; border: 0; border-radius: var(--r-md);
  background: var(--background-surface); color: var(--text-primary);
  box-shadow: var(--elevation-md); overflow: hidden;
}
.modal[open] { display: flex; flex-direction: column; animation: modal-in .16s ease-out; }
.modal::backdrop { background: var(--backdrop); animation: backdrop-in .16s ease-out; }
@keyframes modal-in { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes backdrop-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .modal[open], .modal::backdrop { animation: none; } }
.modal__header {
  display: flex; align-items: center; gap: var(--space-16); flex-shrink: 0;
  padding: var(--space-24) var(--space-32);
  border-bottom: var(--border-1) solid var(--border-default);
}
.modal__title { flex: 1 0 0; min-width: 0; margin: 0; font-size: 24px; line-height: 32px; font-weight: var(--fw-semibold); letter-spacing: -0.47px; color: var(--text-heading); }
.modal__close {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 24px; height: 24px; padding: 0; border: 0; background: none; cursor: pointer; border-radius: var(--r-xs);
}
.modal__close img { width: 24px; height: 24px; }
.modal__close:hover { opacity: .7; }
.modal__close:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.modal__body {
  display: flex; flex-direction: column; gap: var(--space-20);
  height: 480px; max-height: 100%; min-height: 0; flex: 0 1 auto;
  padding: var(--space-24) var(--space-32);
  overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;
}
.modal__section-title { margin: 0; font-size: 18px; line-height: 24px; font-weight: var(--fw-semibold); letter-spacing: -0.26px; color: var(--text-heading); }
.modal__footer {
  display: flex; align-items: center; justify-content: flex-end; gap: var(--space-12); flex-shrink: 0;
  padding: var(--space-24) var(--space-32);
  border-top: var(--border-1) solid var(--border-default);
}
.modal__footer .btn { min-width: 120px; }
/* Form modal (Add New User 194:14394 / Edit User 202:14554): 620px, body hugs its content */
.modal--form { width: 620px; }
.modal--form .modal__header { border-bottom-color: var(--border-subtle); }
.modal--form .modal__body { height: auto; flex: 1 1 auto; }
.modal--form .modal__footer { border-top-color: var(--border-subtle); }
.modal--form .modal__footer .btn { width: 150px; }
/* Confirmation modal: same pattern as the form modal (use with .modal--form) — 24 Semibold title + X,
   Slate-100 dividers, right-aligned 150px Cancel (secondary) + action button; narrower, body is one message. */
.modal--form.modal--confirm { width: 480px; }
/* ---- Tag / pill -------------------------------------------------------
   <span class="tag">Google Store Kobe</span>            neutral (e.g. a store)
   <span class="tag tag--success">Active</span>          status tones
   Tones: success · info · warning · danger · brand · neutral               */
.tag {
  display: inline-flex; align-items: center; gap: var(--space-6);
  max-width: 100%; padding: 2px var(--space-8);
  background: var(--tag-bg); border: var(--border-1) solid var(--tag-border); border-radius: var(--r-full);
  font-size: 12px; line-height: 18px; font-weight: var(--fw-medium); letter-spacing: -0.02px;
  color: var(--tag-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tag--success { background: var(--status-success-subtle); border-color: var(--status-success-subtle); color: var(--status-success-text); }
.tag--info    { background: var(--status-info-subtle);    border-color: var(--status-info-subtle);    color: var(--status-info-text); }
.tag--warning { background: var(--status-warning-subtle); border-color: var(--status-warning-subtle); color: var(--status-warning-text); }
.tag--danger  { background: var(--status-danger-subtle);  border-color: var(--status-danger-subtle);  color: var(--status-danger-text); }
.tag--brand   { background: var(--brand-subtle);          border-color: var(--brand-subtle);          color: var(--brand-fg); }
/* Neutral status (Inactive): base tag chrome, quieter text and weight than a store pill — per user */
.tag--neutral { color: var(--tag-neutral-text); font-weight: var(--fw-regular); }
/* Subtle outline in each tag's own colour */
@supports (border-color: color-mix(in srgb, red 30%, transparent)) {
  .tag--success { border-color: color-mix(in srgb, var(--status-success) 32%, transparent); }
  .tag--info    { border-color: color-mix(in srgb, var(--status-info) 32%, transparent); }
  .tag--warning { border-color: color-mix(in srgb, var(--status-warning) 32%, transparent); }
  .tag--danger  { border-color: color-mix(in srgb, var(--status-danger) 32%, transparent); }
  .tag--brand   { border-color: color-mix(in srgb, var(--brand-default) 32%, transparent); }
}
/* Status tag: hugs its own text (per user) */
.tag--status { justify-content: center; }
.tag--dot::before { content: ""; width: 6px; height: 6px; border-radius: var(--r-full); background: currentColor; flex-shrink: 0; }
.tag-group { display: flex; flex-wrap: wrap; gap: var(--space-6); }

.modal__text { margin: 0; font-size: 16px; line-height: 24px; letter-spacing: -0.18px; color: var(--text-secondary); }   /* 16/24 per user — matches the app's other 16px style */
.modal__text strong { font-weight: var(--fw-semibold); color: var(--text-primary); }
.modal__fields { display: flex; flex-direction: column; gap: var(--space-16); }
.modal__row { display: flex; gap: var(--space-16); }
.modal__row > .field { flex: 1 0 0; min-width: 0; }
@media (max-width: 767px) {
  .modal__row { flex-direction: column; }
  .modal--form .modal__footer .btn { width: auto; }
}
@media (max-width: 767px) {
  .modal { max-width: calc(100vw - 16px); max-height: calc(100% - 16px); }
  .modal__header, .modal__body, .modal__footer { padding-left: var(--space-16); padding-right: var(--space-16); }
  .modal__header { padding-top: var(--space-16); padding-bottom: var(--space-16); }
  .modal__title { font-size: 20px; line-height: 28px; letter-spacing: -0.33px; }
  /* `max-height: none` is the important one. The base rule sets max-height:
     100% for the desktop case, where the body has a definite 480px height.
     Here the body is height: auto inside a dialog that is ALSO height: auto,
     so `100%` is circular — Blink resolves it to `none`, WebKit resolves it
     against a partially-computed height and pins the body small. That is why
     iPhone Safari AND iOS Chrome (both WebKit) showed a ~160px body while
     desktop Chromium looked perfect. Clearing it lets the body grow with its
     content and scroll only once the dialog hits its own max-height. */
  .modal__body {
    height: auto; max-height: none; flex: 1 1 auto;
    padding-top: var(--space-16); padding-bottom: var(--space-16);
  }
  /* A floor for bodies that can actually be squeezed: the body is the only
     flex child that can shrink (header and footer are flex-shrink: 0), and it
     carries min-height: 0 so it can scroll — which also lets it collapse to
     nothing if anything constrains the dialog. Confirm modals are excluded:
     their body is a sentence or two, so a floor would only add dead space
     under the text. Scales down on short screens so the footer stays visible. */
  .modal:not(.modal--confirm) .modal__body { min-height: min(160px, 35vh); }
  .modal__footer { padding-top: var(--space-16); padding-bottom: var(--space-16); }
  .modal__footer .btn { flex: 1 0 0; min-width: 0; }
}
body.has-modal { overflow: hidden; }
.modal__body:focus { outline: none; }
.modal .table-wrap { flex-shrink: 0; }
.modal .field { flex-shrink: 0; }

/* ---- Card ------------------------------------------------------------- */
.card {
  background: var(--background-surface);
  border: var(--border-1) solid var(--border-default);
  border-radius: var(--r-lg);
  box-shadow: var(--elevation-md);
}

/* ---- Toggle Switch (Figma 138:2329) --------------------------------------
   <button type="button" class="switch" role="switch" aria-checked="true" data-on="Open" data-off="Close">
     <span class="switch__track"><span class="switch__knob"></span></span><span class="switch__label">Open</span>
   </button>   (js/components.js toggles aria-checked + label and fires "change") */
.switch {
  display: inline-flex; align-items: center; gap: var(--space-8); flex-shrink: 0;
  padding: 0; border: 0; background: none; cursor: pointer; font: inherit; text-align: left;
}
.switch__track {
  display: flex; align-items: center; width: 36px; height: 20px; padding: 0 2px; flex-shrink: 0;
  border-radius: var(--r-full); background: var(--switch-off); transition: background-color .15s ease;
}
.switch__knob {
  width: 16px; height: 16px; border-radius: 50%; background: var(--switch-knob);
  box-shadow: var(--shadow-knob);
  transition: transform .15s ease;
}
.switch__label { width: 80px; font-size: 14px; line-height: 20px; letter-spacing: -0.05px; color: var(--text-muted); }
.switch:hover .switch__track { background: var(--switch-off-hover); }
.switch[aria-checked="true"] .switch__track { background: var(--brand-default); }
.switch[aria-checked="true"]:hover .switch__track { background: var(--brand-hover); }
.switch[aria-checked="true"] .switch__knob { transform: translateX(16px); }
.switch:focus-visible { outline: none; }
.switch:focus-visible .switch__track { box-shadow: 0 0 0 3px var(--brand-border); }
.switch:disabled { cursor: not-allowed; }
.switch:disabled .switch__track { background: var(--background-disabled); }
.switch[aria-checked="true"]:disabled .switch__track { background: var(--border-control); }
.switch:disabled .switch__label { color: var(--text-disabled); }
@media (prefers-reduced-motion: reduce) { .switch__track, .switch__knob { transition: none; } }

/* ---- Number Input (Figma 152:2464) ----------------------------------------
   <div class="number-input"><input type="number" …><span class="number-input__stepper">
     <button type="button" data-step="1">▲</button><button type="button" data-step="-1">▼</button></span></div>
   Steppers are wired in js/components.js (respects min/max/step, fires input + change). */
.number-input {
  display: flex; align-items: center; gap: var(--space-8);
  width: 84px; height: var(--control-lg); padding: 0 var(--space-8) 0 var(--space-12); flex-shrink: 0;
  background: var(--background-surface); border: var(--border-1) solid var(--border-input); border-radius: var(--r-sm);
  color: var(--icon-color); transition: border-color .12s, box-shadow .12s;
}
.number-input input {
  flex: 1 0 0; min-width: 0; width: 100%; height: 100%; padding: 0; border: 0; outline: 0; background: transparent;
  font: inherit; font-size: 14px; line-height: 20px; letter-spacing: -0.05px; color: var(--text-primary);
  -moz-appearance: textfield; appearance: textfield;
}
.number-input input::-webkit-outer-spin-button,
.number-input input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.number-input__stepper { display: flex; flex-direction: column; flex-shrink: 0; }
.number-input__stepper button {
  display: flex; width: 12px; height: 12px; padding: 0; border: 0; background: none; color: inherit; cursor: pointer; border-radius: 2px;
}
.number-input__stepper svg { width: 12px; height: 12px; }
.number-input:hover { border-color: var(--border-control-hover); color: var(--text-primary); }
.number-input:focus-within { border-color: var(--focus-ring); box-shadow: inset 0 0 0 1px var(--focus-ring); color: var(--text-primary); }
.number-input.is-error, .number-input.is-error:hover { border-color: var(--status-danger); box-shadow: none; color: var(--icon-color); }
.number-input.is-disabled { background: var(--background-disabled); border-color: var(--border-disabled); color: var(--text-disabled); }
.number-input.is-disabled input { color: var(--text-disabled); }
.number-input.is-disabled button { cursor: not-allowed; }

/* ---- Time picker (secondary button + Dropdown Menu list) ------------------ */
.timepicker { position: relative; display: inline-flex; }
.timepicker__btn { min-width: 0; padding: 0 var(--space-12); font-variant-numeric: tabular-nums; }
.timepicker__btn .btn__icon { color: var(--icon-color); }
.timepicker__btn:disabled .btn__icon { color: currentColor; }
.timepicker .menu { top: calc(100% + 6px); left: 0; min-width: 132px; max-height: 240px; overflow-y: auto; }
.timepicker.is-error .timepicker__btn { border-color: var(--status-danger); }

/* ---- Toast (Figma 308:3873) ------------------------------------------------
   FlyinsUI.toast(message, { status: 'info'|'success'|'warning'|'danger', duration }) — transient, stacks top-centre 16px under the header.
   Icon and close button sit on the first line (top-aligned) so multi-line messages read cleanly.
   400px, white, 1px Slate-200, r8, pad 12/14, gap 10, Elevation/md; 20px status icon, 14 Medium Slate-900, 16px close (Slate-500). */
.toast-region {
  position: fixed; left: 50%; top: var(--toast-top, 104px); z-index: 60; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: var(--space-12);
  width: 400px; max-width: calc(100vw - 32px); pointer-events: none;
}
.toast {
  display: flex; align-items: flex-start; gap: var(--space-10); width: 100%;
  padding: var(--space-12) var(--space-14);
  background: var(--background-raised); border: var(--border-1) solid var(--border-default); border-radius: var(--r-md);
  box-shadow: var(--elevation-md);
  pointer-events: auto;
  animation: toast-in .2s ease-out;
}
.toast.is-leaving { animation: toast-out .18s ease-in forwards; }
.toast__icon { width: 20px; height: 20px; flex-shrink: 0; }
.toast__msg { flex: 1 0 0; min-width: 0; margin: 0; font-size: 14px; line-height: 20px; font-weight: var(--fw-medium); letter-spacing: -0.05px; color: var(--text-primary); overflow-wrap: anywhere; }
.toast__close {
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 16px; height: 16px; margin-top: 2px; padding: 0; border: 0; background: none; border-radius: var(--r-xs);
  color: var(--text-muted); cursor: pointer; transition: color .12s;
}
.toast__close svg { width: 16px; height: 16px; }
.toast__close:hover { color: var(--text-primary); }
/* Toast action (e.g. Undo): brand text button on the first line, before the X */
.toast__action {
  flex-shrink: 0; margin: 0 2px; padding: 0 4px; border: 0; background: none; border-radius: var(--r-xs);
  font: inherit; font-size: 14px; line-height: 20px; font-weight: var(--fw-semibold); letter-spacing: -0.05px;
  color: var(--brand-fg); cursor: pointer;
}
.toast__action:hover { color: var(--brand-fg-strong); text-decoration: underline; text-underline-offset: 2px; }
.toast__action:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.toast__close:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
@keyframes toast-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(-8px); } }
@media (max-width: 767px) {
  .toast-region { right: 16px; left: 16px; width: auto; max-width: none; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .toast, .toast.is-leaving { animation-duration: 1ms; } }

/* ---- Option cards (single choice with icon, e.g. Settings › Appearance) ----
   <div class="option-cards segmented" role="radiogroup" aria-labelledby="…">
     <button type="button" class="option-card" role="radio" aria-checked="true" data-value="light">
       <span class="option-card__icon" data-icon="sun"></span><span class="option-card__label">Light</span></button>…</div>
   Selection/keyboard handled by FlyinsUI.segmented (same as the segmented control). */
.option-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-12); padding: 0; }
.option-card {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-6);
  min-height: 88px; padding: var(--space-16) var(--space-12);
  background: var(--background-surface); border: var(--border-1) solid var(--border-default); border-radius: var(--r-md);
  font: inherit; font-size: 14px; line-height: 20px; font-weight: var(--fw-medium); letter-spacing: -0.05px;
  color: var(--text-secondary); cursor: pointer; text-align: center;
  transition: border-color .12s, background-color .12s, color .12s, box-shadow .12s;
}
.option-card__icon { width: 20px; height: 20px; color: var(--icon-color); }
.option-card:hover { border-color: var(--border-control-hover); color: var(--text-primary); }
.option-card[aria-checked="true"] {
  background: var(--option-selected-bg); border-color: var(--brand-fg); color: var(--brand-fg);
  box-shadow: inset 0 0 0 1px var(--brand-fg);   /* 2px selected edge — not colour alone */
}
.option-card[aria-checked="true"] .option-card__icon { color: var(--brand-fg); }
.option-card:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
@media (max-width: 479px) {
  .option-cards { gap: var(--space-8); }
  .option-card { min-height: 76px; padding: var(--space-12) var(--space-8); }
}
@media (prefers-reduced-motion: reduce) { .option-card { transition: none; } }

/* ==== Motion & interaction =================================================
   Subtle, system-like (per user): 120–220ms, small distances, standard easing.
   This block sits at the end of base.css so it wins over the component rules
   it extends, and everything in it is switched off under prefers-reduced-motion.
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* ---- Press feedback ---- */
.btn { transition: background-color var(--dur-fast), border-color var(--dur-fast), color var(--dur-fast), transform var(--dur-fast) var(--ease-standard); }
.btn:not(:disabled):active { transform: scale(.985); }
.icon-btn, .table__action, .btn-text, .table__expand-btn, .table__sort {
  transition: color var(--dur-fast), background-color var(--dur-fast), transform var(--dur-fast) var(--ease-standard);
}
.icon-btn:not(:disabled):active,
.table__action:not(:disabled):active,
.btn-text:not(:disabled):active { transform: scale(.92); }
.table__expand-btn:not(:disabled):active { transform: scale(.9); }

/* ---- Checkbox: the tick grows in instead of appearing ----
   The mark is a background image, so it is always set and the SIZE carries the
   state — a transition (not an animation), so a re-rendered checked row does
   not replay it. */
.checkbox__box {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M9.6025 2.60231C9.82218 2.38277 10.1783 2.38268 10.3979 2.60231C10.6174 2.82195 10.6174 3.17808 10.3979 3.39772L4.89742 8.89748C4.67775 9.11715 4.32168 9.11715 4.10201 8.89748L1.60225 6.39772C1.38258 6.17805 1.38258 5.82198 1.60225 5.60231C1.82192 5.38264 2.17799 5.38264 2.39766 5.60231L4.49971 7.70436L9.6025 2.60231Z' fill='white'/%3E%3C/svg%3E");
  background-size: 0 0;
  transition: background-color var(--dur-fast), border-color var(--dur-fast),
              background-size var(--dur-fast) var(--ease-standard), transform var(--dur-fast);
}
.checkbox input:checked + .checkbox__box { background-size: 12px 12px; }
.checkbox input:indeterminate + .checkbox__box { background-size: 0 0; }
.checkbox:active .checkbox__box { transform: scale(.9); }
.checkbox input:indeterminate + .checkbox__box::after { transition: background-color var(--dur-fast); }
.menu__checkbox { transition: background-color var(--dur-fast), border-color var(--dur-fast); }

/* ---- Dropdown menus: fade only ----
   Opacity never changes the box, so placeFixed can still measure the menu
   correctly while this runs (a transform here would break the alignment fix). */
.menu:not([hidden]) { animation: menu-in var(--dur-fast) var(--ease-out); }
@keyframes menu-in { from { opacity: 0; } }

/* ---- Tabs: one pill that slides between tabs ----
   Mounted by FlyinsUI (tabs__indicator); the container only gets
   `.tabs--indicator` once it has been measured, so without JS the tabs keep
   their own selected styling. */
.tabs { position: relative; }
.tabs__indicator {
  position: absolute; z-index: 0; left: 0; top: 0;
  width: var(--ind-w, 0); height: var(--ind-h, 0);
  transform: translate3d(var(--ind-x, 0), var(--ind-y, 0), 0);
  background: var(--background-selected);
  border: var(--border-1) solid var(--border-control);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-tab);
  pointer-events: none;
  transition: transform var(--dur-base) var(--ease-standard),
              width var(--dur-base) var(--ease-standard),
              height var(--dur-base) var(--ease-standard);
}
.tabs--indicator .tab { position: relative; z-index: 1; }
.tabs--indicator .tab[aria-selected="true"],
.tabs--indicator [role="radio"][aria-checked="true"] {
  background: transparent; border-color: transparent; box-shadow: none;
}

/* ---- Option cards ---- */
.option-card { transition: background-color var(--dur-fast), border-color var(--dur-fast), color var(--dur-fast), box-shadow var(--dur-fast), transform var(--dur-fast) var(--ease-standard); }
.option-card:active { transform: scale(.99); }

/* ---- Tag / status ---- */
.tag { transition: background-color var(--dur-fast), border-color var(--dur-fast), color var(--dur-fast); }

/* ---- Tables ---- */
.table tbody tr > td { transition: background-color var(--dur-fast); }
@keyframes row-flash { from { background-color: var(--brand-subtle); } }
.table tbody tr.is-flash > td { animation: row-flash 900ms var(--ease-out); }
@keyframes rows-in { from { opacity: 0; transform: translateY(2px); } }
.table tbody.rows-in > tr { animation: rows-in var(--dur-base) var(--ease-out); }   /* no fill mode: a left-over transform would make every row a stacking context */

/* ---- Loading: skeleton rows + busy buttons ---- */
.skeleton {
  display: block; height: 12px; border-radius: var(--r-full);
  background: var(--skeleton-bg); position: relative; overflow: hidden;
}
.skeleton::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--skeleton-sheen), transparent);
  animation: shimmer 1.2s linear infinite;
}
@keyframes shimmer { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .skeleton::after { display: none; } }
.table tbody tr.is-skeleton > td { vertical-align: middle; }

.btn__spinner {
  width: 14px; height: 14px; flex-shrink: 0; border-radius: var(--r-full);
  border: 2px solid currentColor; border-top-color: transparent;
  animation: spin .6s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.btn[aria-busy="true"] { cursor: progress; }

/* ---- Empty states fade in rather than appear ---- */
@keyframes fade-in { from { opacity: 0; } }
.empty-state { animation: fade-in var(--dur-slow) var(--ease-out); }
.table tbody tr.table__empty > td { animation: fade-in var(--dur-slow) var(--ease-out); }

/* ---- Page & panel entrance ----
   The page's top-level blocks rise in with a short stagger, so a page reads as
   settling rather than snapping. Only the first few are staggered; anything
   further down is below the fold anyway. */
@keyframes block-in { from { opacity: 0; transform: translateY(6px); } }
/* `backwards`, never `both`: `both` leaves the final transform applied forever, which
   makes every one of these blocks a stacking context — and then a dropdown in one block
   can no longer paint above the table in the next one. `backwards` only fills during the
   delay, so once the animation ends the element carries no transform at all. */
.app-main.page > * { animation: block-in var(--dur-slow) var(--ease-out) backwards; }
.app-main.page > *:nth-child(1) { animation-delay: 0ms; }
.app-main.page > *:nth-child(2) { animation-delay: 40ms; }
.app-main.page > *:nth-child(3) { animation-delay: 80ms; }
.app-main.page > *:nth-child(n+4) { animation-delay: 110ms; }

/* Tab panels fade in as they take over */
.tab-panel:not([hidden]) { animation: fade-in var(--dur-base) var(--ease-out); }

/* Panels inside a page stack settle with the page, not on their own */
.panel { transition: border-color var(--dur-fast), box-shadow var(--dur-fast); }

/* ---- Toast, inverse variant — THE DEFAULT (per user) ----------------------
   FlyinsUI.toast(msg) — darkest slate, laid out as
   icon │ message with a subtle slate divider between them. The divider runs the
   full height, so the padding lives on the two cells rather than on the toast.
   The original white toast is still there: FlyinsUI.toast(msg, { variant: 'default' }). */
.toast--inverse {
  align-items: stretch;
  gap: 0;
  padding: 0;
  background: var(--toast-inverse-bg);
  border-color: var(--toast-inverse-border);
}
.toast--inverse .toast__icon-cell {
  display: flex; align-items: center; flex-shrink: 0;
  padding: var(--space-12) var(--space-14);
  border-right: var(--border-1) solid var(--toast-inverse-divider);
}
.toast--inverse .toast__icon { width: 20px; height: 20px; margin: 0; }
.toast--inverse .toast__body {
  display: flex; align-items: center; gap: var(--space-10);
  flex: 1 0 0; min-width: 0;
  padding: var(--space-12) var(--space-14);
}
.toast--inverse .toast__msg { color: var(--toast-inverse-text); }
.toast--inverse .toast__close { margin-top: 0; color: var(--toast-inverse-muted); }
.toast--inverse .toast__close:hover { color: var(--toast-inverse-text); }
.toast--inverse .toast__action { color: var(--toast-inverse-action); }
.toast--inverse .toast__action:hover { color: var(--toast-inverse-text); }

/* ======================================================================
   Touch & small-screen ergonomics
   Sits at the very end so it wins over the component rules it extends
   (same reasoning as the Motion & interaction block above).

   Two jobs, both mobile-only — the desktop Figma spec is untouched:
   1. 16px fields. iOS Safari zooms the page whenever a focused control is
      under 16px and never zooms back out, so every text control steps up
      at <= 767px. Field chrome is a fixed 42px, so nothing reflows.
   2. 24px+ touch targets (WCAG 2.2 AA 2.5.8). The icons stay their Figma
      size; a transparent ::after grows the HIT AREA only, so no layout
      moves. Where two targets sit side by side the gap is widened first,
      so the enlarged areas meet but never overlap — tapping Reject must
      never land on Approve.
   ====================================================================== */
@media (max-width: 767px) {

  /* ---- 1. 16px text controls (no iOS zoom on focus) ------------------ */
  .input input,
  .textarea,
  .number-input input,
  input[type="text"], input[type="email"], input[type="password"],
  input[type="search"], input[type="tel"], input[type="number"],
  input[type="url"], select {
    font-size: 16px;
    line-height: 22px;
  }
  /* The search field and its scope trigger are defined in layout.css, which
     loads after this file — their mobile overrides live at the end of it. */

  /* ---- 2. Hit areas ---------------------------------------------------
     min 44px where there is room, 24px where the control is inline. */
  .icon-btn,
  .table__expand-btn,
  .pagination__nav,
  .input__icon-btn,
  .table__action,
  .switch,
  .number-input__stepper button {
    position: relative;
  }
  .icon-btn::after,
  .table__expand-btn::after,
  .pagination__nav::after,
  .input__icon-btn::after,
  .table__action::after,
  .switch::after {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    width: 100%; height: 100%;
    min-width: 44px; min-height: 44px;
    transform: translate(-50%, -50%);
  }
  /* The steppers are stacked 12px apart inside a 42px field: a 44px area
     would swallow its twin, so they split the field height instead. */
  .number-input__stepper button::after {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    width: 40px; height: 20px;
    transform: translate(-50%, -50%);
  }

  /* ---- Tab bar fills the width -------------------------------------
     The bar hugs its labels by design (Figma), which on a phone leaves it
     stranded against the left edge. Here it spans the container and the
     tabs split it evenly. `min-width: 0` lets a tab shrink below its label
     so two long labels can't force the bar to overflow, and the sliding
     indicator follows because it measures layout coordinates on resize. */
  .tabs { display: flex; width: 100%; }
  .tabs > .tab, .tabs > [role="radio"] {
    flex: 1 1 0; min-width: 0;
    padding-left: var(--space-8); padding-right: var(--space-8);
    text-align: center;
    overflow: hidden; text-overflow: ellipsis;
  }

  /* Widen the gaps so neighbouring hit areas meet rather than overlap.
     20px icon + 44px area = 12px of overhang per side; 28px of gap keeps
     4px of clear space between the two. */
  .icon-group { gap: 28px; }
  .pagination__pages { gap: var(--space-16); }

  /* An expand caret shares its row with the cell label, so it only needs
     to be tall enough — full width would cover the label's tap area. */
  .table td.table__expand .table__expand-btn::after { min-width: 44px; }
}
