/* ============================================================================
   Self-hosted fonts (offline-first PWA). Subsets: latin, latin-ext, vietnamese.
   Space Grotesk + JetBrains Mono. No render-blocking network request.
   ============================================================================ */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/jetbrains-mono-400-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/jetbrains-mono-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/jetbrains-mono-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/jetbrains-mono-500-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/jetbrains-mono-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/jetbrains-mono-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/jetbrains-mono-600-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/jetbrains-mono-600-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/jetbrains-mono-600-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/space-grotesk-400-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/space-grotesk-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/space-grotesk-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/space-grotesk-500-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/space-grotesk-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/space-grotesk-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/space-grotesk-600-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/space-grotesk-600-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/space-grotesk-600-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/space-grotesk-700-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/space-grotesk-700-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/space-grotesk-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ============================================================================
   INCLUSIVA SOLUTIONS — Employee Portal
   Design tokens. Palette is taken from the company logo.

   COLOUR RULE (important, do not "tidy" this away):
   Brand BLUE leads the interface — buttons, links, active states.
   Brand GREEN confirms — paid, saved, success.
   Brand RED IS RESERVED FOR ALERTS ONLY — overdue deadlines and money
   warnings. If red is also used for ordinary buttons and headings, staff stop
   seeing it, and "PAST DUE" on a filing deadline becomes just another red
   thing on the screen. Keep red rare so it keeps meaning "stop and look".

   No web fonts: this is a PWA that must work on bad mobile data and offline.
   A render-blocking Google Fonts @import used to sit at the top of this file.
   ============================================================================ */

:root {
  color-scheme: light;

  --brand-blue: #3538cd;
  --brand-green: #2f9e57;
  --brand-red: #e5484d;

  --chrome: #ffffff;
  --chrome-2: #f6f7f9;
  --chrome-ink: #0b0f17;
  --chrome-muted: #5b6472;
  --chrome-border: #e9ebf0;

  --bg: #fbfbfc;
  --surface: #ffffff;
  --surface-strong: #ffffff;
  --surface-muted: #f6f7f9;
  --ink: #0b0f17;
  --muted: #5b6472;

  --primary: #3538cd;
  --primary-hover: #2a2ca6;
  --primary-ink: #ffffff;
  --primary-soft: #eef1fe;

  --success: #2f9e57;
  --success-soft: #e7f6ec;
  --danger: #e5484d;
  --danger-soft: #fdeceb;
  --warning: #b5852f;
  --warning-soft: #fbf1df;

  /* 2026-08-25: text colour to pair with --danger-soft / --warning-soft.
     These backgrounds flip per theme; the inks used to be hard-coded dark
     (#8c1e17 / #6d3d00), so on the dark translucent fills they were dark-on-dark
     at ~2:1 - the DEADLINE counters on Overview and Today were near-invisible. */
  --danger-ink: #8c1e17;
  --warning-ink: #6d3d00;

  /* Solid danger fills that carry text on top (destructive buttons, PAST DUE
     badges). --danger is tuned as a BORDER/accent colour; white text on it is only
     ~3.9:1 in light and ~2.8:1 in dark, so the fill gets its own value here and is
     paired with an ink that actually reads. */
  --danger-solid: #a3241e;
  --danger-solid-hover: #7e1a15;
  --on-danger-solid: #ffffff;

  --accent: var(--primary);
  --accent-soft: var(--primary-soft);

  --border: #e9ebf0;
  --border-strong: #dfe2ea;

  --shadow-xl: 0 1px 2px rgba(16, 24, 40, 0.06);
  --shadow-md: 0 1px 2px rgba(16, 24, 40, 0.05);

  --radius-xl: 14px;
  --radius-lg: 12px;
  --radius-md: 9px;

  --font-main: "Space Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur: 180ms;
  --dur-slow: 420ms;
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --brand-blue: #6c8cff;
  --brand-green: #4ec98a;
  --brand-red: #ff6b5e;

  --chrome: #0c1017;
  --chrome-2: #141a26;
  --chrome-ink: #eef2f8;
  --chrome-muted: #8b95a8;
  --chrome-border: #1d2431;

  --bg: #0a0d14;
  --surface: #10141d;
  --surface-strong: #141a26;
  --surface-muted: #141a26;
  --ink: #eef2f8;
  --muted: #8b95a8;

  --primary: #6c8cff;
  --primary-hover: #89a2ff;
  --primary-ink: #0a0d14;
  --primary-soft: rgba(108, 140, 255, 0.16);

  --success: #4ec98a;
  --success-soft: rgba(78, 201, 138, 0.15);
  --danger: #ff6b5e;
  --danger-soft: rgba(255, 107, 94, 0.15);
  --warning: #e2a53a;
  --warning-soft: rgba(226, 165, 58, 0.15);

  --danger-ink: #ff9b91;
  --warning-ink: #e8c078;

  --danger-solid: #ff6b5e;
  --danger-solid-hover: #ff9b91;
  --on-danger-solid: #240705;

  --accent: var(--primary);
  --accent-soft: var(--primary-soft);

  --border: #1d2431;
  --border-strong: #2a3342;

  --shadow-xl: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 1px 2px rgba(0, 0, 0, 0.4);
}

/* Respect the OS setting. Vestibular disorders make motion genuinely painful,
   and this is a work tool people cannot opt out of using. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

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

body {
  margin: 0;
  font-family: var(--font-main);
  /* Flat surface. The old triple radial-gradient "glow" tinted every screen
     blue and peach, which fought the logo and read as consumer-app decoration. */
  background: var(--bg);
  color: var(--ink);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

#app {
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 20px 96px;
}

/* Full-bleed chrome: the bar spans the viewport, its contents are re-centred to
   the same 1080px column as the content below it. */
.app-header {
  background: var(--chrome);
  border: 0;
  position: relative;
  padding: 0 20px;
  margin-bottom: 22px;
}

.app-header-inner {
  max-width: 1080px;
  margin: 0 auto;
  padding: 13px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

/* The signature: the logo's three colours as a rule under the header. This is
   the one piece of pure identity in the interface — it appears once, at the
   top, and nowhere else, so it reads as a mark rather than decoration. */
.app-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  border-radius: 0;
  background: var(--border);
}

.app-header .ghost {
  background: transparent;
  color: var(--chrome-ink);
  border-color: var(--chrome-border);
}

.app-header .ghost:hover:not(:disabled) {
  background: var(--chrome-2);
  border-color: var(--chrome-muted);
  color: var(--chrome-ink);
}

.app-header .lang-select {
  color: var(--chrome-muted);
}

.app-header .lang-select select {
  background: var(--chrome-2);
  color: var(--chrome-ink);
  border-color: var(--chrome-border);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.lang-select {
  display: grid;
  gap: 6px;
  font-size: 12px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--muted);
}

.lang-select select {
  min-width: 146px;
  padding: 9px 12px;
  border-radius: 10px;
  border: 1px solid var(--border);
  font-size: 13px;
  background: var(--surface);
  color: var(--ink);
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

/* The header sits on black, so the logo needs no chip or plate — it simply sits
   on its own background. */
.brand-mark {
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  object-fit: contain;
  border-radius: 0;
  background: transparent;
  border: 0;
  padding: 0;
}

.brand-logo {
  width: 34px;
  height: 34px;
  object-fit: contain;
}

.brand-text {
  font-size: 16px;
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: 0.005em;
  color: var(--chrome-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Sign-in screen: the full lockup, centred, on the light card. The artwork is
   transparent so it needs no plate behind it. */
.login-card {
  max-width: 440px;
  margin: 0 auto;
  text-align: center;
}

.login-logo {
  display: block;
  width: min(210px, 62vw);
  height: auto;
  margin: 4px auto 22px;
}

.login-card .form {
  text-align: left;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: 24px;
  box-shadow: var(--shadow-xl);
}

.card h1 {
  margin: 0;
  font-size: clamp(1.25rem, 1.6vw, 1.5rem);
  line-height: 1.25;
  font-weight: 650;
  letter-spacing: -0.015em;
}

.forms-toolbar {
  margin-top: 18px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.search-field {
  display: grid;
  gap: 8px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.search-field input {
  width: min(380px, 100%);
}

.forms-meta {
  margin: 0;
  font-size: 13px;
}

.grid {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(228px, 1fr));
  margin-top: 18px;
}

.intake-grid {
  margin-top: 18px;
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

.menu-grid {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.intake-path {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px;
  background: var(--surface-muted);
}

.intake-path h2 {
  margin: 0;
  font-size: 1.08rem;
  font-weight: 600;
}

.intake-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.client-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin: 18px 0 8px;
  flex-wrap: wrap;
  padding: 14px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: var(--surface-muted);
}

.client-form {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}

.client-form label {
  min-width: 180px;
}

/* Tiles are list rows, not floating cards. Flat, full-width, with a clear hover
   and a left accent that appears on hover so the row you are about to tap is
   unambiguous on a phone. */
.tile {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  background: var(--surface);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
  text-align: left;
  width: 100%;
  font-family: inherit;
  color: inherit;
}

.tile:hover {
  border-color: var(--primary);
  background: var(--primary-soft);
}

.tile:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.tile h3 {
  margin: 0;
  font-size: 0.975rem;
  font-weight: 620;
}

.tile-meta {
  margin-top: 10px;
  font-size: 12px;
  font-family: var(--font-main);
  color: var(--muted);
}

.tile-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}

.tile-badge {
  flex-shrink: 0;
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.tile-badge.ready {
  color: #0f4b25;
  background: #dafbe7;
}

.tile-badge.locked {
  color: #7f5300;
  background: #fff3d0;
}

.tile-badge.restricted {
  color: #8f1424;
  background: #ffe0e5;
}

.tile:hover {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--primary) 55%, var(--border));
  box-shadow: var(--shadow-md);
}

.tile.disabled {
  cursor: not-allowed;
  opacity: 0.86;
}

.tile.disabled:hover {
  transform: none;
  border-color: var(--border);
  box-shadow: none;
}

.muted {
  color: var(--muted);
  margin-top: 4px;
}

.form {
  display: grid;
  gap: 16px;
  margin-top: 18px;
}

label {
  display: grid;
  gap: 7px;
  font-weight: 500;
}

label span {
  font-size: 0.95rem;
}

.required-label::after {
  content: " *";
  color: var(--danger);
}

input,
select,
textarea {
  padding: 10px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-strong);
  /* 16px prevents iOS Safari from zooming the viewport on focus — staff fill
     these forms on phones, and the zoom-then-scroll dance loses their place. */
  font-size: 16px;
  font-family: inherit;
  color: var(--ink);
  background: var(--surface-strong);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
  min-height: 42px;
}

input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
}

textarea {
  min-height: 118px;
  resize: vertical;
}

.signature-field {
  display: grid;
  gap: 8px;
}

.signature-label {
  font-weight: 500;
}

.signature-canvas {
  width: 100%;
  min-height: 180px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: #fff;
  touch-action: none;
}

.signature-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

.signature-actions .ghost {
  padding: 8px 12px;
  font-size: 13px;
}

button {
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  padding: 10px 16px;
  font-weight: 600;
  cursor: pointer;
  font-size: 14px;
  font-family: inherit;
  /* Colour change only. Buttons that lift and float on hover read as a consumer
     app; staff tapping the same button 40 times a day want a steady target. */
  transition: background-color 0.15s ease, border-color 0.15s ease;
  min-height: 42px;
}

button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

button:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

.primary {
  background: var(--primary);
  color: var(--primary-ink);
  border-color: var(--primary);
}

.primary:hover:not(:disabled) {
  background: var(--primary-hover);
  border-color: var(--primary-hover);
}

.ghost {
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--border-strong);
}

.ghost:hover:not(:disabled) {
  background: var(--surface-muted);
  border-color: var(--primary);
  color: var(--primary);
}

/* Destructive / irreversible actions only. Deliberately NOT used for ordinary
   buttons — see the colour rule at the top of this file. */
.danger {
  background: var(--danger-solid);
  color: var(--on-danger-solid);
  border-color: var(--danger-solid);
}

.danger:hover:not(:disabled) {
  background: var(--danger-solid-hover);
  border-color: var(--danger-solid-hover);
}

/* `.hidden` is a utility, so it must beat whatever `display` a component sets on
   itself regardless of source order. Without !important this loses to any later
   rule of equal specificity — which is exactly what happened: `.tab-bar` sets
   `display: flex` 1100 lines further down, so the navigation stayed on screen on
   the sign-in page even though the JS had correctly added `.hidden`. The same
   trap applies to the profile tab panels. */
.hidden {
  display: none !important;
}

.form-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.progress-panel {
  margin-top: 16px;
  padding: 12px 14px;
  border-radius: var(--radius-md);
  background: var(--surface-muted);
  border: 1px solid var(--border);
}

.progress-topline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.progress-topline p {
  margin: 0;
}

.progress-track {
  margin-top: 8px;
  height: 10px;
  border-radius: 999px;
  overflow: hidden;
  background: rgba(22, 49, 111, 0.14);
}

.progress-fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: inherit;
  background: var(--primary);
  transition: width 0.25s ease;
}

.section-title {
  margin-top: 14px;
  margin-bottom: 2px;
  font-size: 17px;
  font-weight: 600;
}

.file-preview {
  margin-top: 8px;
  background: var(--accent-soft);
  border-radius: 12px;
  padding: 10px 12px;
  font-size: 13px;
  font-family: var(--font-main);
  color: #73400a;
  border: 1px solid rgba(236, 111, 12, 0.2);
}

.toast {
  position: fixed;
  /* sit above the fixed bottom tab bar (z-index 60, ~80px tall incl. safe area) */
  bottom: calc(92px + env(safe-area-inset-bottom, 0px));
  right: 22px;
  z-index: 120;
  max-width: min(420px, calc(100vw - 32px));
  background: var(--ink);
  color: #fff;
  padding: 12px 16px;
  border-radius: var(--radius-md);
  box-shadow: 0 4px 12px rgba(16, 24, 40, 0.18);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

/* A view that supplies its own heading (the client profile) leaves the card's
   h1 empty; collapse it so it does not reserve blank space above the content. */
.card h1:empty,
.card .form-header p:empty {
  display: none;
}

/* ============================================================================
   CRAFT LAYER — the details that separate a tool from a product.
   ============================================================================ */

/* TABULAR NUMBERS. Money in a column must align on the decimal point. With
   proportional digits, $600.00 and $47.62 sit at different widths and a column
   of figures looks ragged — the single clearest tell of amateur financial UI. */
.ov-value,
.today-stat-num,
.pay-row span,
.profile-value,
.receipt-line span,
.stamp-cell,
.ov-attn-meta,
.ov-stage-count {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  font-family: var(--font-mono);
}

/* Views arrive rather than appear. 12px is deliberately small: enough to read
   as motion, not so much that it feels like a page transition on every tap. */
#viewRoot > .card {
  animation: view-in var(--dur-slow) var(--ease) both;
}

@keyframes view-in {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* SKELETONS. A shape that matches what is coming, so the layout does not jump
   when data lands. Better than a spinner: it tells you what to expect. */
.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--surface-muted);
  border-color: transparent;
  min-height: 84px;
}

.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: var(--border);
  animation: shimmer 1.4s infinite;
}

@keyframes shimmer {
  to {
    transform: translateX(100%);
  }
}

/* ---- Forms Library ---- */
.forms-group {
  margin-bottom: 22px;
}

.forms-group-head {
  padding-bottom: 6px;
  border-bottom: 2px solid var(--border-strong);
  margin-bottom: 10px;
}

.forms-group-title {
  margin: 0;
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.01em;
}

.forms-group-note {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--muted);
}

.forms-section-title {
  margin: 16px 0 6px;
  font-size: 11px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

/* One form. Row on wide screens; the actions wrap under on a phone. */
.forms-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 11px 0;
  border-bottom: 1px solid var(--border);
}

.forms-row:last-child {
  border-bottom: 0;
}

.forms-row-main {
  min-width: 0;
  flex: 1 1 260px;
}

.forms-row-top {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.forms-num {
  font-size: 12px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: var(--primary);
  background: var(--primary-soft);
  padding: 2px 7px;
  border-radius: 4px;
  white-space: nowrap;
}

.forms-name {
  font-size: 14px;
  font-weight: 500;
}

.forms-tag {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  padding: 1px 7px;
  white-space: nowrap;
}

.forms-tag-es {
  color: var(--warning-ink);
  background: var(--warning-soft);
  border-color: var(--warning);
}

.forms-when {
  margin: 3px 0 0;
  font-size: 12px;
  color: var(--muted);
}

.forms-actions {
  display: flex;
  gap: 8px;
  flex: 0 0 auto;
  flex-wrap: wrap;
}

.forms-link {
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  color: var(--primary);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  padding: 7px 12px;
  white-space: nowrap;
  transition: background-color 0.15s var(--ease), border-color 0.15s var(--ease);
}

.forms-link:hover {
  background: var(--surface-muted);
  border-color: var(--primary);
}

.forms-link.primary-link {
  background: var(--primary);
  color: var(--primary-ink);
  border-color: var(--primary);
}

.forms-link.primary-link:hover {
  background: var(--primary-hover);
  border-color: var(--primary-hover);
}

.forms-empty {
  padding: 20px 0;
  text-align: center;
}

/* ---- In-app PDF viewer ---- */
.form-viewer-card {
  display: flex;
  flex-direction: column;
}

.form-frame-wrap {
  margin-top: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface-muted);
}

.form-frame {
  display: block;
  width: 100%;
  /* Fill most of the viewport so the form is usable without a cramped scroll.
     Falls back gracefully on short screens. */
  height: calc(100vh - 240px);
  min-height: 420px;
  border: 0;
}

.form-refbox {
  margin-top: 14px;
  padding: 28px 20px;
  text-align: center;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-muted);
}

.form-refbox p {
  margin: 0 0 14px;
}

.form-refbox a {
  display: inline-block;
}

.form-viewer-note {
  margin: 10px 0 0;
  font-size: 12px;
}

.forms-link-inline {
  color: var(--primary);
  font-weight: 600;
  text-decoration: underline;
}

/* On the desktop rail layout the header is fixed, so give the frame the room. */
@media (min-width: 1024px) {
  .form-frame {
    height: calc(100vh - 200px);
  }
}

/* ---- Overview: metric cards ---- */
.ov-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

.ov-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px;
  min-width: 0;
  transition: border-color var(--dur) var(--ease);
}

.ov-card-danger {
  border-color: var(--danger);
  background: var(--danger-soft);
}

.ov-label {
  margin: 0;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
}

.ov-card-danger .ov-label,
.ov-card-danger .ov-value,
.ov-card-danger .ov-note {
  color: var(--danger-ink);
}

.ov-value {
  margin: 6px 0 0;
  font-size: 23px;
  font-weight: 650;
  letter-spacing: -0.025em;
  line-height: 1.1;
  color: var(--ink);
}

.ov-note {
  margin: 4px 0 0;
  font-size: 11px;
  color: var(--muted);
}

/* ---- Overview: panels ---- */
.ov-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  margin-bottom: 10px;
}

@media (min-width: 760px) {
  .ov-grid {
    grid-template-columns: 1.5fr 1fr;
  }
}

.ov-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 15px;
  min-width: 0;
}

.ov-panel-title {
  margin: 0 0 13px;
  font-size: 13px;
  font-weight: 650;
  letter-spacing: -0.005em;
}

.ov-empty {
  margin: 0;
  font-size: 13px;
}

/* ---- Overview: collections chart ---- */
.ov-chart {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 92px;
}

.ov-bar-col {
  flex: 1;
  display: flex;
  align-items: flex-end;
  height: 100%;
  min-width: 0;
}

.ov-bar {
  width: 100%;
  background: #b9cbe4;
  border-radius: 3px 3px 0 0;
  /* Animated from 0 in JS on first paint. */
  transition: height var(--dur-slow) var(--ease);
}

.ov-bar-current {
  background: var(--primary);
}

.ov-axis {
  display: flex;
  justify-content: space-between;
  margin-top: 7px;
  font-size: 10px;
  color: var(--muted);
}

/* ---- Overview: cases by stage ---- */
.ov-stage {
  margin-bottom: 11px;
}

.ov-stage:last-child {
  margin-bottom: 0;
}

.ov-stage-head {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  margin-bottom: 5px;
}

.ov-stage-count {
  color: var(--muted);
}

.ov-stage-track {
  height: 5px;
  background: var(--surface-muted);
  border-radius: 3px;
  overflow: hidden;
}

.ov-stage-fill {
  height: 100%;
  background: var(--primary);
  border-radius: 3px;
  transition: width var(--dur-slow) var(--ease);
}

.ov-stage-done {
  background: var(--success);
}

/* ---- Overview: needs attention ---- */
.ov-attn {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}

.ov-attn:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.ov-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex: 0 0 auto;
}

.ov-dot-danger {
  background: var(--danger);
}

.ov-dot-warn {
  background: var(--warning);
}

.ov-dot-info {
  background: var(--primary);
}

.ov-attn-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ov-attn-meta {
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--muted);
}

.ov-attn-overdue {
  color: var(--danger-ink);
  font-weight: 600;
}

/* ---- Client profile: identity spine ---- */
.profile-id {
  display: flex;
  align-items: center;
  gap: 13px;
  padding-bottom: 14px;
}

.profile-avatar {
  width: 46px;
  height: 46px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--primary-soft);
  color: var(--primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 650;
  letter-spacing: 0.02em;
}

.profile-id-text {
  min-width: 0;
}

.profile-id-name {
  margin: 0;
  font-size: 18px;
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1.25;
}

.profile-id-meta {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--muted);
}

.profile-quick {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  padding-bottom: 16px;
}

.profile-quick button {
  flex: 1 1 auto;
  min-width: 120px;
}

/* ---- Client profile: tabs ---- */
.profile-tabs {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 18px;
  overflow-x: auto;
  scrollbar-width: none;
}

.profile-tabs::-webkit-scrollbar {
  display: none;
}

.profile-tab {
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  color: var(--muted);
  font-size: 14px;
  font-weight: 600;
  padding: 10px 14px;
  white-space: nowrap;
  min-height: 0;
}

.profile-tab:hover:not(.active) {
  color: var(--ink);
}

.profile-tab.active {
  color: var(--primary);
  border-bottom-color: var(--primary);
}

.profile-panel > .profile-section:first-child {
  margin-top: 0;
}

/* ---- Today: count strip ----
   The whole picture before any scrolling. Only the deadline cell can take a
   colour, and only when it is non-zero — a strip of four coloured tiles would
   be wallpaper, and the one number that means "a client loses their case"
   would stop standing out. */
.today-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin: 0 0 20px;
}

.today-stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 10px 8px;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.today-stat-danger {
  background: var(--danger-soft);
  border-color: var(--danger);
}

.today-stat-num {
  font-size: 20px;
  font-weight: 650;
  line-height: 1.1;
  color: var(--ink);
}

.today-stat-danger .today-stat-num,
.today-stat-danger .today-stat-label {
  color: var(--danger-ink);
}

.today-stat-label {
  font-size: 11px;
  line-height: 1.25;
  color: var(--muted);
  overflow-wrap: anywhere;
}

.today-allclear {
  margin: 4px 0 0;
  padding: 14px;
  text-align: center;
  font-size: 13px;
  background: var(--surface-muted);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
}

/* The deadline section's marker is the only one that turns red. */
.section-danger .profile-heading::before {
  background: var(--danger);
}

/* Legal deadlines. Urgency is carried by the WORDS ("PAST DUE", "TODAY") as well
   as the colour — colour alone fails for colour-blind staff and vanishes in print. */
.deadline-row {
  margin: 6px 0;
  padding: 8px 12px;
  border-left: 3px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-muted);
  font-size: 14px;
}

.deadline-row.deadline-soon {
  border-left-color: var(--warning);
  background: var(--warning-soft);
  color: var(--warning-ink);
}

.deadline-row.deadline-today {
  border-left-color: var(--danger);
  background: var(--danger-soft);
  color: var(--danger-ink);
  font-weight: 600;
}

.deadline-row.deadline-overdue {
  border-left-width: 4px;
  border-left-color: var(--danger);
  background: var(--danger-soft);
  color: var(--danger-ink);
  font-weight: 700;
}

/* Deadline tiles on Today. Same semantics as the rows above, applied to the
   whole tile so an overdue case is obvious while scrolling a list. */
.deadline-tile.deadline-soon {
  border-left: 4px solid var(--warning);
}

.deadline-tile.deadline-today,
.deadline-tile.deadline-overdue {
  border-left: 4px solid var(--danger);
  background: var(--danger-soft);
}

.deadline-tile.deadline-overdue:hover,
.deadline-tile.deadline-today:hover {
  background: #fbdedb;
  border-color: var(--danger);
}

.deadline-tile.deadline-overdue .case-badge,
.deadline-tile.deadline-today .case-badge {
  background: var(--danger-solid);
  color: var(--on-danger-solid);
  border-color: var(--danger-solid);
}

/* In-app confirm dialog (replaces window.confirm on money actions).
   z-index sits above the toast (120) so a toast can never cover the buttons. */
.confirm-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(10, 13, 19, 0.55);
}

.confirm-box {
  width: min(420px, 100%);
  /* 2026-08-25: white modal + var(--ink) text = unreadable confirm dialogs in dark. */
  background: var(--surface);
  border-radius: 14px;
  padding: 22px;
  box-shadow: 0 18px 44px rgba(10, 13, 19, 0.32);
}

.confirm-title {
  margin: 0 0 8px;
  font-size: 1.05rem;
}

.confirm-message {
  margin: 0 0 18px;
  color: var(--muted, #5b6472);
  line-height: 1.45;
}

.confirm-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}

/* Provider signature pad (Log Check) */
.sig-wrap {
  margin: 12px 0;
}

.sig-canvas {
  display: block;
  width: 100%;
  max-width: 480px;
  height: 150px;
  background: #ffffff;
  border: 1.5px dashed var(--border, #c4ccd8);
  border-radius: 10px;
  touch-action: none;
  cursor: crosshair;
  margin: 6px 0;
}

/* Stamp sheet (printable payment schedule) */
.stamp-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 14px;
}

.stamp-table th,
.stamp-table td {
  border: 1px solid #444;
  padding: 8px 10px;
  font-size: 13px;
  text-align: left;
}

.stamp-table th {
  background: #eef2f1;
}

.stamp-cell {
  width: 130px;
  height: 56px;
}

.stamp-copy-label {
  margin: 0 0 10px;
  padding: 6px 10px;
  border: 1px dashed #444;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-align: center;
  background: #eef2f1;
}

/* On screen, separate the two copies so they don't read as one long sheet. */
.stamp-sheet + .stamp-sheet {
  margin-top: 28px;
}

@media print {
  .stamp-sheet .stamp-table th {
    background: #fff !important;
  }
  .stamp-table td,
  .stamp-table th {
    border: 1px solid #000 !important;
  }
  .stamp-copy-label {
    background: #fff !important;
    border: 1px dashed #000 !important;
  }
  /* Client copy and office copy each get their own sheet of paper. */
  .stamp-sheet + .stamp-sheet {
    margin-top: 0;
    break-before: page;
    page-break-before: always;
  }
  .stamp-sheet {
    break-inside: avoid-page;
  }
}

.toast.show {
  opacity: 1;
  transform: translateY(0);
}

@media (max-width: 860px) {
  #app {
    padding: 24px 16px 48px;
  }

  .app-header {
    flex-direction: column;
    align-items: flex-start;
  }

  .header-actions {
    width: 100%;
    justify-content: space-between;
  }
}

@media (max-width: 640px) {
  .card {
    padding: 16px;
    border-radius: var(--radius-lg);
  }

  .form-header {
    flex-direction: column-reverse;
    align-items: flex-start;
  }

  .forms-toolbar {
    align-items: stretch;
  }

  .search-field input {
    width: 100%;
  }

  .client-form {
    width: 100%;
  }

  .intake-actions button {
    width: 100%;
  }

  .client-form button,
  .client-form label,
  .header-actions .ghost,
  .lang-select select {
    width: 100%;
  }

  .header-actions {
    flex-direction: column;
    align-items: stretch;
  }

  .tile-top {
    flex-direction: column;
    align-items: flex-start;
  }

  .signature-actions {
    align-items: stretch;
  }

  .signature-actions .ghost {
    width: 100%;
  }
}

/* ---- Client lookup & profile ---- */

.client-tile {
  text-align: left;
}

/* ---- Section framing (profile, today, money) ---- */
.profile-section {
  margin-top: 26px;
  padding: 20px;
  background: var(--surface-strong);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: 0 6px 16px rgba(19, 33, 68, 0.05);
}

.profile-heading {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 14px;
}

/* Section markers echo the header rule at small scale. Neutral by default so
   they organise rather than shout; the deadline section overrides to red below,
   which is the only place the marker carries urgency. */
.profile-heading::before {
  content: "";
  width: 3px;
  height: 15px;
  border-radius: 0;
  background: var(--brand-blue);
  flex: 0 0 auto;
}

.profile-subheading {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 16px 0 4px;
}

.profile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 14px 24px;
}

.profile-row {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 10px 12px;
  background: rgba(245, 249, 255, 0.6);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.profile-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
}

.profile-value {
  font-weight: 600;
  font-size: 15px;
  overflow-wrap: anywhere;
}

/* ---- Case blocks & badges ---- */
.case-block {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px 18px;
  margin-top: 14px;
  background: var(--surface);
}

.case-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.case-head h2,
.case-head h3 {
  margin: 0;
}

/* Neutral by default. A badge is a label, not an alarm — colouring every stage
   chip orange made real warnings compete with routine metadata. */
.case-badge {
  font-size: 11px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--surface-muted);
  color: var(--muted);
  border: 1px solid var(--border-strong);
  white-space: nowrap;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

/* When a service form is opened from a specific case ("Add a document to this
   case"), the status line makes that scope obvious so staff don't file paperwork
   against the wrong case. */
.client-status-case {
  color: var(--text);
  font-weight: 600;
  border-left: 3px solid var(--brand-blue, #2b5ea7);
  padding-left: 10px;
}

.case-notes {
  white-space: pre-line;
  padding: 12px 14px;
  background: rgba(245, 249, 255, 0.6);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

/* ---- Documents ---- */
.doc-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  margin-top: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  flex-wrap: wrap;
}

.doc-info p {
  margin: 3px 0 0;
}

.doc-link {
  text-decoration: none;
  padding: 8px 14px;
  border-radius: 10px;
  font-weight: 600;
  font-size: 13px;
}

/* ---- Payment schedule table ---- */
.pay-row {
  display: grid;
  grid-template-columns: 2.6rem 1.2fr 1fr 1fr 1.2fr auto;
  gap: 10px;
  padding: 10px 12px;
  align-items: center;
  border-radius: 10px;
}

.pay-row:not(.pay-head):nth-child(odd) {
  background: rgba(245, 249, 255, 0.55);
}

.pay-head {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
  margin-top: 12px;
  border-bottom: 1px solid var(--border-strong);
  border-radius: 0;
  padding-bottom: 8px;
}

.pay-paid {
  color: var(--success);
  font-weight: 700;
  background: var(--success-soft);
  border: 1px solid var(--success);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 12px;
  justify-self: start;
}

.pay-due {
  color: var(--muted);
  font-weight: 600;
  background: var(--surface-muted);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 12px;
  justify-self: start;
}

.pay-btn {
  padding: 7px 14px;
  font-size: 12px;
  font-weight: 600;
  border-radius: 10px;
}

/* ---- Forms (plans, case detail, money) ---- */
.plan-form,
.detail-controls {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 14px;
  align-items: end;
  margin: 14px 0 4px;
  padding: 18px;
  /* 2026-08-25: was hard-coded #fff, so this panel stayed WHITE in dark mode.
     --surface is #ffffff in light, so light mode is byte-identical. */
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.plan-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.plan-field span {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
}

.plan-field input,
.plan-field select,
.plan-field textarea {
  padding: 11px 12px;
  border-radius: 10px;
  border: 1px solid var(--border-strong);
  font: inherit;
  font-size: 14px;
  /* 2026-08-25: was #fff while color stays var(--ink) — in dark mode that is
     near-white text on a white box, i.e. every typed value was INVISIBLE. */
  background: var(--surface);
  color: var(--ink);
}

.plan-field input:focus,
.plan-field select:focus,
.plan-field textarea:focus {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
  border-color: var(--primary);
}

.plan-field input[readonly] {
  background: var(--accent-soft);
  border-color: rgba(236, 111, 12, 0.3);
  font-weight: 700;
  color: var(--accent);
}

.detail-controls .full-width,
.plan-form .full-width {
  grid-column: 1 / -1;
}

.plan-form > button,
.detail-controls > button {
  justify-self: start;
  min-width: 170px;
}

.money-form {
  margin-bottom: 6px;
}

.today-empty {
  margin: 2px 0 0;
  padding: 10px 12px;
  background: rgba(245, 249, 255, 0.6);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md);
}

/* ---- Receipt ---- */
.receipt-paper {
  max-width: 460px;
  margin: 18px auto;
  padding: 28px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  background: #fff;
  color: #14181f;
  box-shadow: var(--shadow-md);
}

.receipt-company h2 {
  margin: 0 0 4px;
  font-size: 22px;
}

.receipt-company p {
  margin: 0;
  font-size: 13px;
  color: var(--muted);
  line-height: 1.5;
}

.receipt-paper hr {
  border: none;
  border-top: 1px solid var(--border);
  margin: 16px 0;
}

.receipt-heading {
  font-size: 26px;
  margin: 4px 0 12px;
}

.receipt-line {
  margin: 8px 0;
  font-size: 15px;
}

.receipt-paid {
  font-weight: 700;
  color: #15803d;
  font-size: 17px;
  margin: 16px 0 8px;
}

.receipt-thanks {
  margin: 8px 0 26px;
  color: var(--muted);
}

.receipt-signature {
  margin-top: 20px;
  font-weight: 600;
}

.receipt-card > .primary {
  display: block;
  margin: 0 auto;
  min-width: 220px;
}

@media print {
  .app-header,
  .no-print,
  .toast {
    display: none !important;
  }
  body,
  #app {
    background: #fff !important;
  }
  .card.receipt-card {
    box-shadow: none !important;
    border: none !important;
    padding: 0 !important;
    background: #fff !important;
  }
  .receipt-paper {
    border: none;
    box-shadow: none;
    max-width: none;
    margin: 0;
  }
}

@media (max-width: 640px) {
  .pay-row {
    grid-template-columns: 2rem 1fr 1fr auto;
  }
  .pay-row span:nth-child(4),
  .pay-row span:nth-child(5) {
    display: none;
  }
  .pay-row.pay-head span:nth-child(4),
  .pay-row.pay-head span:nth-child(5) {
    display: none;
  }
  .pay-row .pay-paid,
  .pay-row .pay-due {
    display: inline-flex;
  }
}

/* ---- Bottom tab bar ---- */
#app {
  padding-bottom: 104px;
}

.tab-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-around;
  align-items: center;
  gap: 4px;
  padding: 6px 8px calc(8px + env(safe-area-inset-bottom, 0px));
  background: var(--chrome);
  border-top: 0;
  z-index: 60;
}

/* ============================================================================
   RESPONSIVE SHELL — phone · tablet · desktop

   The navigation is ONE piece of markup that changes shape with the viewport:
   a bottom tab bar on phones and portrait tablets, a left side rail from
   1024px up. Doing this in CSS alone means the JS (ids, .tab-btn, data-tab,
   refreshTabs) is untouched, so navigation logic cannot regress.
   ============================================================================ */

/* Mirrors the header rule, so the app is framed top and bottom by the brand. */
.tab-bar::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--border);
}

.tab-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--chrome-muted);
  font-family: var(--font-main);
  padding: 6px 10px;
  border-radius: var(--radius-md);
  min-width: 0;
  flex: 1 1 0;
  max-width: 84px;
  transition: color 0.15s ease, background-color 0.15s ease;
}

/* Six tabs must fit the narrowest phones without overflow. The label shrinks
   and truncates before the bar scrolls. */
.tab-btn span:last-child {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 380px) {
  .tab-btn {
    padding: 6px 4px;
  }
  .tab-btn span:last-child {
    font-size: 10px;
  }
}

.tab-icon {
  font-size: 20px;
  line-height: 1;
}

.tab-btn span:last-child {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.tab-btn.active {
  color: var(--chrome-ink);
  background: var(--chrome-2);
}

@media print {
  .tab-bar {
    display: none !important;
  }
}

/* ============================================================================
   DEVICE CLASSES
   phone            < 700px   single column, bottom tabs
   tablet portrait  700–1023  two-column content, bottom tabs (thumb reach)
   tablet landscape 1024–1279 side rail, two columns
   desktop          >= 1280   side rail, two columns, wider gutters
   ============================================================================ */

/* Tablet and up: let content use the width instead of one tall column. */
@media (min-width: 700px) {
  .profile-grid {
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  }

  .today-columns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 14px;
    align-items: start;
  }
}

/* 1024px and up: the bottom bar becomes a left rail. Same markup, same JS. */
@media (min-width: 1024px) {
  .tab-bar {
    top: 0;
    bottom: 0;
    right: auto;
    width: 208px;
    flex-direction: column;
    justify-content: flex-start;
    align-items: stretch;
    gap: 2px;
    /* Start below the fixed header. --header-h is measured from the real element
       in JS, because the header's height is not a constant: the language select
       carries a label above it, Vietnamese labels are longer and can wrap, and
       the user's browser zoom or font-size setting changes it again. The
       previous hardcoded 76px was a guess that came up short, so the first nav
       item was clipped by the header. */
    padding: calc(var(--header-h, 76px) + 12px) 12px 16px;
    border-right: 1px solid var(--chrome-border);
  }

  /* The brand rule runs down the rail's inside edge instead of across the top. */
  .tab-bar::before {
    top: 0;
    bottom: 0;
    left: auto;
    right: 0;
    width: 3px;
    height: auto;
    background: var(--border);
  }

  .tab-btn {
    flex-direction: row;
    justify-content: flex-start;
    gap: 11px;
    padding: 10px 14px;
    min-width: 0;
    width: 100%;
    /* The phone rule caps tabs at 84px so six fit a narrow bottom bar. On the
       desktop side rail that cap truncated every label to a single letter
       ("O..", "T..."). Release it here so full labels show. */
    max-width: none;
    flex: 0 0 auto;
  }

  .tab-btn span:last-child {
    font-size: 13px;
    letter-spacing: 0;
    /* Full label on the rail — no ellipsis truncation. */
    overflow: visible;
    text-overflow: clip;
  }

  .app-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 70;
  }

  #app {
    padding-left: 232px;
    padding-top: calc(var(--header-h, 76px) + 20px);
    max-width: 1400px;
  }

  .app-header-inner {
    max-width: none;
    padding-left: 4px;
  }
}

@media (min-width: 1280px) {
  #app {
    padding-right: 32px;
  }
}


/* Theme toggle button in the header */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border-radius: var(--radius-md);
  border: 1px solid var(--chrome-border);
  background: var(--chrome-2);
  color: var(--chrome-muted);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.icon-btn:hover:not(:disabled) {
  color: var(--chrome-ink);
  border-color: var(--chrome-muted);
}

/* ===== In-app document filler ===== */
.fill-doc { max-width: 940px; margin: 0 auto; }
.fill-doc-head { margin-bottom: 18px; }
.fill-doc-title { margin: 10px 0 4px; }
.fill-doc-pages { display: flex; flex-direction: column; gap: 22px; align-items: center; }
.fill-doc-page { position: relative; width: 100%; max-width: 820px; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; box-shadow: 0 4px 18px rgba(11,15,23,0.12); background: #fff; }
.fill-doc-img { display: block; width: 100%; height: auto; -webkit-user-drag: none; user-select: none; }
.fill-doc-overlay { position: absolute; inset: 0; }
.fill-doc-overlay > * { position: absolute; box-sizing: border-box; }
.fill-text { border: none; background: rgba(53,56,205,0.06); border-bottom: 1.5px solid rgba(53,56,205,0.5); font-family: inherit; font-size: 13px; line-height: 1.05; padding: 0 3px; color: #0f172a; resize: none; overflow: hidden; }
.fill-text:focus { outline: none; background: rgba(53,56,205,0.14); }
textarea.fill-text { padding-top: 2px; line-height: 1.15; }
.fill-cb { display: flex; align-items: center; justify-content: center; border: 1.5px solid rgba(53,56,205,0.65); border-radius: 3px; background: rgba(53,56,205,0.06); cursor: pointer; min-width: 11px; min-height: 11px; }
.fill-cb:hover { background: rgba(53,56,205,0.12); }
.fill-cb-mark { font-weight: 700; font-size: 88%; line-height: 1; color: #1d4ed8; opacity: 0; }
.fill-cb.on { background: rgba(53,56,205,0.16); }
.fill-cb.on .fill-cb-mark { opacity: 1; }
.fill-sig { display: flex; align-items: center; justify-content: center; border: 1.5px dashed rgba(53,56,205,0.7); border-radius: 4px; background: rgba(53,56,205,0.06); cursor: pointer; overflow: hidden; }
.fill-sig:hover { background: rgba(53,56,205,0.12); }
.fill-sig-label { font-size: 11px; font-weight: 600; color: #1d4ed8; white-space: nowrap; pointer-events: none; }
.fill-sig.signed { border-style: solid; border-color: rgba(53,56,205,0.4); background: #fff; }
.fill-sig-thumb { max-width: 100%; max-height: 100%; object-fit: contain; }
.fill-doc-actions { display: flex; flex-wrap: wrap; gap: 12px; justify-content: flex-end; margin-top: 22px; }
.fill-doc-status { text-align: center; padding: 32px; }
/* Signature capture modal */
.sig-modal-back { position: fixed; inset: 0; z-index: 1200; display: flex; align-items: center; justify-content: center; padding: 16px; background: rgba(11,15,23,0.55); }
.sig-modal { width: 100%; max-width: 460px; background: var(--surface); color: var(--ink); border: 1px solid var(--border); border-radius: 14px; padding: 20px; box-shadow: 0 24px 60px rgba(11,15,23,0.35); }
.sig-modal-title { margin: 0 0 14px; }
.sig-modal-canvas { width: 100%; height: 190px; background: #fff; border: 1px solid var(--border-strong); border-radius: 8px; touch-action: none; cursor: crosshair; }
.sig-modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 16px; }

/* Profile load-error banner + document-filler missing-page notice */
.profile-loadwarn { margin: 0 0 14px; padding: 10px 14px; border-radius: 8px; background: #fff4e5; border: 1px solid #ffd8a8; color: #8a5300; font-size: 14px; }
/* 2026-08-25: the tile badges use light pastel fills that are readable but glaring
   against the dark UI. Same hues, translucent, so they sit in the dark surface. */
[data-theme="dark"] .tile-badge.ready { color: #7ee2a8; background: rgba(78,201,138,0.16); }
[data-theme="dark"] .tile-badge.locked { color: #e8c078; background: rgba(226,165,58,0.16); }
[data-theme="dark"] .tile-badge.restricted { color: #ff9b91; background: rgba(255,107,94,0.16); }
[data-theme="dark"] .profile-loadwarn { background: rgba(255,180,80,0.12); border-color: rgba(255,180,80,0.32); color: #ffcc80; }
.fill-doc-imgerr { text-align: center; padding: 10px; color: #8a5300; }

/* ============================================================================
 * Phase 4 — notes, tasks, reports, admin. Uses the app's theme variables so
 * light/dark both work. All classes are namespaced p4- to avoid collisions.
 * ========================================================================== */
button.small { padding: 5px 11px; font-size: 13px; border-radius: var(--radius-md); }
.p4-del { color: var(--danger-ink); }

/* 2026-08-25: per-file upload failures. The uploader used to report only a count,
   so a staffer scanning a batch could not tell an oversized file from a wrong
   format — and re-scanned blindly. Each row now names the file and the reason. */
.p4-doc-fails {
  list-style: none;
  /* .p4-form is a grid; without this the failure list and status line get squeezed
     into one narrow column and wrap after three words. */
  grid-column: 1 / -1;
  margin: 10px 0 0;
  padding: 10px 14px;
  border-radius: var(--radius-md);
  background: var(--danger-soft);
  border: 1px solid var(--danger);
  color: var(--danger-ink);
  font-size: 13px;
  display: grid;
  gap: 5px;
}
.p4-doc-fails li { overflow-wrap: anywhere; }
.p4-doc-status { grid-column: 1 / -1; }
.p4-del:hover:not(:disabled) { background: var(--danger-soft); }

.p4-chips { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.p4-chip { padding: 6px 14px; border-radius: 999px; border: 1px solid var(--border-strong);
  background: var(--surface); color: var(--muted); font-size: 13px; font-weight: 600; cursor: pointer; }
.p4-chip.active { background: var(--primary); color: var(--primary-ink); border-color: var(--primary); }

.p4-form-wrap { margin-bottom: 16px; }
.p4-add-toggle { margin-bottom: 10px; }
.p4-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px;
  align-items: end; background: var(--surface-muted); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 16px; }
.p4-form .field { display: flex; flex-direction: column; gap: 5px; }
.p4-form .field > span { font-size: 12px; font-weight: 600; color: var(--muted); }
.p4-form input, .p4-form select, .p4-form textarea {
  padding: 9px 11px; border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  background: var(--surface); color: var(--ink); font-family: inherit; font-size: 14px; }

.p4-list { display: grid; gap: 10px; }
.p4-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: 14px 16px; box-shadow: var(--shadow-xl); }
.p4-card.p4-danger { border-left: 3px solid var(--danger); }
.p4-card.p4-muted { opacity: 0.6; }
.p4-card-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.p4-card-head strong { font-size: 15px; }
.p4-due { font-size: 12px; color: var(--muted); white-space: nowrap; }
.p4-overdue { color: var(--danger-ink); font-weight: 700; }
.p4-meta { font-size: 12.5px; margin: 4px 0 0; }
.p4-details { font-size: 13.5px; margin: 6px 0 0; }
.p4-actions { display: flex; gap: 8px; margin-top: 10px; }
.p4-empty { padding: 24px 0; text-align: center; }

.p4-kv-row { display: flex; gap: 12px; flex-wrap: wrap; }
.p4-kv { flex: 1 1 120px; background: var(--surface-muted); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 12px 14px; }
.p4-kv-label { display: block; font-size: 12px; font-weight: 600; }
.p4-kv-val { display: block; font-size: 20px; font-weight: 700; margin-top: 3px; font-family: var(--font-mono); }

.p4-bars { display: grid; gap: 10px; }
.p4-bar-row { display: grid; grid-template-columns: 120px 1fr 40px; align-items: center; gap: 10px; }
.p4-bar-label { font-size: 13px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.p4-bar-track { height: 10px; background: var(--surface-muted); border-radius: 999px; overflow: hidden; }
.p4-bar-fill { height: 100%; background: var(--primary); border-radius: 999px; transition: width var(--dur-slow) var(--ease); }
.p4-bar-count { font-size: 13px; font-weight: 700; text-align: right; font-family: var(--font-mono); }

.p4-staff { display: grid; gap: 8px; margin-bottom: 16px; }
.p4-staff-row { display: flex; align-items: center; gap: 12px; padding: 10px 12px;
  background: var(--surface-muted); border: 1px solid var(--border); border-radius: var(--radius-md); }
.p4-staff-row.p4-muted { opacity: 0.55; }
.p4-staff-info { flex: 1; display: flex; flex-direction: column; }
.p4-staff-code { font-size: 12px; font-family: var(--font-mono); }
.p4-staff-row select { padding: 6px 9px; border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  background: var(--surface); color: var(--ink); font-family: inherit; }
.p4-addstaff { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }

.p4-admin-bar { display: flex; gap: 8px; margin-bottom: 14px; }
.p4-note-add { display: flex; gap: 10px; align-items: flex-start; margin: 10px 0 16px; }
.p4-note-input { flex: 1; padding: 10px 12px; border: 1px solid var(--border-strong);
  border-radius: var(--radius-md); background: var(--surface); color: var(--ink);
  font-family: inherit; font-size: 14px; resize: vertical; min-height: 44px; }
.p4-note-list { display: grid; gap: 10px; }
.p4-note { background: var(--surface-muted); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 11px 14px; }
.p4-note-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.p4-note-by { font-size: 12.5px; font-weight: 700; color: var(--primary); }
.p4-note-when { font-size: 12px; }
.p4-note-body { margin: 0; font-size: 14px; white-space: pre-wrap; }
.p4-note .small { margin-top: 8px; }
