/* assets/css/theme.css — the surface, second pass.
 *
 * The first pass changed tokens and little else, on purpose: the point was to
 * prove that nothing breaks when only colour and radius move. It did, and it
 * also looked like almost nothing had happened. This one goes further.
 *
 * The constraints have not changed, and they are what make this safe to switch
 * off with one link rather than maintain as a second interface:
 *
 *   1. No layout properties. No display, position, float, or width on anything
 *      structural. A rule that moves an element can break a page this was never
 *      meant to touch, and there are two hundred of those pages.
 *   2. Never make a control less visible than Bootstrap makes it, and never
 *      weaken a focus outline. That is what somebody navigating by keyboard has
 *      instead of a pointer.
 *   3. Density stays close. This application is mostly tables that people read
 *      all day; a fashionable amount of whitespace would mean six rows on a
 *      screen that used to show fifteen.
 *
 * The accent is the house navy from pecunino.com (#0B294D). It replaced a
 * green on 2026-09-07; look-2026-09-06 is the tag that still has the green.
 */

/* Inter, because the system stack is the single thing that most makes an
   interface look like it was built a decade ago. Loaded with display=swap, so a
   slow font never leaves the page blank; the fallback below is the stack
   Bootstrap would have used anyway. */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

:root {
  /* ---- neutrals: cool, to sit under a navy rather than a green, and a real
     ramp rather than three greys */
  --pt-0:  #ffffff;
  --pt-25: #fafbfc;
  --pt-50: #f4f6f8;
  --pt-100:#e9edf1;
  --pt-200:#dbe1e8;
  --pt-300:#b9c2cc;
  /* Muted text was too light against the page: at --pt-300 a placeholder was
     grey on lighter grey and the form hints were barely there. These two are
     the ones that decide whether the interface is readable. */
  --pt-400:#8a95a3;
  --pt-500:#6b7684;
  --pt-700:#3a4450;
  --pt-900:#151a20;

  /* ---- the accent: the house navy from pecunino.com. */
  --pt-accent:       #0b294d;
  --pt-accent-dark:  #071d38;
  --pt-accent-soft:  #e6ecf3;
  --pt-accent-ink:   #0b294d;

  --bs-body-bg: var(--pt-50);
  --bs-body-color: var(--pt-900);
  --bs-secondary-color: var(--pt-500);
  --bs-border-color: var(--pt-200);
  --bs-border-color-translucent: rgba(21, 26, 32, .09);

  --bs-primary: var(--pt-accent);
  --bs-primary-rgb: 11, 41, 77;
  --bs-link-color: var(--pt-accent-ink);
  --bs-link-color-rgb: 11, 41, 77;
  --bs-link-hover-color: var(--pt-accent-dark);

  --bs-border-radius: .6rem;
  --bs-border-radius-sm: .45rem;
  --bs-border-radius-lg: .9rem;

  --bs-font-sans-serif: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --pt-shadow: 0 1px 2px rgba(21, 26, 32, .05), 0 2px 6px rgba(21, 26, 32, .05);
  --pt-shadow-lift: 0 6px 24px rgba(21, 26, 32, .12), 0 2px 6px rgba(21, 26, 32, .07);
}

body {
  background: var(--pt-50);
  font-family: var(--bs-font-sans-serif);
  -webkit-font-smoothing: antialiased;
  letter-spacing: -.006em;
}

h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6 {
  letter-spacing: -.021em;
  font-weight: 650;
  color: var(--pt-900);
}
.display-6 { font-weight: 650; letter-spacing: -.03em; }
.text-muted { color: var(--pt-500) !important; }
.small, small { font-size: .8125rem; }

/* Figures line up in columns. In a tool that is mostly hours and percentages
   this is not a detail — proportional digits make a column of numbers wobble. */
.table, .display-6, .badge, input[type="number"], .font-monospace {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* ---------------------------------------------------------------- surfaces */
.card {
  background: var(--pt-0);
  border: 1px solid var(--pt-200);
  border-radius: var(--bs-border-radius-lg);
  box-shadow: var(--pt-shadow);
}
/* The grey header bar is the single most dated thing about stock Bootstrap.
   A hairline and a confident label say the same and take less ink. */
.card-header {
  background: transparent;
  border-bottom: 1px solid var(--pt-100);
  padding-top: .7rem;
  padding-bottom: .7rem;
  font-weight: 600;
  color: var(--pt-700);
}
.card-footer {
  background: var(--pt-25);
  border-top: 1px solid var(--pt-100);
  color: var(--pt-500);
}
.card-body { padding: 1rem 1.15rem; }
.card-body.py-2 { padding-top: .7rem !important; padding-bottom: .7rem !important; }
.shadow-sm { box-shadow: var(--pt-shadow) !important; }

/* Cards used as counters read better without a border fighting the shadow. */
.card.border-warning { border-color: #e6c98a; box-shadow: 0 0 0 1px #f4e3bf inset, var(--pt-shadow); }
.card.border-danger  { border-color: #e5b3ad; box-shadow: 0 0 0 1px #f6d9d5 inset, var(--pt-shadow); }
.card.border-primary { border-color: var(--pt-accent); box-shadow: 0 0 0 1px var(--pt-accent-soft) inset, var(--pt-shadow); }

/* ------------------------------------------------------------------ navbar */
.app-nav {
  background: rgba(255, 255, 255, .86) !important;
  backdrop-filter: saturate(1.6) blur(10px);
  -webkit-backdrop-filter: saturate(1.6) blur(10px);
  border-bottom: 1px solid var(--pt-200) !important;
}
.app-nav .navbar-brand {
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--pt-accent-ink);
}
.app-nav .nav-link {
  border-radius: 999px;
  /* Horizontal padding matches Bootstrap's own .5rem exactly. The pill wants
     more room and cannot have it: this navigation carries nine items plus two
     dropdowns, and a wider link tips the whole bar into a horizontal scroll on
     a 1280-wide screen. The rounded background does the work instead. */
  padding: .35rem .5rem;
  color: var(--pt-700);
  font-weight: 500;
}
.app-nav .nav-link:hover { background: var(--pt-100); color: var(--pt-900); }
.app-nav .nav-link.active,
.navbar-nav .nav-link.active {
  background: var(--pt-accent-soft);
  color: var(--pt-accent-ink) !important;
  font-weight: 600;
}

/* ---------------------------------------------------------------- controls */
.btn {
  border-radius: var(--bs-border-radius);
  font-weight: 550;
  letter-spacing: -.004em;
  padding: .42rem .85rem;
}
.btn-sm { padding: .28rem .6rem; border-radius: var(--bs-border-radius-sm); }
.btn-primary {
  --bs-btn-bg: var(--pt-accent);
  --bs-btn-border-color: var(--pt-accent);
  --bs-btn-hover-bg: var(--pt-accent-dark);
  --bs-btn-hover-border-color: var(--pt-accent-dark);
  --bs-btn-active-bg: #05162a;
  --bs-btn-active-border-color: #05162a;
  --bs-btn-disabled-bg: #93a0b0;
  --bs-btn-disabled-border-color: #93a0b0;
  box-shadow: 0 1px 2px rgba(21, 26, 32, .16);
}
.btn-outline-secondary {
  --bs-btn-color: var(--pt-700);
  --bs-btn-border-color: var(--pt-300);
  --bs-btn-hover-bg: var(--pt-100);
  --bs-btn-hover-border-color: var(--pt-300);
  --bs-btn-hover-color: var(--pt-900);
}
.btn-outline-primary {
  --bs-btn-color: var(--pt-accent-ink);
  --bs-btn-border-color: #a8b8cb;
  --bs-btn-hover-bg: var(--pt-accent-soft);
  --bs-btn-hover-border-color: var(--pt-accent);
  --bs-btn-hover-color: var(--pt-accent-dark);
}
.btn-group > .btn.active,
.btn-outline-secondary.active {
  background: var(--pt-accent-soft);
  border-color: var(--pt-accent);
  color: var(--pt-accent-ink);
}

.form-control, .form-select {
  background: var(--pt-0);
  border-color: var(--pt-300);
  border-radius: var(--bs-border-radius);
  color: var(--pt-900);
}
.form-control::placeholder { color: var(--pt-400); opacity: 1; }
/* Safari and Firefox both need saying to, and both default to a lighter grey
   than the one above. */
.form-control::-webkit-input-placeholder { color: var(--pt-400); opacity: 1; }
.form-control::-moz-placeholder { color: var(--pt-400); opacity: 1; }
/* A disabled or readonly field still has to be readable — it is showing a value
   somebody needs, not decoration. */
.form-control:disabled, .form-control[readonly], .form-select:disabled {
  background: var(--pt-50);
  color: var(--pt-700);
  opacity: 1;
}
.form-control:focus, .form-select:focus {
  border-color: var(--pt-accent);
  box-shadow: 0 0 0 3px rgba(11, 41, 77, .15);
}
.form-check-input:checked { background-color: var(--pt-accent); border-color: var(--pt-accent); }
.form-check-input:focus { border-color: var(--pt-accent); box-shadow: 0 0 0 3px rgba(11, 41, 77, .15); }
.input-group-text { background: var(--pt-50); border-color: var(--pt-300); color: var(--pt-500); }
:focus-visible { outline-offset: 2px; }

/* ------------------------------------------------------------------ tables */
.table {
  --bs-table-border-color: var(--pt-100);
  color: var(--pt-900);
}
.table > :not(caption) > * > * { border-bottom-width: 1px; }
.table > thead { --bs-table-bg: transparent; }
.table > thead th {
  font-weight: 600;
  font-size: .75rem;
  letter-spacing: .02em;
  color: var(--pt-500);
  border-bottom: 1px solid var(--pt-200);
  padding-top: .55rem;
  padding-bottom: .55rem;
}
.table-light, .table > thead.table-light { --bs-table-bg: var(--pt-25); }
.table-sm > :not(caption) > * > * { padding: .5rem .6rem; }
.table-hover > tbody > tr:hover > * { --bs-table-accent-bg: var(--pt-50); }
.table > tbody > tr:last-child > * { border-bottom-width: 0; }

/* The states that carry meaning here: overdue, waiting, an unknown sender.
   Tinted rather than shouted, and never removed. */
.table-danger  { --bs-table-bg: #fdf0ee; --bs-table-color: #7a2c22; }
.table-warning { --bs-table-bg: #fdf6e8; --bs-table-color: #6b5216; }

/* ------------------------------------------------------------------ badges */
.badge {
  font-weight: 550;
  border-radius: 999px;
  padding: .34em .68em;
  font-size: .73rem;
  letter-spacing: .002em;
}
/* Soft fills. A row of solid blocks is the other thing that dates an interface. */
.text-bg-primary   { background: var(--pt-accent-soft) !important; color: var(--pt-accent-ink) !important; }
.text-bg-secondary { background: var(--pt-100) !important; color: var(--pt-700) !important; }
.text-bg-light     { background: var(--pt-50) !important; color: var(--pt-700) !important; }
.text-bg-success   { background: #e2f0e7 !important; color: #1f5a32 !important; }
.text-bg-warning   { background: #fbeecd !important; color: #6b5216 !important; }
.text-bg-danger    { background: #fadedb !important; color: #7d2f24 !important; }
.text-bg-dark      { background: var(--pt-700) !important; color: var(--pt-25) !important; }
/* The badge that must still shout: an unread count. */
.bg-danger.rounded-pill { background: #b3392b !important; color: #fff !important; }
.bg-primary.rounded-pill { background: var(--pt-accent) !important; color: #fff !important; }

/* ------------------------------------------------------------------ alerts */
.alert {
  border-radius: var(--bs-border-radius-lg);
  border-width: 1px;
  padding: .7rem .95rem;
}
.alert-success   { background: #edf6f0; border-color: #cbe4d5; color: #1f5a32; }
.alert-warning   { background: #fdf6e8; border-color: #f0dfb6; color: #6b5216; }
.alert-danger    { background: #fdf0ee; border-color: #efc9c3; color: #7d2f24; }
.alert-secondary { background: var(--pt-25); border-color: var(--pt-200); color: var(--pt-700); }

/* --------------------------------------------------------------- list rows */
.list-group-item { border-color: var(--pt-100); background: var(--pt-0); }
.list-group-item-action:hover { background: var(--pt-50); }
.list-group-item.active {
  background: var(--pt-accent);
  border-color: var(--pt-accent);
  color: #fff;
}

/* ------------------------------------------------------------------- menus */
.dropdown-menu {
  border: 1px solid var(--pt-200);
  border-radius: var(--bs-border-radius-lg);
  box-shadow: var(--pt-shadow-lift);
  padding: .35rem;
}
.dropdown-item {
  border-radius: var(--bs-border-radius-sm);
  padding: .42rem .65rem;
  color: var(--pt-700);
  font-weight: 500;
}
.dropdown-item:hover { background: var(--pt-50); color: var(--pt-900); }
.dropdown-item:active, .dropdown-item.active { background: var(--pt-accent); color: #fff; }
.dropdown-divider { border-color: var(--pt-100); }

/* ------------------------------------------------------------ odds and ends */
.progress { border-radius: 999px; background: var(--pt-100); height: .5rem; }
.progress-bar { background: var(--pt-accent); }
.progress-bar.bg-success { background: #2f7a49 !important; }
mark { background: #ffe9a8; padding: 0 .1em; border-radius: .2em; }
code { background: var(--pt-100); color: var(--pt-accent-ink); padding: .1em .35em; border-radius: .3em; }
hr { border-color: var(--pt-200); opacity: 1; }
a { text-underline-offset: .18em; }

/* No dark palette here on purpose. Half the pages set their own background
 * colours inline, so a dark mode built from tokens alone would be a patchwork —
 * worse than not having one. It needs those inline styles removed first. */
