/* ===========================================================================
   The design tokens. ONE file, imported by the staff tracker and the client
   portal both.

   WHY THIS EXISTS. On 21 Sep 2026 the six stylesheets in this project held
   579 distinct colors across 860 uses — an average of 1.5 uses per color, so
   very nearly every color was a one-off. organizer.css alone carried #edf2f7,
   #edf3f7, #edf3f8, #edf4f8, #eef3f7 and #eef4f8: six light warm-grays that
   are all slightly different and none of which was a token. There were 16
   border-radius values and 19 font sizes with no ratio between them.

   No person picks 579 colors. That happens when each feature's stylesheet is
   written on its own and the next value is eyeballed rather than looked up,
   and the accumulated near-misses are what the eye reads as blur. Daniel's
   word for the result was "AI vibe coded". The drift, not the layout, is the
   cause.

   THE RULE FROM HERE. A color, a radius, a size, a space or a shadow that is
   not in this file does not go in a stylesheet. If something genuinely needs
   a value that is not here, it is added here first, with a reason.

   WARM, NOT COOL. app.css was designed warm — cream paper, a warm rule, warm
   muted text — and every feature stylesheet since drifted cool blue-gray, by
   639 uses to 163. The warm ramp below restores the original palette rather
   than inventing a new one, and warm neutrals are the natural partner for the
   gold in the firm's mark. Cool blue-gray is also what almost every generated
   interface defaults to, which is the look being moved away from.

   TYPOGRAPHY IS BRAND. Daniel chose the faces on 25 Sep 2026; they are set
   once below. Change them only with his sign-off.
   =========================================================================== */

/* Self-hosted faces. Latin covers English and Spanish; Latin Extended covers
   other accented names. */
@font-face {
  font-family: 'Source Sans 3';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('fonts/source-sans-3-latin-wght-normal.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: 'Source Sans 3';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('fonts/source-sans-3-latin-ext-wght-normal.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: 'Source Sans 3';
  font-style: italic;
  font-weight: 200 900;
  font-display: swap;
  src: url('fonts/source-sans-3-latin-wght-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122;
}
@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('fonts/source-serif-4-latin-wght-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122;
}

:root {
  /* -- Brand. The mark's navy and gold. Unchanged. ------------------------ */
  --navy: #0a2240;
  --navy-soft: #14345c;
  --navy-line: #1d3f68;
  --gold: #ffb347;
  --gold-deep: #d98b16;
  /* Gold is unreadable as text on white at 4.5:1. This is the darkened one to
     SET gold-colored words in; --gold stays for fills, rules and dots. */
  --gold-ink: #8a5a10;

  /* -- Neutrals. ONE warm ramp, 00 lightest to 90 darkest. ---------------- */
  --n-00: #ffffff; /* surfaces that sit on the page ground */
  --n-05: #f8f7f4; /* an inset well inside a surface */
  --n-10: #f1f0ec; /* hover, zebra, an inset well */
  --n-20: #e4e2dc; /* the standard hairline */
  --n-30: #d3d0c8; /* a rule that has to be seen: card edges, table head, focus ring */
  --n-50: #6f6b63; /* text that is present but not being read; 4.5:1 on paper and wells (28 Sep 2026) */
  --n-60: #5d5a52; /* secondary text */
  --n-80: #3d3a33; /* strong secondary, rarely needed */
  --n-90: #16202e; /* primary text */

  /* Names for the jobs, so a stylesheet says what it means rather than which
     step of the ramp it happens to want. */
  --surface: var(--n-00);
  /* Daniel, 25 Sep 2026: "no contrast ... zero separation between the
     sections." The page ground is a clearly darker warm tone so white surfaces
     read as surfaces; --paper stays the light well used inside them. */
  --ground: var(--n-05); /* warm ground, white cards on it, like My desk (30 Sep 2026) */
  --paper: var(--n-05);
  --well: var(--n-10);
  --rule: var(--n-20);
  --rule-strong: var(--n-30);
  --ink: var(--n-90);
  --ink-muted: var(--n-60);
  --ink-faint: var(--n-50);

  /* Every focus outline in the project was its own blue — #4385b3, #4b90cf,
     #4e91d0, #5189b9, #5f98c3, #6f9ec9, six of them doing one job. A focus
     ring has to be clearly visible against both the paper and the navy
     sidebar, and it is the one place a color outside the warm ramp earns its
     place, because a warm ring on warm paper cannot be seen. */
  --focus: #2f6ba8;
  /* Secondary text on the navy sidebar. The focus blue was used here and
     read at about 2:1 against the navy. */
  --on-navy-muted: color-mix(in srgb, var(--n-00) 62%, var(--navy));
  /* The border on a pending or gold-tinted panel. Was five near-identical
     desaturated golds (#c8ad87, #cba36b, #d8b276, #d9be87, #dfbb7b). */
  --gold-line: #dcc39a;

  /* -- State. Three, so a row can only ever say one thing loudly. --------- */
  --good: #177545; /* 4.5:1 on --good-bg */
  --good-bg: #e8f5ee;
  --warn: #9a5c00; /* 4.5:1 on --warn-bg */
  --warn-bg: #fdf1dd;
  --bad: #b42318;
  --bad-bg: #fdeceb;

  /* -- Radius. Two, plus the circle. 16 different ones was the problem. --- */
  --r-sm: 4px;
  --r: 6px;
  --r-pill: 999px;
  /* Kept so the existing rules in app.css that name them keep working. */
  --radius: var(--r);
  --radius-sm: var(--r-sm);

  /* -- Space. A scale, so vertical rhythm is the same on every screen. ---- */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  --s7: 48px;
  --s8: 64px;

  /* -- Type. Six sizes on a ~1.2 ratio, replacing nineteen arbitrary ones. */
  --t-xs: 12px; /* meta, timestamps, table heads */
  --t-sm: 13px; /* secondary text, help */
  --t-base: 15px; /* body */
  --t-md: 17px; /* a row title, a card heading */
  --t-lg: 21px; /* section heading */
  --t-xl: 27px; /* page heading */
  --t-2xl: 34px; /* the one big number or welcome line */
  --lh-tight: 1.2;
  --lh: 1.55;

  /* -- Shadow. Two. A third is how a flat interface starts to look puffy. - */
  --shadow-card: 0 1px 2px rgb(10 34 64 / 0.05); /* white cards lift off the warm ground */
  --shadow-pop: 0 4px 6px -1px rgb(10 34 64 / 0.1), 0 10px 24px -4px rgb(10 34 64 / 0.15);

  /* -- Type faces. BRAND. --------------------------------------------------
     Daniel, 25 Sep 2026, approved Source Sans 3 for everything, with Source
     Serif 4 for page titles in the client portal only. Both are self-hosted
     (fonts/, SIL Open Font License), so every computer and phone shows the
     same face and no page asks a third party for it. Numbers use the same
     face with even-width digits (see the tabular-nums rule below), not a
     code font. */
  --font:
    'Source Sans 3', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue',
    Arial, sans-serif;
  --font-display: var(--font);
  --font-serif: 'Source Serif 4', Georgia, 'Times New Roman', serif;
  --font-num: var(--font);

  /* -- Density. The one agreed difference between the two apps. ----------- */
  /* Default is the staff tracker: dense, because somebody works a queue in it
     all day. The portal opts into the roomy set below. */
  --row-y: 12px;
  --pad-card: 16px;
  --page-max: 1240px; /* staff pages: capped and centered */
  --sidebar-w: 216px;

  /* Portal controls and authentication. Auth is a single readable column;
     these widths must never constrain Clerk's separate account-profile UI. */
  --auth-width: 448px;
  --control-h: 44px;
  /* Staff buttons come in two heights: standard, and compact for rows and
     tight toolbars. Thirteen ad hoc heights were in use before. */
  /* Secondary buttons are a soft gray fill, never a white box with a border
     (Daniel, 25 Sep 2026: "i don't really like the white buttons"). One navy
     primary per screen; everything else is a quiet action. */
  --btn-bg: #efede8;
  --btn-bg-hover: #e4e1da;
  --btn-h: 34px; /* the same height as a text field, so toolbars line up */
  --btn-h-sm: 28px;
  --action-width: 160px;
  /* Short portal request lists need a shorter reading line than file tables
     so their actions stay close to the text they belong to. */
  --portal-summary-width: 800px;
  /* Display dimensions of the firm's existing, unchanged logo asset. */
  --brand-logo-width: 245px;
  --brand-logo-height: 48px;

  /* File manager: compact rows and controls, with stable navigation and
     metadata columns. Keep these distinct from roomy form/dialog controls. */
  --file-control-h: var(--btn-h);
  --file-row-h: 44px;
  --file-rail-w: 280px;
  --file-rail-min: 200px;
  --file-rail-max: 384px;
  --file-folder-w: 200px;
  --file-date-w: 128px;
  --file-size-w: 80px;
  --file-state-w: 112px;
  --file-table-min: 800px;
  --file-search-w: 280px;
  --file-browser-h: 640px;
  --file-mobile-h: 580px;
  --file-active-bg: color-mix(in srgb, var(--navy) 7%, var(--surface));
  /* CRM accents reuse the firm's blue and gold without coloring whole rows. */
  --crm-accent-bg: color-mix(in srgb, var(--navy-line) 9%, var(--surface));
  --crm-accent-line: color-mix(in srgb, var(--navy-line) 24%, var(--surface));
  --crm-hover-bg: color-mix(in srgb, var(--navy-line) 4%, var(--surface));
  /* Stable CRM stage identities; labels remain visible, not color alone. */
  /* Each stage has its own color (Daniel, 6 Oct 2026: the prospects screen
     was "completely devoid of color"). Every one carries white text at 4.5:1
     or better, and the label is always written, so color is never alone. */
  --crm-stage-new: #2f62c8;
  --crm-stage-booked: #6a4bc9;
  --crm-stage-preparing: #b45309;
  --crm-stage-sent: #0d7f74;
  /* Slightly darker than the general success green for small tinted labels. */
  --crm-stage-won: color-mix(in srgb, var(--good) 90%, var(--ink));
  --crm-stage-lost: var(--ink-muted);
  --crm-status-width: 164px;
  --crm-status-height: 30px;
  /* View-control labels change, but neighboring buttons should not move. */
  --crm-view-control-width: 112px;
}

[data-density='roomy'] {
  --row-y: 18px;
  --pad-card: 24px;
  --page-max: 960px;
}

/* Tabular numerals wherever figures stack in a column. A date or a dollar
   amount whose digits do not line up reads as sloppy at a glance, and every
   one of these screens is a column of dates. */
table,
time,
.num,
[data-num] {
  font-variant-numeric: tabular-nums;
}

/* One placeholder color everywhere: present, readable, and clearly not an
   entered value. It was once painted in the error background by mistake. */
::placeholder {
  color: var(--ink-muted);
  opacity: 1;
}

/* No lone word on the last line of a paragraph, and headings that break
   evenly. Browsers without support simply wrap as before. */
p,
li,
dd,
td,
th,
summary,
label,
figcaption,
.help,
.hint,
.sub,
.notice,
.work-step__hint {
  text-wrap: pretty;
}
h1,
h2,
h3 {
  text-wrap: balance;
}

/* One inline error, used everywhere. Daniel, 25 Sep 2026: an error bar across
   the whole page is not necessary. It sits beside what failed and is only as
   wide as its words. */
.alert-inline,
.pm-error,
#portal-error {
  display: flex;
  align-items: center;
  gap: 8px;
  width: fit-content;
  max-width: 100%;
  box-sizing: border-box;
  margin: 0 0 var(--s3, 12px);
  padding: 8px 12px;
  border-radius: 8px;
  background: var(--bad-bg);
  color: var(--bad);
  font-size: var(--t-sm, 14px);
  line-height: 1.4;
}
.alert-inline[hidden],
.pm-error[hidden] {
  display: none;
}

/* Form controls use the page face, never the browser's default. */
button,
input,
select,
textarea {
  font-family: inherit;
}

/* Reserve the scrollbar's space on every page, so centered content does not
   shift sideways when one tab is long enough to scroll and another is not
   (Daniel noticed it in the portal between Home, Documents and Questionnaires). */
html {
  scrollbar-gutter: stable;
}
