/* ============================================================
   APP — base, layout, components
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }

/* `hidden` has to actually hide. The UA rule is only `display: none`,
   which any component rule setting a display outranks — .btn is
   `inline-flex`, so a `<button class="btn" hidden>` stayed on screen and
   every JS `el.hidden = true` on one silently did nothing. This is why
   .modal[hidden], .corporate-hint[hidden] and friends below each had to
   re-state it; they can stay, but nothing new needs to. */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0;
  font-family: var(--font-body);
  background: var(--color-app-bg);
  color: var(--color-charcoal);
  height: 100%;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 { font-family: var(--font-heading); margin: 0; color: var(--color-ink); }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
.num, .ltr-num { direction: ltr; unicode-bidi: isolate; display: inline-block; }
/* The inline-block above is what keeps a run of digits from being reordered
   by the surrounding RTL text — but on a <td> it drops the cell out of the
   table's column layout, and the body row then stops short of the header
   row it is supposed to line up under. The isolation is what these cells
   want; the display change is not. */
td.num, th.num, td.ltr-num, th.ltr-num { display: table-cell; }

/* =========================================================
   Custom scrollbars — themed, slim, never reserve gutter
   ========================================================= */
/* Firefox */
* { scrollbar-width: thin; scrollbar-color: rgba(110, 110, 105, 0.35) transparent; }

/* WebKit / Blink */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-thumb {
  background-color: rgba(110, 110, 105, 0.35);
  background-clip: padding-box;
  border: 2px solid transparent;
  border-radius: 999px;
  min-height: 32px;
  min-width: 32px;
}
::-webkit-scrollbar-thumb:hover  { background-color: rgba(55, 53, 47, 0.55); background-clip: padding-box; }
::-webkit-scrollbar-thumb:active { background-color: var(--color-primary); background-clip: padding-box; }

/* Dark theme: lighter thumb on dark surface */
:root[data-theme="dark"] { scrollbar-color: rgba(255, 255, 255, 0.2) transparent; }
:root[data-theme="dark"] ::-webkit-scrollbar-thumb       { background-color: rgba(255, 255, 255, 0.2); background-clip: padding-box; }
:root[data-theme="dark"] ::-webkit-scrollbar-thumb:hover { background-color: rgba(255, 255, 255, 0.35); background-clip: padding-box; }

/* =========================================================
   App shell
   ========================================================= */
.app-shell  { display: flex; height: 100vh; overflow: hidden; }
.app-main   { flex: 1; min-width: 0; display: flex; flex-direction: column; background: var(--color-app-bg); }
.app-content{ flex: 1; overflow: auto; padding: 28px 32px; }

/* =========================================================
   Sidebar
   ========================================================= */
.side {
  width: 248px; flex-shrink: 0;
  background: var(--color-app-panel);
  display: flex; flex-direction: column;
  transition: width 200ms ease-out;
}
[dir="rtl"] .side { border-left:  1px solid var(--color-app-border); }
[dir="ltr"] .side { border-right: 1px solid var(--color-app-border); }

.side .brand {
  display: flex; align-items: center; gap: 10px;
  padding: 0 16px;
  height: var(--nav-height);
  flex-shrink: 0;
  border-bottom: 1px solid var(--color-app-border);
  font-family: var(--font-heading);
  font-weight: 700;
  color: var(--color-ink);
  text-decoration: none;
}
.side .brand-logo {
  width: 32px; height: 32px; border-radius: 8px;
  background: var(--color-primary);
  color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700;
}
.side-section-head {
  padding: 14px 16px 6px;
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.6px;
  color: var(--color-stone); font-weight: 600;
}
.side-list { padding: 4px 0; flex: 1; min-height: 0; overflow-y: auto; }

.nav-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; margin: 0 8px;
  border-radius: 8px;
  font-size: 14px;
  color: var(--color-charcoal);
  cursor: pointer;
  transition: background 120ms, color 120ms;
}
.nav-item:hover { background: var(--color-app-hover); }
.nav-item.active {
  background: var(--color-primary-soft);
  color: var(--color-primary);
  font-weight: 600;
}
.nav-item .nav-icon { width: 18px; height: 18px; flex-shrink: 0; }
.nav-item .nav-badge {
  margin-inline-start: auto;
  background: var(--color-primary); color: #fff;
  font-size: 11px; font-weight: 600;
  padding: 1px 7px; border-radius: 9999px;
}

/* Stacked radio option rows (e.g. export report-type chooser) */
.radio-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--color-app-border); border-radius: 8px;
  font-size: 14px; font-weight: 400; cursor: pointer;
  transition: border-color 120ms, background 120ms;
}
.radio-row:hover { background: var(--color-app-hover); }
.radio-row:has(input:checked) {
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
}
/* Override the full-width .fld input rule for the inline radio control. */
.fld .radio-row input[type="radio"] {
  width: 16px; height: 16px;
  flex: 0 0 auto;
  margin: 0; padding: 0;
  accent-color: var(--color-primary);
}
.radio-row > span { flex: 1 1 auto; line-height: 1.4; }

/* Progress bar (bulk update-all) */
.progress {
  height: 8px; width: 100%;
  background: var(--color-app-border);
  border-radius: 9999px; overflow: hidden;
}
.progress-fill {
  display: block; height: 100%; width: 0;
  background: var(--color-primary);
  border-radius: 9999px;
  transition: width 280ms ease;
}
.progress-fill.is-error { background: var(--color-error); }

/* Subscriber-summary modal — animated totals tiles */
.sum-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
}
@media (max-width: 640px) { .sum-grid { grid-template-columns: repeat(2, 1fr); } }
.sum-tile {
  border: 1px solid var(--color-app-border);
  border-radius: 12px; padding: 12px 14px;
  background: var(--color-app-bg);
  animation: sum-pop .35s ease both;
}
.sum-tile-primary { border-color: var(--color-primary); background: var(--color-card-tint-mint, var(--color-app-bg)); }
.sum-tile .sum-label { display: block; font-size: 11px; color: var(--color-stone); }
.sum-tile .sum-value { display: block; font-size: 18px; font-weight: 800; margin-top: 2px; }
.sum-grid .sum-tile:nth-child(2) { animation-delay: .05s; }
.sum-grid .sum-tile:nth-child(3) { animation-delay: .10s; }
.sum-grid .sum-tile:nth-child(4) { animation-delay: .15s; }
.sum-grid .sum-tile:nth-child(5) { animation-delay: .20s; }
.sum-grid .sum-tile:nth-child(6) { animation-delay: .25s; }
@keyframes sum-pop {
  from { opacity: 0; transform: translateY(6px) scale(.97); }
  to   { opacity: 1; transform: none; }
}
.flex-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.bulk-results { max-height: 46vh; overflow: auto; }
.bulk-row {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 0; border-top: 1px solid var(--color-app-border);
  font-size: 13px;
}
.bulk-row .bulk-name { font-weight: 600; flex: 1 1 auto; min-width: 0; }
.bulk-row .bulk-log {
  flex: 2 1 0; min-width: 0; color: var(--color-stone); font-size: 12px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; direction: ltr;
}

.side .side-foot {
  padding: 12px 16px;
  border-top: 1px solid var(--color-app-border);
  font-size: 12px; color: var(--color-stone);
  flex-shrink: 0;
}

/* =========================================================
   Topbar
   ========================================================= */
.topbar {
  height: 64px; flex-shrink: 0;
  background: var(--color-app-panel);
  border-bottom: 1px solid var(--color-app-border);
  display: flex; align-items: center; gap: 14px;
  padding: 0 24px;
}
.topbar h1 {
  font-size: 18px; font-weight: 700; color: var(--color-ink);
  font-family: var(--font-heading);
}
.topbar .topbar-user { display: flex; align-items: center; gap: 10px; }
.topbar .topbar-user-trigger {
  display: flex; align-items: center; gap: 10px;
  background: none; border: none; cursor: pointer; padding: 2px;
  color: inherit; font: inherit; border-radius: 8px;
}
.topbar .topbar-user-trigger:hover { background: var(--color-app-hover); }
.topbar .topbar-user-caret { color: var(--color-stone); flex-shrink: 0; }
.topbar .topbar-user-text { display: flex; flex-direction: column; line-height: 1.1; align-items: flex-start; }
.topbar .topbar-user-text .name { font-size: 13px; font-weight: 600; color: var(--color-ink); }
.topbar .topbar-user-text .role { font-size: 12px; color: var(--color-stone); }

/* =========================================================
   Buttons
   ========================================================= */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font-family: var(--font-body);
  font-size: 14px; font-weight: 500; line-height: 1.3;
  padding: 10px 18px;
  border-radius: 8px;
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: background 150ms, border-color 150ms, color 150ms;
}
.btn-primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.btn-primary:hover  { background: var(--color-primary-pressed); }
.btn-primary:active { background: var(--color-primary-pressed); }
.btn-secondary {
  background: transparent;
  color: var(--color-ink);
  border-color: var(--color-app-border);
}
.btn-secondary:hover { background: var(--color-app-hover); }
.btn-ghost {
  background: transparent;
  color: var(--color-ink);
  padding: 8px 12px;
  border-radius: var(--radius-sm);
}
.btn-ghost:hover { background: var(--color-app-hover); }
.btn-danger {
  background: var(--color-error);
  color: #fff;
}
.btn-danger:hover  { filter: brightness(0.95); }
.btn-danger:active { filter: brightness(0.9); }
.btn-warning {
  background: var(--color-status-pending-bg);
  color: var(--color-status-pending-fg);
  border-color: rgba(217, 119, 6, 0.35);
}
.btn-warning:hover  { background: rgba(252, 211, 77, 0.45); }
.btn-warning:active { background: rgba(252, 211, 77, 0.6); }
.btn-link {
  background: transparent;
  color: var(--color-link-blue);
  font-size: 13px;
  padding: 0;
  border: none;
}
.btn-icon {
  width: 36px; height: 36px; padding: 0; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid transparent;
  color: var(--color-slate);
  cursor: pointer; transition: background 120ms;
}
.btn-icon:hover { background: var(--color-app-hover); color: var(--color-ink); }
.btn-block { width: 100%; }

/* =========================================================
   Panels / cards
   ========================================================= */
.panel {
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 12px;
}
.panel-pad    { padding: 20px; }
.panel-pad-lg { padding: 28px; }
.panel-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--color-app-border);
}
.panel-head h2, .panel-head h3 {
  font-size: 15px; font-weight: 700; color: var(--color-ink);
}

/* =========================================================
   KPI cards (small, top row on dashboard — 4 across)
   ========================================================= */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}
.kpi {
  position: relative;
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 14px;
  padding: 18px 20px;
  display: flex; flex-direction: column; gap: 8px;
  box-shadow: var(--shadow-1);
  overflow: hidden;
  transition: transform 160ms ease-out, box-shadow 160ms ease-out;
}
.kpi:hover { transform: translateY(-1px); box-shadow: var(--shadow-2); }
.kpi::before {
  /* Coloured accent strip at the top — set per-accent below. */
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: currentColor; opacity: 0.85;
  color: var(--color-stone);
}
.kpi-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
}
.kpi-label { font-size: 13px; color: var(--color-slate); font-weight: 500; }
.kpi-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border-radius: 10px;
  background: var(--color-app-bg);
  color: var(--color-stone);
  flex-shrink: 0;
}
.kpi-icon i, .kpi-icon svg { width: 18px; height: 18px; }
.kpi-value { font-family: var(--font-heading); font-size: 28px; font-weight: 700; color: var(--color-ink); letter-spacing: -0.5px; line-height: 1.15; }
.kpi-delta { font-size: 12px; font-weight: 500; display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.kpi-delta.up   { color: #16A34A; }
.kpi-delta.down { color: #DC2626; }
.kpi-delta .text-stone { color: var(--color-stone); font-weight: 400; }

/* Per-card accent — drives both the top strip and the icon tint. */
.kpi-accent-teal   { color: #0D9488; }
.kpi-accent-teal   .kpi-icon { background: rgba(13, 148, 136, 0.12); color: #0D9488; }
.kpi-accent-amber  { color: #E59947; }
.kpi-accent-amber  .kpi-icon { background: rgba(229, 153, 71, 0.14); color: #B25E1A; }
.kpi-accent-violet { color: #6649EB; }
.kpi-accent-violet .kpi-icon { background: rgba(102, 73, 235, 0.12); color: #6649EB; }
.kpi-accent-rose   { color: #D44C7A; }
.kpi-accent-rose   .kpi-icon { background: rgba(212, 76, 122, 0.12); color: #D44C7A; }

/* =========================================================
   Grids
   ========================================================= */
.grid-kpi { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.grid-2-1 { display: grid; grid-template-columns: 2fr 1fr; gap: 16px; }
.grid-1-1 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

/* =========================================================
   Window toggle — dashboard time-window segmented control.
   ========================================================= */
.window-toggle {
  display: inline-flex;
  padding: 4px;
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 10px;
  gap: 2px;
}
.window-toggle-btn {
  /* Used as both <a> (the window tabs, which navigate) and <button>
     (the chart resolution switch, which doesn't). The button defaults —
     grey background, outset border, Arial — have to be cleared here or
     the inactive segments render as raw browser buttons in the wrong
     font. Same treatment as .settings-tab below. */
  appearance: none;
  background: none;
  border: 0;
  padding: 6px 14px;
  border-radius: 7px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--color-slate);
  cursor: pointer;
  text-decoration: none;
  transition: background 120ms, color 120ms;
}
.window-toggle-btn:hover { background: var(--color-app-hover); color: var(--color-ink); }
.window-toggle-btn.is-active {
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.window-toggle-btn.is-active:hover {
  background: var(--color-primary-pressed);
  color: var(--color-on-primary);
}

/* =========================================================
   Settings tabs — segmented sub-nav on the /settings pages.
   ========================================================= */
.settings-tabs {
  display: inline-flex;
  padding: 4px;
  margin-bottom: 16px;
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 10px;
  gap: 2px;
}
.settings-tab {
  /* Used as both <a> (settings pages) and <button> (in-modal tabs). The
     button defaults — grey background, border, UA font — have to be
     cleared here or the inactive tabs render as raw buttons. */
  background: none;
  border: 0;
  padding: 6px 16px;
  border-radius: 7px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--color-slate);
  cursor: pointer;
  text-decoration: none;
  transition: background 120ms, color 120ms;
}
.settings-tab:hover { background: var(--color-app-hover); color: var(--color-ink); }
.settings-tab.is-active {
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.settings-tab.is-active:hover {
  background: var(--color-primary-pressed);
  color: var(--color-on-primary);
}

/* =========================================================
   Welcome banner (dashboard)
   ========================================================= */
.welcome {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  margin-bottom: 24px;
}
.welcome-title {
  font-family: var(--font-heading);
  font-size: 26px; font-weight: 700; line-height: 1.2;
  color: var(--color-ink);
  display: inline-flex; align-items: center; gap: 8px;
  letter-spacing: -0.4px;
}
.welcome-wave {
  display: inline-block;
  transform-origin: 70% 70%;
  animation: mc-wave 1.8s ease-in-out 1;
}
@keyframes mc-wave {
  0%   { transform: rotate(0); }
  20%  { transform: rotate(14deg); }
  40%  { transform: rotate(-8deg); }
  60%  { transform: rotate(14deg); }
  80%  { transform: rotate(-4deg); }
  100% { transform: rotate(0); }
}
.welcome-sub { color: var(--color-slate); font-size: 14px; margin-top: 4px; }
.btn-export { white-space: nowrap; }

/* =========================================================
   Stat cards (KPI + chart) — 2x2 grid
   ========================================================= */
.stat-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}
.stat-card {
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 14px;
  padding: 22px 22px 16px;
  display: flex; flex-direction: column; gap: 12px;
  min-height: 220px;
  overflow: hidden;
}
.stat-card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
}
.stat-label  { color: var(--color-slate); font-size: 13px; font-weight: 500; }
.stat-delta  {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; font-weight: 600;
  padding: 2px 8px; border-radius: 999px;
}
.stat-delta.up   { color: #15803D; background: #DCFCE7; }
.stat-delta.down { color: #B91C1C; background: #FEE2E2; }
.stat-value {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 36px;
  color: var(--color-ink);
  letter-spacing: -0.5px;
  line-height: 1.1;
}
.stat-chart { margin-top: auto; min-height: 88px; }

/* Chart.js canvas wrapper — explicit height so the chart sizes
   correctly inside a flex .stat-card without exploding. */
.chart-canvas-wrap {
  position: relative;
  width: 100%;
  height: 240px;
  margin-top: 12px;
}
.chart-canvas-wrap canvas { width: 100% !important; height: 100% !important; }
/* The full-width income/profit plot gets the room two side-by-side
   cards used to occupy between them. */
.chart-canvas-tall { height: 340px; }

/* =========================================================
   Chart panel — the full-width income vs. profit plot.
   ========================================================= */
.chart-panel {
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 14px;
  padding: 22px 22px 18px;
}
.chart-panel-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.chart-panel-titles { min-width: 0; }
.chart-panel-title {
  display: flex; align-items: center; gap: 8px;
  margin: 0;
  font-family: var(--font-heading);
  font-size: 17px; font-weight: 600;
  color: var(--color-ink);
}
.chart-panel-sub {
  margin: 4px 0 0;
  font-size: 12.5px;
  color: var(--color-slate);
}
/* Keep the resolution switch on one line even when the panel wraps —
   four short labels reflowing mid-group reads as broken. */
.chart-panel-intervals { flex: 0 0 auto; }

/* Pulsing dot to signal a panel is on a live-poll refresh loop. */
.live-pulse {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--color-success);
  box-shadow: 0 0 0 0 rgba(74, 156, 97, 0.55);
  animation: live-pulse 1800ms ease-out infinite;
}
@keyframes live-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(74, 156, 97, 0.55); }
  70%  { box-shadow: 0 0 0 10px rgba(74, 156, 97, 0);  }
  100% { box-shadow: 0 0 0 0 rgba(74, 156, 97, 0);     }
}

/* Chart loading states ---------------------------------------------
   A polled chart waits twice, and the two waits deserve different
   answers. The first one has nothing on screen yet — an empty grid that
   reads as "no sales" rather than "not loaded" — so it gets the panel: a
   spinner over the plot until real numbers land. Every refresh after it
   is redrawing a chart somebody is in the middle of reading, so it gets
   a hairline at the top edge and nothing more. */
.chart-loader {
  position: absolute;
  inset: 0;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: var(--color-app-panel);
  border-radius: 10px;
  z-index: 2;
}
.chart-canvas-wrap.is-loading .chart-loader,
.chart-canvas-wrap.is-failed  .chart-loader,
.chart-canvas-wrap.is-empty   .chart-loader { display: flex; }

.chart-spinner {
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 3px solid var(--color-app-border);
  border-top-color: var(--color-primary);
  animation: chart-spin 720ms linear infinite;
}
/* Only the wait spins. A finished state that keeps spinning is a lie. */
.chart-canvas-wrap.is-failed .chart-spinner,
.chart-canvas-wrap.is-empty  .chart-spinner { display: none; }
@keyframes chart-spin { to { transform: rotate(360deg); } }

.chart-loader-text { font-size: 12.5px; color: var(--color-slate); }
.chart-canvas-wrap.is-failed .chart-loader-text { color: var(--color-error); }
.chart-loader-retry {
  display: none;
  padding: 6px 14px;
  border: 1px solid var(--color-app-border);
  border-radius: 999px;
  background: var(--color-app-panel);
  color: var(--color-charcoal);
  font-size: 12.5px; font-weight: 600;
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.chart-canvas-wrap.is-failed .chart-loader-retry { display: inline-flex; }
.chart-loader-retry:hover { border-color: var(--color-primary); color: var(--color-primary); }

/* The refresh tell: a light sweeping the top edge, drawn with
   background-position rather than a transform so it runs the same way
   in both directions and needs nothing clipped to contain it. */
.chart-canvas-wrap.is-refreshing::after {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  border-radius: 2px;
  background-image: linear-gradient(90deg, transparent 0%, var(--color-primary) 50%, transparent 100%);
  background-size: 40% 100%;
  background-repeat: no-repeat;
  animation: chart-refresh 1200ms ease-in-out infinite;
  z-index: 2;
}
@keyframes chart-refresh {
  0%   { background-position: -40% 0; }
  100% { background-position: 140% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .chart-spinner { animation-duration: 2400ms; }
  .chart-canvas-wrap.is-refreshing::after {
    animation: none;
    background-image: none;
    background-color: var(--color-primary);
    opacity: .35;
  }
}

/* Brief highlight when a KPI value changes on a live update. */
.kpi-flash { animation: kpi-flash 700ms ease-out; }
@keyframes kpi-flash {
  0%   { color: var(--color-primary); }
  100% { color: var(--color-ink); }
}

/* =========================================================
   Charts (inline SVG)
   ========================================================= */
.chart-svg { width: 100%; height: 100px; display: block; overflow: visible; }
.chart-bar-cool { fill: var(--color-accent); }
.chart-bar-warm { fill: var(--color-brand-orange); }
.chart-area-line {
  fill: none;
  stroke: var(--color-primary);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.chart-area-fill { fill: url(#areaGrad); }
.chart-area-dot  { fill: var(--color-primary); }
.chart-area-dot.is-last { fill: var(--color-primary); stroke: var(--color-app-panel); stroke-width: 2; }

/* Donut */
.donut-wrap { display: flex; align-items: center; gap: 18px; }
.donut { width: 110px; height: 110px; flex-shrink: 0; }
.donut .donut-track { fill: none; stroke: var(--color-app-border); stroke-width: 12; }
.donut .donut-bar   {
  fill: none; stroke: var(--color-primary); stroke-width: 12;
  stroke-linecap: round;
  transition: stroke-dasharray 600ms ease-out;
}
.donut .donut-text  {
  font-family: var(--font-heading);
  font-weight: 700; font-size: 22px;
  fill: var(--color-ink);
}
.donut-legend {
  display: flex; flex-direction: column; gap: 6px;
  font-size: 13px; color: var(--color-charcoal);
}
.donut-legend > div { display: flex; align-items: center; gap: 6px; }
.donut-legend .dot {
  width: 8px; height: 8px; border-radius: 50%;
  display: inline-block;
}
.donut-legend .dot-track { background: var(--color-app-border); }
.donut-legend .dot-bar   { background: var(--color-primary); }
.donut-legend span:not(.dot) { color: var(--color-slate); }
.donut-legend .num { color: var(--color-ink); font-weight: 600; margin-inline-start: 2px; }

/* =========================================================
   Status pills + tags
   ========================================================= */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 600;
  padding: 3px 10px; border-radius: 9999px;
  white-space: nowrap;
}
.pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .85; }
.pill.active    { background: var(--color-status-active-bg);    color: var(--color-status-active-fg); }
.pill.pending   { background: var(--color-status-pending-bg);   color: var(--color-status-pending-fg); }
.pill.blocked   { background: var(--color-status-blocked-bg);   color: var(--color-status-blocked-fg); }
.pill.draft     { background: var(--color-status-draft-bg);     color: var(--color-status-draft-fg); }
.pill.published { background: var(--color-status-published-bg); color: var(--color-status-published-fg); }

/* =========================================================
   Data table
   ========================================================= */
.dt-wrap { overflow-x: auto; }
.dt { width: 100%; border-collapse: collapse; min-width: 720px; }
.dt thead th {
  font-size: 12px; font-weight: 600; color: var(--color-slate);
  text-align: start;
  padding: 12px 14px;
  background: var(--color-app-bg);
  border-bottom: 1px solid var(--color-app-border);
  white-space: nowrap;
}
.dt tbody td {
  padding: var(--row-pad-y) 14px;
  font-size: 14px;
  color: var(--color-charcoal);
  border-bottom: 1px solid var(--color-app-border-soft);
  vertical-align: middle;
}
.dt tbody tr:hover { background: var(--color-app-hover); }
.dt tbody tr:last-child td { border-bottom: none; }
.dt .row-actions { display: inline-flex; gap: 4px; }
.dt tfoot td {
  padding: 12px 14px;
  font-size: 14px;
  font-weight: 700;
  color: var(--color-ink);
  background: var(--color-app-bg);
  border-top: 2px solid var(--color-app-border);
}
.dt tbody tr.is-hidden { display: none; }

/* Row-selection checkboxes (stores bulk actions) */
.dt th.dt-check, .dt td.dt-check { width: 36px; padding-inline-end: 0; text-align: center; }
.dt .dt-check input[type="checkbox"] {
  width: 16px; height: 16px;
  accent-color: var(--color-primary);
  cursor: pointer;
  vertical-align: middle;
}
.dt tbody tr.is-selected,
.dt tbody tr.is-selected:hover { background: var(--color-app-hover); }

/* =========================================================
   Pagination
   ========================================================= */
.pagination {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  padding: 12px 16px;
  border-top: 1px solid var(--color-app-border);
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--color-slate);
}
.pagination-info .num,
.pagination-info { font-variant-numeric: tabular-nums; }
.pagination-nav { display: inline-flex; align-items: center; gap: 4px; }
.page-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 32px; height: 32px;
  padding: 0 8px;
  border-radius: 8px;
  font-family: var(--font-body);
  font-size: 13px; font-weight: 500;
  color: var(--color-charcoal);
  border: 1px solid transparent;
  background: transparent;
  text-decoration: none;
  cursor: pointer;
  transition: background 120ms, border-color 120ms, color 120ms;
  user-select: none;
}
.page-btn:hover { background: var(--color-app-hover); border-color: var(--color-app-border); }
.page-btn.is-active {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: var(--color-primary);
}
.page-btn.is-active:hover { background: var(--color-primary-pressed); border-color: var(--color-primary-pressed); }
.page-btn.is-disabled { opacity: 0.4; pointer-events: none; }
.page-btn i, .page-btn svg { width: 16px; height: 16px; }
.page-dot {
  padding: 0 4px;
  color: var(--color-stone);
  user-select: none;
  font-size: 14px;
}

@media (max-width: 640px) {
  .pagination { justify-content: center; padding: 10px 12px; }
  .pagination-info { width: 100%; text-align: center; order: 2; }
  .pagination-nav  { order: 1; }
}

/* =========================================================
   Stat tiles (sleek summary cards above a list page)
   ========================================================= */
.stat-row {
  display: grid;
  grid-template-columns: 1fr 2.2fr;
  gap: 16px;
}
/* Three tiles read as three equals; the default 1fr/2.2fr pair is for a
   hero beside one secondary, and dropping a third into it wraps the last
   tile onto its own full-width line. */
.stat-row-3 { grid-template-columns: repeat(3, 1fr); }
.stat-tile {
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 14px;
  padding: 16px 18px;
  display: flex; align-items: center; gap: 14px;
  min-height: 88px;
}
.stat-tile-icon {
  width: 44px; height: 44px;
  border-radius: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-primary-soft);
  color: var(--color-primary);
  flex-shrink: 0;
}
.stat-tile-icon i { width: 22px; height: 22px; }
.stat-tile-icon-neutral { background: var(--color-app-hover); color: var(--color-slate); }
.stat-tile-text { display: flex; flex-direction: column; flex: 1; gap: 4px; min-width: 0; }
.stat-tile-label { font-size: 13px; color: var(--color-slate); font-weight: 500; }
.stat-tile-value {
  font-family: var(--font-heading);
  font-size: 28px; font-weight: 700;
  color: var(--color-ink);
  letter-spacing: -0.4px;
  line-height: 1.05;
}

.stat-tile-row { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; margin-top: 4px; }
.stat-divider { width: 1px; align-self: stretch; background: var(--color-app-border); }
.stat-sub { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--color-slate); }
.stat-sub-label { color: var(--color-charcoal); font-weight: 500; }
.stat-sub-value {
  font-family: var(--font-heading);
  font-size: 20px; font-weight: 700;
  color: var(--color-ink);
  margin-inline-start: 2px;
  line-height: 1;
}
.stat-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.stat-dot.active   { background: var(--color-success); box-shadow: 0 0 0 3px rgba(74, 156, 97, 0.18); }
.stat-dot.disabled { background: var(--color-error);   box-shadow: 0 0 0 3px rgba(212, 76, 71, 0.18); }
.stat-dot.linked   { background: var(--color-primary); box-shadow: 0 0 0 3px var(--color-primary-soft); }
.stat-dot.pending  { background: var(--color-status-pending-fg); box-shadow: 0 0 0 3px var(--color-status-pending-bg); }
.stat-dot.partner  { background: var(--color-warning); box-shadow: 0 0 0 3px rgba(229, 153, 71, 0.18); }
/* The two states a request can end in. Both were drawn by the settlements
   summary and neither had a rule, so a rejected or cancelled count came
   with an invisible dot beside it. Same fg/bg pairing as the pills the
   table uses for the identical states. */
.stat-dot.blocked  { background: var(--color-status-blocked-fg); box-shadow: 0 0 0 3px var(--color-status-blocked-bg); }
.stat-dot.draft    { background: var(--color-status-draft-fg);   box-shadow: 0 0 0 3px var(--color-status-draft-bg); }
.stat-dot.published{ background: var(--color-status-published-fg); box-shadow: 0 0 0 3px var(--color-status-published-bg); }

/* Partner balance — a money column, so it reads as one: tabular
   figures, and a debt that has gone the wrong way is not silently the
   same colour as one that has not. */
.partner-balance {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: 13px;
  color: var(--color-ink);
  white-space: nowrap;
}
.partner-balance.is-negative { color: var(--color-error); }
/* The value is replaced in place by the poll; a brief tint marks the
   ones that actually moved so a changing figure is noticed. */
.partner-balance.is-changed,
[data-bind="partner-due"].is-changed { animation: partner-flash 900ms ease-out; }
@keyframes partner-flash {
  0%   { background: var(--color-primary-soft); }
  100% { background: transparent; }
}

@media (max-width: 1100px) {
  .stat-row-3 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 768px) {
  .stat-row, .stat-row-3 { grid-template-columns: 1fr; gap: 12px; }
  .stat-tile { min-height: 76px; padding: 14px 16px; }
  .stat-tile-value { font-size: 24px; }
  .stat-tile-row { gap: 16px; }
  .stat-divider { display: none; }
}

/* =========================================================
   Role pills (table column)
   ========================================================= */
.role-pill {
  display: inline-flex; align-items: center;
  font-size: 12px; font-weight: 600;
  padding: 3px 10px;
  border-radius: 9999px;
  white-space: nowrap;
}
.role-pill.role-admin   { background: var(--color-card-tint-lavender); color: var(--color-brand-purple-800); }
.role-pill.role-manager { background: var(--color-card-tint-mint);     color: var(--color-brand-green); }

/* =========================================================
   Jawwal-pay status dot (per-row indicator)
   ========================================================= */
.jawwal-dot {
  display: inline-block;
  width: 9px; height: 9px;
  border-radius: 50%;
  margin-inline-start: 10px;
  vertical-align: middle;
  position: relative;
  flex-shrink: 0;
  cursor: help;
}
.jawwal-dot.on  { background: var(--color-success); animation: mc-pulse-on  1.6s ease-in-out infinite; }
.jawwal-dot.off { background: var(--color-error);   animation: mc-pulse-off 1.6s ease-in-out infinite; }
@keyframes mc-pulse-on {
  0%, 100% { box-shadow: 0 0 0 0 rgba(74, 156, 97, 0.55); }
  50%      { box-shadow: 0 0 0 7px rgba(74, 156, 97, 0);   }
}
@keyframes mc-pulse-off {
  0%, 100% { box-shadow: 0 0 0 0 rgba(212, 76, 71, 0.5); }
  50%      { box-shadow: 0 0 0 7px rgba(212, 76, 71, 0);  }
}
/* Honour reduced-motion preferences */
@media (prefers-reduced-motion: reduce) {
  .jawwal-dot.on, .jawwal-dot.off { animation: none; }
}
/* Wallet account-type hint next to the linked dot (partner / personal). */
.jawwal-cell { display: inline-flex; align-items: center; gap: 8px; }
.jawwal-cell .jawwal-dot { margin-inline-start: 0; }
.jawwal-paytype {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.6;
  white-space: nowrap;
}
.jawwal-paytype.partner  { background: var(--color-status-active-bg);  color: var(--color-status-active-fg); }
.jawwal-paytype.personal { background: var(--color-app-hover);         color: var(--color-slate); }

/* =========================================================
   Row-actions menu
   ========================================================= */
.menu-wrap { position: relative; }
.menu {
  position: absolute; top: 100%; margin-top: 4px;
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 10px;
  box-shadow: var(--shadow-2);
  min-width: 180px;
  padding: 4px;
  z-index: 1000;
  animation: mc-fade-in 120ms ease-out forwards;
}
[dir="rtl"] .menu { left: 0;  right: auto; }
[dir="ltr"] .menu { right: 0; left:  auto; }
/* JS lifts the menu out of its scroll-clipped wrapper by switching to
   fixed positioning and writing top/left inline. */
.menu.is-floating { position: fixed; margin: 0; }
.menu button, .menu a {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: none; background: transparent; cursor: pointer;
  border-radius: 6px;
  font-size: 13px;
  color: var(--color-charcoal);
  text-align: start;
  text-decoration: none;
  font-family: var(--font-body);
}
.menu button:hover, .menu a:hover { background: var(--color-app-hover); color: var(--color-ink); }
.menu button.danger { color: var(--color-error); }
.menu button.danger:hover { background: rgba(212, 76, 71, 0.08); }
.menu button i, .menu button svg,
.menu a i, .menu a svg { width: 16px; height: 16px; flex-shrink: 0; }

/* =========================================================
   Avatar
   ========================================================= */
.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; color: #fff; font-weight: 600;
  font-family: var(--font-heading);
  flex-shrink: 0;
  width: 32px; height: 32px; font-size: 13px;
  background: var(--color-primary);
}
.avatar-sm  { width: 24px; height: 24px; font-size: 11px; }
.avatar-lg  { width: 40px; height: 40px; font-size: 15px; }
.avatar-img { object-fit: cover; background: var(--color-app-hover); }

/* =========================================================
   Modal
   ========================================================= */
.modal[hidden] { display: none !important; }
.modal {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  animation: mc-fade-in 160ms ease-out;
}
.modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(15, 15, 15, 0.5);
}
.modal-panel {
  position: relative;
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 14px;
  width: 100%;
  max-width: 560px;
  max-height: calc(100vh - 48px);
  display: flex; flex-direction: column;
  box-shadow: 0 24px 48px -12px rgba(15, 15, 15, 0.32);
  animation: mc-slide-up 200ms ease-out;
}
.modal-panel.modal-sm { max-width: 420px; }
.modal-panel.modal-lg { max-width: 880px; }

/* Financial-statement — bank-statement document layout */
.stmt-toolbar {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 12px; flex-wrap: wrap; margin-bottom: 4px;
}

.stmt-doc-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  padding-bottom: 12px; border-bottom: 2px solid var(--color-ink); margin-bottom: 10px;
}
.stmt-doc-title { font-family: var(--font-heading); font-size: 18px; font-weight: 700; color: var(--color-ink); }
.stmt-doc-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.stmt-doc-period {
  display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  font-size: 13px; color: var(--color-slate); margin-bottom: 12px;
}

.stmt-summary { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin-bottom: 18px; }
.stmt-summary-item {
  display: flex; flex-direction: column; gap: 4px;
  border: 1px solid var(--color-app-border); border-radius: 10px; padding: 12px 14px;
}
.stmt-summary-item .lbl { font-size: 12px; color: var(--color-slate); }
.stmt-summary-item .val { font-family: var(--font-heading); font-size: 18px; font-weight: 700; color: var(--color-ink); }

.stmt-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 28px; }
@media (max-width: 720px) { .stmt-summary, .stmt-grid { grid-template-columns: 1fr; } }

.stmt-section-title {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 14px; font-weight: 700; color: var(--color-ink);
  padding-bottom: 6px; margin-bottom: 2px; border-bottom: 2px solid var(--color-app-border);
}
.stmt-line {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 0; border-bottom: 1px dashed var(--color-app-border); font-size: 14px;
}
.stmt-line:last-child { border-bottom: none; }
.stmt-line-label { flex: 1; color: var(--color-slate); }
.stmt-line-meta  { color: var(--color-stone); font-size: 12px; }
.stmt-line-val   { min-width: 96px; text-align: end; font-weight: 600; color: var(--color-ink); }
.stmt-line-negative .stmt-line-val { color: var(--color-error); }
.stmt-line-total { border-top: 2px solid var(--color-app-border); border-bottom: none; margin-top: 2px; }
.stmt-line-total .stmt-line-label { color: var(--color-ink); font-weight: 700; }
.stmt-line-total .stmt-line-val { color: var(--color-primary-deep, #0D9488); font-weight: 700; }

.stmt-loading {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 40px 0; color: var(--color-stone);
}
.stmt-spinner {
  width: 32px; height: 32px; border-radius: 50%;
  border: 3px solid var(--color-app-border);
  border-top-color: var(--color-primary, #0D9488);
  animation: mc-spin 700ms linear infinite;
}
@keyframes mc-spin { to { transform: rotate(360deg); } }
@keyframes mc-slide-up {
  from { transform: translateY(12px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--color-app-border);
  flex-shrink: 0;
}
.modal-title {
  font-family: var(--font-heading);
  font-size: 16px; font-weight: 700;
  color: var(--color-ink);
  margin: 0;
}
.modal-body {
  padding: 20px;
  overflow-y: auto;
  flex: 1;
  display: flex; flex-direction: column; gap: 14px;
}
.modal-foot {
  padding: 14px 20px;
  border-top: 1px solid var(--color-app-border);
  display: flex; justify-content: flex-end; gap: 8px;
  flex-shrink: 0;
}

/* Two-column form layout inside modals */
.grid-form-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.grid-form-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; }
.checkbox-row { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; }

/* Switch — a checkbox for settings that read as on/off rather than
   as a form field to fill in (see the corporate-API master switch).
   The <input> stays a real checkbox for keyboard + form semantics and
   is painted over by the track. */
.switch { position: relative; display: inline-block; width: 46px; height: 26px; flex-shrink: 0; }
.switch input[type="checkbox"] {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; z-index: 1; cursor: pointer;
}
.switch .switch-track {
  position: absolute; inset: 0;
  background: var(--color-app-border);
  border-radius: 999px;
  transition: background .18s ease;
}
.switch .switch-track::before {
  content: "";
  position: absolute; top: 3px; inset-inline-start: 3px;
  width: 20px; height: 20px;
  background: #fff; border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
  transition: transform .18s ease;
}
.switch input:checked + .switch-track { background: var(--color-primary); }
/* Logical inset-inline-start already flips the knob's origin for RTL,
   so the "on" travel has to flip with it. */
.switch input:checked + .switch-track::before { transform: translateX(20px); }
[dir="rtl"] .switch input:checked + .switch-track::before { transform: translateX(-20px); }
.switch input:focus-visible + .switch-track {
  outline: 2px solid var(--color-primary); outline-offset: 2px;
}
.switch input:disabled { cursor: not-allowed; }
.switch input:disabled + .switch-track { opacity: .5; }

.switch-row { display: flex; align-items: center; gap: 12px; }

/* The portal-without-API warning. `display` lives here rather than as an
   inline style because an inline `display: block` outranks the [hidden]
   attribute, which would pin the warning on screen permanently. */
.corporate-hint { display: block; margin-top: 8px; }
.corporate-hint[hidden] { display: none; }

/* Corporate-accounts modal: a table of row actions needs a button that
   fits a table cell, and a monospace run for usernames / credentials
   that must be copied character-for-character. */
.btn-sm { padding: 4px 10px; font-size: 12px; min-height: 0; }
.mono { font-family: var(--font-mono); }
/* The settings tab strip, re-used inside a modal. `.modal-body` is a flex
   column, so its default `align-items: stretch` would blow the strip out
   to the full width and leave the tabs floating in a long empty box —
   shrink-wrap it back. */
.modal [data-corp-tabs] {
  align-self: flex-start;
  max-width: 100%;
  margin-bottom: 2px;
  flex-wrap: wrap;
}
.modal [data-corp-tabs] .settings-tab { cursor: pointer; white-space: nowrap; }

/* Regenerate button, tucked into the end of its input.
   The wrapper is what the button is positioned against — anchoring to
   the whole .fld would need a magic top offset that breaks the moment a
   label wraps to two lines.
   Sides are PHYSICAL, not logical: these inputs carry dir="ltr" (they
   hold credentials), so `padding-inline-end` on the input resolves to the
   right while `inset-inline-end` on the button resolves against the RTL
   page and lands on the left — the button then sits on top of the text. */
.gen-wrap { position: relative; display: block; }
.gen-wrap .gen-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border: 0; border-radius: 7px;
  background: none; color: var(--color-stone);
  cursor: pointer;
  transition: background 120ms, color 120ms;
}
.gen-wrap .gen-btn:hover { background: var(--color-app-hover); color: var(--color-primary); }
.gen-wrap .gen-btn i { width: 15px; height: 15px; }
/* Default (LTR page): button at the right of the field. */
.gen-wrap .gen-btn { right: 6px; }
.gen-wrap input { padding-right: 42px; }
/* RTL page: the far end of the field is the left, so both move together. */
[dir="rtl"] .gen-wrap .gen-btn { right: auto; left: 6px; }
[dir="rtl"] .gen-wrap input { padding-right: 12px; padding-left: 42px; }

.corp-new { margin-top: 16px; border-top: 1px dashed var(--color-app-border); padding-top: 12px; }
.corp-new > summary { cursor: pointer; user-select: none; color: var(--color-primary); }
.corp-new > summary::marker { color: var(--color-stone); }
[data-corp-list] { overflow-x: auto; }
[data-corp-list] .dt { margin: 0; }
[data-corp-list] .dt td { vertical-align: middle; }
/* Keep the three row actions on one line: wrapping them made the row
   twice as tall, and letting them overflow hid the destructive one. */
[data-corp-list] .actions-row { flex-wrap: nowrap; white-space: nowrap; }

/* =========================================================
   Corporate-guide generation overlay
   =========================================================
   Shown while the manager's integration .md is being generated, then
   held open with the download link. Blocking on purpose: the file is
   the whole point of the action, so it must not be missed. */
.guide-overlay {
  position: fixed; inset: 0;
  background: rgba(15, 15, 15, 0.55);
  display: flex; align-items: center; justify-content: center;
  z-index: 10001;
  opacity: 0;
  animation: mc-fade-in 0.2s ease-out forwards;
}
.guide-overlay[hidden] { display: none; }
.guide-card {
  background: var(--color-app-surface, #fff);
  color: var(--color-ink);
  border-radius: 14px;
  padding: 32px 34px;
  width: min(420px, calc(100vw - 32px));
  text-align: center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28);
}
.guide-card .guide-spin { display: flex; justify-content: center; margin-bottom: 16px; color: var(--color-primary); }
.guide-card .guide-spin[hidden] { display: none; }
.guide-card .guide-spin .spinner { width: 34px; height: 34px; border-width: 3px; }
.guide-card .guide-spin .checkmark { width: 34px; height: 34px; color: var(--color-success, #16A34A); }
.guide-card .guide-spin .xmark     { width: 34px; height: 34px; color: var(--color-error, #DC2626); }
.guide-card .guide-title { margin: 0 0 6px; font-weight: 600; font-size: 15px; }
.guide-card .guide-sub   { margin: 0; }
/* Indeterminate sweep — the API gives no progress, so don't fake a
   percentage; show that work is happening and nothing more. */
.guide-bar {
  margin-top: 18px; height: 3px; border-radius: 999px;
  background: var(--color-app-border); overflow: hidden;
}
.guide-bar > span {
  display: block; height: 100%; width: 40%;
  background: var(--color-primary); border-radius: 999px;
  animation: mc-guide-sweep 1.1s ease-in-out infinite;
}
@keyframes mc-guide-sweep {
  0%   { transform: translateX(-110%); }
  100% { transform: translateX(260%); }
}
[dir="rtl"] .guide-bar > span { animation-name: mc-guide-sweep-rtl; }
@keyframes mc-guide-sweep-rtl {
  0%   { transform: translateX(110%); }
  100% { transform: translateX(-260%); }
}
.guide-overlay.is-settled .guide-bar { display: none; }
.guide-actions { display: flex; gap: 8px; justify-content: center; margin-top: 20px; }
.guide-actions[hidden] { display: none; }

/* One-time password readout */
.otp-box {
  background: var(--color-primary-soft);
  border: 1px solid rgba(13, 148, 136, 0.25);
  border-radius: 10px;
  padding: 14px 16px;
}
.otp-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-primary-deep);
  margin-bottom: 10px;
}
.otp-display { display: flex; align-items: center; gap: 8px; }
.otp-value {
  flex: 1;
  font-family: var(--font-mono);
  font-size: 16px; font-weight: 600;
  color: var(--color-ink);
  background: var(--color-app-panel);
  padding: 9px 12px;
  border-radius: 6px;
  border: 1px solid var(--color-app-border);
  user-select: all;
  word-break: break-all;
  letter-spacing: 0.5px;
  min-width: 0;
}
.otp-copy-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px;
  flex-shrink: 0;
  background: var(--color-primary);
  color: #fff;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: background 150ms ease-out, transform 100ms ease-out;
}
.otp-copy-btn:hover  { background: var(--color-primary-pressed); }
.otp-copy-btn:active { transform: scale(0.94); }
.otp-copy-btn.is-copied { background: var(--color-success); animation: mc-pop 280ms ease-out; }
.otp-copy-btn i, .otp-copy-btn svg { width: 18px; height: 18px; }
@keyframes mc-pop {
  0%   { transform: scale(0.92); }
  50%  { transform: scale(1.08); }
  100% { transform: scale(1); }
}
:root[data-theme="dark"] .otp-value { background: var(--color-app-bg); }

/* Body-scroll lock while a modal is open */
body.modal-open { overflow: hidden; }

@media (max-width: 640px) {
  .modal { padding: 12px; align-items: flex-end; }
  .modal-panel { max-width: 100%; border-radius: 12px 12px 0 0; }
  .grid-form-2, .grid-form-3 { grid-template-columns: 1fr; }
}

/* =========================================================
   Form fields
   ========================================================= */
.fld { display: flex; flex-direction: column; gap: 6px; }
.fld label { font-size: 13px; font-weight: 500; color: var(--color-charcoal); }
.fld .hint  { font-size: 12px; color: var(--color-stone); }
.fld .error { font-size: 12px; color: var(--color-error); }

/* The live username verdict, under the field it is about. Sized and
   coloured like .hint / .error above rather than as a new kind of thing:
   it IS a hint, and the state is the only part that varies. */
.username-note { font-size: 12px; color: var(--color-stone); margin: 0; }
.username-note.is-checking { color: var(--color-stone); }
.username-note.is-free     { color: var(--color-success); }
.username-note.is-taken    { color: var(--color-error); }
.username-note.is-invalid  { color: var(--color-error); }
/* Free, but a cashier holds the same name — worth saying, not a refusal. */
.username-note.is-free[data-warn] { color: var(--color-warning); }
/* An action button standing in for an input (the Jawwal token refresh):
   the column's default stretch would blow it out to the full field width. */
.fld > .btn { align-self: flex-start; }
.fld input, .fld select, .fld textarea {
  font-family: var(--font-body);
  background: var(--color-app-panel);
  color: var(--color-ink);
  border: 1px solid var(--color-app-border);
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 14px;
  outline: none;
  transition: border-color 120ms, box-shadow 120ms;
  width: 100%;
}
.fld input:focus, .fld select:focus, .fld textarea:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-soft);
}
.fld input[readonly] {
  background: var(--color-app-bg);
  color: var(--color-slate);
  border-style: dashed;
  cursor: not-allowed;
}
.fld input[readonly]:focus {
  border-color: var(--color-app-border);
  box-shadow: none;
}
.fld label .fld-lock {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px;
  color: var(--color-stone);
  margin-inline-start: 6px;
  vertical-align: -2px;
}
.fld label .fld-lock i, .fld label .fld-lock svg { width: 12px; height: 12px; }

.search-box {
  display: flex; align-items: center; gap: 10px;
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 8px;
  padding: 0 12px;
  height: 38px;
  color: var(--color-stone);
  min-width: 280px;
  font-family: var(--font-body);
}
.search-box input {
  border: none; outline: none;
  flex: 1;
  background: transparent;
  color: var(--color-ink);
  font-family: var(--font-body);     /* Tajawal / Cairo — not the browser default */
  font-size: 14px;
  line-height: 1.4;
}
.search-box input::placeholder {
  font-family: var(--font-body);
  color: var(--color-stone);
  opacity: 1;
}

/* Pill-style select used in filter rows */
.select-pill {
  height: 38px;
  padding: 0 32px 0 12px;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--color-ink);
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 8px;
  cursor: pointer;
  outline: none;
  transition: border-color 120ms, box-shadow 120ms;
  appearance: none;
  -webkit-appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--color-slate) 50%),
    linear-gradient(135deg, var(--color-slate) 50%, transparent 50%);
  background-position:
    calc(100% - 16px) 16px,
    calc(100% - 11px) 16px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
[dir="rtl"] .select-pill {
  padding: 0 12px 0 32px;
  background-position: 16px 16px, 11px 16px;
}
.select-pill:hover  { border-color: var(--color-hairline-strong); }
.select-pill:focus  { border-color: var(--color-primary); box-shadow: 0 0 0 3px var(--color-primary-soft); }

/* =========================================================
   Page header
   ========================================================= */
.page-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; margin-bottom: 20px;
}
.page-header h1 { font-size: 24px; font-weight: 700; }
.filter-row  { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.actions-row { display: flex; gap: 8px; flex-wrap: wrap; }

/* =========================================================
   Flash / alerts
   ========================================================= */
.alert {
  padding: 12px 16px;
  border-radius: 8px;
  font-size: 14px;
  margin-bottom: 16px;
  border: 1px solid transparent;
  display: flex;
  align-items: center;
  gap: 10px;
}
.alert .alert-icon { width: 18px; height: 18px; flex-shrink: 0; }
.alert[hidden] { display: none; }
.alert-success { background: var(--color-status-active-bg);  color: var(--color-status-active-fg);  border-color: #BBF7D0; }
.alert-error   { background: var(--color-status-blocked-bg); color: var(--color-status-blocked-fg); border-color: #FECACA; }
.alert-warning { background: var(--color-status-pending-bg); color: var(--color-status-pending-fg); border-color: #FDE68A; }
.alert-info    { background: var(--color-status-published-bg); color: var(--color-status-published-fg); border-color: #BFDBFE; }

/* Floating toast stack — transient success/error feedback, fixed to the
   viewport so it's never tied to the page scroll. Drops in from the top
   inline-end corner (right in LTR, left in RTL). */
.toast-stack {
  position: fixed;
  top: 20px;
  inset-inline-end: 20px;
  display: flex; flex-direction: column; gap: 10px;
  z-index: 10000;
  pointer-events: none;
  max-width: calc(100vw - 40px);
}
.toast {
  pointer-events: auto;
  display: flex; align-items: center; gap: 10px;
  min-width: 280px; max-width: 420px;
  padding: 12px 14px;
  border-radius: 10px;
  font-size: 14px;
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  box-shadow: var(--shadow-2);
  animation: toast-in 220ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
.toast.is-leaving { animation: toast-out 200ms ease-in both; }
.toast-icon { width: 20px; height: 20px; flex-shrink: 0; }
.toast-msg  { flex: 1; line-height: 1.4; color: var(--color-charcoal); }
.toast-close {
  background: transparent; border: none; cursor: pointer;
  color: var(--color-stone); font-size: 20px; line-height: 1;
  padding: 2px 6px; border-radius: 6px;
  font-family: inherit;
}
.toast-close:hover { background: var(--color-app-hover); color: var(--color-ink); }
.toast-success { border-color: #BBF7D0; background: var(--color-status-active-bg);  color: var(--color-status-active-fg); }
.toast-success .toast-msg { color: var(--color-status-active-fg); }
.toast-error   { border-color: #FECACA; background: var(--color-status-blocked-bg); color: var(--color-status-blocked-fg); }
.toast-error   .toast-msg { color: var(--color-status-blocked-fg); }
.toast-warning { border-color: #FDE68A; background: var(--color-status-pending-bg); color: var(--color-status-pending-fg); }
.toast-warning .toast-msg { color: var(--color-status-pending-fg); }

@keyframes toast-in {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes toast-out {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(-8px); }
}

@media (max-width: 640px) {
  .toast-stack { top: 12px; inset-inline-end: 12px; inset-inline-start: 12px; }
  .toast { min-width: 0; max-width: 100%; }
}

/* =========================================================
   Session-expired overlay — shown when the admin's auth
   expiry deadline has elapsed; the JS auto-submits /logout
   right after this fades in.
   ========================================================= */
.session-expired-overlay {
  position: fixed; inset: 0;
  z-index: 20000;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: rgba(15, 15, 15, 0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  animation: session-overlay-in 280ms ease-out both;
}
.session-expired-overlay[hidden] { display: none; }
.session-expired-card {
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 16px;
  box-shadow: var(--shadow-3);
  padding: 28px 32px;
  max-width: 380px;
  width: 100%;
  text-align: center;
  animation: session-card-in 320ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
.session-expired-spinner {
  width: 44px; height: 44px;
  margin: 0 auto 16px;
  border-radius: 50%;
  border: 3px solid var(--color-app-border);
  border-top-color: var(--color-primary);
  animation: session-spin 700ms linear infinite;
}
.session-expired-title {
  font-family: var(--font-heading);
  font-size: 18px; font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 8px;
}
.session-expired-msg {
  font-size: 14px;
  color: var(--color-slate);
  line-height: 1.5;
  margin: 0;
}
@keyframes session-overlay-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes session-card-in {
  from { opacity: 0; transform: translateY(8px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0)   scale(1); }
}
@keyframes session-spin {
  to { transform: rotate(360deg); }
}

/* =========================================================
   Icon-prefixed inputs (login fields)
   ========================================================= */
.input-icon-wrap {
  position: relative;
  display: flex;
  align-items: center;
}
.input-icon-wrap .input-icon-lead {
  position: absolute;
  width: 18px; height: 18px;
  color: var(--color-stone);
  pointer-events: none;
  z-index: 1;
}
[dir="rtl"] .input-icon-wrap .input-icon-lead { right: 12px; }
[dir="ltr"] .input-icon-wrap .input-icon-lead { left:  12px; }

.input-icon-wrap .input-icon-trail {
  position: absolute;
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  background: transparent;
  border: none;
  color: var(--color-stone);
  cursor: pointer;
  border-radius: 6px;
  z-index: 1;
}
.input-icon-wrap .input-icon-trail:hover { color: var(--color-ink); background: var(--color-app-hover); }
.input-icon-wrap .input-icon-trail i { width: 18px; height: 18px; }
[dir="rtl"] .input-icon-wrap .input-icon-trail { left:  6px; }
[dir="ltr"] .input-icon-wrap .input-icon-trail { right: 6px; }

.input-with-icon {
  width: 100%;
  height: 44px;
  font-family: var(--font-body);
  background: var(--color-app-panel);
  color: var(--color-ink);
  border: 1px solid var(--color-app-border);
  border-radius: 8px;
  font-size: 14px;
  outline: none;
  transition: border-color 120ms, box-shadow 120ms;
}
[dir="rtl"] .input-with-icon { padding: 0 40px 0 14px; }
[dir="ltr"] .input-with-icon { padding: 0 14px 0 40px; }
.input-with-icon.has-trail[dir="rtl"],
[dir="rtl"] .input-with-icon.has-trail { padding-left: 44px; }
.input-with-icon.has-trail[dir="ltr"],
[dir="ltr"] .input-with-icon.has-trail { padding-right: 44px; }
.input-with-icon:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-soft);
}
.input-with-icon.is-invalid {
  border-color: var(--color-error);
  box-shadow: 0 0 0 3px rgba(212, 76, 71, 0.18);
}
.input-with-icon::placeholder { color: var(--color-stone); }

/* =========================================================
   Stateful button (loading / success / error)
   ========================================================= */
.btn-stateful {
  position: relative;
  overflow: hidden;
  transition: background 200ms ease-out, color 200ms ease-out;
}
.btn-stateful .btn-content,
.btn-stateful .btn-state {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  transition: opacity 180ms ease-out, transform 220ms ease-out;
}
.btn-stateful .btn-state {
  position: absolute; inset: 0;
  opacity: 0; transform: scale(0.85);
  pointer-events: none;
}
.btn-stateful[data-state="loading"] .btn-content { opacity: 0; transform: scale(0.95); }
.btn-stateful[data-state="loading"] .btn-state   { opacity: 1; transform: scale(1); }
.btn-stateful[data-state="success"] .btn-content { opacity: 0; }
.btn-stateful[data-state="success"] .btn-state   { opacity: 1; transform: scale(1); }
.btn-stateful[data-state="error"]   .btn-content { opacity: 0; }
.btn-stateful[data-state="error"]   .btn-state   { opacity: 1; transform: scale(1); }
.btn-stateful[data-state]:not([data-state=""]) { pointer-events: none; }
.btn-stateful.btn-primary[data-state="success"] { background: var(--color-success); }
.btn-stateful.btn-primary[data-state="error"]   { background: var(--color-error); }

.spinner {
  display: inline-block;
  width: 18px; height: 18px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: mc-spin 0.7s linear infinite;
}
@keyframes mc-spin { to { transform: rotate(360deg); } }

/* Animated checkmark drawn via stroke-dashoffset */
.checkmark {
  width: 22px; height: 22px;
  display: inline-block;
}
.checkmark svg { width: 100%; height: 100%; overflow: visible; }
.checkmark circle, .checkmark path {
  fill: none; stroke: currentColor; stroke-width: 2.5;
  stroke-linecap: round; stroke-linejoin: round;
}
.checkmark circle { stroke-dasharray: 76; stroke-dashoffset: 76; animation: mc-draw 0.35s ease-out forwards; }
.checkmark path   { stroke-dasharray: 28; stroke-dashoffset: 28; animation: mc-draw 0.3s 0.25s ease-out forwards; }
@keyframes mc-draw { to { stroke-dashoffset: 0; } }

/* Animated X */
.xmark {
  width: 22px; height: 22px;
  display: inline-block;
}
.xmark svg { width: 100%; height: 100%; overflow: visible; }
.xmark line, .xmark circle {
  fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round;
}
.xmark circle { stroke-dasharray: 76; stroke-dashoffset: 76; animation: mc-draw 0.3s ease-out forwards; }
.xmark line:nth-child(2) { stroke-dasharray: 18; stroke-dashoffset: 18; animation: mc-draw 0.22s 0.22s ease-out forwards; }
.xmark line:nth-child(3) { stroke-dasharray: 18; stroke-dashoffset: 18; animation: mc-draw 0.22s 0.34s ease-out forwards; }

/* Shake on error (applied to the whole login card) */
@keyframes mc-shake {
  0%, 100% { transform: translateX(0); }
  15%, 55% { transform: translateX(-6px); }
  30%, 70% { transform: translateX(6px); }
  85%      { transform: translateX(-3px); }
}
.shake { animation: mc-shake 0.45s ease-in-out; }

/* Fields locked during submit */
.is-locked input, .is-locked button:not(.btn-stateful), .is-locked select { opacity: 0.6; cursor: not-allowed; }

/* =========================================================
   Redirect overlay (full-screen, branded)
   ========================================================= */
.redirect-overlay {
  position: fixed; inset: 0;
  background: linear-gradient(160deg, var(--color-primary-deep) 0%, var(--color-primary) 100%);
  color: #fff;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 18px;
  z-index: 10000;
  opacity: 0;
  animation: mc-fade-in 0.25s ease-out forwards;
}
@keyframes mc-fade-in { to { opacity: 1; } }
.redirect-overlay .ro-logo {
  width: 76px; height: 76px;
  background: rgba(255,255,255,0.16);
  border-radius: 18px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-heading); font-weight: 700;
  font-size: 36px; color: #fff;
  animation: mc-pulse 1.4s ease-in-out infinite;
}
@keyframes mc-pulse {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(255,255,255,0.4); }
  50%      { transform: scale(1.06); box-shadow: 0 0 0 18px rgba(255,255,255,0); }
}
.redirect-overlay .ro-title {
  font-family: var(--font-heading); font-weight: 700; font-size: 22px;
  letter-spacing: -0.3px;
}
.redirect-overlay .ro-sub {
  display: flex; align-items: center; gap: 10px;
  font-size: 14px; opacity: 0.85;
}
.redirect-overlay .ro-sub .spinner {
  width: 14px; height: 14px; border-width: 2px;
}
.redirect-overlay .ro-progress {
  width: 220px; height: 3px; border-radius: 999px;
  background: rgba(255,255,255,0.2);
  overflow: hidden;
  margin-top: 6px;
}
.redirect-overlay .ro-progress::before {
  content: ""; display: block; height: 100%;
  background: #fff;
  width: 30%;
  border-radius: 999px;
  animation: mc-slide 1.2s ease-in-out infinite;
}
@keyframes mc-slide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(380%); }
}

/* =========================================================
   Login layout
   ========================================================= */
.login-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  min-height: 100vh;
  background: var(--color-app-bg);
}
.login-side {
  background: linear-gradient(160deg, var(--color-primary-deep) 0%, var(--color-primary) 100%);
  color: #fff;
  padding: 56px;
  display: flex; flex-direction: column; justify-content: space-between;
}
.login-side .brand-mark { display: flex; align-items: center; gap: 12px; font-family: var(--font-heading); font-weight: 700; font-size: 20px; }
.login-side .brand-mark .dot { width: 32px; height: 32px; border-radius: 8px; background: rgba(255,255,255,0.18); display: inline-flex; align-items: center; justify-content: center; }
.login-hero-block { max-width: 100%; }
.login-hero {
  font-family: var(--font-heading);
  font-size: 56px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -1px;
  margin: 0;
  color: #fff;
  white-space: nowrap;
  background: linear-gradient(135deg, #ffffff 0%, rgba(255, 255, 255, 0.82) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  text-shadow: 0 4px 24px rgba(0, 0, 0, 0.12);
}
.login-hero-accent {
  width: 60px;
  height: 4px;
  border-radius: 999px;
  background: #fff;
  margin-top: 20px;
  opacity: 0.95;
}
.login-side .login-foot { font-size: 13px; opacity: 0.75; }

.login-pane {
  background: var(--color-app-panel);
  padding: 64px;
  display: flex; align-items: center; justify-content: center;
}
.login-card { width: 100%; max-width: 380px; }
.login-card h1 { font-size: 28px; font-weight: 700; margin-bottom: 6px; }
.login-card .lede { color: var(--color-slate); font-size: 14px; margin-bottom: 28px; }
.login-row { display: flex; flex-direction: column; gap: 16px; }
.login-options { display: flex; align-items: center; justify-content: space-between; font-size: 13px; color: var(--color-slate); }
.login-options label { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }

/* =========================================================
   Empty state
   ========================================================= */
.empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 48px 24px;
  color: var(--color-stone);
  text-align: center;
  gap: 6px;
}
.empty .title { font-family: var(--font-heading); font-weight: 700; font-size: 16px; color: var(--color-charcoal); }

/* =========================================================
   Utilities
   ========================================================= */
.flex          { display: flex; }
.flex-col      { display: flex; flex-direction: column; }
.items-center  { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-2 { gap: 8px; }  .gap-3 { gap: 12px; } .gap-4 { gap: 16px; }
.flex-1 { flex: 1; }
.mt-2 { margin-top: 8px; }  .mt-4 { margin-top: 16px; } .mt-6 { margin-top: 24px; }
.mb-2 { margin-bottom: 8px; } .mb-4 { margin-bottom: 16px; } .mb-6 { margin-bottom: 24px; }
.text-slate { color: var(--color-slate); }
.text-stone { color: var(--color-stone); }
.text-ink   { color: var(--color-ink); }
.text-sm    { font-size: 13px; }
.text-xs    { font-size: 12px; }
.fw-500 { font-weight: 500; } .fw-600 { font-weight: 600; } .fw-700 { font-weight: 700; }

input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--color-primary); cursor: pointer; }

/* =========================================================
   Responsive
   ========================================================= */
/* =========================================================
   Off-canvas sidebar (mobile drawer)
   ========================================================= */
.menu-btn { display: none; }

.side-backdrop {
  position: fixed; inset: 0;
  background: rgba(15, 15, 15, 0.4);
  z-index: 101;
  opacity: 0; pointer-events: none;
  transition: opacity 180ms ease-out;
}
.side-backdrop.is-active { opacity: 1; pointer-events: auto; }

@media (max-width: 1024px) {
  .grid-kpi   { grid-template-columns: repeat(2, 1fr); }
  .kpi-row    { grid-template-columns: repeat(2, 1fr); gap: 12px; }
  .grid-2-1   { grid-template-columns: 1fr; }
  .stat-grid  { grid-template-columns: 1fr 1fr; gap: 16px; }
  .stat-card  { padding: 18px; min-height: 200px; }
  .stat-value { font-size: 30px; }
  .chart-panel { padding: 18px; }
  .chart-canvas-tall { height: 300px; }
  .login-grid { grid-template-columns: 1fr; }
  .login-side { display: none; }
  .app-content { padding: 20px 18px; }
  .welcome-title { font-size: 22px; }

  /* Sidebar becomes an off-canvas drawer */
  .menu-btn { display: inline-flex; }
  .side {
    position: fixed; top: 0; bottom: 0;
    z-index: 102;
    width: 280px;
    box-shadow: 0 16px 48px -8px rgba(15, 15, 15, 0.16);
    transition: transform 220ms ease-out;
  }
  [dir="rtl"] .side { right: 0; left: auto; transform: translateX(100%); }
  [dir="ltr"] .side { left:  0; right: auto; transform: translateX(-100%); }
  .side.is-open { transform: translateX(0) !important; }
  .app-main { width: 100%; }
}
@media (max-width: 640px) {
  .grid-kpi   { grid-template-columns: 1fr; gap: 12px; }
  .kpi-row    { grid-template-columns: 1fr; gap: 12px; }
  .grid-1-1   { grid-template-columns: 1fr; gap: 12px; }
  .stat-grid  { grid-template-columns: 1fr; gap: 12px; }
  .kpi        { padding: 16px; }
  .kpi-value  { font-size: 24px; }
  .stat-card  { min-height: 180px; padding: 16px; }
  .stat-value { font-size: 26px; }
  .stat-chart { min-height: 70px; }
  .chart-panel { padding: 16px; }
  .chart-canvas-tall { height: 250px; }
  /* The four resolution buttons need the full width on a phone. */
  .chart-panel-head       { gap: 12px; }
  .chart-panel-intervals  { width: 100%; justify-content: space-between; }
  .chart-panel-intervals .window-toggle-btn { flex: 1; text-align: center; padding: 6px 8px; }
  .chart-svg  { height: 80px; }
  .donut      { width: 88px; height: 88px; }
  .app-content { padding: 16px 14px; }
  .topbar { height: 56px; padding: 0 12px; gap: 8px; }
  .topbar .search-box { display: none; }
  .topbar .topbar-user-text { display: none; }
  .topbar h1 { font-size: 15px; }
  .login-pane { padding: 24px; }
  .login-hero { font-size: 36px; line-height: 1.15; letter-spacing: -0.5px; }
  .login-hero-accent { margin-top: 14px; width: 48px; }
  .welcome { gap: 8px; }
  .welcome-title { font-size: 20px; }
  .btn-export { width: 100%; justify-content: center; }
}

/* =========================================================
   Deploy storefront modal (confirm → progress → result)
   ========================================================= */
.deploy-modal [data-deploy-phase][hidden],
.deploy-modal [data-deploy-title][hidden],
.deploy-modal [data-deploy-footer][hidden] { display: none; }

/* Push the "Download .env" button to the leading edge of the footer
   so it sits apart from the active Retry / Override DNS group. */
.deploy-modal [data-deploy-action="download-env"]:not([hidden]) {
  margin-inline-end: auto;
}

.deploy-progress { display: flex; flex-direction: column; gap: 10px; }

.deploy-progress-meter {
  position: relative;
  height: 8px;
  background: var(--color-app-border);
  border-radius: 999px;
  overflow: hidden;
}
.deploy-progress-fill {
  position: absolute; inset-block: 0; inset-inline-start: 0;
  width: 0%;
  background: linear-gradient(90deg,
    var(--color-primary) 0%,
    var(--color-primary-pressed) 50%,
    var(--color-primary) 100%);
  background-size: 200% 100%;
  border-radius: inherit;
  transition: width 600ms cubic-bezier(0.22, 0.61, 0.36, 1);
  animation: mc-deploy-shimmer 1.6s linear infinite;
}
@keyframes mc-deploy-shimmer {
  from { background-position:  0% 0; }
  to   { background-position: 200% 0; }
}

.deploy-progress-row {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13px;
}
.deploy-progress-label { color: var(--color-ink); font-weight: 600; }
.deploy-progress-timer {
  font-family: var(--font-mono);
  color: var(--color-primary-deep);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.5px;
}

/* Result panel — shared layout, icon swaps via data-state */
.deploy-result {
  display: flex; flex-direction: column; align-items: center;
  text-align: center; gap: 12px;
}
.deploy-result-icon {
  width: 56px; height: 56px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.deploy-result-icon svg { width: 28px; height: 28px; stroke-width: 2.5; }
.deploy-modal[data-state="success"] .deploy-result-icon {
  background: rgba(16, 185, 129, 0.12);
  color: var(--color-success);
  animation: mc-pop 320ms ease-out;
}
.deploy-modal[data-state="error"] .deploy-result-icon {
  background: rgba(239, 68, 68, 0.12);
  color: var(--color-error);
  animation: mc-pop 320ms ease-out;
}
.deploy-result-message {
  font-size: 14px; color: var(--color-ink);
  margin: 0;
}
.deploy-result-log {
  width: 100%;
  max-height: 180px;
  overflow: auto;
  background: var(--color-app-bg);
  border: 1px solid var(--color-app-border);
  border-radius: 8px;
  padding: 10px 12px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--color-stone);
  text-align: start;
  white-space: pre-wrap;
  direction: ltr;
}

/* Domain ↔ deploy_host DNS mismatch panel */
.deploy-mismatch {
  width: 100%;
  background: var(--color-app-bg);
  border: 1px solid var(--color-app-border);
  border-radius: 8px;
  padding: 12px;
}
.deploy-mismatch-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  text-align: start;
}
.deploy-mismatch-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-stone);
  margin-bottom: 4px;
}
.deploy-mismatch-name {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--color-ink);
  margin-bottom: 4px;
  word-break: break-all;
}
.deploy-mismatch-ips {
  list-style: none;
  padding: 0;
  margin: 0;
}
.deploy-mismatch-ips li {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--color-primary-deep);
  padding: 2px 0;
}
.deploy-mismatch-ips li.is-empty {
  color: var(--color-stone);
  font-style: italic;
}
@media (max-width: 480px) {
  .deploy-mismatch-grid { grid-template-columns: 1fr; }
}

/* cPanel auto-deploy disclosure on the "Add store" form */
.deploy-disclosure {
  border: 1px solid var(--color-app-border);
  border-radius: 10px;
  background: var(--color-app-bg);
}
.deploy-disclosure > summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 14px;
  cursor: pointer;
  list-style: none;
  font-weight: 600;
  font-size: 14px;
  color: var(--color-ink);
  user-select: none;
}
.deploy-disclosure > summary::-webkit-details-marker { display: none; }
.deploy-disclosure > summary::after {
  content: "›";
  margin-inline-start: auto;
  font-size: 18px;
  color: var(--color-stone);
  transition: transform 150ms ease-out;
}
.deploy-disclosure[open] > summary::after { transform: rotate(90deg); }
.deploy-disclosure > summary i { width: 16px; height: 16px; color: var(--color-primary); }
.deploy-disclosure-hint { font-weight: 400; }
.deploy-disclosure-body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 14px;
  border-top: 1px solid var(--color-app-border);
}
.deploy-overrides > summary {
  cursor: pointer;
  padding: 6px 0;
  list-style: none;
}
.deploy-overrides > summary::-webkit-details-marker { display: none; }
.deploy-overrides > summary::before {
  content: "▸";
  display: inline-block;
  margin-inline-end: 6px;
  transition: transform 150ms ease-out;
}
.deploy-overrides[open] > summary::before { transform: rotate(90deg); }

.deploy-disclosure-body input.is-invalid,
.deploy-disclosure-body select.is-invalid {
  border-color: var(--color-error);
  box-shadow: 0 0 0 3px rgba(212, 76, 71, 0.18);
}

/* ── Copyable command blocks (أوامر مايكروتيك) ────────────────────────
   A router command is copied, not read for pleasure: the block leads
   with what it does and why, and puts the copy button where the eye
   lands before the code. Monospace, LTR and selectable — the commands
   are Latin even on an Arabic page. */
.codebox {
  border: 1px solid var(--color-app-border);
  border-radius: 12px;
  overflow: hidden;
  margin-bottom: 14px;
  background: var(--color-app-panel);
}
.codebox-primary { border-color: var(--color-primary); }
.codebox-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  padding: 13px 16px;
  background: var(--color-app-bg);
  border-bottom: 1px solid var(--color-app-border);
}
.codebox-head h3 {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  color: var(--color-ink);
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.codebox-head p {
  margin: 5px 0 0;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--color-slate);
  max-width: 68ch;
}
.codebox-head .btn { flex: none; }
/* The copied state lives on the button rather than a toast: the pointer
   is already there, and a toast in the corner is a second place to look. */
.codebox-head .btn.is-copied {
  background: var(--color-success);
  border-color: var(--color-success);
  color: #FFFFFF;
}
.codebox-body {
  margin: 0;
  padding: 14px 16px;
  font: 12.5px/1.85 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--color-charcoal);
  background: var(--color-app-panel);
  white-space: pre;
  overflow-x: auto;
  tab-size: 2;
}
:root[data-theme="dark"] .codebox-body { color: #D6E2DC; }

.mt-hosts {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 18px;
}
.mt-host {
  font: 12px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  padding: 5px 9px;
  border-radius: 999px;
  background: var(--color-primary-soft);
  color: var(--color-primary-deep);
}
:root[data-theme="dark"] .mt-host { color: var(--color-ink); }
.mt-section-title {
  margin: 22px 0 12px;
  font-size: 15px;
  font-weight: 700;
  color: var(--color-ink);
}

/* The editor's fields sit where the read-only text sat, so the page
   reads the same whether it is being written or looked at. */
.mt-title, .mt-note {
  width: 100%;
  border: 1px solid transparent;
  background: transparent;
  border-radius: 6px;
  padding: 4px 8px;
  font: inherit;
  color: var(--color-ink);
}
.mt-title { font-size: 14px; font-weight: 700; }
.mt-note  { font-size: 12.5px; color: var(--color-slate); margin-top: 2px; }
.mt-title:hover, .mt-note:hover { border-color: var(--color-app-border); }
.mt-title:focus, .mt-note:focus {
  outline: 0;
  border-color: var(--color-primary);
  background: var(--color-app-panel);
}
.mt-row-actions { display: flex; align-items: center; gap: 8px; flex: none; }
.mt-req {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--color-slate); cursor: pointer; user-select: none;
}
.mt-req input { accent-color: var(--color-primary); }
.mt-del { color: var(--color-error); background: transparent; border: 1px solid transparent; }
.mt-del:hover { background: var(--color-status-blocked-bg); border-color: #FECACA; }
/* A textarea that looks like the block it replaces: same face, same
   padding, no browser chrome that would make it read as a form field. */
textarea.mt-body {
  width: 100%;
  border: 0;
  resize: vertical;
  min-height: 92px;
  white-space: pre;
  overflow-wrap: normal;
}
textarea.mt-body:focus { outline: 2px solid var(--color-primary); outline-offset: -2px; }
.mt-actions {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 16px;
}


/* =========================================================
   احصائيات مرئية — small-multiples income cards.
   ========================================================= */
/* auto-fill, not auto-fit: a single subscriber should occupy one card's
   width, not stretch to the full row. */
.spark-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px;
}
.spark-grid.is-busy { opacity: 0.5; pointer-events: none; transition: opacity 120ms; }
.spark-grid-sm { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; }

.spark-card {
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 12px;
  padding: 12px 14px 10px;
  display: flex; flex-direction: column; gap: 8px;
  min-width: 0;                     /* let long names ellipsis, not stretch the grid */
  transition: border-color 120ms, box-shadow 120ms;
}
.spark-card {
  /* The whole card opens the full-scale view, so it has to look like it
     does something. */
  cursor: pointer;
}
.spark-card:hover {
  border-color: var(--color-primary);
  box-shadow: 0 4px 14px -6px rgba(15, 15, 15, 0.12);
}
.spark-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 8px; min-width: 0;
}
.spark-titles { min-width: 0; }
.spark-title {
  margin: 0;
  font-family: var(--font-body);
  font-size: 13px; font-weight: 600;
  color: var(--color-ink);
  /* Subscriber names run long and a card is narrow; one line, clipped,
     with the full name on hover. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.spark-sub { font-size: 11px; color: var(--color-stone); }
.spark-value {
  font-family: var(--font-heading);
  font-size: 15px; font-weight: 700;
  color: var(--color-ink);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* Short enough that a grid of them fits on one screen, tall enough that
   a trend is still a shape and not a flat smear. */
.spark-canvas-wrap { position: relative; width: 100%; height: 74px; }
.spark-canvas-wrap canvas { width: 100% !important; height: 100% !important; }

.spark-drill {
  appearance: none;
  background: none; border: 0;
  padding: 4px 0 0;
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-body);
  font-size: 11.5px; font-weight: 500;
  color: var(--color-slate);
  cursor: pointer;
  align-self: flex-start;
  transition: color 120ms;
}
.spark-drill:hover { color: var(--color-primary); }
.spark-drill i, .spark-drill svg { width: 13px; height: 13px; }

@media (max-width: 640px) {
  .spark-grid, .spark-grid-sm { grid-template-columns: 1fr; }
}


/* Date-range picker on the visual-statistics header. */
.visual-controls {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  justify-content: flex-end;
}
.date-range {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 8px;
  background: var(--color-app-panel);
  border: 1px solid var(--color-app-border);
  border-radius: 10px;
}
.date-range-label { font-size: 12px; color: var(--color-slate); }
.date-input {
  font-family: var(--font-body);
  font-size: 12.5px;
  color: var(--color-ink);
  background: transparent;
  border: 1px solid var(--color-app-border);
  border-radius: 7px;
  padding: 4px 8px;
  outline: none;
}
.date-input:focus { border-color: var(--color-primary); }
.btn-sm { padding: 5px 12px; font-size: 12.5px; }

@media (max-width: 900px) {
  .visual-controls { width: 100%; justify-content: flex-start; }
  .date-range { flex-wrap: wrap; }
}
