@import "tailwindcss";
@import "tailwindcss-primeui";

/* ==========================================================================
   KeluargaMart family design tokens — ERP
   Mode: Operate. Density and scanability outrank expression.
   See DESIGN.md at the repo root for the usage rules these tokens encode.
   ========================================================================== */

@theme {
  --font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* ---- Type scale -------------------------------------------------------
     `label` is the only mono step; pair it with `font-mono`.
     `micro` legitimises the 11px stamps this app already relies on. */
  --text-headline: 1.5rem;
  --text-headline--line-height: 1.25;
  --text-headline--font-weight: 600;
  --text-headline--letter-spacing: -0.015em;

  --text-title: 1.125rem;
  --text-title--line-height: 1.4;
  --text-title--font-weight: 600;

  --text-body: 0.875rem;
  --text-body--line-height: 1.5;
  --text-body--font-weight: 400;

  --text-body-sm: 0.8125rem;
  --text-body-sm--line-height: 1.45;
  --text-body-sm--font-weight: 400;

  --text-label: 0.75rem;
  --text-label--line-height: 1.33;
  --text-label--font-weight: 500;
  --text-label--letter-spacing: 0.04em;

  --text-micro: 0.6875rem;
  --text-micro--line-height: 1.3;
  --text-micro--font-weight: 500;

  --text-badge: 0.625rem;
  --text-badge--line-height: 1.3;
  --text-badge--font-weight: 600;

  --text-tiny: 0.5625rem;
  --text-tiny--line-height: 1.3;
  --text-tiny--font-weight: 600;

  /* ---- Spacing ----------------------------------------------------------
     4px base. Permitted steps: 4 8 12 16 20 24 32 40 48
     (= 1 2 3 4 5 6 8 10 12). p-5 / py-3 rhythm is legal by design. */
  --spacing: 4px;

  /* ---- Surfaces -------------------------------------------------------- */
  --color-background: #f5f8ff;
  --color-surface: #ffffff;
  --color-surface-muted: #eef3fa;

  /* ---- Lines ----------------------------------------------------------- */
  --color-border: #d9e2f0;
  --color-border-strong: #bccbe4;

  /* ---- Ink ------------------------------------------------------------
     ink          primary text, every surface
     ink-muted    secondary text, every surface (7.0:1 on #F5F8FF)
     ink-subtle   #FFFFFF only (4.76:1) — never on page or muted surfaces
     ink-disabled NON-TEXT only: disabled controls, ≥24px icons, rules */
  --color-ink: #14213d;
  --color-ink-muted: #475569;
  --color-ink-subtle: #64748b;
  --color-ink-disabled: #94a3b8;

  /* ---- Brand scale ----------------------------------------------------- */
  --color-brand-50: #f0f5ff;
  --color-brand-100: #dce7fc;
  --color-brand-200: #c4d4f5;
  --color-brand-300: #9db8ea;
  --color-brand-400: #28459a;
  --color-brand-500: #142b80;
  --color-brand-600: #102268;
  --color-brand-700: #071f68;
  --color-brand-800: #051952;
  --color-brand-900: #04123d;

  /* ---- Status tones: fg / soft / line ---------------------------------- */
  --color-primary: #142b80;
  --color-primary-hover: #102268;
  --color-primary-soft: #dce7fc;
  --color-primary-border: #c4d4f5;

  --color-success: #15803d;
  --color-success-soft: #ecfaf0;
  --color-success-border: #bbf7d0;

  --color-warning: #b45309;
  --color-warning-soft: #fff8eb;
  --color-warning-border: #fde68a;

  --color-danger: #c0372c;
  --color-danger-hover: #9c2c23;
  --color-danger-soft: #fbe7e4;
  --color-danger-border: #f3c6c0;

  --color-info: #0e7490;
  --color-info-soft: #ecfeff;
  --color-info-border: #a5f3fc;

  --color-neutral: #475569;
  --color-neutral-soft: #eef3fa;
  --color-neutral-border: #d9e2f0;

  /* ---- Radius: badge 8 · button/input 8 · card 12 · modal 16 ---------- */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 8px;
  --radius-xl: 12px;
  --radius-2xl: 16px;

  /* ---- Elevation, navy-tinted ----------------------------------------- */
  --shadow-card: 0 1px 2px rgb(20 33 61 / 0.04), 0 1px 3px rgb(20 33 61 / 0.06);
  --shadow-popover: 0 6px 20px rgb(20 33 61 / 0.1), 0 1px 3px rgb(20 33 61 / 0.06);
  --shadow-modal: 0 16px 48px rgb(20 33 61 / 0.18), 0 4px 12px rgb(20 33 61 / 0.08);
}

@layer base {
  *,
  ::before,
  ::after {
    border-color: var(--color-border);
  }

  html {
    -webkit-text-size-adjust: 100%;
  }

  body {
    background-color: var(--color-background);
    color: var(--color-ink);
    font-family: var(--font-sans);
    font-size: var(--text-body);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    min-height: 100dvh;
    overflow-x: hidden;
  }

  ::selection {
    background: var(--color-primary-soft);
    color: var(--color-primary);
  }

  button {
    cursor: pointer;
  }

  /* One focus treatment for every interactive element in the app, including
     the ~40 hand-rolled buttons in the sidebar, topbar, table headers and
     pagination that never declared one. The outline follows each element's
     own border-radius, so nothing is restyled beyond the ring itself. */
  a:focus-visible,
  button:focus-visible,
  input:focus-visible,
  select:focus-visible,
  textarea:focus-visible,
  summary:focus-visible,
  [role="button"]:focus-visible,
  [tabindex]:not([tabindex="-1"]):focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
  }

  /* Thin, quiet scrollbars */
  * {
    scrollbar-width: thin;
    scrollbar-color: var(--color-border-strong) transparent;
  }
  *::-webkit-scrollbar {
    width: 8px;
    height: 8px;
  }
  *::-webkit-scrollbar-track {
    background: transparent;
  }
  *::-webkit-scrollbar-thumb {
    background: var(--color-border-strong);
    border-radius: 8px;
  }
  *::-webkit-scrollbar-thumb:hover {
    background: var(--color-ink-disabled);
  }
}

@utility tabular {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}

/* Retained for the components that already reference it; it now emits the
   same outline as the global rule so focus looks identical everywhere. */
@utility focus-ring {
  &:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
  }
}

@utility no-scrollbar {
  scrollbar-width: none;
  &::-webkit-scrollbar {
    display: none;
  }
}

/* Skip link: visible only once focused. */
@utility skip-link {
  position: absolute;
  left: 12px;
  top: -100px;
  z-index: 80;
  border-radius: var(--radius-lg);
  background: var(--color-primary);
  color: #fff;
  padding: 8px 16px;
  font-size: var(--text-body-sm);
  font-weight: 600;
  &:focus-visible {
    top: 12px;
  }
}

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

  /* A frozen spinner is a broken loading indicator — slow it, don't stop it. */
  .animate-spin {
    animation-duration: 1.6s !important;
    animation-iteration-count: infinite !important;
  }
}

/* Compact & responsive Select overlay for PrimeVue across ERP */
.p-select-overlay {
  max-width: min(calc(100vw - 2rem), 480px) !important;
  border-radius: 0.75rem !important;
  font-size: 0.8125rem !important;
}

.p-select-list-container {
  max-height: 12rem !important;
}

@media (min-width: 640px) {
  .p-select-list-container {
    max-height: 15rem !important;
  }
}

.p-select-option {
  padding: 0.375rem 0.625rem !important;
  font-size: 0.75rem !important;
  line-height: 1.25rem !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
}

.p-select-option span,
.p-select-option div {
  font-size: 0.75rem !important;
}

.p-select-filter-container {
  padding: 0.375rem 0.5rem !important;
}

.p-select-filter {
  height: 2rem !important;
  font-size: 0.75rem !important;
  padding: 0.25rem 0.5rem !important;
}

/* Report printing: strips the ERP app chrome (sidebar, topbar, footer,
   skip link, mobile overlay) so only the report body reaches the printer.
   Modal overlays without a printable document are hidden; the one modal
   holding a `.print-area` printable doc is stripped of overlay chrome and
   the page behind it is hidden, so the document prints instead of a blank
   modal or the underlying list. Forced color adjust keeps tints legible. */
@media print {
  .no-print,
  .skip-link,
  aside,
  header,
  footer {
    display: none !important;
  }

  /* Open modal overlays with no printable doc: hide entirely. */
  .fixed.inset-0:not(:has(.print-area)) {
    display: none !important;
  }

  /* Page behind an open printable modal: hide so only the doc prints and no blank page 1 is generated. */
  body:has(.print-area) #app,
  body:has(.fixed.inset-0 .print-area) #app,
  body:has(.fixed.inset-0 .print-area) #main,
  body:has(.fixed.inset-0 .print-area) aside,
  body:has(.fixed.inset-0 .print-area) header,
  body:has(.fixed.inset-0 .print-area) footer {
    display: none !important;
  }

  /* Printable modal: strip overlay chrome, flow as plain page. */
  .fixed.inset-0:has(.print-area) {
    position: static !important;
    display: block !important;
    padding: 0 !important;
    background: #fff !important;
    backdrop-filter: none !important;
    overflow: visible !important;
  }
  .fixed.inset-0:has(.print-area) > div {
    box-shadow: none !important;
    max-height: none !important;
    overflow: visible !important;
    border-radius: 0 !important;
    max-width: none !important;
    width: 100% !important;
    margin: 0 !important;
    border: 0 !important;
  }
  /* AppModal title bar + close button never print. */
  .fixed.inset-0:has(.print-area) > div > div:first-child {
    display: none !important;
  }
  /* AppModal slot container: remove max-height and scrolling for print so content flows */
  .fixed.inset-0:has(.print-area) > div > div {
    max-height: none !important;
    overflow: visible !important;
    padding: 0 !important;
  }

  #main {
    padding: 0 !important;
    max-width: none !important;
  }

  * {
    -webkit-print-color-adjust: exact !important;
    print-color-adjust: exact !important;
  }
}

/* ==========================================================================
   Data tables — scanability
   Reported 1 Nov: with money columns right-aligned and text columns
   left-aligned, and no vertical rule between them, the eye loses the row it
   is reading. Two cheap fixes at the component level, so every table in the
   app (KTable, KDataTable, the dashboard drilldowns) behaves the same:

   1. The header reads as a band: bold, tinted, with a solid rule underneath.
   2. A hairline vertical rule between columns, plus a hover tint, so a value
      can be traced back to its header without a ruler.

   Selectors are doubled (`.p-datatable .p-datatable-thead …`) on purpose:
   PrimeVue injects its own component styles at runtime, and a single-class
   rule loses that cascade no matter where the stylesheet sits in the bundle.
   ========================================================================== */
.p-datatable .p-datatable-table {
  /* Separate, not collapse: with collapse the vertical rule is drawn by the
     neighbouring cell and disappears on the first column. */
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
  table-layout: fixed;
}

/* Ensure data tables inside scroll containers maintain readable width on mobile without crushing columns */
@media (max-width: 640px) {
  .overflow-x-auto > table:not([style*="min-width"]):not([class*="min-w-"]),
  .overflow-auto > table:not([style*="min-width"]):not([class*="min-w-"]) {
    min-width: max(100%, 36rem);
  }
}

.p-datatable .p-datatable-thead > tr > th {
  font-weight: 700;
  letter-spacing: 0.02em;
  background: var(--color-surface-muted);
  border-bottom: 1px solid var(--color-border-strong);
  border-right: 1px solid var(--color-border);
  padding: 0.625rem 0.75rem;
}
.p-datatable .p-datatable-thead > tr > th:last-child {
  border-right: 0;
}

.p-datatable .p-datatable-tbody > tr > td {
  border-bottom: 1px solid var(--color-border);
  border-right: 1px solid var(--color-border);
  padding: 0.625rem 0.75rem;
  overflow-wrap: anywhere;
  word-break: normal;
}
.p-datatable .p-datatable-tbody > tr > td:last-child {
  border-right: 0;
}

.p-datatable .p-datatable-tbody > tr:hover > td {
  background: var(--color-surface-muted);
}

.p-datatable .p-datatable-thead > tr > th.p-datatable-column-frozen,
.p-datatable .p-datatable-tbody > tr > td.p-datatable-column-frozen {
  background-color: var(--color-surface);
}
.p-datatable .p-datatable-thead > tr > th.p-datatable-column-frozen {
  background-color: var(--color-surface-muted);
}
.p-datatable .p-datatable-tbody > tr:hover > td.p-datatable-column-frozen {
  background-color: var(--color-surface-muted);
}

.p-datatable.p-datatable-sm .p-datatable-thead > tr > th,
.p-datatable.p-datatable-sm .p-datatable-tbody > tr > td {
  padding: 0.375rem 0.5rem;
}

/* Digits must line up column-wise for money to be comparable at a glance. */
.p-datatable .p-datatable-tbody > tr > td .tabular,
.p-datatable .p-datatable-tbody > tr > td.p-numeric {
  font-variant-numeric: tabular-nums;
}
