/*
 * FSI theme — Expenses.
 * Canonical design tokens live in fsi-tokens.css (single source of truth for
 * the whole FSI ecosystem); imported first so the aliases below resolve.
 * The legacy --brand-* / --color-* / --font-* names remain as a thin
 * compatibility layer over the canonical --fsi-* schema.
 */
@import url("fsi-tokens.css");

:root {
  /* Legacy Expenses token names mapped onto the canonical --fsi-* schema.
     Values converge on fsi-tokens.css; app-specific tokens (buttons, hero,
     footer, shadow tint) with no canonical counterpart keep literal values. */

  /* Typography */
  --font-family-display: var(--fsi-font-display);
  --font-family-body: var(--fsi-font-body);
  --font-size-display-1: var(--fsi-fs-display-1);
  --font-size-display-2: var(--fsi-fs-display-2);
  --font-size-body-lg: var(--fsi-fs-body-lg);
  --font-size-body-md: var(--fsi-fs-body-md);
  --font-size-body-sm: var(--fsi-fs-body-sm);
  --line-height-display: var(--fsi-lh-display);
  --line-height-body: var(--fsi-lh-body);
  --font-weight-regular: var(--fsi-fw-regular);
  --font-weight-medium: var(--fsi-fw-medium);
  --font-weight-bold: var(--fsi-fw-bold);

  /* Brand ramp */
  --brand-primary: var(--fsi-primary);
  --brand-primary-alt: var(--fsi-primary-strong);
  --brand-secondary: var(--fsi-secondary);
  --brand-accent: var(--fsi-accent);
  --brand-neutral-900: var(--fsi-neutral-900);
  --brand-neutral-700: var(--fsi-neutral-700);
  --brand-neutral-500: var(--fsi-neutral-500);
  --brand-neutral-300: var(--fsi-neutral-300);

  /* Semantic colors */
  --color-bg: var(--fsi-surface);
  --color-surface: var(--fsi-white);
  --color-text: var(--fsi-text);
  --color-text-inverse: #ffffff;
  --color-border: var(--fsi-border);
  --color-muted: var(--fsi-muted);
  --color-primary: var(--fsi-primary);
  --color-primary-hover: var(--fsi-primary-strong);
  --color-secondary: var(--fsi-secondary);
  --color-accent: var(--fsi-accent);
  --color-link: var(--fsi-primary);
  --color-link-hover: var(--fsi-primary-strong);
  --color-danger: var(--fsi-danger);

  /* Buttons (app-specific composition of the brand tokens) */
  --button-primary-bg: var(--fsi-primary);
  --button-primary-bg-hover: var(--fsi-primary-strong);
  --button-primary-border: var(--fsi-primary);
  --button-primary-border-hover: var(--fsi-primary-strong);
  --button-primary-text: var(--color-text-inverse);
  --button-secondary-bg: color-mix(in srgb, var(--fsi-primary) 8%, transparent);
  --button-secondary-bg-hover: var(--fsi-primary);
  --button-secondary-border: color-mix(in srgb, var(--fsi-primary) 32%, transparent);
  --button-secondary-border-hover: var(--fsi-primary);
  --button-secondary-text: var(--fsi-primary);
  --button-secondary-text-hover: var(--color-text-inverse);

  /* App-specific surfaces */
  --color-footer-bg: var(--fsi-neutral-900);
  --color-hero-gradient: linear-gradient(135deg, var(--accent) 0%, var(--accent-hover) 100%);
  --color-hero-overlay: rgba(var(--color-shadow-rgb), 0.75);
  --color-shadow-rgb: 15, 23, 42;

  /* Spacing — base 1–4 are the Fleet UI Kit 4px scale as literals; 5–10 are
     app extensions. NOTE: do not write these as var(--fsi-space-N). The
     canonical bridge defines --fsi-space-N: var(--space-N), so aliasing
     --space-N back to it forms a circular reference that invalidates the
     whole scale (every gap/padding using var(--space-*) collapses to 0). */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-7: 2rem;
  --space-8: 2.5rem;
  --space-9: 3rem;
  --space-10: 4rem;

  /* Layout — page container width (Fleet UI Kit v1.6.0 "Wide Container").
     Fluid between today's ~1240px baseline and 1800px; replaces Bootstrap's
     stock stepped .container max-widths (540/720/960/1140/1320px) below,
     which left most pages sitting in the middle two-thirds of a wide
     monitor. A max-width never forces an element wider than its viewport,
     so this only raises the wide-desktop ceiling — breakpoints below
     1240px are untouched. */
  --container-max: clamp(1240px, 92vw, 1800px);

  /* Radius */
  --radius-sm: var(--fsi-radius-sm);
  --radius-md: var(--fsi-radius-md);
  --radius-lg: var(--fsi-radius-lg);
  --radius-pill: var(--fsi-radius-pill);

  /* Shadow */
  --shadow-sm: var(--fsi-shadow-sm);
  --shadow-md: var(--fsi-shadow-md);
  --shadow-lg: var(--fsi-shadow-lg);
}

[data-bs-theme='dark'],
[data-theme='dark'] {
  /* Core token dark values (bg, surface, text, border, muted, primary,
     secondary, accent, links) are inherited from fsi-tokens.css. Only the
     app-specific tokens below need explicit dark overrides. */
  --color-danger: var(--danger-label);
  /* The accent tokens already carry the FSI blue ramp in dark (--accent is
     the darkest blue, --accent-hover the primary), so the buttons follow
     them rather than a hard-coded dark palette. */
  --button-primary-bg: var(--accent);
  --button-primary-bg-hover: var(--accent-hover);
  --button-primary-border: var(--accent);
  --button-primary-border-hover: var(--accent-hover);
  --button-primary-text: var(--text);
  --button-secondary-bg: color-mix(in srgb, var(--accent-hover) 16%, transparent);
  --button-secondary-bg-hover: color-mix(in srgb, var(--accent-hover) 28%, transparent);
  --button-secondary-border: color-mix(in srgb, var(--accent-hover) 55%, transparent);
  --button-secondary-border-hover: var(--accent-hover);
  --button-secondary-text: var(--text);
  --button-secondary-text-hover: var(--text);
  --color-footer-bg: #061020;
  --color-hero-gradient: linear-gradient(135deg, #030f26 0%, var(--accent) 100%);
  --color-shadow-rgb: 0, 0, 0;
}


html {
  background-color: var(--color-bg);
  color: var(--color-text);
}

body {
  font-family: var(--font-family-body);
  background-color: var(--color-bg);
  color: var(--color-text);
}

/* Shared global form placeholder styling */
input::placeholder {
  color: #6c757d;
  opacity: 1;
}

.fsi-display {
  font-family: var(--font-family-display);
  font-size: var(--font-size-display-1);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-display);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.fsi-section-title {
  font-family: var(--font-family-display);
  font-size: var(--font-size-display-2);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-display);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.fsi-body {
  font-family: var(--font-family-body);
  font-size: var(--font-size-body-md);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-body);
  color: var(--color-text);
}

.fsi-body-muted {
  font-family: var(--font-family-body);
  font-size: var(--font-size-body-sm);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-body);
  color: var(--color-muted);
}

.fsi-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-md);
  border-radius: var(--radius-md);
}

.fsi-button-primary,
.fsi-button-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  font-weight: var(--font-weight-medium);
  line-height: 1.2;
  text-decoration: none;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease,
    box-shadow 0.2s ease;
}

.fsi-button-primary {
  background-color: var(--button-primary-bg);
  border-color: var(--button-primary-border);
  color: var(--button-primary-text);
}

.fsi-button-primary:hover {
  background-color: var(--button-primary-bg-hover);
  border-color: var(--button-primary-border-hover);
  color: var(--button-primary-text);
}

.fsi-button-primary:disabled,
.fsi-button-primary[aria-disabled='true'] {
  background-color: var(--color-border);
  border-color: var(--color-border);
  color: var(--color-muted);
  cursor: not-allowed;
}

.fsi-button-secondary {
  background-color: var(--button-secondary-bg);
  border-color: var(--button-secondary-border);
  color: var(--button-secondary-text);
}

.fsi-button-secondary:hover {
  background-color: var(--button-secondary-bg-hover);
  border-color: var(--button-secondary-border-hover);
  color: var(--button-secondary-text-hover);
}

.fsi-button-secondary:disabled,
.fsi-button-secondary[aria-disabled='true'] {
  border-color: var(--color-border);
  color: var(--color-muted);
  cursor: not-allowed;
}

.fsi-button-primary:focus-visible,
.fsi-button-secondary:focus-visible,
.fsi-navbar__menu a:focus-visible {
  outline: 3px solid var(--color-secondary);
  outline-offset: 2px;
}

.fsi-navbar {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}

.fsi-navbar__container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
}

.fsi-navbar__brand {
  color: var(--color-link);
  font-family: var(--font-family-display);
  letter-spacing: 0.04em;
  text-decoration: none;
  text-transform: uppercase;
}

.fsi-navbar__menu {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  list-style: none;
  margin: 0;
  padding: 0;
}

.fsi-navbar__menu a {
  color: var(--color-link);
  text-decoration: none;
}

.fsi-navbar__menu a:hover,
.fsi-navbar__menu a:focus {
  color: var(--color-link-hover);
}

.fsi-nav-action {
  --bs-btn-padding-y: 0.2rem;
  --bs-btn-padding-x: 0.55rem;
  --bs-btn-border-radius: var(--radius-sm);
  --bs-btn-font-size: var(--font-size-body-sm);
  --bs-btn-line-height: 1.2;
  --bs-btn-bg: var(--button-secondary-bg);
  --bs-btn-border-color: var(--button-secondary-border);
  --bs-btn-color: var(--button-secondary-text);
  --bs-btn-hover-bg: var(--button-secondary-bg-hover);
  --bs-btn-hover-border-color: var(--button-secondary-border-hover);
  --bs-btn-hover-color: var(--button-secondary-text-hover);
  --bs-btn-focus-shadow-rgb: var(--color-shadow-rgb);
  --bs-btn-active-bg: var(--button-secondary-bg-hover);
  --bs-btn-active-border-color: var(--button-secondary-border-hover);
  --bs-btn-active-color: var(--button-secondary-text-hover);
  min-height: 2rem;
  border-width: 1px;
  white-space: nowrap;
}

.fsi-nav-action.dropdown-toggle::after {
  margin-left: var(--space-2);
}

.fsi-navbar .navbar-collapse {
  overflow: visible;
}

@media (max-width: 991.98px) {
  .fsi-navbar__menu {
    align-items: flex-start;
    flex-direction: column;
    gap: var(--space-2);
    padding-top: var(--space-2);
  }

  .fsi-nav-action {
    justify-content: flex-start;
    width: 100%;
  }

  .fsi-navbar .dropdown-menu.dropdown-menu-end {
    left: 0;
    right: auto;
  }
}

.hero {
  background: var(--color-hero-gradient);
  color: var(--color-text-inverse);
  padding: var(--space-10) var(--space-7);
}

.hero .fsi-display {
  font-size: var(--font-size-display-1);
  line-height: var(--line-height-display);
}

.hero-overlay {
  background: var(--color-hero-overlay);
}

.form-control,
.form-select,
.form-check-input {
  background-color: var(--color-surface);
  color: var(--color-text);
  border-color: var(--color-border);
}

.form-control:focus,
.form-select:focus,
.form-check-input:focus {
  background-color: var(--color-surface);
  color: var(--color-text);
}

.form-control::placeholder {
  color: var(--color-muted);
  opacity: 0.7;
}

footer {
  background-color: var(--color-footer-bg);
  color: var(--color-text-inverse);
}

.fsi-badge {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--font-size-body-sm);
  padding: 0.2rem 0.55rem;
}

.fsi-badge-success {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.fsi-badge-primary {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.fsi-text-success {
  color: var(--color-accent);
}

.fsi-text-danger {
  color: var(--color-danger);
}

.fsi-navbar .dropdown-toggle {
  color: var(--color-link);
  text-decoration: none;
}

.fsi-navbar .dropdown-toggle:hover,
.fsi-navbar .dropdown-toggle:focus {
  color: var(--color-link-hover);
}

.fsi-navbar .dropdown-menu {
  max-width: min(20rem, calc(100vw - 2rem));
}

.fsi-navbar .dropdown-menu .dropdown-header strong {
  overflow-wrap: anywhere;
}

.table-responsive {
  width: 100%;
  overflow-x: auto;
}

.th-hint {
  display: block;
  font-size: 0.75rem;
  font-weight: 400;
  color: #6c757d;
  line-height: 1.4;
  margin-top: 4px;
}

.th-hint i {
  font-size: 0.85rem;
  margin-right: 4px;
  vertical-align: baseline;
}

.expense-lines-table th {
  vertical-align: top;
  min-width: 120px;
}

.expense-lines-table td[data-label='Actions'] {
  min-width: 7.5rem;
}

@media (max-width: 575.98px) {
  .th-hint {
    display: none !important;
  }
}

@media (max-width: 767.98px) {
  .expense-lines-wrapper {
    border: 0;
  }

  .expense-lines-table,
  .expense-lines-table thead,
  .expense-lines-table tbody,
  .expense-lines-table tr,
  .expense-lines-table th,
  .expense-lines-table td {
    display: block;
    width: 100%;
  }

  .expense-lines-table thead {
    display: none;
  }

  .expense-line-row {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-3);
    margin-bottom: var(--space-3);
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
  }

  .expense-lines-table td {
    border: 0;
    padding: var(--space-2) 0;
  }

  .expense-lines-table td::before {
    content: attr(data-label);
    display: block;
    font-size: var(--font-size-body-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-muted);
    margin-bottom: var(--space-1);
  }

  .expense-lines-table .form-control,
  .expense-lines-table .remove-line-btn,
  #add-line-btn,
  #expense-form [name='submit_action'] {
    width: 100%;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   Fleet UI Kit alignment  (canonical: ~/Repos/fleet-ui-kit/tokens.css)
   v1.1.0 "FSI Brand Standard" reinstates uppercase Bebas Neue display
   headings — the measured freightservices.net display type. (v1.0.0 was
   system-font-only and had retired them; that retirement is reverted.)
   The gold accent stays retired: the brand ramp is the single FSI blue.
   Appended last, so it wins the cascade over the legacy rules above.
   ══════════════════════════════════════════════════════════════════════ */
.fsi-display,
.fsi-section-title {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--fsi-text);
}

/* ══════════════════════════════════════════════════════════════════════
   Status-tint pattern (Fleet UI Kit v1.1.0)

   EXPENSES renders its status chips with Bootstrap contextual badge
   classes. Restyling them here converts every chip to the kit's
   translucent-tint pattern without touching markup: the fill is a
   translucent status color so it tracks the page surface, and only the
   label swaps between themes (the --*-label tokens flip in
   fsi-tokens.css). Never opaque pastels — they float on a dark surface.
   ══════════════════════════════════════════════════════════════════════ */
.badge.bg-success,
.badge.text-bg-success {
  background-color: var(--success-tint) !important;
  color: var(--success-label) !important;
}

.badge.bg-warning,
.badge.text-bg-warning {
  background-color: var(--warning-tint) !important;
  color: var(--warning-label) !important;
}

.badge.bg-danger,
.badge.text-bg-danger {
  background-color: var(--danger-tint) !important;
  color: var(--danger-label) !important;
}

.badge.bg-info,
.badge.text-bg-info {
  background-color: var(--info-tint) !important;
  color: var(--info-label) !important;
}

.badge.bg-secondary,
.badge.text-bg-secondary,
.badge.bg-dark,
.badge.text-bg-dark {
  background-color: var(--neutral-tint) !important;
  color: var(--neutral-label) !important;
}

/* bg-primary is brand, not status, so it takes an accent tint. */
.badge.bg-primary,
.badge.text-bg-primary {
  background-color: color-mix(in srgb, var(--accent) 12%, transparent) !important;
  color: var(--accent) !important;
}

/* The tint pattern carries legibility via the label token, so text-dark /
   text-light utilities paired with badges must not fight it. */
.badge.bg-success.text-dark,
.badge.bg-info.text-dark,
.badge.bg-secondary.text-dark,
.badge.bg-danger.text-light,
.badge.bg-dark.text-light {
  color: inherit;
}

.badge.bg-warning.text-dark {
  color: var(--warning-label) !important;
}

[data-bs-theme='dark'] .fsi-display,
[data-theme='dark'] .fsi-display,
[data-bs-theme='dark'] .fsi-section-title,
[data-theme='dark'] .fsi-section-title {
  color: var(--fsi-text);
}

/* Brand wordmark uses the single blue accent (not gold) in both themes. */
.fsi-navbar__brand-name {
  color: var(--fsi-primary);
}

[data-bs-theme='dark'] .fsi-navbar__brand-name,
[data-theme='dark'] .fsi-navbar__brand-name {
  color: var(--fsi-primary);
}

/* Primary button follows the accent tokens (retires hard-coded hovers). */
.fsi-button-primary:hover,
.fsi-button-primary:focus-visible {
  background-color: var(--fsi-primary-strong);
  border-color: var(--fsi-primary-strong);
  color: #fff;
}

/* ---------------------------------------------------------------------------
   Help center screenshots

   Rendered by templates/help/index.html for topics that declare a
   `screenshots` list in HELP_TOPICS (app/help.py). Images are served from
   app/theme/static/help/ via url_for('theme.static', ...) — this project has
   no app-level static folder.
   --------------------------------------------------------------------------- */
.fsi-help-figure {
  margin: var(--space-6) 0;
}

.fsi-help-screenshot {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

.fsi-help-figure figcaption {
  margin-top: var(--space-2);
  font-size: var(--font-size-sm, 0.875rem);
  line-height: 1.5;
}

[data-bs-theme='dark'] .fsi-help-screenshot,
[data-theme='dark'] .fsi-help-screenshot {
  /* Captures are light-mode; soften them so they don't glare in dark mode. */
  filter: brightness(0.92);
}

.fsi-help-zoom-hint {
  display: block;
  margin-top: var(--space-1);
  font-size: 0.8125rem;
  opacity: 0.75;
}

.fsi-help-figure a:focus-visible .fsi-help-screenshot {
  outline: 2px solid var(--fsi-primary);
  outline-offset: 2px;
}


/* ============================================================
   Error badge — shared error-state illustration ("Mongo")

   Source of truth: Fleet UI Kit, components/17-error-badge.html.
   Rendered by the Jinja macro in templates/partials/error_badge.html.

   Deliberately NOT `.badge` — that is Bootstrap's / the kit's status pill and a
   different component.

   No colour is declared here, on purpose. The artwork's ink is `currentColor`,
   so it inherits whatever --text resolved to for the active theme and one asset
   serves both light and dark. Declaring a colour here would break that.

   The SVG must be INLINED (the macro does this). Through <img src> or
   background-image an external SVG cannot see this page's CSS, `currentColor`
   falls back to black, and it stops adapting. Use the --mask variant if an
   external image is ever unavoidable.
   ============================================================ */
.fsi-error-badge {
  display: block;
  width: 100%;
  max-width: var(--fsi-error-badge-w, 22rem);
  margin: 0 auto var(--space-4);
}

.fsi-error-badge svg {
  display: block;
  width: 100%;
  height: auto;
}

/* Same adaptivity without inlining: paints a currentColor block through the
   artwork's alpha channel. Requires mongo-error-mask.png in theme static. */
.fsi-error-badge--mask {
  aspect-ratio: 1037 / 684;
  background-color: currentColor;
  -webkit-mask: var(--fsi-error-badge-mask) center / contain no-repeat;
          mask: var(--fsi-error-badge-mask) center / contain no-repeat;
}

/* Release-tier banner (RELEASE_POLICY.md §3) — shown only when FSI_TIER=test.
   Warning tint so it reads as "attention", in both themes, without shouting. */
.fsi-tier-banner {
  background-color: var(--warning-tint);
  color: var(--warning-label);
  border-bottom: 1px solid var(--warning);
  padding: 0.4rem 1rem;
  text-align: center;
  font-size: 0.9rem;
  line-height: 1.3;
}

.fsi-tier-banner strong {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: 1.05rem;
}

.fsi-tier-banner__build {
  margin-left: 0.75rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  opacity: 0.8;
}

/* Queue count badge — the red "waiting on you" pill on a nav queue link.
   Rendered by the Jinja macro in templates/partials/queue_badge.html and fed
   by app/services/queue_badges.py.

   Solid danger rather than the softer .badge.bg-danger tint above: this sits
   on an already-tinted secondary button, where a tint on a tint disappears.
   Sized in em so it tracks the nav button's own font size. */
.fsi-queue-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5em;
  height: 1.5em;
  padding: 0 0.42em;
  margin-left: 0.45em;
  border-radius: 999px;
  background-color: var(--danger);
  color: #fff;
  font-size: 0.78em;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  vertical-align: middle;
}

/* The danger red is fixed across light and dark, so the pill stays legible in
   both; the hairline just separates it from the button tint underneath. */
.fsi-nav-action .fsi-queue-badge {
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18);
}

/* ══════════════════════════════════════════════════════════════════════
   App-wide container width (Fleet UI Kit v1.6.0 --container-max)

   Bootstrap's default `.container` steps to a fixed max-width per
   breakpoint (540/720/960/1140/1320px), which left this app's pages
   confined to the middle of the screen on wide monitors — no override
   existed here at all before this token. A single unconditional rule is
   enough: --container-max is already a clamp(), so it scales fluidly
   between 1240px and 1800px without separate @media steps (contrast
   QUOTES's two-breakpoint version, written before the shared token
   existed). Bare `.container` (not `body .container`) is sufficient to
   win the cascade — base.html loads this file's <link> after Bootstrap's,
   so equal-specificity rules here already come later in source order.
   Only `.container` is touched; `.container-fluid` stays 100% by design.
   ══════════════════════════════════════════════════════════════════════ */
.container {
  max-width: var(--container-max);
}

/* Table density (fleet-ui-kit v1.7.0): Bootstrap's stock .5rem cell padding -> the
   suite pair. .table-sm is left compact on purpose. Loads after bootstrap.min.css. */
.table:not(.table-sm) > :not(caption) > * > * {
  padding: var(--cell-py) var(--cell-px);
}
