/* ============================================================
   MsgLens design tokens — shared with the UIS design system
   (UIS.Web/src/src/styles/{tokens,theme,base}.css).

   Layer 1: UIS palette primitives, ported verbatim.
   Layer 2: UIS semantic tokens, redefined per [data-theme], followed by a
            bridge that maps MsgLens' original alias names onto them so the
            component rules below stay untouched.
   Theme is switched by data-theme on <html>; only layer 2 changes.
   ============================================================ */

@font-face {
  font-family: 'Thmanyah Sans';
  src: url("vendor/fonts/thmanyah-sans-regular.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans Arabic";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("vendor/fonts/ibm-plex-sans-arabic-arabic-400-normal.woff2") format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+FB50-FDFF, U+FE70-FEFF;
}
@font-face {
  font-family: "IBM Plex Sans Arabic";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("vendor/fonts/ibm-plex-sans-arabic-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans Arabic";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("vendor/fonts/ibm-plex-sans-arabic-arabic-500-normal.woff2") format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+FB50-FDFF, U+FE70-FEFF;
}
@font-face {
  font-family: "IBM Plex Sans Arabic";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("vendor/fonts/ibm-plex-sans-arabic-latin-500-normal.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans Arabic";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("vendor/fonts/ibm-plex-sans-arabic-arabic-600-normal.woff2") format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+FB50-FDFF, U+FE70-FEFF;
}
@font-face {
  font-family: "IBM Plex Sans Arabic";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("vendor/fonts/ibm-plex-sans-arabic-latin-600-normal.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans Arabic";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("vendor/fonts/ibm-plex-sans-arabic-arabic-700-normal.woff2") format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+FB50-FDFF, U+FE70-FEFF;
}
@font-face {
  font-family: "IBM Plex Sans Arabic";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("vendor/fonts/ibm-plex-sans-arabic-latin-700-normal.woff2") format("woff2");
}

:root {
  /* ---------- Layer 1 — UIS palette primitives ---------- */

  /* Color — primary (Saudi flag green scale) */
  --color-primary-50: #e6f2ec;
  --color-primary-100: #c3e0d2;
  --color-primary-200: #9ccdb5;
  --color-primary-300: #5fa985;
  --color-primary-400: #2f8a63;
  --color-primary-500: #0b6b3a;
  --color-primary-600: #006c35;
  --color-primary-700: #054a27;
  --color-primary-800: #073a20;
  --color-primary-900: #03301a;

  /* Color — neutral (gray scale) */
  --color-neutral-0: #ffffff;
  --color-neutral-50: #f7f8f7;
  --color-neutral-100: #eef0ef;
  --color-neutral-200: #dde1df;
  --color-neutral-300: #c2c8c5;
  --color-neutral-400: #9aa29e;
  --color-neutral-500: #78807c;
  --color-neutral-600: #5c645f;
  --color-neutral-700: #454b47;
  --color-neutral-800: #2b302d;
  --color-neutral-900: #12181a;

  /* Color — accent (gold / sand) */
  --color-accent-100: #f5edd8;
  --color-accent-200: #ecdcb0;
  --color-accent-300: #ddc27f;
  --color-accent-400: #d4b45a;
  --color-accent-500: #b08d2b;
  --color-accent-600: #8f7222;
  --color-accent-700: #7a5f1b;

  /* Color — semantic base hues */
  --color-success-500: #1e8e5a;
  --color-warning-500: #b7791f;
  --color-error-500: #c0392b;
  --color-info-500: #2563eb;

  /* Color — corporate blue scale (non-individual modes) */
  --color-corporate-50: #e8f3fb;
  --color-corporate-100: #c5e0f4;
  --color-corporate-200: #9ecbeb;
  --color-corporate-300: #6bafd9;
  --color-corporate-400: #3088c8;
  --color-corporate-500: #2570a8;
  --color-corporate-600: #1c5a88;
  --color-corporate-700: #154568;
  --color-corporate-800: #0f3350;
  --color-corporate-900: #0a2238;

  /* Typography */
  --font-family-ar: 'Thmanyah Sans', "IBM Plex Sans Arabic", 'Segoe UI', system-ui, sans-serif;
  --font-family-en: 'Inter', 'Thmanyah Sans', "IBM Plex Sans Arabic", 'Segoe UI', system-ui, sans-serif;

  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.25rem;
  --font-size-2xl: 1.5rem;
  --font-size-3xl: 1.875rem;
  --font-size-4xl: 2.25rem;

  --font-weight-regular: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;

  --line-height-tight: 1.25;
  --line-height-normal: 1.5;
  --line-height-relaxed: 1.75;

  /* Spacing (4px base) */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;

  /* Radii */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 24px;
  --radius-full: 9999px;

  /* Motion */
  --backdrop-blur-base: blur(16px);
  --duration-fast: 150ms;
  --duration-base: 250ms;
  --duration-slow: 400ms;
  --duration-slower: 600ms;
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-decelerate: cubic-bezier(0, 0, 0.2, 1);
  --ease-accelerate: cubic-bezier(0.4, 0, 1, 1);

  /* Z-index */
  --z-header: 100;
  --z-dropdown: 500;
  --z-modal: 1000;
  --z-toast: 1100;

  /* ---------- MsgLens alias tokens ----------
     The original MsgLens names, re-pointed at the UIS scale so the component
     rules below need no rewrite. */

  --radius: var(--radius-md);
  --radius-pill: var(--radius-full);

  --font: var(--font-family-ar);
  --mono: "IBM Plex Mono", "Cascadia Code", Consolas, monospace;

  --text-2xs: var(--font-size-xs);
  --text-xs: var(--font-size-xs);
  --text-sm: var(--font-size-sm);
  --text-base: var(--font-size-sm);
  --text-md: var(--font-size-base);
  --text-lg: var(--font-size-lg);
  --text-xl: var(--font-size-xl);
  --text-2xl: var(--font-size-2xl);
  --text-3xl: var(--font-size-3xl);

  --weight-normal: var(--font-weight-regular);
  --weight-medium: var(--font-weight-medium);
  --weight-semibold: var(--font-weight-semibold);
  --weight-bold: var(--font-weight-bold);

  --leading-tight: var(--line-height-tight);
  --leading-normal: var(--line-height-normal);
  --leading-loose: 1.6;

  --track-tight: -.01em;
  --track-wide: .05em;
  --track-wider: .1em;

  --control-h: 40px;
  --avatar: 44px;
  --dot: 7px;
  --ring: 3px;

  /* Layering: base sits above scroll content, sticky above that, header above
     all. --z-header upward comes from the UIS z-scale. */
  --z-base: 1;
  --z-sticky: 50;

  --transition: var(--duration-fast) var(--ease-standard);
}

/* ============================================================
   Layer 2 — UIS semantic tokens, plus the MsgLens alias bridge
   ============================================================ */

:root,
[data-theme="light"] {
  color-scheme: light;
  --color-brand: var(--color-primary-600);
  --color-brand-strong: var(--color-primary-700);
  --color-brand-soft: var(--color-primary-50);
  --color-accent-brand: var(--color-accent-500);

  --color-surface: var(--color-neutral-0);
  --color-surface-alt: var(--color-neutral-50);
  --color-surface-raised: var(--color-neutral-0);
  --color-border: var(--color-neutral-200);
  --color-border-strong: var(--color-neutral-300);

  --color-text-primary: var(--color-neutral-900);
  --color-text-secondary: var(--color-neutral-600);
  --color-text-muted: var(--color-neutral-500);
  --color-text-inverse: var(--color-neutral-0);
  --color-text-on-brand: var(--color-neutral-0);

  --color-success: var(--color-success-500);
  --color-success-bg: #e7f5ee;
  --color-warning: var(--color-warning-500);
  --color-warning-bg: #fbf1e2;
  --color-error: var(--color-error-500);
  --color-error-bg: #fbeae8;
  --color-info: var(--color-info-500);
  --color-info-bg: #e8f0fe;

  --shadow-1: 0 1px 2px rgba(18, 24, 26, 0.06), 0 1px 1px rgba(18, 24, 26, 0.04);
  --shadow-2: 0 4px 12px rgba(18, 24, 26, 0.08);
  --shadow-3: 0 12px 32px rgba(18, 24, 26, 0.14);

  --overlay-scrim: rgba(18, 24, 26, 0.5);

  --color-footer-text: var(--color-primary-600);
  --color-icon-chip: var(--color-brand);
  --color-header-brand: #0b4d33;

  /* On-brand (elements placed over the brand-coloured header) */
  --color-brand-highlight: #38d69e;
  --color-on-brand-muted: rgba(255, 255, 255, 0.6);
  --color-on-brand-subtle: rgba(255, 255, 255, 0.75);
  --glass-bg: rgba(255, 255, 255, 0.08);
  --glass-border: rgba(255, 255, 255, 0.16);

  --color-scrollbar-track: transparent;
  --color-scrollbar-thumb: var(--color-primary-200);
  --color-scrollbar-thumb-hover: var(--color-primary-300);

  /* Bridge to the MsgLens alias names used by the component rules below. */
  --bg: var(--color-surface-alt);
  --surface: var(--color-surface-raised);
  --surface-2: var(--color-neutral-50);
  --surface-3: var(--color-neutral-100);
  --border: var(--color-border);
  --border-strong: var(--color-border-strong);
  --text: var(--color-text-primary);
  --muted: var(--color-text-secondary);
  --faint: var(--color-text-muted);

  --accent: var(--color-brand);
  --accent-hover: var(--color-brand-strong);
  --accent-soft: var(--color-brand-soft);
  --on-accent: var(--color-text-on-brand);

  --warn: var(--color-warning);
  --danger: var(--color-error);
  --star: var(--color-accent-brand);

  --bubble-out: var(--color-brand-soft);
  --mark-bg: var(--color-accent-200);
  --mark-text: var(--color-accent-700);

  --shadow-sm: var(--shadow-1);
  --shadow: var(--shadow-2);
  --shadow-lg: var(--shadow-3);
  --overlay: rgba(18, 24, 26, 0.04);
  --on-accent-overlay: rgba(255, 255, 255, 0.22);
  --scrim: var(--overlay-scrim);

  /* A data URI cannot read a custom property, so the icon is itself a token. */
  --icon-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2378807c' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.6-3.6'/%3E%3C/svg%3E");
}

[data-theme="dark"] {
  color-scheme: dark;
  --color-brand: var(--color-primary-400);
  --color-brand-strong: var(--color-primary-300);
  --color-brand-soft: rgba(47, 138, 99, 0.16);
  --color-accent-brand: var(--color-accent-400);

  --color-surface: #0f1e18;
  --color-surface-alt: #15281f;
  --color-surface-raised: #1b2f26;
  --color-border: #28453a;
  --color-border-strong: #345a4b;

  --color-text-primary: #f2f4f3;
  --color-text-secondary: #aab2ae;
  --color-text-muted: #838c88;
  --color-text-inverse: var(--color-neutral-900);
  --color-text-on-brand: var(--color-neutral-0);

  --color-success: #3ba876;
  --color-success-bg: rgba(30, 142, 90, 0.16);
  --color-warning: #d69a44;
  --color-warning-bg: rgba(183, 121, 31, 0.18);
  --color-error: #e0685a;
  --color-error-bg: rgba(192, 57, 43, 0.18);
  --color-info: #5b8def;
  --color-info-bg: rgba(37, 99, 235, 0.18);

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 1px rgba(0, 0, 0, 0.2);
  --shadow-2: 0 4px 12px rgba(0, 0, 0, 0.4);
  --shadow-3: 0 12px 32px rgba(0, 0, 0, 0.5);

  --overlay-scrim: rgba(0, 0, 0, 0.65);

  --color-footer-text: var(--color-neutral-0);
  --color-icon-chip: var(--color-neutral-0);
  --color-header-brand: var(--color-surface);

  /* On-brand */
  --color-brand-highlight: #4de0a8;
  --color-on-brand-muted: rgba(255, 255, 255, 0.6);
  --color-on-brand-subtle: rgba(255, 255, 255, 0.75);
  --glass-bg: rgba(255, 255, 255, 0.08);
  --glass-border: rgba(255, 255, 255, 0.16);

  --color-scrollbar-track: transparent;
  --color-scrollbar-thumb: var(--color-primary-400);
  --color-scrollbar-thumb-hover: var(--color-primary-300);

  /* Bridge */
  --bg: var(--color-surface);
  --surface: var(--color-surface-alt);
  --surface-2: var(--color-surface-raised);
  --surface-3: #22392e;
  --border: var(--color-border);
  --border-strong: var(--color-border-strong);
  --text: var(--color-text-primary);
  --muted: var(--color-text-secondary);
  --faint: var(--color-text-muted);

  --accent: var(--color-brand);
  --accent-hover: var(--color-brand-strong);
  --accent-soft: var(--color-brand-soft);
  --on-accent: var(--color-text-on-brand);

  --warn: var(--color-warning);
  --danger: var(--color-error);
  --star: var(--color-accent-brand);

  --bubble-out: var(--color-brand-soft);
  --mark-bg: var(--color-accent-400);
  --mark-text: var(--color-neutral-900);

  --shadow-sm: var(--shadow-1);
  --shadow: var(--shadow-2);
  --shadow-lg: var(--shadow-3);
  --overlay: rgba(255, 255, 255, 0.05);
  --on-accent-overlay: rgba(0, 0, 0, 0.22);
  --scrim: var(--overlay-scrim);

  --icon-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23838c88' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.6-3.6'/%3E%3C/svg%3E");
}

/* ============================================================
   Layer 3 — palette overrides for non-individual modes.
   Applied via [data-palette='corporate'] on <html>; inert until then.
   ============================================================ */

[data-palette='corporate'][data-theme="light"] {
  --color-brand: var(--color-corporate-400);
  --color-brand-strong: var(--color-corporate-600);
  --color-brand-soft: var(--color-corporate-50);
  --color-accent-brand: var(--color-corporate-500);
  --color-footer-text: var(--color-corporate-500);
  --color-icon-chip: var(--color-corporate-400);
  --color-header-brand: var(--color-corporate-600);
  --color-brand-highlight: #5bb8f0;
  --color-on-brand-muted: rgba(255, 255, 255, 0.65);
  --color-on-brand-subtle: rgba(255, 255, 255, 0.8);
  --color-scrollbar-thumb: var(--color-corporate-200);
  --color-scrollbar-thumb-hover: var(--color-corporate-300);
}

[data-palette='corporate'][data-theme="dark"] {
  --color-brand: var(--color-corporate-300);
  --color-brand-strong: var(--color-corporate-200);
  --color-brand-soft: rgba(48, 136, 200, 0.16);
  --color-accent-brand: var(--color-corporate-300);
  --color-surface: #0f1a22;
  --color-surface-alt: #132230;
  --color-surface-raised: #182a3a;
  --color-border: #253d52;
  --color-border-strong: #345a78;
  --color-footer-text: var(--color-corporate-200);
  --color-icon-chip: var(--color-corporate-200);
  --color-header-brand: #0c1e2e;
  --color-brand-highlight: #6bafd9;
  --color-on-brand-muted: rgba(255, 255, 255, 0.6);
  --color-on-brand-subtle: rgba(255, 255, 255, 0.75);
  --glass-bg: rgba(48, 136, 200, 0.08);
  --glass-border: rgba(48, 136, 200, 0.16);
  --color-scrollbar-thumb: var(--color-corporate-300);
  --color-scrollbar-thumb-hover: var(--color-corporate-200);
  --surface-3: #1f3346;
}

/* Smooth colour shift when switching palettes. Colour properties only, so the
   transform/opacity animations below are untouched. */
*:not([class*='page-fade']):not([class*='v-']),
*:not([class*='page-fade']):not([class*='v-'])::before,
*:not([class*='page-fade']):not([class*='v-'])::after {
  transition:
    background-color var(--duration-slow) var(--ease-standard),
    border-color var(--duration-slow) var(--ease-standard),
    box-shadow var(--duration-slow) var(--ease-standard),
    color var(--duration-base) var(--ease-standard);
}

/* ============================================================
   Base
   ============================================================ */

* { box-sizing: border-box; }

html { height: 100%; }

body {
  margin: 0;
  height: 100%;
  font-family: var(--font);
  font-size: var(--text-md);
  line-height: var(--leading-normal);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition:
    background-color var(--duration-base) var(--ease-standard),
    color var(--duration-base) var(--ease-standard);
}

html[lang='en'] body { font-family: var(--font-family-en); }

#app {
  height: 100%;
  display: flex;
  flex-direction: column;
}

h1, h2, h3 { margin: 0; font-weight: var(--weight-semibold); letter-spacing: var(--track-tight); }
h2 { font-size: var(--text-lg); margin: var(--space-5) 0 var(--space-3); }

a { color: var(--accent); }

code {
  font-family: var(--mono);
  font-size: .9em;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 1px 5px;
}

:focus-visible {
  outline: 2px solid var(--color-brand);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

* {
  scrollbar-width: thin;
  scrollbar-color: var(--color-scrollbar-thumb) var(--color-scrollbar-track);
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--color-scrollbar-track); }
::-webkit-scrollbar-thumb {
  background-color: var(--color-scrollbar-thumb);
  border-radius: var(--radius-full);
  border: 2px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background-color: var(--color-scrollbar-thumb-hover); }

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

/* ============================================================
   Shared keyframes and transition classes (UIS animations.css)
   ============================================================ */

@keyframes fade-up {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes pop-in {
  from { transform: scale(0.8); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

@keyframes pulse-dot {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-brand) 45%, transparent); }
  70% { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

@keyframes shimmer-sweep {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

@keyframes shimmer-slide {
  from { transform: translateX(-150%); }
  to { transform: translateX(150%); }
}

@keyframes draw-check {
  to { stroke-dashoffset: 0; }
}

@keyframes v-ripple-expand {
  to { transform: scale(1); opacity: 0; }
}

:where(.v-ripple) {
  position: relative;
  overflow: hidden;
}

.v-ripple__wave {
  position: absolute;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, currentColor 45%, transparent);
  transform: scale(0);
  animation: v-ripple-expand 600ms var(--ease-decelerate);
  pointer-events: none;
}

.fade-slide-enter-active,
.fade-slide-leave-active {
  transition:
    opacity var(--duration-base) var(--ease-standard),
    transform var(--duration-base) var(--ease-standard);
}
.fade-slide-enter-from { opacity: 0; transform: translateY(8px); }
.fade-slide-leave-to { opacity: 0; transform: translateY(-8px); }

.page-fade-enter-active,
.page-fade-leave-active {
  transition: opacity var(--duration-base) var(--ease-standard);
}
.page-fade-enter-from,
.page-fade-leave-to { opacity: 0; }

.modal-backdrop-enter-active,
.modal-backdrop-leave-active {
  transition: opacity var(--duration-base) var(--ease-standard);
}
.modal-backdrop-enter-from,
.modal-backdrop-leave-to { opacity: 0; }

.modal-panel-enter-active {
  transition:
    opacity var(--duration-base) var(--ease-decelerate),
    transform var(--duration-base) var(--ease-decelerate);
}
.modal-panel-leave-active {
  transition:
    opacity var(--duration-fast) var(--ease-accelerate),
    transform var(--duration-fast) var(--ease-accelerate);
}
.modal-panel-enter-from,
.modal-panel-leave-to { opacity: 0; transform: translateY(16px) scale(0.97); }

/* ============================================================
   Utilities (UIS utilities.css)
   ============================================================ */

.container {
  width: 100%;
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: var(--space-6);
}

@media (max-width: 480px) {
  .container { padding-inline: var(--space-4); }
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

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

.grid-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-5);
}

.source-label { font-weight: var(--font-weight-bold); }

.source-chip {
  display: inline-block;
  font-weight: var(--font-weight-regular);
  font-size: var(--font-size-xs);
  line-height: var(--line-height-tight);
  color: var(--color-brand);
  background-color: var(--color-brand-soft);
  border: 1px solid var(--color-brand-soft);
  border-radius: var(--radius-full);
  padding: var(--space-1) var(--space-2);
  margin-inline-start: var(--space-1);
  margin-block-start: var(--space-1);
}

/* ============================================================
   Controls
   ============================================================ */

input, select, button, textarea { font: inherit; color: inherit; }

input[type="search"],
input[type="text"],
input[type="password"],
input[type="date"],
input[type="number"],
select {
  background: var(--color-surface);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  transition:
    border-color var(--duration-fast) var(--ease-standard),
    box-shadow var(--duration-fast) var(--ease-standard);
}

input::placeholder { color: var(--color-text-muted); }

input:hover, select:hover { border-color: var(--border-strong); }

input:focus, select:focus {
  outline: none;
  border-color: var(--color-brand);
  box-shadow: 0 0 0 var(--ring) var(--color-brand-soft);
}

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

button { cursor: pointer; }

.more {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  white-space: nowrap;
  background: var(--color-surface);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-6);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
  box-shadow: var(--shadow-1);
  transition:
    background-color var(--duration-fast) var(--ease-standard),
    border-color var(--duration-fast) var(--ease-standard),
    transform var(--duration-fast) var(--ease-standard),
    opacity var(--duration-fast) var(--ease-standard);
}

.more:hover { background: var(--surface-2); border-color: var(--border-strong); }
.more:active:not(:disabled) { transform: scale(.98); }
.more:disabled { opacity: .6; cursor: not-allowed; }

.check {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-base);
  color: var(--muted);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

.check:hover { color: var(--text); }

.field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--faint);
}

.field input, .field select { font-size: var(--text-base); text-transform: none; letter-spacing: 0; font-weight: var(--weight-normal); }

.status { font-size: var(--text-sm); color: var(--muted); }

/* ============================================================
   App shell
   ============================================================ */

.topbar {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-3) var(--space-5);
  background: color-mix(in srgb, var(--color-surface) 82%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-block-end: 1px solid var(--color-border);
  flex-wrap: wrap;
  z-index: var(--z-header);
  /* Own compositor layer, or the blur is recomputed on every scroll frame. */
  transform: translateZ(0);
  will-change: transform;
}

.topbar h1 {
  font-size: var(--text-xl);
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}

.topbar h1 .subtitle {
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  color: var(--faint);
  text-transform: uppercase;
  letter-spacing: var(--track-wider);
}

/* Which build is live. Monospace so a commit sha stays readable, and
   selectable so it can be pasted into a bug report. */
.topbar h1 .release {
  font-family: var(--mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  color: var(--faint);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 1px 6px;
  cursor: pointer;
  user-select: text;
  white-space: nowrap;
}

/* Segmented control, matching the UIS header pill group. */
.tabs {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  flex-wrap: wrap;
}

.tab {
  background: transparent;
  border: none;
  color: var(--muted);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-full);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  white-space: nowrap;
  transition:
    background-color var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard);
}

.tab:hover { color: var(--text); background: var(--overlay); }

.tab.active {
  background: var(--color-surface-raised);
  color: var(--text);
  font-weight: var(--font-weight-semibold);
  box-shadow: var(--shadow-1);
}

.topbar-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--muted);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  padding: var(--space-1) var(--space-4);
}

.badge::before {
  content: "";
  width: var(--dot);
  height: var(--dot);
  border-radius: 50%;
  background: var(--faint);
}

.badge.ok { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); background: var(--accent-soft); }
.badge.ok::before { background: var(--accent); box-shadow: 0 0 0 var(--ring) var(--accent-soft); }
.badge.error { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, transparent); }
.badge.error::before { background: var(--danger); }

.theme-toggle {
  display: grid;
  place-items: center;
  width: var(--control-h);
  height: var(--control-h);
  font-size: var(--font-size-base);
  line-height: 1;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  transition:
    background-color var(--duration-fast) var(--ease-standard),
    border-color var(--duration-fast) var(--ease-standard),
    transform var(--duration-fast) var(--ease-standard);
}

.theme-toggle:hover { background: var(--surface-3); border-color: var(--border-strong); }
.theme-toggle:active { transform: scale(.98); }

main { flex: 1; overflow: hidden; }

.view {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow-y: auto;
}

.view.padded { padding: var(--space-5); }

/* ============================================================
   Search + filters
   ============================================================ */

.search-row {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-5);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
}

.search-row input[type="search"] {
  flex: 1 1 300px;
  min-width: 0;
  padding-inline-start: 40px;
  background-repeat: no-repeat;
  background-position: 14px center;
  background-size: 16px;
  background-image: var(--icon-search);
}

.search-row .field { flex-direction: row; align-items: center; gap: var(--space-2); }

.filter-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  background: var(--color-surface);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-1);
  transition:
    background-color var(--duration-fast) var(--ease-standard),
    border-color var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard);
}

.filter-toggle:hover { border-color: var(--border-strong); background: var(--surface-2); }

.filter-toggle.open {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-soft);
}

.filter-toggle .count {
  background: var(--accent);
  color: var(--on-accent);
  border-radius: var(--radius-pill);
  padding: 0 7px;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

.filter-panel {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}

.filter-panel .toggles {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: center;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: var(--space-3) var(--space-4);
  margin: 0;
}

.filter-panel .toggles legend {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--faint);
  padding: 0 var(--space-2);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: var(--space-3) var(--space-5) 0;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--color-surface);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  padding: var(--space-1) var(--space-3);
  font-size: var(--font-size-xs);
  line-height: var(--line-height-tight);
  box-shadow: var(--shadow-1);
  transition:
    border-color var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard);
}

.chip:hover { border-color: var(--danger); color: var(--danger); }
.chip-x { font-size: var(--text-lg); line-height: 1; opacity: .6; }
.chip:hover .chip-x { opacity: 1; }
.chip.clear-all { border-style: dashed; color: var(--muted); box-shadow: none; }

.note {
  padding: var(--space-3) var(--space-5);
  font-size: var(--text-sm);
  color: var(--muted);
}

.note:empty { display: none; }

/* ============================================================
   Message results
   ============================================================ */

.message-list { display: flex; flex-direction: column; }

.result {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--border);
  /* Direction cue: a message we sent gets an accent-coloured left edge. */
  box-shadow: inset 3px 0 0 transparent;
  transition: background var(--transition), box-shadow var(--transition);
}

.result:hover { background: var(--surface); }
.result.out { box-shadow: inset 3px 0 0 var(--accent); }

/* The row itself opens the message; the controls inside it keep their own
   cursor, so a click target never looks like the row. */
.result.clickable { cursor: pointer; }
.result.clickable button,
.result.clickable a { cursor: pointer; }

.result-main { flex: 1; min-width: 0; }

.result-avatar {
  flex: 0 0 36px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--surface-3);
  color: var(--text);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  user-select: none;
}

.result-avatar.group { background: var(--accent-soft); color: var(--accent); }

/* Compact inline variant for table cells and dense rows, where a full 36px
   avatar would blow out the row height. */
.avatar-dot {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--surface-3);
  color: var(--text);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  line-height: 1;
  user-select: none;
  vertical-align: middle;
}

.avatar-dot.group { background: var(--accent-soft); color: var(--accent); }

/* Keeps the dot and the name on one line without the name pushing it around. */
.chat-cell { display: inline-flex; align-items: center; gap: var(--space-2); min-width: 0; }
.chat-cell > span { overflow: hidden; text-overflow: ellipsis; }

.result-head {
  display: flex;
  gap: var(--space-2);
  align-items: baseline;
  flex-wrap: wrap;
  font-size: var(--text-sm);
  color: var(--muted);
  margin-bottom: 3px;
}

.result-head .chat { color: var(--text); font-weight: var(--weight-semibold); font-size: var(--text-base); }
.result-head .sender { color: var(--accent); font-weight: var(--weight-medium); }
.result-head .time { margin-left: auto; color: var(--faint); font-size: var(--text-xs); white-space: nowrap; }

.meta-star { color: var(--star); font-size: var(--text-base); line-height: 1; }
.meta-label {
  font-size: var(--text-xs);
  color: var(--faint);
  text-transform: uppercase;
  letter-spacing: .04em;
}

.snippet { display: block; white-space: pre-wrap; word-break: break-word; }

/* ---------- Bidirectional text ----------
   dir="auto" has to stay: it is what resolves each string's base direction, so
   Arabic shapes correctly and its punctuation, digits and embedded Latin words
   land in the right places. What it must not keep doing is drag text-align with
   it — that flushes every Arabic row right and every Latin row left, and reading
   down a mixed list turns into a zig-zag. Pinning alignment to the LTR chrome's
   edge gives every row one shared reading edge; ordering inside each string is
   still decided by the text. */
.snippet,
.correction-pane p,
.chat-name,
.chat-preview,
.chat-cell > span,
.chat-option-name,
.table td[dir="auto"] {
  text-align: left;
}

mark {
  background: var(--mark-bg);
  color: var(--mark-text);
  border-radius: 3px;
  padding: 0 2px;
  font-weight: var(--weight-semibold);
}

.receipt-line {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding-left: var(--space-2);
  border-left: 2px solid var(--accent);
  font-size: var(--text-sm);
  color: var(--muted);
}

/* The receipt summary doubles as the way into its editor. */
.receipt-line-open {
  width: 100%;
  background: none;
  border: none;
  border-left: 2px solid var(--accent);
  text-align: start;
  cursor: pointer;
}

.receipt-line-open:hover { background: var(--overlay); }

.add-receipt {
  align-self: flex-start;
  margin-top: 2px;
  padding: 1px 8px;
  background: none;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-full);
  color: var(--muted);
  font-size: var(--text-2xs);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--transition), color var(--transition), border-color var(--transition);
}

/* Quiet until the row is deliberately hovered, like the delete control. */
.result:hover .add-receipt,
.add-receipt:focus-visible { opacity: 1; }
.add-receipt:hover { color: var(--accent); border-color: var(--accent); border-style: solid; }

@media (hover: none) { .add-receipt { opacity: 1; } }

.receipt-line .amount {
  color: var(--accent);
  font-weight: var(--weight-semibold);
  font-size: var(--text-base);
  white-space: nowrap;
}

/* Thumbnail and text sit side by side so a media row costs one line, not a block. */
.result-body { display: flex; gap: var(--space-3); align-items: flex-start; }

.result-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.media-thumb {
  flex: none;
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  font-size: 22px;
  text-decoration: none;
  transition: border-color var(--transition);
}

.media-thumb:hover { border-color: var(--accent); }

/* Full-size blobs scaled down by the browser; loading="lazy" keeps offscreen
   rows from fetching. Localhost-only, so the bytes never cross a network. */
.media-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Inline "nothing here" text. Distinct from .empty, which is a centred
   full-width empty state with space-12 padding and must not be reused in a row. */
.inline-empty { color: var(--faint); font-size: var(--text-sm); }

/* Destructive, so it stays quiet until the row is deliberately hovered. */
.btn-delete {
  margin-left: var(--space-2);
  padding: 2px 6px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--faint);
  font-size: var(--text-xs);
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--transition), color var(--transition), border-color var(--transition);
}

.result:hover .btn-delete,
.btn-delete:focus-visible { opacity: 1; }
.btn-delete:hover { color: var(--danger, #d92d20); border-color: currentColor; }

/* Hover cannot reveal anything on touch, so it is always visible there. */
@media (hover: none) {
  .btn-delete { opacity: 1; }
}

.badges { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }

.tag {
  display: inline-flex;
  align-items: center;
  font-size: var(--font-size-xs);
  line-height: var(--line-height-tight);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  background: var(--color-surface-alt);
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
}

a.tag:hover { border-color: var(--accent); color: var(--accent); }
.tag.receipt-flag { border-color: color-mix(in srgb, var(--accent) 45%, transparent); color: var(--accent); background: var(--accent-soft); }

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-2);
  padding: var(--space-12) var(--space-4);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

/* ============================================================
   Chat list (WhatsApp style)
   ============================================================ */

.chat-list { display: flex; flex-direction: column; }

.chat-section-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5) var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--faint);
  position: sticky;
  top: 0;
  background: var(--bg);
  z-index: var(--z-base);
}

.chat-section-count {
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: var(--radius-pill);
  padding: 0 7px;
  font-size: var(--text-xs);
  letter-spacing: 0;
}

.chat-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--border);
  transition: background var(--transition);
}

.chat-row:hover { background: var(--surface); }

.chat-row.favourite {
  border-left: 3px solid var(--star);
  padding-left: calc(var(--space-5) - 3px);
  background: color-mix(in srgb, var(--star) 6%, transparent);
}

.avatar {
  flex: 0 0 var(--avatar);
  width: var(--avatar);
  height: var(--avatar);
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--surface-3);
  color: var(--text);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  user-select: none;
}

.avatar.group { background: var(--accent-soft); color: var(--accent); }

.chat-body { flex: 1; min-width: 0; }
.chat-top { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); }
.chat-name { font-weight: var(--weight-semibold); font-size: var(--text-md); }
.chat-time { font-size: var(--text-xs); color: var(--faint); white-space: nowrap; }

.chat-bottom {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  margin-top: 1px;
}

.chat-preview {
  font-size: var(--text-base);
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-count {
  font-size: var(--text-xs);
  color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 0 8px;
  white-space: nowrap;
}

.star {
  background: none;
  border: none;
  font-size: var(--text-2xl);
  line-height: 1;
  color: var(--faint);
  padding: 2px;
  border-radius: var(--radius-sm);
  transition: color var(--transition), transform var(--transition);
}

.star:hover { color: var(--star); transform: scale(1.15); }
.star.on { color: var(--star); }

.bulk-bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-5);
  background: var(--accent-soft);
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
}

/* ============================================================
   Tables
   ============================================================ */

/* A wide table scrolls inside its own box; without this the whole page scrolls
   sideways and the header/filters drift off screen with it. */
.table-wrap {
  width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-1);
  font-size: var(--font-size-sm);
}

.table th {
  text-align: left;
  padding: var(--space-3) var(--space-4);
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--track-wide);
  color: var(--faint);
  position: sticky;
  top: 0;
  z-index: var(--z-base);
}

.table td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  /* break-word, not anywhere: anywhere splits ordinary names mid-word
     ("Moha/mmed") the moment a column gets tight. */
  overflow-wrap: break-word;
}

/* Opaque ids have no break point of their own, so they opt in explicitly. */
.audit-record, .detail-list dd { overflow-wrap: anywhere; }

.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover { background: var(--surface-2); }
.table tr.editor:hover { background: var(--surface); }

.editor-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: flex-end;
  padding: var(--space-3) 0;
}

.receipt-preview {
  max-width: 220px;
  max-height: 220px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}

/* ============================================================
   Stats
   ============================================================ */

.stat-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--space-4);
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition);
}

.card:hover { transform: translateY(-2px); box-shadow: var(--shadow); }

.card .value { font-size: var(--text-3xl); font-weight: var(--weight-bold); letter-spacing: -.02em; }
.card .value.value-sm { font-size: var(--text-lg); line-height: var(--leading-tight); letter-spacing: 0; }
.card .label { font-size: var(--text-xs); color: var(--faint); text-transform: uppercase; letter-spacing: .06em; margin-top: 2px; }

/* ============================================================
   Narrow screens
   ============================================================ */

@media (max-width: 720px) {
  .topbar { gap: var(--space-3); padding: var(--space-3); }
  /* The title row is tight on a phone; the build id is the first thing to go. */
  .topbar h1 .release { display: none; }
  .topbar-right { margin-left: 0; }
  .search-row, .filter-panel, .chips, .note, .result, .chat-row, .chat-section-title {
    padding-left: var(--space-3);
    padding-right: var(--space-3);
  }
  .view.padded { padding: var(--space-3); }
  .chat-row.favourite { padding-left: calc(var(--space-3) - 3px); }

  /* Search should keep the full row; the controls below it share the next line. */
  .search-row input[type="search"] { flex: 1 1 100%; }

  /* Four actions per receipt cannot sit on one line at this width. */
  .receipt-actions { flex-wrap: wrap; justify-content: flex-start; }

  .quick-controls { justify-content: flex-start; }
  .stat-cards { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
  .card .value { font-size: var(--text-2xl); }

  /* The timestamp stops being pinned right once the head wraps to two lines. */
  .result-head .time, .ai-head .time { margin-left: 0; }
  .ai-error-preview { flex-basis: 100%; }
}

@media (max-width: 480px) {
  .topbar h1 .subtitle { display: none; }
  .tabs { width: 100%; justify-content: space-between; }
  .tab { padding: var(--space-2) var(--space-3); }
  .result { gap: var(--space-2); padding-left: var(--space-2); padding-right: var(--space-2); }
  .result-avatar { flex-basis: 28px; width: 28px; height: 28px; font-size: var(--text-xs); }
  .avatar { flex-basis: 36px; width: 36px; height: 36px; font-size: var(--text-md); }
  .correction-columns { grid-template-columns: 1fr; }
  .stat-cards { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
}

/* ============================================================
   AI processing log
   ============================================================ */

/* One operation per row, every figure on that row, so the numbers can be
   compared straight across instead of hunted for down a stacked card. */
.ai-summary {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5) 0;
}

.ai-stat-row {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.ai-stat-name {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--faint);
  margin-inline-end: auto;
}

.ai-stat { display: inline-flex; align-items: baseline; gap: 5px; white-space: nowrap; }
.ai-stat b { font-size: var(--text-lg); font-weight: var(--weight-bold); letter-spacing: -.02em; }
.ai-stat i {
  font-style: normal;
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--faint);
}

.ai-stat.bad b { color: var(--danger); }

.ai-list { display: flex; flex-direction: column; }

.ai-row { border-bottom: 1px solid var(--border); }
.ai-row.failed { border-left: 3px solid var(--danger); }

.ai-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-5);
  cursor: pointer;
  transition: background var(--transition);
}

.ai-head:hover { background: var(--surface); }
.ai-model { font-family: var(--mono); font-size: var(--text-xs); color: var(--faint); }
.ai-chat { font-size: var(--text-base); font-weight: var(--weight-semibold); }
.ai-duration {
  font-family: var(--mono);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: var(--radius-sm);
  padding: 1px 7px;
}
.ai-head .time { margin-left: auto; font-size: var(--text-xs); color: var(--faint); }
.ai-caret { color: var(--faint); font-size: var(--text-xs); }
.tag.flag-error { color: var(--danger); border-color: var(--danger); background: transparent; }

/* Sits between the meta and the right-aligned time, clipped to one line. */
.ai-error-preview {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--text-xs);
  color: var(--danger);
}

.live-note {
  margin-inline-start: auto;
  font-size: var(--text-2xs);
  color: var(--color-success, var(--accent));
  white-space: nowrap;
}

.ai-detail {
  padding: var(--space-3) var(--space-5) var(--space-5);
  background: var(--surface-2);
  display: grid;
  gap: var(--space-3);
}

.ai-times {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  font-size: var(--text-sm);
  color: var(--muted);
}
.ai-times strong { color: var(--faint); font-weight: var(--weight-semibold); margin-right: 5px; }

.ai-pane h3 {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--track-wide);
  color: var(--faint);
  margin-bottom: var(--space-2);
}

.ai-pane pre {
  margin: 0;
  padding: var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-family: var(--mono);
  font-size: var(--text-sm);
  line-height: var(--leading-loose);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 320px;
  overflow: auto;
}

.ai-pane.error pre { border-color: var(--danger); color: var(--danger); }

/* Live poll control */
.live-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  color: var(--color-success, var(--accent));
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  border-radius: var(--radius-full);
  white-space: nowrap;
}

.live-toggle.paused { color: var(--faint); background: var(--surface-2); border-color: var(--border); }

/* Success meter, sized to sit inline at the end of the stat row. */
.rate-bar {
  flex: none;
  display: block;
  width: 90px;
  height: 5px;
  border-radius: var(--radius-full);
  background: var(--surface-3);
  overflow: hidden;
}

.rate-bar > span { display: block; height: 100%; background: var(--color-success, var(--accent)); }
.rate-bar.poor > span { background: var(--warn); }

/* Recurring failure causes */
.failure-panel {
  margin: var(--space-4) var(--space-5) 0;
  padding: var(--space-3) var(--space-4);
  background: var(--color-error-bg);
  border: 1px solid color-mix(in srgb, var(--danger) 30%, transparent);
  border-radius: var(--radius-lg);
}

.failure-panel h3 {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--track-wide);
  color: var(--danger);
  margin-bottom: var(--space-2);
}

.failure-scope { text-transform: none; letter-spacing: 0; color: var(--faint); font-weight: var(--weight-normal); }

.failure-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: 4px 0;
  background: none;
  border: none;
  text-align: start;
  font-size: var(--text-sm);
  color: var(--text);
}

.failure-row:hover .failure-text { text-decoration: underline; }

.failure-count {
  flex: none;
  font-family: var(--mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--danger);
  min-width: 32px;
}

.failure-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }

/* Caption of the source message, shown where a run or receipt is identified. */
.ai-caption {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--text-xs);
  color: var(--muted);
  text-align: left;
}

.receipt-caption {
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted);
}

.verify-caption {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-inline-start: 3px solid var(--accent);
  border-radius: var(--radius);
  font-size: var(--text-base);
  text-align: left;
}

.verify-caption-label {
  display: block;
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--faint);
}

/* ============================================================
   Audit
   ============================================================ */

.audit-controls {
  display: flex;
  align-items: flex-end;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}

.audit-search { flex: 1 1 260px; max-width: 420px; }
.audit-when { white-space: nowrap; font-size: var(--text-xs); color: var(--muted); }
.audit-record { font-size: var(--text-2xs); }

.op {
  display: inline-block;
  padding: 1px 8px;
  border-radius: var(--radius-full);
  border: 1px solid currentColor;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: .04em;
  white-space: nowrap;
}

.op-create { color: var(--color-success, var(--accent)); }
.op-update { color: var(--color-info, var(--accent)); }
.op-delete { color: var(--danger); }

.audit-change {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  min-width: 220px;
}

.audit-old { color: var(--danger); text-decoration: line-through; opacity: .8; }
.audit-new { color: var(--color-success, var(--accent)); font-weight: var(--weight-medium); }
.audit-arrow { color: var(--faint); flex: none; }
.tag.audit-source { margin-inline-start: var(--space-2); font-size: var(--text-2xs); }

/* ============================================================
   Quick access + multi-select chat picker
   ============================================================ */

.quick-bar {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.quick-pills, .quick-controls {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.quick-controls { justify-content: flex-end; }
.quick-controls:empty { display: none; }

.quick-label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--faint);
  margin-right: var(--space-1);
}

.quick-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  transition: all var(--transition);
  max-width: 260px;
}

.quick-pill:hover { border-color: var(--border-strong); background: var(--surface-3); }

.quick-pill.on {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: var(--weight-semibold);
}

.quick-pill.on .quick-count { background: var(--on-accent-overlay); color: inherit; border-color: transparent; }
.quick-pill.ghost { border-style: dashed; color: var(--muted); background: transparent; }
.quick-icon { font-size: var(--text-sm); }

.quick-count {
  font-size: var(--text-2xs);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 0 6px;
  color: var(--muted);
}

.chat-picker { grid-column: span 2; }
.chat-picker input[type="search"] { text-transform: none; letter-spacing: 0; font-weight: var(--weight-normal); }

/* Compact multi-select: a button that drops a floating checkbox list. */
.ms { position: relative; display: inline-block; min-width: 0; }

.ms-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  width: 100%;
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  background: var(--color-surface);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-1);
  cursor: pointer;
}

.ms-toggle:hover { border-color: var(--border-strong); background: var(--surface-2); }
.ms-toggle.open { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }

.ms-label { flex: 1; text-align: start; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ms-caret { color: var(--faint); font-size: var(--text-xs); }

.ms-toggle .count {
  background: var(--accent);
  color: var(--on-accent);
  border-radius: var(--radius-pill);
  padding: 0 7px;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

.ms-panel {
  position: absolute;
  z-index: var(--z-dropdown, 50);
  top: calc(100% + 4px);
  inset-inline-start: 0;
  min-width: 280px;
  max-width: 360px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3, 0 8px 24px rgba(0, 0, 0, .18));
  padding: var(--space-2);
}

.ms-search { width: 100%; margin-bottom: var(--space-2); }
.ms-list { max-height: 240px; overflow-y: auto; }

.ms-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding-top: var(--space-2);
  margin-top: var(--space-2);
  border-top: 1px solid var(--border);
  font-size: var(--text-xs);
  color: var(--faint);
}

.ms-clear {
  background: none;
  border: none;
  color: var(--accent);
  font-size: var(--text-xs);
  cursor: pointer;
  text-decoration: underline;
}

.ms-clear:disabled { color: var(--faint); cursor: default; text-decoration: none; }

.chat-options {
  margin-top: 6px;
  max-height: 190px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.chat-option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 6px var(--space-3);
  font-size: var(--text-base);
  font-weight: var(--weight-normal);
  letter-spacing: 0;
  text-transform: none;
  color: var(--text);
  cursor: pointer;
  border-bottom: 1px solid var(--border);
}

.chat-option:last-child { border-bottom: none; }
.chat-option:hover { background: var(--surface-2); }
.chat-option-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 720px) {
  .quick-bar { padding: var(--space-3); }
  .chat-picker { grid-column: span 1; }
}

/* ============================================================
   Receipt verification dialog
   ============================================================ */

.dialog-backdrop {
  position: fixed;
  inset: 0;
  background: var(--overlay-scrim);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  display: grid;
  place-items: center;
  padding: var(--space-4);
  z-index: var(--z-modal);
}

.dialog {
  width: min(1080px, 100%);
  max-height: 92vh;
  display: flex;
  flex-direction: column;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-3);
  overflow: hidden;
}

.dialog-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
}

.dialog-head h2 { font-size: var(--text-xl); margin: 0; }
.dialog-sub { font-size: var(--text-sm); color: var(--muted); }
.dialog-actions { display: flex; gap: var(--space-2); }
.dialog-actions .more { padding: var(--space-2) var(--space-4); }

.dialog-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 420px);
  gap: 0;
  overflow: hidden;
}

.verify-source {
  background: var(--bg);
  border-inline-end: 1px solid var(--border);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  overflow: auto;
  min-height: 320px;
}

.verify-source img {
  width: 100%;
  object-fit: contain;
  max-height: 62vh;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
  cursor: zoom-in;
}

.verify-source.zoomed img { max-height: none; cursor: zoom-out; }

.verify-source-meta {
  display: flex;
  justify-content: space-between;
  font-size: var(--text-xs);
  color: var(--faint);
}

/* ============================================================
   Media lightbox — reuses the receipt dialog's shell and image pane
   ============================================================ */

/* Details affordance, kept as quiet as delete until the row is hovered. */
.btn-detail {
  margin-left: auto;
  padding: 2px 6px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--faint);
  font-size: var(--text-sm);
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--transition), color var(--transition), border-color var(--transition);
}

.result:hover .btn-detail,
.btn-detail:focus-visible { opacity: 1; }
.btn-detail:hover { color: var(--accent); border-color: currentColor; }
@media (hover: none) { .btn-detail { opacity: 1; } }

/* .time already claims margin-left:auto; with the buttons after it the detail
   button must not claim it again or the row splits in two. */
.result-head .btn-detail { margin-left: 0; }

/* A message with no attachment still deserves the large pane: its text goes there. */
.detail-text-pane {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 220px;
  padding: var(--space-5);
}

.detail-message {
  margin: 0;
  font-size: var(--text-lg);
  line-height: var(--leading-loose);
  white-space: pre-wrap;
  word-break: break-word;
  text-align: left;
}

.detail-original { color: var(--muted); text-decoration: line-through; }
.detail-sub { font-size: var(--text-2xs); color: var(--faint); }
.detail-tags { display: flex; gap: 6px; flex-wrap: wrap; }

.send-state {
  align-self: flex-start;
  padding: 2px 10px;
  border-radius: var(--radius-full);
  border: 1px solid currentColor;
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
}

.send-sent { color: var(--color-info, var(--accent)); }
.send-pending { color: var(--warn); }
.send-failed { color: var(--danger); }
.send-unsent { color: var(--faint); }

/* Details beside the image, matching the receipt dialog's side panel. */
.detail-block { display: flex; flex-direction: column; gap: 4px; }

.detail-label {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--faint);
}

.detail-value {
  margin: 0;
  font-size: var(--text-base);
  white-space: pre-wrap;
  word-break: break-word;
  text-align: left;
}

.detail-list {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  border-block-start: 1px solid var(--border);
  padding-block-start: var(--space-3);
}

.detail-list > div {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  gap: var(--space-2);
  align-items: baseline;
}

.detail-list dt {
  font-size: var(--text-xs);
  color: var(--faint);
}

.detail-list dd {
  margin: 0;
  min-width: 0;
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
  text-align: left;
}

.lightbox-id {
  font-family: var(--mono);
  font-size: var(--text-2xs);
  color: var(--faint);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 1px 6px;
}

.lightbox-id:hover { color: var(--accent); border-color: var(--accent); }

.verify-form {
  padding: var(--space-4) var(--space-5);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.verify-hint {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  color: var(--warn);
  background: var(--color-warning-bg);
  border: 1px solid var(--color-warning);
  border-radius: var(--radius);
}

[data-theme="dark"] .verify-hint { background: transparent; }

.verify-field { display: flex; flex-direction: column; gap: 4px; }

/* Whole reais and cents sit on one row but persist to a single amount column. */
.amount-split { display: flex; align-items: center; gap: 6px; }
.amount-split input { width: 100%; min-width: 0; }
.amount-split input:last-of-type { flex: 0 0 4.5em; }
.amount-prefix, .amount-sep { color: var(--faint); font-weight: var(--weight-semibold); }

.verify-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--faint);
}

.verify-flag {
  text-transform: none;
  letter-spacing: 0;
  font-weight: var(--weight-medium);
  font-size: var(--text-2xs);
  padding: 0 6px;
  border-radius: var(--radius-pill);
  background: var(--color-warning-bg);
  color: var(--color-warning);
  border: 1px solid var(--color-warning);
}

.verify-flag.changed {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent);
}

.verify-revert {
  margin-inline-start: auto;
  background: none;
  border: none;
  color: var(--accent);
  font-size: var(--text-2xs);
  text-transform: none;
  letter-spacing: 0;
  text-decoration: underline;
}

.verify-optional { text-transform: none; letter-spacing: 0; color: var(--faint); font-weight: var(--weight-normal); }
.verify-field.dirty input { border-color: var(--accent); }
.verify-field.blank input { border-style: dashed; }
.verify-field.invalid input { border-color: var(--danger); }
.verify-error { font-size: var(--text-xs); color: var(--danger); }
.verify-was { font-size: var(--text-xs); color: var(--faint); }

.verify-bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-top: var(--space-2);
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}

.verify-bar .more { padding: var(--space-2) var(--space-4); font-size: var(--font-size-sm); }
.verify-bar .status { flex-basis: 100%; }

.more.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: var(--weight-semibold);
}

.more.primary:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); }
.verify-shortcut { font-size: var(--text-2xs); color: var(--faint); font-family: var(--mono); }

.verify-history summary { font-size: var(--text-sm); color: var(--muted); cursor: pointer; }
.verify-history ul { list-style: none; margin: var(--space-2) 0 0; padding: 0; display: grid; gap: 6px; }
.verify-history li {
  font-size: var(--text-xs);
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: baseline;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.verify-history em { color: var(--faint); font-style: normal; margin-inline-start: auto; }
.verify-reason { width: 100%; color: var(--faint); font-style: italic; }

.receipt-row { cursor: pointer; }
.receipt-row.incomplete td:first-child { box-shadow: inset 3px 0 0 var(--color-warning); }
/* Nothing to open on a row with no receipt, so it does not offer the pointer. */
.receipt-row.pending { cursor: default; }
.receipt-row.pending td:first-child { box-shadow: inset 3px 0 0 var(--faint); }
.receipt-row.pending td { color: var(--faint); }
/* Its own column now, so it gets the width its buttons need rather than
   squeezing the neighbouring cells. */
.receipt-actions { display: flex; align-items: center; gap: 6px; justify-content: flex-end; flex-wrap: nowrap; }
/* The flex lives on an inner div: a display:flex <td> leaves the table's column
   sizing and the cell's own box disagreeing, which collapsed this column to 32px
   while its buttons still needed 384px. width:1% is the table idiom for
   "shrink to fit the content". */
.table th.col-actions, .table td.col-actions { width: 1%; white-space: nowrap; }

/* Columns share the container width rather than being sized by their content,
   which is what let free-text columns push the table into a sideways scroll. */
.receipts-table { table-layout: fixed; width: 100%; }

/* With fixed layout a cell must clip, or its text simply spills over the next. */
.receipts-table td.clip,
.receipts-table td.receipt-chat {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Same guard for the actions cell: its contents are nowrap, so without this an
   over-wide status tag rendered straight across the neighbouring Chat cell. */
.receipts-table td.col-actions { overflow: hidden; }

/* Six controls share this cell, so the column is budgeted for their real width:
   clipping instead would simply hide the delete button. */
.receipt-actions { gap: 4px; }
.receipt-actions .more { padding: 4px 8px; font-size: var(--text-xs); }
.receipt-actions .tag { padding: 1px 5px; }
.receipts-table td.col-actions { padding-inline: var(--space-2); }

.receipt-chat .chat-cell { max-width: 100%; }
.receipt-chat .chat-cell > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.receipt-actions .tag { white-space: nowrap; }
.tag.warn-tag { color: var(--color-warning); border-color: var(--color-warning); background: transparent; }
.tag.manual-tag { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.tag.approved-tag { color: var(--color-success, #1a7f37); border-color: currentColor; background: transparent; }

/* Delivered and immutable. Deliberately calmer than the action buttons: it is a
   state to be read, not something to click. */
.tag.sent-tag {
  color: var(--color-info, var(--accent));
  border-color: color-mix(in srgb, var(--color-info, var(--accent)) 45%, transparent);
  background: var(--color-info-bg, var(--accent-soft));
  font-weight: var(--weight-semibold);
}

.receipt-row.sent td { opacity: .82; }

/* Sortable headers. The caret only occupies space on the active column, so the
   others keep their full width for the label. */
.table th.sortable {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

.table th.sortable:hover { color: var(--text); background: var(--surface-3); }
.table th.sortable.on { color: var(--accent); }
.sort-caret { font-size: 9px; margin-inline-start: 4px; }

.msgid-filter { font-family: var(--mono); font-size: var(--text-xs); width: 190px; }

.ref-copy { background: none; border: none; padding: 0; font: inherit; color: inherit; cursor: pointer; }
.ref-copy:hover { color: var(--accent); text-decoration: underline; }

/* Message numbers are a different sequence from receipt numbers, so they do not
   get to look the same. */
.ref-msg { color: var(--faint); font-style: italic; }

.receipt-msgid { white-space: nowrap; }

.msgid {
  font-family: var(--mono);
  font-size: var(--text-2xs);
  color: var(--faint);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 1px 6px;
  cursor: pointer;
}

.msgid:hover { color: var(--accent); border-color: var(--accent); }

/* Document date over arrival time; the list is ordered by the latter. */
.receipt-date { white-space: nowrap; line-height: var(--line-height-tight); }
.date-doc { display: block; }
.date-received { display: block; font-size: var(--text-2xs); color: var(--faint); }

.verify-locked {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  background: var(--color-info-bg, var(--accent-soft));
  border: 1px solid color-mix(in srgb, var(--color-info, var(--accent)) 35%, transparent);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  color: var(--color-info, var(--accent));
  text-align: left;
}
.receipt-row.approved td:first-child { box-shadow: inset 3px 0 0 var(--color-success, #1a7f37); }

@media (max-width: 860px) {
  .dialog-body { grid-template-columns: 1fr; }
  .verify-source { border-inline-end: none; border-bottom: 1px solid var(--border); }
  .verify-source img { max-height: 34vh; }
}

.verify-noimage {
  display: grid;
  gap: var(--space-2);
  place-content: center;
  text-align: center;
  min-height: 260px;
  padding: var(--space-5);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  color: var(--muted);
  font-size: var(--text-sm);
}

/* ============================================================
   Message rows: separation + AI correction diff
   ============================================================ */

/* Alternating surfaces so adjacent rows read as separate records. */
.message-list .result:nth-child(odd) { background: var(--surface); }
.message-list .result { border-bottom: 1px solid var(--border-strong); }
.message-list .result:hover { background: var(--surface-2); }

/* Collapsed it is just a chip in the flow; only an opened diff earns a card. */
.correction { margin-top: var(--space-1); border-radius: var(--radius); }

.correction.open {
  border: 1px solid var(--border);
  border-inline-start: 3px solid var(--warn);
  background: var(--surface-2);
  overflow: hidden;
}

.correction.open.emptied { border-inline-start-color: var(--danger); }

.correction-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 8px 2px 4px;
  background: none;
  border: none;
  border-radius: var(--radius-full);
  text-align: start;
  font-size: var(--text-xs);
  color: var(--muted);
}

.correction.open .correction-toggle { width: 100%; padding: 6px var(--space-3); }
.correction-toggle:hover { background: var(--overlay); }
.correction-toggle:hover .correction-chip { border-color: currentColor; }

.correction-chip {
  display: inline-flex;
  align-items: center;
  padding: 1px 8px;
  border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent);
  border-radius: var(--radius-full);
  color: var(--warn);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  line-height: var(--line-height-tight);
  white-space: nowrap;
}

.correction-chip.emptied { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 45%, transparent); }

.btn-delete {
  background: none;
  border: 1px solid transparent;
  color: var(--faint);
  font-size: var(--text-xs);
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition), background var(--transition);
}
.btn-delete:hover {
  color: var(--danger);
  border-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 10%, transparent);
}
.correction-counts { display: flex; gap: 6px; font-family: var(--mono); font-size: var(--text-xs); }
.correction-counts .del { color: var(--danger); }
.correction-counts .ins { color: var(--accent); }
.correction-caret { font-size: var(--text-2xs); color: var(--faint); }
.correction.open .correction-caret { margin-inline-start: auto; }

.correction-body {
  padding: var(--space-3);
  border-top: 1px solid var(--border);
  display: grid;
  gap: var(--space-3);
}

.correction-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}

.correction-pane h4 {
  margin: 0 0 4px;
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--track-wide);
  color: var(--faint);
}

.correction-pane p {
  margin: 0;
  padding: var(--space-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-base);
  white-space: pre-wrap;
  word-break: break-word;
}

.diff del {
  background: color-mix(in srgb, var(--danger) 18%, transparent);
  color: var(--danger);
  text-decoration: line-through;
  border-radius: 2px;
}

.diff ins {
  background: var(--accent-soft);
  color: var(--accent);
  text-decoration: none;
  border-radius: 2px;
}

@media (max-width: 720px) {
  .correction-columns { grid-template-columns: 1fr; }
}

.quick-order {
  font-size: var(--text-sm);
  padding: 4px 8px;
  border-radius: var(--radius-sm);
}

/* Drag is only offered in "My order", so the grab cursor is the affordance for it. */
.quick-pill[draggable="true"] { cursor: grab; }
.quick-pill[draggable="true"]:active { cursor: grabbing; }
.quick-pill.dragging { opacity: .4; }

.quick-hint {
  font-size: var(--text-2xs);
  color: var(--faint);
  white-space: nowrap;
}

.ref {
  font-family: var(--mono);
  font-size: var(--text-xs);
  color: var(--faint);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0 5px;
  white-space: nowrap;
  user-select: all;
}

/* ---- Message activity timeline (message detail dialog) -------------------
   AI runs and audit entries in one column, oldest first, so the life of a
   receipt reads as a sequence instead of two filtered tables. */
/* The tab strip above it already separates it from the header, so no rule here. */
.timeline-block { padding-block-start: var(--space-1, 4px); }

.timeline-error { color: var(--danger); }

.timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.tl-item {
  position: relative;
  padding-inline-start: var(--space-4);
  border-inline-start: 1px solid var(--border);
  padding-block-end: 2px;
}

.tl-dot {
  position: absolute;
  inset-inline-start: -4px;
  top: 6px;
  width: 7px;
  height: 7px;
  border-radius: var(--radius-full);
  background: var(--faint);
}

.tl-ai .tl-dot { background: var(--color-info, var(--accent)); }
.tl-audit .tl-dot { background: var(--color-success, var(--accent)); }

.tl-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.tl-clickable { cursor: pointer; }

.tl-title { font-size: var(--text-sm); font-weight: var(--weight-medium); }

.tl-sub {
  font-size: var(--text-xs);
  color: var(--muted);
  overflow-wrap: anywhere;
}

.tl-head .time { margin-inline-start: auto; white-space: nowrap; }

.tl-change { margin-block-start: 4px; font-size: var(--text-sm); flex-wrap: wrap; }

.tl-reason {
  margin: 4px 0 0;
  font-size: var(--text-xs);
  color: var(--muted);
}

.tl-error-preview {
  margin: 4px 0 0;
  font-size: var(--text-xs);
  color: var(--danger);
  overflow-wrap: anywhere;
}

.tl-detail {
  margin-block-start: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* The side panel is tabbed: details, receipt, AI runs and changes answer
   different questions, and a busy receipt has enough audit rows to bury the rest
   if they share one column. The message itself stays visible beside them. */
.tl-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1, 4px);
  margin-block: 0 var(--space-3);
  border-block-end: 1px solid var(--border);
  /* The side panel scrolls, so the strip stays put; it has to carry the dialog's
     own background or rows scroll through it. */
  position: sticky;
  top: calc(var(--space-4) * -1);
  z-index: 1;
  padding-block: var(--space-4) 0;
  margin-block-start: calc(var(--space-4) * -1);
  background: var(--color-surface-raised);
}

.tl-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: none;
  border-block-end: 2px solid transparent;
  margin-block-end: -1px;
  padding: 4px var(--space-2);
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  cursor: pointer;
}

.tl-tab:hover { color: var(--text); }

.tl-tab.active {
  color: var(--text);
  border-block-end-color: var(--accent);
  font-weight: var(--weight-semibold);
}

.tl-count {
  font-size: var(--text-2xs);
  color: var(--faint);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  padding: 0 6px;
}

.tl-count.failed { color: var(--danger); border-color: currentColor; background: transparent; }

/* ============================================================
   Sign-in — the login screen, the boot placeholder that stands in
   while /api/session answers, and the account controls in the topbar
   ============================================================ */

/* Shown for the one request it takes to learn whether there is a session.
   Without it every reload of a signed-in tab would flash the login card. */
.boot {
  min-height: 100vh;
  display: grid;
  place-items: center;
  color: var(--faint);
  font-size: var(--text-sm);
}

.login-screen {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--space-5);
  background:
    radial-gradient(60rem 30rem at 50% -10%, var(--accent-soft), transparent 70%),
    var(--bg);
}

.login-card {
  width: min(380px, 100%);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6) var(--space-5);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-3);
}

.login-brand {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--text-xl);
}

.login-brand .subtitle {
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  color: var(--faint);
  text-transform: uppercase;
  letter-spacing: var(--track-wider);
}

.login-lede {
  margin: calc(var(--space-3) * -1) 0 0;
  font-size: var(--text-sm);
  color: var(--muted);
}

.login-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.login-field > span {
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--muted);
}

.login-field input { width: 100%; }
.login-field small { font-size: var(--text-2xs); color: var(--faint); }

.login-error {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--danger);
}

.login-ok {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--accent);
}

.login-submit { justify-content: center; padding: var(--space-3) var(--space-4); }

.login-foot {
  margin: 0;
  display: flex;
  justify-content: center;
  min-height: 1.2em;
}

.login-foot .release {
  font-family: var(--mono);
  font-size: var(--text-2xs);
  color: var(--faint);
}


.password-dialog { width: min(420px, 100%); }

.password-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
}

.password-body .more.primary { justify-content: center; padding: var(--space-3) var(--space-4); }

/* The account menu. Replaces a bare name that opened a dialog and an unlabelled
   door icon: one control, two named actions, and ~50px less top bar. */
.user-menu { position: relative; display: flex; }

.user-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 16ch;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--muted);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  padding: var(--space-1) var(--space-3) var(--space-1) var(--space-4);
  transition:
    color var(--duration-fast) var(--ease-standard),
    border-color var(--duration-fast) var(--ease-standard);
}

.user-chip:hover,
.user-chip.open { color: var(--text); border-color: var(--border-strong); }

.user-chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.user-chip-caret {
  flex: none;
  opacity: 0.7;
  transition: transform var(--duration-fast) var(--ease-standard);
}

.user-chip.open .user-chip-caret { transform: rotate(180deg); }

.user-menu-panel {
  position: absolute;
  z-index: var(--z-dropdown, 500);
  top: calc(100% + 6px);
  inset-inline-end: 0;
  min-width: 200px;
  padding: var(--space-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
}

/* Names the account in full, so the chip itself can stay short. */
.user-menu-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-2) var(--space-3) var(--space-3);
  margin-bottom: var(--space-2);
  border-bottom: 1px solid var(--border);
}

.user-menu-head strong { font-size: var(--text-sm); }
.user-menu-head span { font-size: var(--text-2xs); color: var(--faint); font-family: var(--mono); }

.user-menu-item {
  display: block;
  width: 100%;
  text-align: start;
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  color: var(--muted);
  transition:
    background-color var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard);
}

.user-menu-item:hover { background: var(--overlay); color: var(--text); }

/* ---- Top bar fit ----
   The bar has always been allowed to wrap to a second row on small screens.
   What changed is where that starts: the account controls widened it, and a
   ~1270px viewport (1080p at 150% Windows scaling) landed on the wrong side of
   the line. The decorative subtitle now stands down below 1280, which buys back
   more than the menu costs. Below that the right-hand group still stays whole --
   nowrap keeps the controls from stacking among themselves, and the status text
   clips rather than pushing them apart. */
.topbar-right { flex-wrap: nowrap; min-width: 0; }

.topbar-right .badge {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.topbar-right .badge::before { flex: none; }

@media (max-width: 1280px) {
  .topbar h1 .subtitle { display: none; }
}
