/* ===== application.css ===== */
/* ==========================================================================
   Base styles
   ========================================================================== */
@import url("https://fonts.googleapis.com/css2?family=Quicksand:wght@300..700&display=swap");

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  font-family: "Quicksand", sans-serif;
}

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

body {
  font-weight: normal;
  color: var(--color-text);
  background-color: var(--color-canvas);
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-weight: 600;
  color: var(--color-primary-dark);
}

svg {
  overflow: visible !important;
}

strong {
  font-family: var(--font-family-bold);
  font-weight: bold;
}

::selection {
  background-color: var(--tint-green-28);
}

/* Consistent, slim scrollbars */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--color-border-strong) transparent;
}

*::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

*::-webkit-scrollbar-thumb {
  background-color: var(--color-border-strong);
  border-radius: var(--radius-full);
}

*::-webkit-scrollbar-track {
  background: transparent;
}

/* Keyboard focus is always visible */
:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.light-text {
  font-weight: 300;
}

.hidden {
  display: none !important;
}

.field-with-error {
  border-color: var(--color-danger) !important;
}

.field-with-error:focus {
  box-shadow: var(--focus-ring-danger) !important;
  border-color: var(--color-danger) !important;
}


/* ===== config/variables.css ===== */
/* ==========================================================================
   Design Tokens
   Brand colors and typography are fixed — everything else derives from them.
   ========================================================================== */
:root {
  /* --- Brand palette (unchanged) --- */
  --color-primary-dark: #243a51;
  --color-secondary-dark: #3a4a5c;
  --color-primary-green: #5dcfa2;

  --color-primary-pink: #f6576c;

  --color-danger: #f5455c;
  --color-danger-light: #f6576c;

  --color-success: #10b981;
  --color-success-dark: #059669;

  --color-warning: #f59e0b;
  --color-warning-dark: #92400e;

  --color-yellow-100: #fcfce5;

  /* --- Brand tints (alpha variants of the palette above) --- */
  --tint-navy-04: rgba(36, 58, 81, 0.04);
  --tint-navy-06: rgba(36, 58, 81, 0.06);
  --tint-navy-10: rgba(36, 58, 81, 0.1);
  --tint-navy-16: rgba(36, 58, 81, 0.16);
  --tint-green-10: rgba(93, 207, 162, 0.1);
  --tint-green-16: rgba(93, 207, 162, 0.16);
  --tint-green-28: rgba(93, 207, 162, 0.28);
  --tint-danger-10: rgba(245, 69, 92, 0.1);
  --tint-danger-16: rgba(245, 69, 92, 0.16);
  --tint-white-10: rgba(255, 255, 255, 0.1);
  --tint-white-16: rgba(255, 255, 255, 0.16);
  --tint-white-24: rgba(255, 255, 255, 0.24);
  /* Enough white to lift a control off the canvas without reading as a surface.
     Used by an inactive tab on hover (see components/app_tabs). */
  --tint-white-60: rgba(255, 255, 255, 0.6);

  /* The side rail keeps its own palette, because it has two of them — green and
     navy — and a theme is easier to read as one block of overrides next to the
     rules that use it. See components/sidenav. */

  /* --- Neutrals --- */
  --color-white: #ffffff;
  --color-canvas: #f4f6f9;
  --color-surface: #ffffff;
  --color-surface-sunken: #f8fafc;
  --color-border: #e3e9f0;
  --color-border-strong: #cbd5e1;
  --color-text: #1f2937;
  --color-text-muted: #64748b;
  --color-text-faint: #94a3b8;

  /* Legacy aliases still referenced by older sheets */
  --color-background-secondary: var(--color-surface-sunken);
  --color-gray-700: #374151;

  /* --- Typography (unchanged) --- */
  --font-family-base: "Quicksand";
  --font-family-bold: "Quicksand";

  --font-size-small: 12px;
  --font-size-medium: 14px;
  --font-size-large: 16px;
  --font-size-xlarge: 18px;
  --font-size-xxlarge: 24px;
  --font-size-xxxlarge: 30px;

  /* Legacy aliases */
  --font-size-sm: var(--font-size-small);
  --font-size-base: var(--font-size-medium);
  --font-weight-medium: 500;

  /* Micro-label: uppercase eyebrow used on table headers, form labels, etc. */
  --label-letter-spacing: 0.06em;

  /* --- Spacing scale --- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;

  /* --- Radii --- */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-xl: 20px;
  --radius-full: 999px;

  /* Legacy alias */
  --border-radius-lg: var(--radius-lg);

  /* --- Elevation --- */
  --shadow-xs: 0 1px 2px rgba(15, 30, 45, 0.06);
  --shadow-sm: 0 1px 3px rgba(15, 30, 45, 0.08), 0 1px 2px rgba(15, 30, 45, 0.04);
  --shadow-md: 0 4px 12px rgba(15, 30, 45, 0.08), 0 2px 4px rgba(15, 30, 45, 0.05);
  --shadow-lg: 0 12px 32px rgba(15, 30, 45, 0.14), 0 4px 8px rgba(15, 30, 45, 0.06);
  --shadow-glow-green: 0 0 0 3px var(--tint-green-16);

  /* --- Focus ring --- */
  --focus-ring: 0 0 0 3px var(--tint-green-28);
  --focus-ring-danger: 0 0 0 3px var(--tint-danger-16);

  /* --- Motion --- */
  --transition-fast: 0.15s ease;
  --transition-base: 0.2s ease;
  --transition-slow: 0.3s cubic-bezier(0.4, 0, 0.2, 1);

  /* --- Layout dimensions --- */
  --topbar-height: 64px;
  /* The row of open pages, across the top of the main content area. Deep enough
     for a 12px label and a close control, and no deeper: it is taken off the
     height of every page in the application. See components/app_tabs. */
  --app-tabs-height: 38px;
  --sidenav-width-collapsed: 64px;
  --sidenav-width-expanded: 240px;
  /* The rail's inner gutter and row height. Collapsed, a row is a square:
     64 - (2 * 12) = 40, so the icon inside it lands on the rail's centre line
     and does not move when the rail widens. */
  --sidenav-gutter: var(--space-3);
  --sidenav-row-height: 40px;

  /* --- Z-index scale --- */
  --z-sticky: 10;
  /* The cookie banner: above the page it sits over, and below everything the
     user might be doing on top of it. A passive notice that outranked a drawer
     would swallow the clicks meant for the drawer's buttons. */
  --z-cookie-notice: 50;
  --z-sidenav: 100;
  --z-topbar: 1000;
  --z-drawer: 1002;
  --z-modal: 1100;
}


/* ===== layouts/dashboard.css ===== */
/* ==========================================================================
   Dashboard shell layout
   ========================================================================== */
.dashboard {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
  background-color: var(--color-canvas);
}

.dashboard__content-wrapper {
  display: flex;
  flex: 1;
  position: relative;
  overflow: hidden;
  margin-top: var(--topbar-height);
  height: calc(100vh - var(--topbar-height));
}

/* Holds the tab strip and, under it, the page. Neither the padding nor the
   scrolling lives here any more — both moved onto the panel inside the tabs, so
   that the strip stays put while the page under it scrolls (see
   components/app_tabs). What is left is the room made for the side rail. */
.dashboard__main-content {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  margin-left: var(--sidenav-width-collapsed);
  transition: margin var(--transition-slow), width var(--transition-slow);
  width: calc(100% - var(--sidenav-width-collapsed));
  overflow: hidden;
  height: 100%;
}

/* Room made for a rail the user has pinned open. An unpinned rail widening
   under the pointer floats over this instead of moving it — reflowing a wide
   table every time the pointer crosses the nav is the more expensive of the
   two, and the least asked for (see components/sidenav). */
.dashboard__main-content--nav-expanded {
  margin-left: var(--sidenav-width-expanded);
  width: calc(100% - var(--sidenav-width-expanded));
  height: 100%;
}

/* No application nav to leave room for — see layouts/dashboard. Declared after
   the expanded modifier so it wins whichever class the sidenav controller has
   left behind. */
.dashboard__main-content--no-nav,
.dashboard__main-content--no-nav.dashboard__main-content--nav-expanded {
  margin-left: 0;
  width: 100%;
}

@media (max-width: 768px) {
  .dashboard__main-content {
    margin-left: var(--sidenav-width-collapsed);
    width: calc(100% - var(--sidenav-width-collapsed));
  }

  .dashboard__main-content--nav-expanded {
    margin-left: var(--sidenav-width-collapsed);
    width: calc(100% - var(--sidenav-width-collapsed));
  }

  .dashboard__main-content--no-nav,
  .dashboard__main-content--no-nav.dashboard__main-content--nav-expanded {
    margin-left: 0;
    width: 100%;
  }
}


/* ===== components/app_tabs.css ===== */
/* ==========================================================================
   Application tabs — the strip of open pages, and the panel one is drawn in

   The strip sits inside the main content area rather than across the window, so
   it starts where the side rail ends and moves with it. Its own height is fixed
   and the panel below takes the rest, which is what keeps an index table's
   scroller sized to the window (see components/table).
   ========================================================================== */
.app-tabs {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

.app-tabs__strip {
  display: flex;
  align-items: flex-end;
  gap: var(--space-1);
  flex: 0 0 auto;
  min-width: 0;
  height: var(--app-tabs-height);
  padding: 0 var(--space-4);
  background-color: var(--color-canvas);
  border-bottom: 1px solid var(--color-border);
}

/* The tabs themselves scroll sideways once there are more than the strip can
   hold, rather than shrinking to nothing: a tab too narrow to read its record's
   name is no use for getting back to it. The scrollbar is hidden — the row is
   dragged or the tabs are closed. */
.app-tabs__list {
  display: flex;
  align-items: flex-end;
  gap: var(--space-1);
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
}

.app-tabs__list::-webkit-scrollbar {
  display: none;
}

/* ==========================================================================
   One tab
   ========================================================================== */
.app-tabs__tab {
  display: flex;
  align-items: center;
  flex: 0 1 auto;
  min-width: 0;
  max-width: 220px;
  height: calc(var(--app-tabs-height) - 6px);
  padding: 0 var(--space-1) 0 var(--space-3);
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  color: var(--color-text-muted);
  transition: background-color var(--transition-base), color var(--transition-base);
}

.app-tabs__tab:hover {
  background-color: var(--tint-white-60, rgba(255, 255, 255, 0.6));
  color: var(--color-text);
}

/* The tab in front reads as the top of the page below it: same surface, and it
   sits over the strip's bottom border rather than under it. */
.app-tabs__tab--active,
.app-tabs__tab--active:hover {
  background-color: var(--color-surface);
  border-color: var(--color-border);
  color: var(--color-text);
  margin-bottom: -1px;
  padding-bottom: 1px;
}

/* A pinned tab is held at the front of the row and takes less of it: it is
   somewhere you are working out of rather than something you are reading, so its
   name only has to be recognisable, not complete. */
.app-tabs__tab--pinned {
  max-width: 150px;
}

/* Where a dragged tab will land. A line in the gap rather than the tabs shuffling
   under the pointer — the strip is redrawn from the controller's own list, and
   redrawing it mid-drag would replace the tab being dragged. */
.app-tabs__tab--drop-before,
.app-tabs__tab--drop-after {
  position: relative;
}

.app-tabs__tab--drop-before::before,
.app-tabs__tab--drop-after::after {
  content: "";
  position: absolute;
  top: 20%;
  bottom: 20%;
  width: 2px;
  background-color: var(--color-primary-green);
  border-radius: 1px;
}

.app-tabs__tab--drop-before::before {
  left: -3px;
}

.app-tabs__tab--drop-after::after {
  right: -3px;
}

.app-tabs__select {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  border: none;
  background: none;
  padding: 0;
  color: inherit;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-family-base);
  font-size: var(--font-size-small);
  line-height: 1.2;
}

.app-tabs__tab--active .app-tabs__select {
  font-family: var(--font-family-bold);
  font-weight: 600;
}

/* Kept at full size for the pointer but only inked on the tab you are on or under
   the pointer, so a row of tabs is a row of names rather than a row of controls. */
.app-tabs__close,
.app-tabs__pin {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-left: 2px;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  padding: 0;
  color: var(--color-text-faint);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--transition-base), background-color var(--transition-base),
    color var(--transition-base);
}

.app-tabs__tab:hover .app-tabs__close,
.app-tabs__tab:hover .app-tabs__pin,
.app-tabs__tab--active .app-tabs__close,
.app-tabs__tab--active .app-tabs__pin,
.app-tabs__close:focus-visible,
.app-tabs__pin:focus-visible {
  opacity: 1;
}

/* A pinned tab wears its pin whether or not you are on it — that is the whole
   signal that the tab is pinned. */
.app-tabs__pin--on {
  opacity: 1;
  color: var(--color-primary-green);
}

.app-tabs__close:hover,
.app-tabs__pin:hover {
  background-color: var(--color-border);
  color: var(--color-text);
}

.app-tabs__pin--on:hover {
  color: var(--color-primary-dark);
}

/* ==========================================================================
   New tab
   ========================================================================== */
.app-tabs__new {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  margin-bottom: var(--space-1);
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  padding: 0;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: background-color var(--transition-base), color var(--transition-base);
}

.app-tabs__new:hover:not(:disabled) {
  background-color: var(--color-surface);
  color: var(--color-text);
}

.app-tabs__new:disabled {
  color: var(--color-text-faint);
  cursor: not-allowed;
}

/* ==========================================================================
   The panel

   This is the box every page in the application is laid out in, and it is the
   one that scrolls. The padding and the scrolling used to belong to
   .dashboard__main-content (see layouts/dashboard); they moved here when the
   strip took the top of that area, so that the strip stays put while the page
   under it scrolls.
   ========================================================================== */
.app-tabs__panels {
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.app-tabs__panel {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  padding: var(--space-6) var(--space-8);
  overflow-y: auto;
  overflow-x: hidden;
}

/* A tab being fetched for the first time — restored into a fresh window, or just
   opened. Turbo marks the frame busy while it is in flight. */
.app-tabs__panel turbo-frame[aria-busy="true"]:empty {
  flex: 1 1 auto;
  min-height: 120px;
  background-image: linear-gradient(
    90deg,
    var(--color-surface-sunken) 0%,
    var(--color-surface) 50%,
    var(--color-surface-sunken) 100%
  );
  background-size: 200% 100%;
  border-radius: var(--radius-md);
  animation: app-tabs-loading 1.2s ease-in-out infinite;
}

@keyframes app-tabs-loading {
  from {
    background-position: 100% 0;
  }
  to {
    background-position: -100% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .app-tabs__panel turbo-frame[aria-busy="true"]:empty {
    animation: none;
  }
}

@media (max-width: 768px) {
  .app-tabs__strip {
    padding: 0 var(--space-2);
  }

  .app-tabs__panel {
    padding: var(--space-4);
  }
}


/* ===== components/audit_history.css ===== */
/* ==========================================================================
   Audit History — activity timeline (drawer / panel)
   ========================================================================== */
.audit-history {
  padding: var(--space-5);
  background-color: var(--color-surface-sunken);
  border-radius: var(--radius-lg);
  border-top: 3px solid var(--color-primary-green);
  min-height: 100%;
}

.audit-history__description {
  margin: 0 0 var(--space-6) 0;
  color: var(--color-text-muted);
  font-family: var(--font-family-base);
  font-size: var(--font-size-medium);
  line-height: 1.5;
}

.audit-history__timeline {
  position: relative;
  padding-left: var(--space-6);
}

.audit-history__timeline::before {
  content: "";
  position: absolute;
  left: 6px;
  top: 4px;
  bottom: 4px;
  width: 2px;
  background-color: var(--color-border-strong);
}

.audit-history__item {
  position: relative;
  margin-bottom: var(--space-6);
  display: flex;
  align-items: flex-start;
}

.audit-history__item:last-child {
  margin-bottom: 0;
}

.audit-history__marker {
  position: absolute;
  left: calc(-1 * var(--space-6) + 1px);
  top: 6px;
  width: 12px;
  height: 12px;
  border-radius: var(--radius-full);
  background-color: var(--color-primary-green);
  border: 2px solid var(--color-surface);
  z-index: 1;
}

.audit-history__content {
  flex: 1;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  box-shadow: var(--shadow-xs);
}

.audit-history__timestamp {
  color: var(--color-text-muted);
  font-family: var(--font-family-base);
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  margin-bottom: var(--space-1);
}

.audit-history__action {
  color: var(--color-text);
  font-family: var(--font-family-base);
  font-size: var(--font-size-medium);
  line-height: 1.5;
}


/* ===== components/bookmarks.css ===== */
/* ==========================================================================
   Bookmarks — the top bar's menu, and the star on a record page

   The menu sits where the account menu does (see components/topbar) but is
   opened by clicking rather than hovering, and is wider: a bookmark carries a
   name and the context that tells two similar ones apart, where the account menu
   carries one word. Its open state is a `hidden` class rather than a :hover rule,
   because you have to be able to move the pointer into it — see
   controllers/dropdown.
   ========================================================================== */
.topbar__bookmarks {
  position: relative;
}

.topbar__bookmarks-trigger {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: none;
  border-radius: var(--radius-md);
  background: none;
  padding: 0;
  color: var(--color-white);
  cursor: pointer;
  transition: background-color var(--transition-base);
}

.topbar__bookmarks-trigger:hover,
.topbar__bookmarks-trigger[aria-expanded="true"] {
  background-color: var(--tint-white-16);
}

.topbar__bookmarks-menu {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  width: 300px;
  max-height: 420px;
  overflow-y: auto;
  padding: var(--space-2);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  z-index: 1;
}

.topbar__bookmarks-heading {
  padding: var(--space-1) var(--space-2) var(--space-2);
  margin-bottom: var(--space-1);
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
}

/* ==========================================================================
   The list
   ========================================================================== */
.bookmarks__list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  list-style: none;
}

/* The remove control sits over the row rather than beside it, so the row's own
   name has the full width and the list does not develop a ragged right edge. */
.bookmarks__item {
  position: relative;
  display: flex;
  align-items: center;
  border-radius: var(--radius-sm);
}

/* The row being dragged stays visible but recedes, so the gap it will land in is
   what the eye follows rather than the row itself. */
.bookmarks__item--dragging {
  opacity: 0.4;
}

.bookmarks__grip {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  padding-left: 2px;
  color: var(--color-text-faint);
  cursor: grab;
  /* Faint rather than hidden, as the remove control is: a handle that only
     appears under the pointer is a handle nobody knows is there, and one on a
     touch screen would never appear at all. */
  opacity: 0.45;
  transition: opacity var(--transition-base);
}

.bookmarks__item:hover .bookmarks__grip {
  opacity: 1;
}

.bookmarks__item--dragging .bookmarks__grip {
  cursor: grabbing;
}

.bookmarks__link {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: var(--space-2) var(--space-8) var(--space-2) var(--space-1);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background-color var(--transition-base);
}

.bookmarks__link:hover {
  background-color: var(--tint-navy-04);
}

.bookmarks__label {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--color-text);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.bookmarks__context {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

/* Which of the four kinds this row is, leading the context line. Inked a shade
   darker than the rest of it so a column of them can be scanned. */
.bookmarks__kind {
  color: var(--color-text);
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.bookmarks__remove {
  position: absolute;
  right: var(--space-1);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  padding: 0;
  color: var(--color-text-faint);
  cursor: pointer;
  /* Faint rather than hidden. The menu was opened deliberately, so the control
     that empties it has no reason to hide — and a row that only reveals it on
     hover cannot be emptied on a touch screen at all. */
  opacity: 0.5;
  transition: opacity var(--transition-base), background-color var(--transition-base),
    color var(--transition-base);
}

.bookmarks__item:hover .bookmarks__remove,
.bookmarks__remove:focus-visible {
  opacity: 1;
}

.bookmarks__remove:hover {
  background-color: var(--tint-danger-10);
  color: var(--color-danger);
}

.bookmarks__empty,
.bookmarks__loading {
  padding: var(--space-3) var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  line-height: 1.5;
}

.bookmarks__loading {
  color: var(--color-text-faint);
}

/* ==========================================================================
   The star on a record page

   Filled is bookmarked, outline is not — one control in two positions, sitting
   in the record header's row of actions.
   ========================================================================== */
.bookmark-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
  padding: 0;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: background-color var(--transition-base), border-color var(--transition-base),
    color var(--transition-base);
}

.bookmark-toggle:hover {
  border-color: var(--color-border-strong);
  color: var(--color-text);
}

.bookmark-toggle--on {
  border-color: var(--color-warning);
  color: var(--color-warning);
}

.bookmark-toggle--on:hover {
  border-color: var(--color-warning-dark);
  color: var(--color-warning-dark);
}

.bookmark-toggle__icon {
  display: block;
}


/* ===== components/breadcrumbs.css ===== */
/* ==========================================================================
   Breadcrumbs
   ========================================================================== */
.breadcrumbs {
  margin-bottom: var(--space-3);
}

.breadcrumbs__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  list-style: none;
  padding: 0;
  margin: 0;
}

.breadcrumbs__item {
  display: flex;
  align-items: center;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
}

.breadcrumbs__separator {
  margin: 0 var(--space-2);
  color: var(--color-text-faint);
}

.breadcrumbs__link {
  display: flex;
  align-items: center;
  text-decoration: none;
  color: var(--color-text-muted);
  transition: color var(--transition-base);
}

.breadcrumbs__link:hover {
  color: var(--color-primary-dark);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.breadcrumbs__icon {
  width: 14px;
  height: 14px;
  margin-right: var(--space-1);
}

.breadcrumbs__text {
  line-height: 1.5;
}

.breadcrumbs__text--current {
  font-family: var(--font-family-bold);
  color: var(--color-primary-dark);
}


/* ===== components/bulk_import.css ===== */
/* ==========================================================================
   Bulk Import — Tools

   Three screens: the hub that offers the templates and lists what has been
   imported, the upload form, and the check of one uploaded file.

   The hub and the upload form scroll as pages, because both are prose and
   panels rather than a table filling the viewport — which is what .index-page
   otherwise arranges for (see components/table). `.bulk-import__scroll` is how
   they opt out of it. The check screen does not opt out: it is a listing, and
   behaves like every other one.
   ========================================================================== */
.bulk-import__scroll {
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding-bottom: var(--space-6);
}

/* Inside a scrolling page the tables size to their rows rather than fighting
   each other for the height the flex chain is handing out. */
.bulk-import__scroll .table-container {
  flex: 0 0 auto;
  min-height: 0;
  margin-bottom: 0;
}

/* == The hub: one block per kind of import == */
.bulk-import__kinds {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5);
  align-items: start;
}

@media (max-width: 1100px) {
  .bulk-import__kinds {
    grid-template-columns: 1fr;
  }
}

.bulk-import__kind,
.bulk-import__panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.bulk-import__kind-header {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
}

.bulk-import__kind-icon {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  color: var(--color-primary-dark);
  background-color: var(--color-surface-sunken);
  border-radius: var(--radius-md);
}

.bulk-import__kind-icon svg {
  width: 22px;
  height: 22px;
}

.bulk-import__kind-title {
  font-size: var(--font-size-large);
  margin-bottom: var(--space-1);
}

.bulk-import__kind-summary,
.bulk-import__lead {
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}

.bulk-import__kind-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: auto;
}

/* == The column reference, folded away until it is wanted == */
.bulk-import__columns-summary {
  cursor: pointer;
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
  padding: var(--space-2) 0;
}

.bulk-import__columns-summary:hover {
  color: var(--color-primary-green);
}

.bulk-import__columns[open] .bulk-import__columns-summary {
  margin-bottom: var(--space-3);
}

.bulk-import__columns-note {
  margin-top: var(--space-3);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.bulk-import__requirement {
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-medium);
}

.bulk-import__requirement--required {
  color: var(--color-warning-dark);
}

.bulk-import__requirement--optional {
  color: var(--color-text-faint);
}

/* == The check: the numbers that decide what happens next == */
.bulk-import__summary {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-4);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.bulk-import__figures {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
}

.bulk-import__figure {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.bulk-import__figure-value {
  font-size: var(--font-size-xlarge);
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
  line-height: 1;
}

.bulk-import__figure--good .bulk-import__figure-value {
  color: var(--color-success-dark);
}

.bulk-import__figure--bad .bulk-import__figure-value {
  color: var(--color-danger);
}

.bulk-import__figure-label {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.bulk-import__state,
.bulk-import__note {
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}

.bulk-import__blocker {
  padding: var(--space-4) var(--space-5);
  font-size: var(--font-size-medium);
  color: var(--color-danger);
  background-color: var(--color-danger-light);
  border-radius: var(--radius-lg);
}

/* == Waiting on a job ==
   Checking a file and writing it both happen in the background, so this is what
   the page shows in the place the rows will be. Same shape as the report
   generator's own wait (see .report-run__progress in reports.css). */
.bulk-import__progress {
  display: flex;
  flex: 0 0 auto;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-primary-green);
  border-radius: var(--radius-lg);
  background: var(--tint-green-10);
  font-size: var(--font-size-medium);
}

.bulk-import__progress-message {
  margin: 0;
}

.bulk-import__progress-spinner {
  flex: 0 0 auto;
  width: 1rem;
  height: 1rem;
  border: 2px solid var(--color-border);
  border-top-color: var(--color-primary-green);
  border-radius: 50%;
  animation: bulk-import-spin 0.9s linear infinite;
}

@keyframes bulk-import-spin {
  to {
    transform: rotate(360deg);
  }
}

/* The page reloads itself every few seconds regardless, so the spin is
   decoration — nothing is lost by holding it still. */
@media (prefers-reduced-motion: reduce) {
  .bulk-import__progress-spinner {
    animation: none;
  }
}

/* == All rows / rows with problems == */
.bulk-import__row-toolbar {
  display: flex;
  flex: 0 0 auto;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.bulk-import__row-tab {
  padding: var(--space-2) var(--space-4);
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
  text-decoration: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
}

.bulk-import__row-tab:hover {
  color: var(--color-primary-dark);
  border-color: var(--color-border-strong);
}

.bulk-import__row-tab--active {
  color: var(--color-white);
  background-color: var(--color-primary-dark);
  border-color: var(--color-primary-dark);
}

.bulk-import__row-number {
  width: 72px;
  color: var(--color-text-muted);
}

/* Everything wrong with one row, one line each. A row with four problems is
   shown with four, because the person fixing the file is doing it in another
   window and one problem per upload is how a morning disappears. */
.bulk-import__problems {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
  padding-left: var(--space-4);
  font-size: var(--font-size-small);
  color: var(--color-danger);
}


/* ===== components/business_records.css ===== */
/* ==========================================================================
   Business Records — complaint show page layout + shared record-form pieces
   Card-based two-column layout: complaint details + narrative on the left,
   resolution on the right, tabulation below.
   ========================================================================== */
.complaint-record {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* == Layout grid == */
.complaint-record__grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-5);
  align-items: start;
}

.complaint-record__column {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}

@media (max-width: 1024px) {
  .complaint-record__grid {
    grid-template-columns: 1fr;
  }
}

/* == Cards == */
.complaint-record__card {
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.complaint-record__card-title {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

/* == Detail grid == */
.complaint-record__details {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5);
}

.complaint-record__details-column {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}

.complaint-record__detail {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.complaint-record__detail-label {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.complaint-record__detail-value {
  margin: 0;
  font-size: var(--font-size-medium);
  color: var(--color-text);
  overflow-wrap: anywhere;
}

/* == Narrative (subject / details) == */
.complaint-record__long-text {
  margin: 0;
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
  font-size: var(--font-size-medium);
  line-height: 1.6;
  color: var(--color-text);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ==========================================================================
   Form error summary — inline validation panel used by record drawer forms
   ========================================================================== */
.form-error-summary {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--tint-danger-16);
  border-left: 3px solid var(--color-danger);
  border-radius: var(--radius-md);
  background-color: var(--tint-danger-10);
  color: var(--color-danger);
}

.form-error-summary__title {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  color: var(--color-danger);
}

.form-error-summary__list {
  margin: 0;
  padding-left: var(--space-4);
  font-size: var(--font-size-small);
}


/* ===== components/button.css ===== */
/* ==========================================================================
   Buttons
   ========================================================================== */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0 var(--space-4);
  height: 40px;
  border-radius: var(--radius-md);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--transition-base), border-color var(--transition-base),
    color var(--transition-base), box-shadow var(--transition-base), transform var(--transition-fast);
  border: 1px solid transparent;
}

.button:hover {
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}

.button:active {
  transform: translateY(0);
  box-shadow: none;
}

.button:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}

.button--primary {
  background-color: var(--color-primary-dark);
  color: var(--color-white);
}

.button--primary:hover {
  background-color: var(--color-secondary-dark);
}

.button--secondary {
  background-color: var(--color-surface);
  color: var(--color-primary-dark);
  border-color: var(--color-border-strong);
}

.button--secondary:hover {
  border-color: var(--color-primary-dark);
  background-color: var(--color-surface-sunken);
}

.button--green {
  background-color: var(--color-primary-green);
  color: var(--color-white);
}

.button--green:hover {
  background-color: var(--color-primary-green);
  filter: brightness(0.95);
}

.button--danger {
  background-color: var(--color-danger);
  color: var(--color-white);
}

.button--danger:hover {
  background-color: var(--color-danger-light);
}

.button--ghost {
  background-color: transparent;
  color: var(--color-primary-dark);
}

.button--ghost:hover {
  background-color: var(--tint-navy-06);
  box-shadow: none;
  transform: none;
}

.button--small {
  height: 32px;
  padding: 0 var(--space-3);
  font-size: var(--font-size-small);
  border-radius: var(--radius-sm);
}

.button--large {
  height: 48px;
  padding: 0 var(--space-6);
  font-size: var(--font-size-large);
}

.button__icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}


/* ===== components/calendar.css ===== */
/* ==========================================================================
   Schedule calendar — page shell, capacity card, week grid, entry chips,
   booking panel, delete modal, settings page and multi-checkbox select.
   ========================================================================== */

/* == Page layout == */
.schedule-page {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.schedule-page__controls {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.schedule-page__workspace {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
}

/* When a booking is open, a details column appears on the right and stays in
   view; until then the calendars take the full width. */
.schedule-page__workspace--details-open {
  grid-template-columns: minmax(0, 1fr) minmax(280px, 340px);
}

.schedule-page__main {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}

/* == Legend == */
.schedule-page__legend {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-4);
}

.schedule-page__legend-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.schedule-page__legend-swatch {
  width: 14px;
  height: 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
}

.schedule-page__legend-swatch--working {
  background-color: var(--color-surface);
}

.schedule-page__legend-swatch--blocked {
  background-color: var(--color-surface-sunken);
  background-image: repeating-linear-gradient(
    -45deg,
    transparent 0 6px,
    var(--tint-navy-04) 6px 12px
  );
}

/* == Capacity card (compact, collapsible) == */
.schedule-capacity {
  padding: var(--space-3) var(--space-4);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.schedule-capacity__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  cursor: pointer;
  list-style: none;
}

.schedule-capacity__summary::-webkit-details-marker {
  display: none;
}

.schedule-capacity__title {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.schedule-capacity__count {
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
}

.schedule-capacity__grid {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: var(--space-2) var(--space-5);
}

.schedule-capacity__row {
  display: grid;
  grid-template-columns: minmax(60px, 0.85fr) minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-2);
}

.schedule-capacity__name {
  font-size: var(--font-size-small);
  color: var(--color-primary-dark);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.schedule-capacity__track {
  width: 100%;
  height: 6px;
  background-color: var(--tint-navy-06);
  border-radius: var(--radius-full);
  overflow: hidden;
}

.schedule-capacity__fill {
  display: block;
  height: 100%;
  background-color: var(--color-primary-green);
  border-radius: var(--radius-full);
  transition: width var(--transition-slow);
}

.schedule-capacity__fill--full {
  background-color: var(--color-warning);
}

.schedule-capacity__percentage {
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-text-muted);
  min-width: 34px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* == Week navigation == */
.schedule-week-nav {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.schedule-week-nav__label {
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
  white-space: nowrap;
}

/* == Stacked per-user calendars == */
.schedule-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}

.schedule-stack__empty {
  padding: var(--space-6);
  text-align: center;
  color: var(--color-text-muted);
  background-color: var(--color-surface);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
}

.schedule-user-calendar {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.schedule-user-calendar__toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.schedule-user-calendar__identity {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}

.schedule-user-calendar__identity-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.schedule-user-calendar__name {
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.schedule-user-calendar__capacity-hint {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.schedule-user-calendar__zoom {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.schedule-user-calendar__day-nav {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.schedule-user-calendar__day-label {
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-primary-dark);
  min-width: 96px;
  text-align: center;
}

/* Collapse a calendar to a single day column when zoomed in. */
.schedule-user-calendar--zoomed .schedule-grid__header,
.schedule-user-calendar--zoomed .schedule-grid__row {
  grid-template-columns: 72px minmax(0, 1fr);
}

/* Scoped under --zoomed so these win over the base .schedule-grid__day-col
   display rule regardless of source order. */
.schedule-user-calendar--zoomed .schedule-grid__day-col--hidden,
.schedule-user-calendar--zoomed .schedule-grid__cell--hidden {
  display: none;
}

/* Richer, roomier booking pills in the single-day (zoomed) view. */
.schedule-entry-chip__time,
.schedule-entry-chip__meta {
  display: none;
}

.schedule-user-calendar--zoomed .schedule-entry-chip {
  padding: var(--space-2) var(--space-6) var(--space-2) var(--space-3);
  gap: var(--space-1);
}

.schedule-user-calendar--zoomed .schedule-entry-chip__time {
  display: block;
  font-weight: 700;
  font-size: var(--font-size-small);
  letter-spacing: var(--label-letter-spacing);
  opacity: 0.75;
}

.schedule-user-calendar--zoomed .schedule-entry-chip__title {
  font-size: var(--font-size-medium);
}

.schedule-user-calendar--zoomed .schedule-entry-chip__meta {
  display: block;
  width: 100%;
  font-size: var(--font-size-small);
  opacity: 0.85;
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* == Filters == */
.schedule-filters {
  display: flex;
  gap: var(--space-3);
  align-items: flex-end;
  flex-wrap: wrap;
}

.schedule-filters__users {
  display: flex;
  gap: var(--space-2);
  flex-direction: column;
  min-width: 260px;
}

/* == Week grid == */
.schedule-grid {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  /* The grid is the single scroll container: vertically for the time range, and
     horizontally so week view can focus Mon–Fri while Sat/Sun sit to the right.
     The header row and the time column are pinned via position: sticky. */
  overflow: auto;
  max-height: 782px;
}

.schedule-grid__toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.schedule-grid__week-label {
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.schedule-grid__header,
.schedule-grid__row {
  display: grid;
  /* Day-column width is computed in JS (schedule_grid_selection_controller) so
     exactly five days fill the viewport; the fallback keeps a sensible size
     before that runs. width: max-content lets the two off-screen days overflow
     into the horizontal scroll instead of being squeezed in. */
  grid-template-columns: 72px repeat(7, var(--schedule-day-width, 160px));
  width: max-content;
  min-width: 100%;
}

.schedule-grid__header {
  border-bottom: 1px solid var(--color-border-strong);
  position: sticky;
  top: 0;
  z-index: 7;
}

/* -- Time column -- */
.schedule-grid__time-col {
  padding: var(--space-1) var(--space-2);
  border-right: 1px solid var(--color-border-strong);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  background-color: var(--color-surface);
  font-weight: 600;
  /* Stays visible while the week scrolls horizontally to reveal the weekend.
     Sits above entry chips (z-index 5) but below the sticky header row. */
  position: sticky;
  left: 0;
  z-index: 6;
}

.schedule-grid__time-col--header {
  padding: var(--space-2);
  border-bottom: none;
  /* The top-left corner overlaps both sticky axes, so it wins over the day
     headers within the sticky header row. */
  z-index: 8;
}

.schedule-grid__time-col--slot {
  display: flex;
  align-items: flex-start;
  height: var(--schedule-row-height, 76px);
  box-sizing: border-box;
}

.schedule-grid__time-col--hour {
  color: var(--color-primary-dark);
  font-weight: 700;
}

.schedule-grid__time-col--quarter {
  color: var(--color-text-faint);
  font-weight: 500;
}

/* -- Day headers -- */
.schedule-grid__day-col {
  padding: var(--space-2) var(--space-3);
  border-right: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  background-color: var(--color-surface);
  transition: background-color var(--transition-fast), box-shadow var(--transition-fast);
}

.schedule-grid__day-col:last-child,
.schedule-grid__cell:last-child {
  border-right: none;
}

.schedule-grid__day-col--today {
  background-color: var(--tint-green-10);
}

.schedule-grid__day-col--today .schedule-grid__day-date {
  color: var(--color-primary-green);
}

.schedule-grid__day-col--drag-active {
  background-color: var(--tint-navy-06);
  box-shadow: inset 0 -2px 0 var(--color-primary-green);
}

.schedule-grid__day-name {
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.schedule-grid__day-date {
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-primary-dark);
}

/* -- Cells -- */
.schedule-grid__cell {
  height: var(--schedule-row-height, 76px);
  min-height: 0;
  border-right: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
  padding: 0;
  background-color: var(--color-surface);
  position: relative;
  overflow: visible;
  box-sizing: border-box;
  transition: background-color var(--transition-fast);
}

.schedule-grid__row--hour .schedule-grid__cell,
.schedule-grid__row--hour .schedule-grid__time-col {
  border-top: 1px solid var(--color-border-strong);
}

.schedule-grid__cell:not(.schedule-grid__cell--blocked):hover {
  background-color: var(--tint-navy-04);
}

.schedule-grid__cell--today {
  background-color: var(--tint-green-10);
}

.schedule-grid__cell--blocked {
  background-color: var(--color-surface-sunken);
  background-image: repeating-linear-gradient(
    -45deg,
    transparent 0 6px,
    var(--tint-navy-04) 6px 12px
  );
  cursor: not-allowed;
}

.schedule-grid__cell--selecting {
  background-color: var(--tint-green-16) !important;
  outline: 2px solid var(--color-primary-green);
  outline-offset: -2px;
}

.schedule-grid__cell--move-preview {
  background-color: var(--tint-navy-10) !important;
  outline: 2px dashed var(--color-primary-dark);
  outline-offset: -2px;
}

.schedule-grid__cell--drag-day-active {
  background-color: var(--tint-navy-04);
}

/* == Entry chips == */
.schedule-entry-chip {
  display: flex;
  align-items: flex-start;
  flex-direction: column;
  gap: var(--space-1);
  border: 1px solid;
  border-left-width: 4px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  padding: var(--space-1) var(--space-5) var(--space-1) var(--space-2);
  font-size: var(--font-size-small);
  position: absolute;
  z-index: 5;
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  cursor: pointer;
  line-height: 1.2;
  transition: box-shadow var(--transition-fast), filter var(--transition-fast);
}

.schedule-entry-chip:hover {
  filter: brightness(0.97);
  box-shadow: var(--shadow-md);
}

.schedule-entry-chip--moving {
  opacity: 0.7;
  cursor: grabbing;
}

.schedule-entry-chip--outside-working {
  border-width: 2px;
  border-left-width: 6px;
  font-weight: 700;
  box-shadow: 0 0 0 2px var(--tint-navy-16), var(--shadow-md);
}

.schedule-entry-chip__delete {
  position: absolute;
  right: var(--space-1);
  top: var(--space-1);
  border: none;
  background: transparent;
  color: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: var(--radius-sm);
  transition: background-color var(--transition-fast);
}

.schedule-entry-chip__delete:hover {
  background-color: var(--tint-white-24);
}

.schedule-entry-chip__title {
  font-weight: 700;
  display: block;
  width: 100%;
  overflow-wrap: anywhere;
  word-break: break-word;
  white-space: normal;
}

.schedule-entry-chip__line {
  font-size: var(--font-size-small);
  opacity: 0.9;
  display: block;
  width: 100%;
  overflow-wrap: anywhere;
  word-break: break-word;
  white-space: normal;
}

/* == Booking details panel == */
.schedule-booking-panel {
  display: none;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  padding: var(--space-4);
  min-height: 180px;
  position: sticky;
  top: var(--space-2);
  transition: background-color var(--transition-base), box-shadow var(--transition-base);
}

.schedule-page__workspace--details-open .schedule-booking-panel {
  display: block;
}

.schedule-booking-panel--open:not(.schedule-booking-panel--empty) {
  box-shadow: inset 0 3px 0 var(--color-primary-green), var(--shadow-xs);
}

.schedule-booking-panel--empty {
  background-color: var(--color-surface-sunken);
}

.schedule-booking-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

.schedule-booking-panel__heading {
  margin: 0;
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.schedule-booking-panel__close {
  border: none;
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-large);
  line-height: 1;
  cursor: pointer;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.schedule-booking-panel__close:hover {
  background-color: var(--tint-navy-06);
  color: var(--color-primary-dark);
}

.schedule-booking-panel__content {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.schedule-booking-panel__title {
  margin: 0;
  font-size: var(--font-size-large);
  color: var(--color-primary-dark);
}

.schedule-booking-panel__row {
  margin: 0;
  color: var(--color-text);
  font-size: var(--font-size-small);
}

.schedule-booking-panel__empty {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  margin: 0;
}

.schedule-booking-panel__actions {
  margin-top: var(--space-2);
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* == Delete confirmation modal == */
.schedule-delete-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
}

.schedule-delete-modal__overlay {
  position: absolute;
  inset: 0;
  background-color: rgba(15, 30, 45, 0.35);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.schedule-delete-modal__content {
  position: relative;
  width: min(420px, calc(100vw - var(--space-8)));
  margin: 18vh auto 0;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-lg);
}

.schedule-delete-modal__title {
  margin: 0 0 var(--space-2);
  color: var(--color-primary-dark);
}

.schedule-delete-modal__message {
  margin: 0 0 var(--space-4);
  color: var(--color-text-muted);
}

.schedule-delete-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
}

/* == Booking details dock (right-hand column of pinned cards) == */
.schedule-booking-dock {
  display: none;
  flex-direction: column;
  position: sticky;
  top: var(--space-2);
  max-height: calc(100vh - var(--space-8));
  overflow: hidden;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.schedule-booking-dock--open {
  display: flex;
  animation: schedule-dock-in var(--transition-base) ease;
}

@keyframes schedule-dock-in {
  from {
    opacity: 0;
    transform: translateX(14px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.schedule-booking-dock__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.schedule-booking-dock__heading {
  margin: 0;
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.schedule-booking-dock__close {
  border: none;
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  cursor: pointer;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.schedule-booking-dock__close:hover {
  background-color: var(--tint-navy-06);
  color: var(--color-primary-dark);
}

.schedule-booking-dock__scroll {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-3);
  overflow-y: auto;
  overflow-x: hidden;
  scroll-behavior: smooth;
}

.schedule-booking-card {
  position: relative;
  flex: 0 0 auto;
  width: 100%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4) var(--space-3) var(--space-3);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-primary-green);
  border-radius: var(--radius-md);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--transition-base), transform var(--transition-base);
}

.schedule-booking-card--in {
  opacity: 1;
  transform: none;
}

.schedule-booking-card--out {
  opacity: 0;
  transform: translateY(8px);
}

.schedule-booking-card--flash {
  animation: schedule-card-flash var(--transition-slow) ease;
}

@keyframes schedule-card-flash {
  0% {
    box-shadow: 0 0 0 0 var(--tint-green-28);
  }

  40% {
    box-shadow: 0 0 0 4px var(--tint-green-28);
  }

  100% {
    box-shadow: 0 0 0 0 transparent;
  }
}

.schedule-booking-card__close {
  position: absolute;
  top: var(--space-1);
  right: var(--space-1);
  border: none;
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-large);
  line-height: 1;
  cursor: pointer;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-sm);
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.schedule-booking-card__close:hover {
  background-color: var(--tint-navy-06);
  color: var(--color-primary-dark);
}

.schedule-booking-card__title {
  margin: 0 var(--space-5) 0 0;
  font-size: var(--font-size-medium);
  color: var(--color-primary-dark);
}

.schedule-booking-card__row {
  margin: 0;
  font-size: var(--font-size-small);
  color: var(--color-text);
}

.schedule-booking-card__actions {
  margin-top: var(--space-2);
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* == Calendar tabs == */
.schedule-tabs__strip {
  display: inline-flex;
  gap: var(--space-1);
  flex-wrap: wrap;
  align-self: flex-start;
  padding: var(--space-1);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.schedule-tabs__tab {
  border: none;
  background: transparent;
  color: var(--color-text-muted);
  font-family: var(--font-family-base);
  font-size: var(--font-size-medium);
  padding: var(--space-2) var(--space-5);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background-color var(--transition-fast), color var(--transition-fast), box-shadow var(--transition-fast);
}

.schedule-tabs__tab:hover {
  background-color: var(--tint-navy-06);
  color: var(--color-primary-dark);
}

.schedule-tabs__tab--active,
.schedule-tabs__tab--active:hover {
  background-color: var(--color-primary-green);
  color: #ffffff;
  font-family: var(--font-family-bold);
  box-shadow: var(--shadow-sm);
}

.schedule-stack--tabbed .schedule-user-calendar--tab-hidden {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .schedule-booking-dock--open,
  .schedule-booking-card,
  .schedule-booking-card--flash {
    animation: none;
    transition: none;
  }
}

/* == Settings page == */
.schedule-settings {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.schedule-settings__panel {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  padding: var(--space-5);
}

.schedule-settings__panel-title {
  margin: 0;
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

.schedule-settings__panel-description {
  margin: var(--space-3) 0 var(--space-4);
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
}

.schedule-settings__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.schedule-settings__field-row {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: 1fr 1fr;
}

.schedule-settings__users {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--space-4);
}

.schedule-settings__user-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  background-color: var(--color-surface);
  box-shadow: var(--shadow-xs);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.schedule-settings__user-card:hover {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-sm);
}

.schedule-settings__user-name {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-medium);
  color: var(--color-primary-dark);
}

/* Per-day working hours on a user override: one row per weekday, each with its
   own start and end time. */
.schedule-settings__days {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.schedule-settings__day-row {
  display: grid;
  grid-template-columns: minmax(96px, 1fr) minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: var(--space-2);
}

.schedule-settings__day-row--head {
  color: var(--color-text-muted);
  font-family: var(--font-family-bold);
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  padding-bottom: var(--space-1);
  border-bottom: 1px solid var(--color-border);
}

.schedule-settings__day-label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-medium);
  color: var(--color-text);
}

.form__select--compact {
  padding-top: var(--space-1);
  padding-bottom: var(--space-1);
  font-size: var(--font-size-small);
}

/* == Multi checkbox select == */
.multi-checkbox-select {
  position: relative;
}

.multi-checkbox-select__button {
  width: 100%;
  min-height: 40px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
  color: var(--color-text);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-base);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  text-align: left;
  transition: border-color var(--transition-fast), background-color var(--transition-fast),
    box-shadow var(--transition-fast);
}

.multi-checkbox-select__button:hover {
  border-color: var(--color-border-strong);
}

.multi-checkbox-select__button:focus-visible {
  outline: none;
  background-color: var(--color-surface);
  border-color: var(--color-primary-green);
  box-shadow: var(--focus-ring);
}

.multi-checkbox-select__caret {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.multi-checkbox-select__menu {
  position: absolute;
  top: calc(100% + var(--space-1));
  left: 0;
  width: 100%;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  z-index: 100;
  padding: var(--space-1);
}

.multi-checkbox-select__options {
  max-height: 220px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.multi-checkbox-select__option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-medium);
  cursor: pointer;
  transition: background-color var(--transition-fast);
}

.multi-checkbox-select__option:hover {
  background-color: var(--tint-navy-06);
}

.multi-checkbox-select__option input[type="checkbox"] {
  margin: 0;
  width: 16px;
  height: 16px;
  accent-color: var(--color-primary-green);
}

.multi-checkbox-select__option--select-all {
  border-bottom: 1px solid var(--color-border);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  margin-bottom: var(--space-1);
}

/* == Responsive == */
@media (max-width: 1200px) {
  .schedule-page__workspace--details-open {
    grid-template-columns: 1fr;
  }

  .schedule-booking-dock {
    position: static;
    max-height: none;
  }
}


/* ===== components/case_record.css ===== */
/* ==========================================================================
   Case Record — detail layout for a single case / firm / complaint record
   Class names are shared across cases, complaints and firms views; keep stable.
   ========================================================================== */
.case-record {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.case-record--scrollable {
  max-height: 100%;
  overflow-y: auto;
}

.case-record__section {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  padding: var(--space-5);
}

.case-record__grid {
  display: grid;
  grid-template-columns: 1fr 0.5fr;
  gap: var(--space-4);
}

.case-record__row {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  gap: var(--space-4);
}

.case-record__column {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.case-record__column--wide {
  flex: 2;
}

.case-record__column--narrow {
  flex: 1;
}

.case-record__column--info,
.case-record__column--dates,
.case-record__column--invoice {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.case-record__column--invoice {
  flex: 1;
}

/* --- Section / block headers --- */
.case-record__button-container {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.case-record__button-header {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.case-record__button-row {
  display: flex;
  flex-direction: row;
  width: 100%;
  justify-content: space-between;
  gap: var(--space-3);
}

.case-record__button-row-spacer {
  flex: 1;
}

/* --- Detail grids --- */
.case-record__details-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
  margin-top: var(--space-2);
}

.case-record__grid-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

.case-record__details-grid-item {
  display: grid;
  grid-template-columns: 0.6fr 1fr;
  align-items: center;
  gap: var(--space-3);
}

.case-record__details-grid-column {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* A detail that sits under the two columns rather than in one of them, because
   its value is a list that wants the width — the case's products.

   Stacked rather than laid out as a key/value pair. Every other detail is a
   narrow label beside a short value, and borrowing that grid for a row of pills
   indented them by the width of the label column and left them floating in the
   middle of the card. The label goes above, the pills start at the card's own
   left edge, and they have the full width to wrap into. */
.case-record__details-grid-item--standalone {
  display: block;
  margin-top: var(--space-5);
}

.case-record__details-grid-item--standalone .case-record__attribute-title {
  display: block;
  margin-bottom: var(--space-2);
}

/* Explicit rather than inherited: the pill row is a flex container of its own
   (see components/case_type_pills) and this is the line that says it begins at
   the left. */
.case-record__details-grid-item--standalone .case-type-pills {
  justify-content: flex-start;
}

/* --- Key/value pairs --- */
.case-record__label,
.case-record__attribute-title {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.case-record__label--narrow {
  white-space: nowrap;
}

.case-record__value,
.case-record__details-grid-item-content {
  font-size: var(--font-size-medium);
  color: var(--color-text);
}

.case-record__value--danger,
.case-record__details-grid-item-content--danger {
  color: var(--color-danger);
  font-family: var(--font-family-bold);
}

/* --- Lists --- */
.case-record__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.case-record__list-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-medium);
  color: var(--color-text);
}

/* --- Notes / free-text areas --- */
.case-record__text-area-container {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.case-record__text-area-title {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.case-record__text-area {
  width: 100%;
  min-height: 100px;
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
  padding: var(--space-3);
  font-size: var(--font-size-medium);
  color: var(--color-text);
  line-height: 1.6;
}

.case-record__text-area_full-border {
  border: 1px solid var(--color-border);
  background-color: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  padding: var(--space-3);
}

.case-record__textarea-wrapper {
  position: relative;
}

.case-record__textarea,
.case-record__textarea_full-border {
  width: 100%;
  min-height: 100px;
  overflow-y: auto;
  border: 1px solid var(--color-border);
  background-color: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  padding-bottom: var(--space-10);
  font-size: var(--font-size-medium);
  color: var(--color-text);
  line-height: 1.6;
  resize: vertical;
  font-family: inherit;
  transition: border-color var(--transition-fast), background-color var(--transition-fast),
    box-shadow var(--transition-fast);
}

.case-record__textarea:focus,
.case-record__textarea_full-border:focus {
  outline: none;
  border-color: var(--color-primary-green);
  background-color: var(--color-surface);
  box-shadow: var(--focus-ring);
}

.case-record__update-button {
  position: absolute;
  bottom: var(--space-3);
  right: var(--space-3);
  background-color: var(--color-primary-green);
  color: var(--color-white);
  border: none;
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  cursor: pointer;
  transition: background-color var(--transition-base);
}

.case-record__update-button:hover {
  filter: brightness(0.95);
}

/* --- Recommendations panel (case show, under Quick Actions) --- */
.case-record__recommendations-hint {
  margin-bottom: var(--space-3);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.case-record__recommendations-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* --- Recommendation removal warning modal list --- */
.case-record__recommendations-loss-list {
  margin: var(--space-2) 0 var(--space-4) var(--space-4);
  padding: 0;
  list-style: disc;
  color: var(--color-danger);
  font-family: var(--font-family-bold);
}

/* The running total above a record's Quick Actions — what a project has cost so
   far (see projects/show/_details). Reads as a figure rather than as a label:
   the number is the point, the word under it only says what of. */
.case-record__time-total {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
}

.case-record__time-total-value {
  font-family: var(--font-family-bold);
  font-size: var(--font-size-large);
  color: var(--color-text);
}

.case-record__time-total-label {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
}


/* ===== components/case_tabulation.css ===== */
/* ==========================================================================
   Case Tabulation — tabbed panel (checklists, notes, updates) on a case/complaint
   ========================================================================== */
.case-tabulation {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.case-tabulation__tabs {
  display: flex;
  gap: var(--space-1);
  border-bottom: 1px solid var(--color-border);
}

.case-tabulation__tab {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  /* Checklist / Notes / Documents are the three headings a case is actually
     worked from, so they are set at the family's bold weight rather than left at
     the body weight the family alone gives them. */
  font-weight: 700;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: color var(--transition-base), border-color var(--transition-base);
  position: relative;
}

.case-tabulation__tab:hover {
  color: var(--color-primary-dark);
}

.case-tabulation__tab--active {
  color: var(--color-primary-dark);
  border-bottom-color: var(--color-primary-green);
}

.case-tabulation__tab--updates.case-tabulation__tab--active {
  color: var(--color-danger-light);
  border-bottom-color: var(--color-danger-light);
}

.case-tabulation__tab-icon {
  width: 1.15rem;
  height: 1.15rem;
  fill: currentColor;
}

/* --- Progress --- */
.case-tabulation__progress {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) 0;
}

.case-tabulation__progress-bar {
  flex: 1;
  height: 8px;
  background-color: var(--color-surface-sunken);
  border-radius: var(--radius-full);
  overflow: hidden;
}

.case-tabulation__progress-fill {
  height: 100%;
  background-color: var(--color-primary-green);
  border-radius: var(--radius-full);
  transition: width var(--transition-slow);
}

.case-tabulation__progress-text {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
  min-width: 120px;
}

.case-tabulation__progress-percentage {
  font-size: var(--font-size-large);
  font-weight: 700;
  color: var(--color-primary-dark);
}

.case-tabulation__progress-items {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* --- Panels --- */
.case-tabulation__content {
  position: relative;
  min-height: 200px;
}

.case-tabulation__panel {
  display: none;
  flex-direction: column;
  gap: var(--space-4);
}

.case-tabulation__panel--active {
  display: flex;
}

.case-tabulation__section {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.case-tabulation__section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  background-color: var(--color-surface-sunken);
  border-bottom: 1px solid var(--color-border);
  cursor: pointer;
  transition: background-color var(--transition-base);
}

.case-tabulation__section-header:hover {
  background-color: var(--tint-navy-06);
}

.case-tabulation__section-title {
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  color: var(--color-primary-dark);
  margin: 0;
}

.case-tabulation__section-toggle {
  background: none;
  border: none;
  cursor: pointer;
  padding: var(--space-1);
  border-radius: var(--radius-sm);
  transition: background-color var(--transition-base);
}

.case-tabulation__section-toggle:hover {
  background-color: var(--tint-navy-10);
}

.case-tabulation__section-icon {
  width: 1rem;
  height: 1rem;
  fill: var(--color-text-muted);
  transition: transform var(--transition-base);
}

.case-tabulation__section-content {
  padding: var(--space-4);
  background-color: var(--color-surface);
  min-height: 100px;
}

.case-tabulation__updates {
  padding: var(--space-4);
  background-color: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  min-height: 200px;
}

.case-tabulation__placeholder,
.case-tabulation__empty-state {
  color: var(--color-text-muted);
  text-align: center;
  padding: var(--space-8) var(--space-4);
}

.case-tabulation__placeholder {
  font-style: italic;
}


/* ===== components/case_type_pills.css ===== */
/* ==========================================================================
   Case type pills — compact chips listing the checklist types on a case.
   Used in the cases table (capped with a +N overflow chip) and elsewhere a
   case's selected checklist types need a tidy, scannable summary.
   ========================================================================== */
.case-type-pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  align-items: center;
}

.case-type-pill {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: var(--radius-pill, 999px);
  background-color: var(--tint-navy-06);
  color: var(--color-primary-dark);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
}

.case-type-pill--more {
  background-color: transparent;
  border: 1px dashed var(--color-border-strong, #cbd5e1);
  color: var(--color-text-muted);
  cursor: default;
}

/* A pill that opens the record it names (see tasks/_tag_list). Underlined only on
   hover, so a cell of them still reads as pills rather than as a row of links. */
.case-type-pill--link {
  text-decoration: none;
  cursor: pointer;
}

.case-type-pill--link:hover {
  text-decoration: underline;
}

/* Products use a distinct tint so the two pill columns read apart at a glance. */
.case-type-pill--product {
  background-color: rgba(99, 102, 241, 0.1);
  color: #4338ca;
}

.case-type-pills__empty {
  color: var(--color-text-muted);
}


/* ===== components/checklist.css ===== */
/* ==========================================================================
   Checklist — runtime checklist, definition builder index, builder form,
   publish modal and definition preview/show.
   NOTE: runtime-checklist classes are shared with cases/reviews views —
   restyle freely, never rename.
   ========================================================================== */

/* == Checklist group (one or more runtime checklists per record) == */
.checklist-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.checklist-group__item {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.checklist-group__item + .checklist-group__item {
  border-top: 1px solid var(--color-border, #e2e8f0);
  padding-top: var(--space-6);
}

.checklist-group__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.checklist-group__badge {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill, 999px);
  background-color: var(--tint-primary-10, rgba(16, 185, 129, 0.1));
  color: var(--color-primary-green);
  font-size: var(--font-size-small);
  font-weight: 600;
}

.checklist-group__progress {
  font-size: var(--font-size-small);
  color: var(--color-text-muted, #64748b);
}

/* == Runtime checklist == */
.runtime-checklist {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-2) 0;
}

.runtime-checklist__version-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.runtime-checklist__version-badge {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  background-color: var(--tint-navy-06);
  border: 1px solid var(--tint-navy-16);
  border-radius: var(--radius-full);
  color: var(--color-primary-dark);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  white-space: nowrap;
}

.runtime-checklist__version-note {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* == Runtime progress == */
.runtime-checklist__progress {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.runtime-checklist__progress-bar {
  flex: 1;
  height: 8px;
  min-width: 200px;
  border-radius: var(--radius-full);
  background-color: var(--tint-navy-10);
  overflow: hidden;
}

.runtime-checklist__progress-fill {
  display: block;
  height: 100%;
  border-radius: var(--radius-full);
  background-color: var(--color-primary-green);
  transition: width var(--transition-slow);
}

.runtime-checklist__progress-meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  white-space: nowrap;
}

.runtime-checklist__progress-percentage {
  color: var(--color-primary-dark);
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.runtime-checklist__progress-items {
  color: var(--color-text-muted);
}

/* == Runtime sections == */
.runtime-checklist__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.runtime-checklist__section {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  padding: var(--space-4) var(--space-5);
  transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.runtime-checklist__section:hover {
  border-color: var(--color-border-strong);
}

.runtime-checklist__section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  cursor: pointer;
  list-style: none;
}

.runtime-checklist__section-header::-webkit-details-marker {
  display: none;
}

.runtime-checklist__section[open] .runtime-checklist__section-header {
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

.runtime-checklist__section-title {
  margin: 0;
  font-size: var(--font-size-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.runtime-checklist__section-icon {
  width: 16px;
  height: 16px;
  color: var(--color-text-faint);
  transition: color var(--transition-fast);
}

.runtime-checklist__section-header:hover .runtime-checklist__section-icon {
  color: var(--color-text-muted);
}

.runtime-checklist__section-icon-group {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}

.runtime-checklist__section-icon--open {
  display: none;
}

.runtime-checklist__section[open] .runtime-checklist__section-icon--open {
  display: inline-flex;
}

.runtime-checklist__section[open] .runtime-checklist__section-icon--closed {
  display: none;
}

/* == Runtime items == */
.runtime-checklist__items {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2) var(--space-3);
  padding-top: var(--space-3);
}

.runtime-checklist__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-size: var(--font-size-medium);
  cursor: pointer;
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.runtime-checklist__item:hover {
  background-color: var(--tint-navy-04);
}

.runtime-checklist__item--completed {
  background-color: var(--tint-green-10);
  border-color: var(--tint-green-28);
}

.runtime-checklist__item--completed:hover {
  background-color: var(--tint-green-16);
}

.runtime-checklist__item--completed .runtime-checklist__item-title {
  text-decoration: line-through;
  color: var(--color-text-muted);
}

.runtime-checklist__checkbox {
  width: 18px;
  height: 18px;
  margin-top: 2px;
  flex-shrink: 0;
  accent-color: var(--color-primary-green);
  cursor: pointer;
}

.runtime-checklist__item-content {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.runtime-checklist__item-title {
  color: var(--color-primary-dark);
  font-family: var(--font-family-bold);
  font-weight: 700;
  transition: color var(--transition-fast);
}

.runtime-checklist__item-details {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.runtime-checklist__item-meta {
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
}

/* == Builder index == */
.checklist-builder-index {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.checklist-builder-index__filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

.checklist-builder-index__filters .form__field {
  min-width: 240px;
}

.checklist-builder-index__scope-note {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.checklist-builder-index__card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.checklist-builder-index__split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
  align-items: start;
}

.checklist-builder-index__panel {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  overflow: hidden;
}

.checklist-builder-index__panel-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.checklist-builder-index__panel-title::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: var(--radius-full);
  flex-shrink: 0;
}

.checklist-builder-index__panel--active .checklist-builder-index__panel-title::before {
  background-color: var(--color-primary-green);
}

.checklist-builder-index__panel--drafts .checklist-builder-index__panel-title::before {
  background-color: var(--color-text-faint);
}

.checklist-builder-index__panel > .checklist-builder-index__cards,
.checklist-builder-index__panel > .checklist-builder-index__empty {
  padding: var(--space-4);
}

.checklist-builder-index__cards {
  display: grid;
  gap: var(--space-3);
}

.checklist-builder-index__card {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-4);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.checklist-builder-index__card:hover {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-sm);
}

.checklist-builder-index__card > .button {
  justify-self: start;
}

.checklist-builder-index__card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  color: var(--color-primary-dark);
}

.checklist-builder-index__badge {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  background-color: var(--tint-navy-06);
  border: 1px solid var(--tint-navy-16);
  border-radius: var(--radius-full);
  color: var(--color-primary-dark);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  white-space: nowrap;
}

.checklist-builder-index__card-meta {
  margin: 0;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.checklist-builder-index__empty {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
}

/* == Builder form == */
.checklist-builder {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  padding: var(--space-6);
}

.checklist-builder__header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.checklist-builder__header-meta {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.checklist-builder__header-actions {
  display: flex;
  gap: var(--space-3);
  flex-shrink: 0;
}

.checklist-builder__title {
  margin: 0;
  font-size: var(--font-size-xlarge);
  color: var(--color-primary-dark);
}

.checklist-builder__version {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.checklist-builder__error-summary {
  border: 1px solid var(--tint-danger-16);
  border-left: 3px solid var(--color-danger);
  border-radius: var(--radius-md);
  background-color: var(--tint-danger-10);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}

.checklist-builder__error-title {
  font-size: var(--font-size-medium);
  color: var(--color-danger);
  margin-bottom: var(--space-1);
}

.checklist-builder__error-list {
  margin: 0;
  padding-left: var(--space-4);
  color: var(--color-danger);
  font-size: var(--font-size-small);
}

.checklist-builder__field-error {
  margin-top: var(--space-1);
  color: var(--color-danger);
  font-size: var(--font-size-small);
}

.checklist-builder__hint {
  margin-top: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.checklist-builder__meta-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-2) var(--space-4);
  margin-bottom: var(--space-5);
}

/* == Builder sections == */
.checklist-builder__sections {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.checklist-builder__section {
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.checklist-builder__section-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.checklist-builder__section-header {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

.checklist-builder__section-header .button {
  margin-bottom: var(--space-1);
}

.checklist-builder__section-title-field {
  flex: 1;
}

/* Beats .form__field's default bottom margin regardless of sheet order */
.checklist-builder__section-header .checklist-builder__section-title-field {
  margin-bottom: 0;
}

.checklist-builder__items-label {
  margin: var(--space-4) 0 var(--space-2);
  font-size: var(--font-size-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.checklist-builder__items {
  display: grid;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.checklist-builder__item {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-primary-green);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xs);
  padding: var(--space-4);
  transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.checklist-builder__item:hover {
  box-shadow: var(--shadow-sm);
}

.checklist-builder__item-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
  margin-bottom: var(--space-3);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.checklist-builder__drag-handle {
  border: 1px solid var(--color-border);
  background-color: var(--color-surface);
  border-radius: var(--radius-sm);
  color: var(--color-text-faint);
  font-size: var(--font-size-medium);
  line-height: 1;
  padding: var(--space-1) var(--space-2);
  cursor: grab;
  transition: color var(--transition-fast), border-color var(--transition-fast),
    background-color var(--transition-fast);
}

.checklist-builder__drag-handle:hover {
  color: var(--color-text-muted);
  border-color: var(--color-border-strong);
  background-color: var(--color-surface-sunken);
}

.checklist-builder__drag-handle:active {
  cursor: grabbing;
}

.checklist-builder__section--dragging,
.checklist-builder__item--dragging {
  opacity: 0.55;
  box-shadow: 0 0 0 2px var(--tint-green-28);
}

/* == Publish modal == */
.checklist-publish-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
}

.checklist-publish-modal__overlay {
  position: absolute;
  inset: 0;
  background-color: rgba(15, 30, 45, 0.35);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.checklist-publish-modal__content {
  position: relative;
  width: min(1100px, calc(100vw - var(--space-10)));
  margin: var(--space-10) auto;
  max-height: calc(100vh - 2 * var(--space-10));
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}

.checklist-publish-modal__title {
  margin: 0;
  font-size: var(--font-size-xlarge);
  color: var(--color-primary-dark);
}

.checklist-publish-modal__description {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
}

.checklist-publish-modal__compare {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
  min-height: 0;
}

.checklist-publish-modal__column {
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  max-height: 50vh;
  overflow: auto;
}

.checklist-publish-modal__column-title {
  margin: 0 0 var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.checklist-publish-modal__empty {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.checklist-publish-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
}

/* == Definition preview == */
.checklist-definition-preview {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.checklist-definition-preview__section {
  padding: var(--space-4);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.checklist-definition-preview__section-title {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.checklist-definition-preview__items {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.checklist-definition-preview__item {
  padding: var(--space-2) var(--space-3);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.checklist-definition-preview__item-title {
  display: block;
  color: var(--color-text);
}

.checklist-definition-preview__item-details {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* == Definition show == */
.checklist-definition-show {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  padding: var(--space-6);
}

.checklist-definition-show__meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.checklist-definition-show__badge {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  background-color: var(--tint-navy-06);
  border: 1px solid var(--tint-navy-16);
  border-radius: var(--radius-full);
  color: var(--color-primary-dark);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  white-space: nowrap;
}

.checklist-definition-show__meta-item {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.checklist-definition-show__meta-item strong {
  color: var(--color-primary-dark);
}

.checklist-definition-show__notes {
  margin-bottom: var(--space-4);
  color: var(--color-text);
  font-size: var(--font-size-medium);
}

/* == Button modifier (used by the builder only) == */
.button--danger-outline {
  background-color: transparent;
  color: var(--color-danger);
  border-color: var(--tint-danger-16);
}

.button--danger-outline:hover {
  background-color: var(--tint-danger-10);
  border-color: var(--color-danger);
}

/* == Responsive == */
@media (max-width: 1024px) {
  .runtime-checklist__items {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .checklist-builder-index__split {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 760px) {
  .runtime-checklist__progress {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
  }

  .runtime-checklist__progress-bar {
    width: 100%;
    min-width: 0;
  }

  .runtime-checklist__items {
    grid-template-columns: 1fr;
  }

  .checklist-builder__meta-grid {
    grid-template-columns: 1fr;
  }

  .checklist-publish-modal__compare {
    grid-template-columns: 1fr;
  }
}


/* ===== components/colour_picker.css ===== */
/* ==========================================================================
   Colour Picker — palette built one colour at a time, backed by a single
   comma-separated hidden input; see colour_picker_controller.js.

   The swatch pill is shared with the read-only cards that report a palette
   (.colour-swatch below), so a colour looks the same whether it is being
   chosen or being read back.
   ========================================================================== */
.colour-picker {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  /* The form field this sits in keeps its labels on one line; the picker's own
     messages are prose and wrap. */
  white-space: normal;
}

.colour-picker__entry {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* The native colour input, unwrapped from its browser chrome so it reads as a
   swatch well sitting alongside the code box. */
.colour-picker__well {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}

.colour-picker__well:hover {
  border-color: var(--color-border-strong);
}

.colour-picker__well:focus-visible {
  outline: none;
  border-color: var(--color-primary-green);
  box-shadow: var(--focus-ring);
}

.colour-picker__well::-webkit-color-swatch-wrapper {
  padding: 3px;
}

.colour-picker__well::-webkit-color-swatch {
  border: none;
  border-radius: var(--radius-sm);
}

.colour-picker__well::-moz-color-swatch {
  border: none;
  border-radius: var(--radius-sm);
}

.colour-picker__code {
  flex: 1;
  min-width: 0;
}

.colour-picker__add {
  flex-shrink: 0;
}

.colour-picker__error {
  margin: 0;
  font-size: var(--font-size-small);
  color: var(--color-danger);
}

.colour-picker__empty {
  margin: 0;
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
}

/* --- Swatch pill (shared with the read-only palette) --------------------- */
.colour-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.colour-swatch {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3) var(--space-1) var(--space-1);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.colour-swatch__chip {
  width: 24px;
  height: 24px;
  border-radius: var(--radius-sm);
  /* An inset border rather than an outline, so a white or very pale brand
     colour is still a visible chip. */
  box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.12);
}

.colour-swatch__code {
  font-size: var(--font-size-medium);
  font-weight: 600;
  color: var(--color-primary-dark);
}

/* Only the editable palette carries these: the read-only pill has nothing to
   take off. */
.colour-swatch__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  margin-left: var(--space-1);
  padding: 0;
  border: none;
  border-radius: var(--radius-full);
  background: transparent;
  font-size: var(--font-size-medium);
  line-height: 1;
  color: var(--color-text-faint);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.colour-swatch__remove:hover {
  background: var(--tint-danger-10);
  color: var(--color-danger);
}

@media (max-width: 720px) {
  .colour-picker__entry {
    flex-wrap: wrap;
  }

  .colour-picker__code {
    flex: 1 1 140px;
  }
}


/* ===== components/confirm_dialog.css ===== */
/* ==========================================================================
   Confirmation dialog — stands in for the browser's confirm box
   ========================================================================== */

/* A native <dialog>, so it is the browser putting this in the top layer: no
   z-index of ours competes with the drawer or the tab strip while it is open.

   `margin: auto` is what centres a modal dialog, and it comes from the browser's
   own stylesheet — which the reset at the top of application.css wipes with
   `* { margin: 0 }`. Without it back the dialog sits in the page's top corner. */
.confirm-dialog {
  margin: auto;
  padding: 0;
  border: none;
  background: none;
  max-width: min(30rem, calc(100vw - var(--space-8)));
  color: var(--color-text);
  overflow: visible;
}

.confirm-dialog::backdrop {
  background-color: rgba(15, 30, 45, 0.4);
  backdrop-filter: blur(3px);
  animation: confirm-dialog-backdrop-in var(--transition-base);
}

.confirm-dialog[open] .confirm-dialog__panel {
  animation: confirm-dialog-in var(--transition-slow);
}

.confirm-dialog__panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  text-align: left;
}

.confirm-dialog__header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.confirm-dialog__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-md);
  color: var(--color-danger);
  background-color: var(--tint-danger-10);
}

.confirm-dialog__icon[hidden] {
  display: none;
}

.confirm-dialog__title {
  margin: 0;
  font-family: var(--font-family-bold);
  font-size: var(--font-size-large);
  color: var(--color-primary-dark);
}

.confirm-dialog__message {
  margin: 0;
  /* Indented to line up with the title rather than the icon, so the two read as
     one block. */
  padding-left: calc(36px + var(--space-3));
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
  line-height: 1.5;
}

.confirm-dialog__message[hidden] {
  display: none;
}

.confirm-dialog__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
}

@keyframes confirm-dialog-in {
  from {
    opacity: 0;
    transform: translateY(-8px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes confirm-dialog-backdrop-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}


/* ===== components/cookie_notice.css ===== */
/* ==========================================================================
   Cookie Notice — the acknowledgement banner

   A bar along the bottom rather than a modal: it has nothing to ask, so it has
   no business blocking the page while it says so.
   ========================================================================== */
.cookie-notice {
  position: fixed;
  right: var(--space-5);
  bottom: var(--space-5);
  left: var(--space-5);
  z-index: var(--z-cookie-notice);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  max-width: 900px;
  margin: 0 auto;
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  animation: cookie-notice-rise var(--transition-slow);
}

@keyframes cookie-notice-rise {
  from {
    opacity: 0;
    transform: translateY(var(--space-4));
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cookie-notice {
    animation: none;
  }
}

.cookie-notice__title {
  font-family: var(--font-family-bold);
  font-weight: 600;
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  margin-bottom: var(--space-1);
}

.cookie-notice__text {
  font-size: var(--font-size-medium);
  line-height: 1.6;
  color: var(--color-text);
}

.cookie-notice__link {
  color: var(--color-primary-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.cookie-notice__form {
  flex-shrink: 0;
}

.cookie-notice__button {
  white-space: nowrap;
}

@media (max-width: 640px) {
  .cookie-notice {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-4);
  }
}

/* ==========================================================================
   Room for it

   The banner is fixed over the bottom of the viewport, so every pane that
   scrolls to a bottom edge has to leave space under its content. Without this
   the banner sits on top of the last thing on the page — which, on the
   acceptance gate, is the button the user has to press to get past it.

   Set from the body class the layouts add while the banner is showing, so the
   space disappears with the banner rather than being left behind as a gap.

   One entry per full-screen backdrop that scrolls inside itself: the auth
   screens, the satisfaction survey, and the two legal pages. Padding the body
   would do nothing for them — each is `position: fixed; inset: 0` and scrolls
   its own contents, so the space has to be added inside.

   A new full-screen page of that shape needs a line here, or the banner will
   sit on whatever button it ends with. The application shell is a different
   problem and is handled below.
   ========================================================================== */
.has-cookie-notice .legal-doc,
.has-cookie-notice .legal-gate,
.has-cookie-notice .login-form,
.has-cookie-notice .survey-page {
  padding-bottom: 12rem;
}



/* ===== components/custom_select.css ===== */
/* ==========================================================================
   Custom Select — brand-styled, searchable replacement for a native <select>
   Backed by a hidden input; see custom_select_controller.js
   ========================================================================== */
.custom-select {
  position: relative;
  width: 100%;
}

/* == Trigger (mirrors .form__select) == */
.custom-select__trigger {
  width: 100%;
  height: 40px;
  padding: 0 var(--space-3);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-base);
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--transition-fast), background-color var(--transition-fast),
    box-shadow var(--transition-fast);
}

.custom-select__trigger:hover {
  border-color: var(--color-border-strong);
}

.custom-select--open .custom-select__trigger,
.custom-select__trigger:focus-visible {
  outline: none;
  background-color: var(--color-surface);
  border-color: var(--color-primary-green);
  box-shadow: var(--focus-ring);
}

.custom-select__value {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.custom-select__placeholder {
  color: var(--color-text-faint);
}

.custom-select__chevron {
  width: 1.5em;
  height: 1.5em;
  flex-shrink: 0;
  color: var(--color-text-muted);
  transition: transform var(--transition-fast);
}

.custom-select--open .custom-select__chevron {
  transform: rotate(180deg);
}

.custom-select--loading .custom-select__trigger {
  cursor: progress;
}

/* == Menu == */
.custom-select__menu {
  position: absolute;
  top: calc(100% + var(--space-1));
  left: 0;
  right: 0;
  z-index: var(--z-modal);
  display: flex;
  flex-direction: column;
  max-height: 280px;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

/* == Search box == */
.custom-select__search {
  position: relative;
  padding: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

.custom-select__search-icon {
  position: absolute;
  left: calc(var(--space-2) + var(--space-2));
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 16px;
  color: var(--color-text-faint);
  pointer-events: none;
}

.custom-select__search-input {
  width: 100%;
  height: 34px;
  padding: 0 var(--space-3) 0 var(--space-8);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background-color: var(--color-surface-sunken);
  font-family: var(--font-family-base);
  font-size: var(--font-size-medium);
  color: var(--color-text);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast),
    background-color var(--transition-fast);
}

.custom-select__search-input:focus {
  outline: none;
  background-color: var(--color-surface);
  border-color: var(--color-primary-green);
  box-shadow: var(--focus-ring);
}

/* == Options == */
.custom-select__options {
  padding: var(--space-1);
  overflow-y: auto;
}

.custom-select__option {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  font-size: var(--font-size-medium);
  font-family: var(--font-family-base);
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--transition-fast);
}

.custom-select__option:hover {
  background-color: var(--tint-navy-06);
}

.custom-select__option--selected {
  background-color: var(--tint-green-16);
  color: var(--color-primary-dark);
  font-weight: 600;
}

.custom-select__empty {
  padding: var(--space-4);
  text-align: center;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* The way to a value that is not on the list yet (see the partial's `creatable`).
   Sits under the options, divided from them, and reads as the action it is rather
   than as one more option to scan past. */
.custom-select__create {
  display: block;
  width: 100%;
  padding: var(--space-3);
  border: none;
  border-top: 1px solid var(--color-border);
  background: none;
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  color: var(--color-primary-dark);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--transition-fast);
}

.custom-select__create:hover {
  background-color: var(--tint-green-16);
}

/* == Multi-select == */
.custom-select__trigger--multi {
  height: auto;
  min-height: 40px;
  padding: var(--space-1) var(--space-2);
  align-items: center;
}

.custom-select__chips {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  min-width: 0;
  padding: var(--space-1) 0;
}

.custom-select__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-1) 2px var(--space-2);
  border-radius: var(--radius-full);
  background-color: var(--tint-green-16);
  border: 1px solid var(--tint-green-28);
  color: var(--color-primary-dark);
  font-size: var(--font-size-small);
  line-height: 1.4;
  max-width: 100%;
}

.custom-select__chip-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.custom-select__chip-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  padding: 0;
  border: none;
  border-radius: var(--radius-full);
  background: none;
  color: var(--color-text-muted);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.custom-select__chip-remove:hover {
  background-color: var(--tint-green-28);
  color: var(--color-primary-dark);
}

.custom-select__option--check {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.custom-select__check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--color-primary-green);
  font-size: 13px;
  opacity: 0;
}

.custom-select__option--selected .custom-select__check {
  opacity: 1;
}


/* ===== components/dashboard_editor.css ===== */
/* ==========================================================================
   Dashboard editor — the edit-mode surface: layout preset picker, the
   draggable widget catalogue, and the removal bin.
   ========================================================================== */
.dashboard-editor {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.dashboard-editor.hidden {
  display: none;
}

.dashboard-editor__group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.dashboard-editor__group--grow {
  flex: 1;
  min-width: 260px;
}

.dashboard-editor__title {
  font-size: var(--font-size-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.dashboard-editor__hint {
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
}

/* == layout preset picker == */
.dashboard-editor__layouts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-1);
}

.layout-option {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast),
    background-color var(--transition-fast);
}

.layout-option:hover {
  border-color: var(--color-border-strong);
}

.layout-option.is-active {
  border-color: var(--color-primary-green);
  background-color: var(--tint-green-10);
  box-shadow: var(--shadow-glow-green);
}

.layout-option__thumb {
  display: grid;
  gap: 2px;
  width: 48px;
  height: 34px;
}

.layout-option__cell {
  background-color: var(--color-border-strong);
  border-radius: 2px;
}

.layout-option.is-active .layout-option__cell {
  background-color: var(--color-primary-green);
}

.layout-option__thumb--stack {
  grid-template-columns: 1fr;
}

.layout-option__thumb--split {
  grid-template-columns: 1fr 1fr;
}

.layout-option__thumb--triptych {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
}

.layout-option__thumb--triptych .layout-option__cell:first-child {
  grid-column: 1 / -1;
}

.layout-option__thumb--hero {
  grid-template-rows: 1.3fr 1fr;
}

.layout-option__thumb--grid {
  grid-template-columns: 1fr;
}

.layout-option__thumb--grid .layout-option__cell {
  background-image: linear-gradient(var(--color-surface) 1px, transparent 1px),
    linear-gradient(90deg, var(--color-surface) 1px, transparent 1px);
  background-size: 10px 9px;
}

.layout-option__name {
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-primary-dark);
}

/* == widget catalogue == */
.dashboard-catalog {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
  min-height: 88px;
}

.dashboard-catalog.is-drop-target {
  border-color: var(--color-danger);
  background-color: var(--tint-danger-10);
}

.catalog-card {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  cursor: grab;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast),
    transform var(--transition-fast);
}

.catalog-card:hover {
  border-color: var(--color-primary-green);
  box-shadow: var(--shadow-xs);
}

.catalog-card--dragging {
  opacity: 0.5;
}

.catalog-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: var(--radius-md);
  background-color: var(--tint-green-16);
  color: var(--color-primary-dark);
}

.catalog-card__icon-svg {
  width: 17px;
  height: 17px;
}

.catalog-card__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.catalog-card__title {
  font-size: var(--font-size-medium);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.catalog-card__desc {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.catalog-card__add {
  margin-left: auto;
  color: var(--color-text-faint);
}

.dashboard-catalog__empty {
  grid-column: 1 / -1;
  align-self: center;
  text-align: center;
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
}

.dashboard-catalog__empty.hidden {
  display: none;
}

/* == removal bin == */
.dashboard-bin {
  display: none;
  position: sticky;
  bottom: var(--space-4);
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-4);
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
  background-color: var(--color-surface);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  box-shadow: var(--shadow-md);
}

.dashboard-home--editing .dashboard-bin {
  display: flex;
}

.dashboard-bin.is-drop-target {
  border-color: var(--color-danger);
  border-style: solid;
  background-color: var(--tint-danger-10);
  color: var(--color-danger);
}

.dashboard-bin__icon {
  width: 18px;
  height: 18px;
}


/* ===== components/dashboard_home.css ===== */
/* ==========================================================================
   Dashboard home — the board shell, layout presets and drop sections.
   Widget cards live in dashboard_widget.css; the edit-mode catalogue,
   layout picker and bin live in dashboard_editor.css.
   ========================================================================== */
.dashboard-home {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding-bottom: var(--space-10);
}

.dashboard-home__customise {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

/* == board: layout presets arrange the sections == */
.dashboard-board {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

.dashboard-board--split {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

.dashboard-board--triptych {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-areas:
    "hero hero"
    "primary secondary";
}

.dashboard-board--triptych [data-section="hero"] {
  grid-area: hero;
}

.dashboard-board--triptych [data-section="primary"] {
  grid-area: primary;
}

.dashboard-board--triptych [data-section="secondary"] {
  grid-area: secondary;
}

/* == section == */
.dashboard-board__section {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-height: 120px;
  padding: var(--space-2);
  border: 1px dashed transparent;
  border-radius: var(--radius-lg);
  transition: background-color var(--transition-base), border-color var(--transition-base);
}

.dashboard-board__section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 0 var(--space-1) var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

.dashboard-board__section-title {
  font-size: var(--font-size-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.dashboard-board__section-hint {
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
  opacity: 0;
  transition: opacity var(--transition-fast);
}

/* A section's widgets, in a grid of a known number of columns.
   The count is explicit — it used to be `auto-fill` over a minimum width, which
   meant nothing knew how many columns a section actually had. A widget set to
   Medium spans two columns and Large spans three (see dashboard_widget.css), so
   in a one-column section — which Stack is entirely, and which every column of
   Split and Triptych is — a widget spanned columns that were not there. The grid
   invented them, and the cards ran over each other and out of the section. That
   is what the Long/Stack layout was doing.

   With the count declared, a widget can be held to it: the rule below makes a
   widget full-width by default, and only the sections that really do have more
   than one column let the sizes mean anything. */
.dashboard-board__widgets {
  --widget-columns: 1;
  flex: 1;
  display: grid;
  gap: var(--space-4);
  grid-auto-flow: dense;
  grid-template-columns: repeat(var(--widget-columns), minmax(0, 1fr));
  align-content: start;
}

/* The safe default: a widget fills its section's row whatever size it is set to.
   Everything below widens it, never past the columns that exist. */
.dashboard-board__widgets .dashboard-widget {
  grid-column: 1 / -1;
}

/* The dense sections — the whole point of which is that widgets pack. */
.dashboard-board--grid .dashboard-board__widgets,
.dashboard-board--hero [data-section="body"] .dashboard-board__widgets,
.dashboard-board--triptych [data-section="hero"] .dashboard-board__widgets {
  --widget-columns: 3;
}

/* `:where()` so these carry no more weight than the class they name, and the
   narrow-screen rules at the foot of this file can still override them. */
:where(
  .dashboard-board--grid,
  .dashboard-board--hero [data-section="body"],
  .dashboard-board--triptych [data-section="hero"]
) .dashboard-board__widgets .dashboard-widget--small {
  grid-column: span 1;
}

:where(
  .dashboard-board--grid,
  .dashboard-board--hero [data-section="body"],
  .dashboard-board--triptych [data-section="hero"]
) .dashboard-board__widgets .dashboard-widget--medium {
  grid-column: span 2;
}

/* Large is the full width of the section rather than a span of three, so it
   still fits once the count drops on a narrower screen. */
:where(
  .dashboard-board--grid,
  .dashboard-board--hero [data-section="body"],
  .dashboard-board--triptych [data-section="hero"]
) .dashboard-board__widgets .dashboard-widget--large {
  grid-column: 1 / -1;
}

/* The spotlight is two columns: wide enough for a pair of small widgets, and
   anything bigger takes the row. */
.dashboard-board--hero [data-section="spotlight"] .dashboard-board__widgets {
  --widget-columns: 2;
}

:where(.dashboard-board--hero [data-section="spotlight"]) .dashboard-board__widgets .dashboard-widget--small {
  grid-column: span 1;
}

.dashboard-board__section-empty {
  display: none;
  grid-column: 1 / -1;
  padding: var(--space-6) var(--space-3);
  text-align: center;
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-md);
}

/* == edit mode == */
.dashboard-home--editing .dashboard-board__section {
  border-color: var(--color-border-strong);
  background-color: var(--color-surface-sunken);
}

.dashboard-home--editing .dashboard-board__section-hint {
  opacity: 1;
}

.dashboard-home--editing .dashboard-board__section-empty:only-child {
  display: block;
}

.dashboard-board__section.is-drop-target {
  border-color: var(--color-primary-green);
  border-style: solid;
  background-color: var(--tint-green-10);
}

/* == responsive == */

/* Three columns of widgets need the room for three. Below that the dense
   sections drop to two, and the spans above follow because Medium is two
   columns and Large is the whole row. */
@media (max-width: 1200px) {
  .dashboard-board--grid .dashboard-board__widgets,
  .dashboard-board--hero [data-section="body"] .dashboard-board__widgets,
  .dashboard-board--triptych [data-section="hero"] .dashboard-board__widgets {
    --widget-columns: 2;
  }
}

@media (max-width: 900px) {
  .dashboard-board--split,
  .dashboard-board--triptych {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: none;
  }

  .dashboard-board--triptych [data-section] {
    grid-area: auto;
  }

  /* One column everywhere, and every widget across it — a two-column span in a
     one-column grid is what put the cards on top of each other in the first
     place. Two class names, so this outweighs the `:where()`-scoped size rules
     above without having to repeat their selectors. */
  .dashboard-board .dashboard-board__widgets {
    --widget-columns: 1;
  }

  .dashboard-board__widgets .dashboard-widget {
    grid-column: 1 / -1;
  }
}


/* ===== components/dashboard_widget.css ===== */
/* ==========================================================================
   Dashboard widget — a purpose-built card rendered by a per-widget partial.
   Card chrome lives here; the board grid/sections live in dashboard_home.css
   and the edit-mode catalogue in dashboard_editor.css.
   ========================================================================== */
.dashboard-widget {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  transition: box-shadow var(--transition-base), border-color var(--transition-base),
    opacity var(--transition-base), transform var(--transition-base);
}

.dashboard-widget:hover {
  box-shadow: var(--shadow-md);
}

/* == size → grid footprint (clamped to a section's available columns) == */
/* How wide each size is left to the section the widget is in: a section knows
   how many columns it has, and a span wider than that is what used to push the
   cards over each other (see .dashboard-board__widgets in dashboard_home.css).
   The classes are still here because they are what the section's rules select
   on. */

/* == header == */
.dashboard-widget__header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

.dashboard-widget__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: var(--radius-md);
  background-color: var(--tint-green-16);
  color: var(--color-primary-dark);
}

.dashboard-widget__icon-svg {
  width: 18px;
  height: 18px;
}

.dashboard-widget__title {
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-medium);
  font-weight: 600;
  color: var(--color-primary-dark);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dashboard-widget__actions {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

/* Size switch, drag handle and remove button only surface while editing. */
.dashboard-widget__sizes,
.dashboard-widget__drag,
.dashboard-widget__remove {
  display: none;
}

.dashboard-widget__sizes {
  gap: 2px;
  padding: 2px;
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
}

.dashboard-widget__size {
  width: 22px;
  height: 22px;
  border: none;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.dashboard-widget__size:hover {
  color: var(--color-primary-dark);
}

.dashboard-widget__size.is-active {
  background-color: var(--color-primary-green);
  color: var(--color-white);
}

.dashboard-widget__drag {
  color: var(--color-text-faint);
  cursor: grab;
}

.dashboard-widget__remove {
  padding: var(--space-1);
  border: none;
  background: transparent;
  color: var(--color-text-faint);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.dashboard-widget__remove:hover {
  background-color: var(--tint-danger-10);
  color: var(--color-danger);
}

/* == body == */
.dashboard-widget__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* == hero (big single figure — schedule/notifications/time small) == */
.widget-hero {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.widget-hero__eyebrow {
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.widget-hero__value {
  font-size: var(--font-size-xxxlarge);
  font-weight: 700;
  line-height: 1.05;
  color: var(--color-primary-dark);
}

.widget-hero__value.is-muted {
  color: var(--color-text-faint);
}

.widget-hero__title {
  font-size: var(--font-size-medium);
  color: var(--color-text);
}

.widget-footnote {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.widget-footnote--truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* == stat tiles == */
.widget-stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-6);
}

.widget-stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 72px;
}

.widget-stat__value {
  font-size: var(--font-size-xxlarge);
  font-weight: 700;
  line-height: 1.1;
  color: var(--color-primary-dark);
}

.widget-stat--accent .widget-stat__value {
  color: var(--color-warning-dark);
}

.widget-stat--danger .widget-stat__value {
  color: var(--color-danger);
}

.widget-stat__label {
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

/* == breakdown bar + legend == */
.widget-breakdown {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.widget-breakdown__bar {
  display: flex;
  height: 10px;
  gap: 2px;
  border-radius: var(--radius-full);
  overflow: hidden;
  background-color: var(--color-surface-sunken);
}

.widget-breakdown__bar--empty::after {
  content: "";
  flex: 1;
  background-color: var(--color-border);
}

.widget-breakdown__seg {
  min-width: 4px;
}

.widget-legend {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
}

.widget-legend__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.widget-legend__dot {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-full);
}

.widget-legend__count {
  font-weight: 700;
  color: var(--color-primary-dark);
}

/* Shared status colour swatches for segments and legend dots. */
.widget-breakdown__seg--green,
.widget-legend__dot--green {
  background-color: var(--color-primary-green);
}

.widget-breakdown__seg--blue,
.widget-legend__dot--blue {
  background-color: #3498db;
}

.widget-breakdown__seg--yellow,
.widget-legend__dot--yellow {
  background-color: var(--color-warning);
}

.widget-breakdown__seg--red,
.widget-legend__dot--red {
  background-color: var(--color-danger);
}

.widget-breakdown__seg--gray,
.widget-legend__dot--gray {
  background-color: var(--color-text-faint);
}

.widget-breakdown__seg--purple,
.widget-legend__dot--purple {
  background-color: #8e44ad;
}

/* == agenda (schedule) == */
.widget-agenda {
  list-style: none;
  display: flex;
  flex-direction: column;
}

.widget-agenda__item {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-2) 0;
}

.widget-agenda__item:not(:first-child) {
  border-top: 1px solid var(--color-border);
}

.widget-agenda__time {
  display: flex;
  flex-direction: column;
  min-width: 74px;
}

.widget-agenda__day {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.widget-agenda__hour {
  font-size: var(--font-size-medium);
  font-weight: 700;
  color: var(--color-primary-dark);
}

.widget-agenda__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.widget-agenda__title {
  font-size: var(--font-size-medium);
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.widget-agenda__type {
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
}

/* == notifications == */
.widget-notifs {
  list-style: none;
  display: flex;
  flex-direction: column;
}

.widget-notifs__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) 0;
}

.widget-notifs__item:not(:first-child) {
  border-top: 1px solid var(--color-border);
}

.widget-notifs__dot {
  width: 8px;
  height: 8px;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  background-color: var(--color-border-strong);
}

.widget-notifs__item.is-unread .widget-notifs__dot {
  background-color: var(--color-primary-green);
}

.widget-notifs__msg {
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-medium);
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.widget-notifs__item.is-unread .widget-notifs__msg {
  font-weight: 600;
  color: var(--color-primary-dark);
}

.widget-notifs__time {
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
  flex-shrink: 0;
}

/* == bar chart (time log) == */
.widget-bars {
  display: flex;
  align-items: flex-end;
  gap: var(--space-2);
  height: 96px;
}

.widget-bars__col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  height: 100%;
}

.widget-bars__value {
  font-size: 10px;
  color: var(--color-text-faint);
}

.widget-bars__track {
  position: relative;
  flex: 1;
  width: 100%;
  max-width: 26px;
  display: flex;
  align-items: flex-end;
  border-radius: var(--radius-sm);
  background-color: var(--color-surface-sunken);
  overflow: hidden;
}

.widget-bars__fill {
  width: 100%;
  min-height: 3px;
  border-radius: var(--radius-sm);
  background: linear-gradient(180deg, var(--color-primary-green), #46b78c);
}

.widget-bars__label {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* == record list (cases/reviews/firms/complaints) == */
.widget-list {
  list-style: none;
  display: flex;
  flex-direction: column;
}

.widget-list__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) 0;
}

.widget-list__item:not(:first-child) {
  border-top: 1px solid var(--color-border);
}

.widget-list__main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.widget-list__label {
  font-size: var(--font-size-medium);
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.widget-list__meta {
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.widget-list__aside {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

.widget-due {
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.widget-due--overdue {
  color: var(--color-danger);
}

/* == inline meta pills (business projects/tasks/checklists) == */
.widget-pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.widget-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  font-size: var(--font-size-small);
  color: var(--color-secondary-dark);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
}

.widget-pill__icon {
  color: var(--color-text-muted);
}

/* == section sub-label inside a large widget == */
.widget-section-label {
  font-size: var(--font-size-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

/* == empty states == */
.widget-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-6) var(--space-3);
  text-align: center;
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
}

.widget-empty--inline {
  padding: var(--space-4) var(--space-3);
}

.widget-empty__icon {
  width: 22px;
  height: 22px;
  opacity: 0.6;
}

/* == states == */
.dashboard-widget--dragging {
  opacity: 0.5;
  box-shadow: var(--shadow-md);
}

.dashboard-home--editing .dashboard-widget {
  cursor: grab;
  border-style: dashed;
}

.dashboard-home--editing .dashboard-widget__sizes {
  display: inline-flex;
}

.dashboard-home--editing .dashboard-widget__drag,
.dashboard-home--editing .dashboard-widget__remove {
  display: inline-flex;
}

.dashboard-home--editing .dashboard-widget__open {
  display: none;
}

/* == "Assigned to me": three kinds of record in one table == */
.assigned-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  overflow-x: auto;
}

.assigned-list__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-small);
}

.assigned-list__table th {
  text-align: left;
  padding: 0 var(--space-2) var(--space-2);
  font-weight: 600;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
}

.assigned-list__table td {
  padding: var(--space-2);
  border-bottom: 1px solid var(--color-border);
  vertical-align: middle;
  color: var(--color-text);
}

.assigned-list__table tr:last-child td {
  border-bottom: none;
}

.assigned-list__link {
  color: inherit;
  text-decoration: none;
  font-weight: 500;
}

.assigned-list__link:hover {
  text-decoration: underline;
}

/* Which of the three kinds of record the row is, set under its name so the
   first column reads as one thing rather than two. */
.assigned-list__type {
  display: block;
  color: var(--color-text-muted);
  font-size: 11px;
}

/* "+2", where a task names more than one firm or client. */
.assigned-list__extra {
  color: var(--color-text-muted);
}

.assigned-list__more {
  margin: 0;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}


/* ===== components/documents.css ===== */
/* ==========================================================================
   Documents — the shared library on a firm record, a case, a review and a task.

   One component for all three of its views: the flat list (which reuses the
   app's table styles), the folder explorer and the tree. What is common to them
   — the toolbar, the file and version pills, the empty states — sits at the top.
   ========================================================================== */
.documents {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  width: 100%;
  min-width: 0;
}

/* == "storage is not connected" banner ==
   Sits above everything, once, for as long as there is no bucket behind the
   library (see Document.storage_connected?). */
.documents__notice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-warning);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  line-height: 1.5;
}

.documents__notice-icon {
  flex: 0 0 auto;
  margin-top: 1px;
  color: var(--color-warning);
}

/* == toolbar == */
.documents__toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.documents__controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

/* == view switcher ==
   A segmented control: three links that look like one control, so which view is
   open reads as a position rather than as a highlighted link. */
.documents__views {
  display: inline-flex;
  padding: 3px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
}

.documents__view {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-decoration: none;
  transition: background-color var(--transition-base), color var(--transition-base);
}

.documents__view:hover {
  color: var(--color-primary-dark);
}

.documents__view--active {
  background-color: var(--color-surface);
  color: var(--color-primary-dark);
  box-shadow: 0 1px 2px var(--tint-navy-10);
}

/* == list view == */
.documents__name-cell {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}

.documents__file-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  background-color: var(--tint-navy-06);
  color: var(--color-primary-dark);
}

.documents__name {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.documents__name-title {
  font-weight: 600;
  color: var(--color-text);
}

/* The filename under the document's name: the same file can be filed under a
   name nobody would recognise it by, so both are shown. */
.documents__name-file {
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* == version pill ==
   Tinted once a document has history behind it, so a replaced file is obvious
   from the row without opening it. */
.documents__version-pill {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  background-color: var(--tint-navy-06);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  white-space: nowrap;
}

.documents__version-pill--history {
  background-color: var(--tint-green-16);
  color: var(--color-primary-dark);
}

.documents__version-active {
  padding: 1px var(--space-2);
  border-radius: var(--radius-full);
  background-color: var(--color-primary-green);
  color: var(--color-white);
  font-size: var(--font-size-small);
  font-weight: 600;
  white-space: nowrap;
}

/* == "showing one folder only" strip, above the list == */
.documents__scope {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background-color: var(--tint-navy-04);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.documents__scope-icon {
  color: var(--color-primary-dark);
}

.documents__scope-clear {
  margin-left: auto;
  color: var(--color-primary-dark);
  font-weight: 600;
  text-decoration: none;
}

.documents__scope-clear:hover {
  text-decoration: underline;
}

/* == folder view == */
.documents__folder-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--space-3);
  list-style: none;
  margin: 0;
  padding: 0;
}

.documents__folder {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  height: 100%;
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
  text-decoration: none;
  transition: border-color var(--transition-base), box-shadow var(--transition-base),
    transform var(--transition-base);
}

.documents__folder:hover {
  border-color: var(--color-primary-green);
  box-shadow: 0 2px 8px var(--tint-navy-10);
  transform: translateY(-1px);
}

/* An empty folder is still a folder — it is part of the filing plan — but it
   should not compete with the ones holding something. */
.documents__folder--empty {
  background-color: var(--color-surface-sunken);
}

.documents__folder--empty .documents__folder-icon,
.documents__folder--empty .documents__folder-name {
  color: var(--color-text-faint);
}

.documents__folder-icon {
  color: var(--color-primary-green);
}

.documents__folder-name {
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.documents__folder-meta {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* == open folder == */
.documents__folder-path {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-medium);
}

.documents__folder-up {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-muted);
  text-decoration: none;
}

.documents__folder-up:hover {
  color: var(--color-primary-dark);
}

.documents__folder-sep {
  color: var(--color-text-faint);
}

.documents__folder-current {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.documents__folder-count {
  margin-left: auto;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.documents__files {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.documents__file {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
}

.documents__file-detail {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
}

.documents__file-name {
  font-weight: 600;
  color: var(--color-text);
}

.documents__file-meta {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* == tree view ==
   Built from <details>, so the browser owns expand/collapse. The caret is the
   only thing that has to know which way round it is. */
.documents__tree {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
}

.documents__node {
  border-radius: var(--radius-sm);
}

.documents__node--document,
.documents__node-empty,
.documents__node > p {
  /* Indent one level per step down the tree, with a guide line back up to the
     parent so a deep list stays readable. */
  margin-left: var(--space-4);
  padding-left: var(--space-3);
  border-left: 1px solid var(--color-border);
}

.documents__node-summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  cursor: pointer;
  list-style: none;
}

.documents__node-summary::-webkit-details-marker {
  display: none;
}

.documents__node-summary:hover {
  background-color: var(--tint-navy-04);
}

.documents__node-caret {
  display: inline-flex;
  flex: 0 0 auto;
  color: var(--color-text-faint);
  transition: transform var(--transition-base);
}

.documents__node[open] > .documents__node-summary .documents__node-caret {
  transform: rotate(90deg);
}

.documents__node-icon {
  display: inline-flex;
  flex: 0 0 auto;
  color: var(--color-primary-green);
}

.documents__node--document > .documents__node-summary .documents__node-icon {
  color: var(--color-primary-dark);
}

.documents__node-label {
  font-weight: 600;
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.documents__node-meta {
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
}

.documents__node-count {
  margin-left: auto;
  padding: 1px var(--space-2);
  border-radius: var(--radius-full);
  background-color: var(--tint-navy-06);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-weight: 600;
}

/* The version pill and count both want the right-hand end; whichever comes
   first takes it and the rest follow. */
.documents__node-summary .documents__version-pill {
  margin-left: auto;
}

.documents__node-summary .documents__node-count ~ .documents__version-pill {
  margin-left: 0;
}

.documents__node-actions {
  margin-left: var(--space-4);
  padding: 0 var(--space-3) var(--space-2);
}

.documents__node-empty {
  padding: var(--space-2) 0;
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
}

.documents__versions {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0 0 var(--space-2) var(--space-4);
  padding-left: var(--space-3);
  border-left: 1px solid var(--color-border);
  list-style: none;
}

.documents__version {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.documents__version--current {
  background-color: var(--tint-green-10);
}

.documents__version-label {
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.documents__version-file {
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.documents__version-meta {
  margin-left: auto;
  color: var(--color-text-faint);
  white-space: nowrap;
}

/* == empty states == */
.documents__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-6) var(--space-4);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
  text-align: center;
  color: var(--color-text-muted);
}

.documents__empty--first {
  padding: var(--space-8) var(--space-4);
}

.documents__empty-icon {
  color: var(--color-text-faint);
}

.documents__empty-title {
  margin: 0;
  font-size: var(--font-size-large);
}

.documents__empty p {
  max-width: 52ch;
  line-height: 1.6;
}

/* == upload control ==
   The real input is laid transparently over the whole zone rather than hidden
   away from it: the label below is the styling, the input is the hit area, and
   nothing has to forward a click. Transparent rather than clipped or display:
   none, so it keeps its size and stays reachable — a clipped input is one
   nothing driving the page can be made to see. */
.documents__dropzone {
  position: relative;
}

.documents__dropzone-input {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.documents__dropzone-label {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-4);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
  color: var(--color-text-muted);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--transition-base), background-color var(--transition-base);
}

.documents__dropzone-label:hover {
  border-color: var(--color-primary-green);
}

/* Keyboard users focus the input, which is off screen — so the label wearing
   the focus ring is the only way the focus is visible. */
.documents__dropzone-input:focus-visible + .documents__dropzone-label {
  border-color: var(--color-primary-green);
  outline: 2px solid var(--color-primary-green);
  outline-offset: 2px;
}

.documents__dropzone--filled .documents__dropzone-label {
  border-style: solid;
  border-color: var(--color-primary-green);
  background-color: var(--tint-green-10);
  color: var(--color-primary-dark);
}

.documents__dropzone-prompt {
  font-family: var(--font-family-bold);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.documents__dropzone-hint {
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
}

.documents__dropzone--filled .documents__dropzone-hint {
  display: none;
}

/* == drawer: document detail and version history == */
.documents__drawer-summary {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  margin-bottom: var(--space-4);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
}

.documents__drawer-name {
  margin: 0;
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.documents__drawer-meta {
  margin: 0;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.documents__detail {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.documents__detail-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3) var(--space-4);
  margin: 0;
}

.documents__detail-grid dt {
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.documents__detail-grid dd {
  margin: var(--space-1) 0 0;
  color: var(--color-text);
  overflow-wrap: anywhere;
}

.documents__detail-description {
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
  color: var(--color-text-muted);
  line-height: 1.6;
}

.documents__detail-heading {
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-medium);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.documents__history {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.documents__history-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.documents__history-item--current {
  border-color: var(--color-primary-green);
  background-color: var(--tint-green-10);
}

.documents__history-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.documents__history-file {
  font-weight: 600;
  color: var(--color-text);
  overflow-wrap: anywhere;
}

.documents__history-meta {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.documents__history-notes {
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  background-color: var(--color-surface-sunken);
  font-size: var(--font-size-small);
  color: var(--color-text);
}

.documents__history-actions {
  display: flex;
  gap: var(--space-2);
}

/* == narrow screens ==
   The library appears inside a tab and inside the firm record's content column,
   both of which are already narrow before the viewport is. */
@media (max-width: 768px) {
  .documents__toolbar {
    flex-direction: column;
    align-items: stretch;
  }

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

  .documents__detail-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .documents__file {
    flex-wrap: wrap;
  }
}

/* Client documents — the Source column, which names the case, review or report a
   row came from and links to it. The pill and the link sit on one line so the
   column reads as one thing rather than two. */
.documents__source {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* A row filed before the bucket was connected: the record is real and the file
   was never kept, so the action cell says so rather than offering a download
   that cannot work (see DocumentStorage). */
.documents__unstored {
  color: var(--color-text-muted);
  font-size: 0.8125rem;
  font-style: italic;
}


/* ===== components/drawer.css ===== */
/* ==========================================================================
   Drawer — right-hand slide-over panel
   ========================================================================== */
.drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-drawer);
  display: flex;
  justify-content: flex-end;
  width: 40%;
  min-width: 420px;
}

.drawer__overlay {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: rgba(15, 30, 45, 0.35);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: calc(var(--z-drawer) - 1);
  opacity: 0;
  transition: opacity var(--transition-slow);
}

.drawer__content {
  position: relative;
  width: 100%;
  height: 100%;
  background-color: var(--color-surface);
  box-shadow: var(--shadow-lg);
  border-left: 1px solid var(--color-border);
  border-radius: var(--radius-xl) 0 0 var(--radius-xl);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform var(--transition-slow);
}

/* Open state — toggled by the drawer controller to play the slide in/out. */
.drawer--shown .drawer__overlay {
  opacity: 1;
}

.drawer--shown .drawer__content {
  transform: translateX(0);
}

@media (prefers-reduced-motion: reduce) {
  .drawer__overlay,
  .drawer__content {
    transition: none;
  }
}

.drawer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 0 var(--space-5);
  background-color: var(--color-primary-green);
  color: var(--color-white);
  height: var(--topbar-height);
  flex-shrink: 0;
}

.drawer__header--danger {
  background-color: var(--color-danger-light);
}

.drawer__title {
  margin: 0;
  font-size: var(--font-size-xlarge);
  font-weight: 600;
  color: var(--color-white);
}

.drawer__close {
  border: none;
  background: var(--tint-white-10);
  color: var(--color-white);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  width: 34px;
  height: 34px;
  border-radius: var(--radius-md);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color var(--transition-base);
}

.drawer__close:hover {
  background: var(--tint-white-24);
}

.drawer__body {
  padding: var(--space-5);
  flex: 1;
  overflow-y: auto;
}

body.drawer--open {
  overflow: hidden;
}

@media (max-width: 768px) {
  .drawer {
    width: 100%;
    min-width: 0;
  }

  .drawer__content {
    border-radius: 0;
  }
}

/* ==========================================================================
   Assignment workflow (rendered inside the drawer)
   ========================================================================== */
.assignment-workflow__steps {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
  padding-bottom: var(--space-2);
}

.assignment-workflow__step {
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-family-bold);
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
  cursor: pointer;
  transition: background-color var(--transition-base), color var(--transition-base);
}

.assignment-workflow__step:hover {
  background: var(--tint-navy-06);
}

.assignment-workflow__step--active {
  color: var(--color-primary-dark);
  border-color: var(--tint-green-28);
  background: var(--tint-green-10);
  box-shadow: inset 0 -2px 0 var(--color-primary-green);
}

.assignment-workflow__panel {
  margin-bottom: var(--space-4);
}

.assignment-workflow__panel h3 {
  margin-bottom: var(--space-1);
  color: var(--color-primary-dark);
}

.assignment-workflow__panel p {
  margin-bottom: var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
}

.assignment-workflow__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
}

.assignment-workflow__errors {
  border: 1px solid var(--tint-danger-16);
  border-left: 3px solid var(--color-danger);
  border-radius: var(--radius-md);
  background: var(--tint-danger-10);
  color: var(--color-danger);
  font-size: var(--font-size-small);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}

.assignment-workflow__errors ul {
  margin: 0;
  padding-left: var(--space-4);
}


/* ===== components/due_date_requests.css ===== */
/* ==========================================================================
   Due-date change requests + shared assignment/drawer helpers
   ========================================================================== */

/* Generic form error summary (assignment + request drawers, notes) */
.form__errors {
  margin-bottom: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--tint-danger-16);
  border-left: 3px solid var(--color-danger);
  border-radius: var(--radius-md);
  background-color: var(--tint-danger-10);
  color: var(--color-danger);
  font-size: var(--font-size-small);
}

.form__errors ul {
  margin: 0;
  padding-left: var(--space-4);
}

.drawer__intro {
  margin: 0 0 var(--space-4);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  line-height: 1.5;
}

/* Pending request cards on the case show page */
/* A card of its own on the case record, so the gap above it is the column's. */
.due-date-requests {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.due-date-request {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-warning);
  border-radius: var(--radius-md);
}

.due-date-request__body {
  min-width: 0;
}

.due-date-request__headline {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.due-date-request__date {
  font-family: var(--font-family-bold);
  color: var(--color-primary-dark);
}

.due-date-request__meta {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.due-date-request__reason {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-small);
  color: var(--color-text);
  line-height: 1.45;
}

.due-date-request__actions {
  display: flex;
  gap: var(--space-2);
  flex-shrink: 0;
}

.due-date-request__awaiting {
  flex-shrink: 0;
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
  font-style: italic;
}


/* ===== components/eos.css ===== */
/* ==========================================================================
   EOS record — nested subnav, page shell, cards, tables and the list builders
   the record is configured from.

   The shell is the firm record's, at the same measurements (see firm_show.css):
   these are pages of one record with a nav down the left, and the two should
   read as the same kind of screen. The classes are the EOS record's own rather
   than borrowed, so a change to how a firm record's tabs look does not silently
   restyle a page about how the practice runs.
   ========================================================================== */

/* --- Shell layout -------------------------------------------------------- */
.eos-show {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: var(--space-8);
  align-items: start;
}

.eos-show__main {
  min-width: 0;
}

.eos-show__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.eos-show__heading {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.eos-show__title {
  margin: 0;
  font-size: var(--font-size-xxlarge);
  font-weight: 600;
  color: var(--color-primary-dark);
}

/* The quarter the whole record is read against. Quiet — it is a fact about the
   page, not a control. */
.eos-show__cycle {
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  background: var(--tint-navy-06);
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  font-weight: 600;
  white-space: nowrap;
}

.eos-show__header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

.eos-show__body {
  min-width: 0;
}

/* --- Subnav -------------------------------------------------------------- */
.eos-subnav {
  position: sticky;
  top: calc(var(--topbar-height) + var(--space-4));
  padding: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.eos-subnav__heading {
  margin: 0 0 var(--space-2);
  padding: var(--space-1) var(--space-3);
  font-size: var(--font-size-small);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.eos-subnav__list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.eos-subnav__link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  font-weight: 500;
  text-decoration: none;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.eos-subnav__link:hover {
  background: var(--tint-navy-04);
  color: var(--color-primary-dark);
}

.eos-subnav__link:hover .eos-subnav__icon {
  color: var(--color-primary-dark);
}

.eos-subnav__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  background: var(--tint-navy-06);
  color: var(--color-text-muted);
  transition: background var(--transition-fast), color var(--transition-fast);
}

.eos-subnav__icon .minor-icon {
  width: 16px;
  height: 16px;
}

.eos-subnav__label {
  min-width: 0;
}

.eos-subnav__link--active {
  background: var(--tint-green-16);
  color: var(--color-primary-dark);
  font-weight: 600;
}

.eos-subnav__link--active .eos-subnav__icon {
  background: var(--color-primary-green);
  color: var(--color-white);
}

/* What is still open on the two lists the team works from. */
.eos-subnav__badge {
  margin-left: auto;
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  background: var(--tint-navy-10);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
}

.eos-subnav__link--active .eos-subnav__badge {
  background: var(--color-white);
}

/* Settings is where the record is configured rather than another part of it to
   read, so it sits below a rule at the foot — as the firm record's sign-out
   does. */
.eos-subnav__footer {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-border);
}

/* --- Body layouts -------------------------------------------------------- */
.eos-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}

.eos-dashboard {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: var(--space-5);
  align-items: start;
}

.eos-dashboard__col {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}

/* --- Card primitive ------------------------------------------------------ */
.eos-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.eos-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.eos-card__heading {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.eos-card__title {
  margin: 0;
  font-size: var(--font-size-xlarge);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.eos-card__subtitle,
.eos-card__blurb,
.eos-card__note,
.eos-card__empty {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  line-height: 1.6;
}

.eos-card__note {
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-yellow-100);
  color: var(--color-warning-dark);
}

.eos-card__meta {
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  white-space: nowrap;
}

.eos-card__header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

.eos-card__actions {
  display: flex;
  gap: var(--space-2);
}

.eos-card__link {
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  text-decoration: none;
  white-space: nowrap;
}

.eos-card__link:hover {
  color: var(--color-primary-dark);
  text-decoration: underline;
}

/* --- V/TO ---------------------------------------------------------------- */
.eos-vto {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6);
  align-items: start;
}

.eos-vto__col {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}

.eos-vto__label {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-small);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.eos-vto__sublabel {
  margin: var(--space-3) 0 var(--space-1);
  font-size: var(--font-size-small);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.eos-vto__sublabel:first-of-type {
  margin-top: 0;
}

.eos-vto__pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.eos-vto__text,
.eos-vto__empty {
  margin: 0;
  color: var(--color-text);
  font-size: var(--font-size-medium);
  line-height: 1.6;
}

.eos-vto__empty {
  color: var(--color-text-faint);
}

.eos-vto__pairs {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
}

.eos-vto__pair {
  display: flex;
  gap: var(--space-2);
  font-size: var(--font-size-medium);
  line-height: 1.6;
}

.eos-vto__pair dt {
  flex-shrink: 0;
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.eos-vto__pair dd {
  margin: 0;
  min-width: 0;
  color: var(--color-text);
}

/* The three horizons read the same way — they are the same statement at three
   distances, and only the date separates them. */
.eos-horizon {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}

.eos-horizon__body {
  margin: 0;
  color: var(--color-text);
  font-size: var(--font-size-medium);
  line-height: 1.6;
}

.eos-horizon__date {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  background: var(--tint-navy-06);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
}

.eos-horizon__date-icon {
  display: inline-flex;
  color: var(--color-primary-green);
}

/* --- Record tables ------------------------------------------------------- */
.eos-records__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.eos-records__title {
  margin: 0;
  font-size: var(--font-size-large);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.eos-records__controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.eos-records .table-container {
  margin-bottom: 0;
}

.eos-records__link {
  color: var(--color-primary-dark);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-decoration: none;
}

.eos-records__link:hover {
  text-decoration: underline;
}

/* The Notes column on the issues and actions tables: how many updates the
   thread holds, and the way into it. A quiet chip rather than a button — it is
   a count first — that reads as a link on hover. */
.eos-records__notes {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--tint-navy-06);
  color: var(--color-primary-dark);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-decoration: none;
  transition: background-color var(--transition-base), color var(--transition-base);
}

.eos-records__notes:hover {
  background: var(--color-primary-dark);
  color: var(--color-surface);
}

/* No thread yet: still the way in — that is where the first update is
   written — but nothing to draw the eye to. */
.eos-records__notes--empty {
  background: transparent;
  color: var(--color-text-faint);
}

/* A summary is a sentence rather than a value, so it is allowed to be the wide
   column and to wrap. */
.eos-records__summary {
  max-width: 480px;
  white-space: normal;
  color: var(--color-text-muted);
}

/* Current / Historic / All, above the goals table. Same control as the
   Active / Deleted switch below it (see .deletion-tabs in table.css), because
   they are the same kind of choice and sit one above the other. */
.eos-cycle-tabs {
  display: inline-flex;
  align-self: flex-start;
  flex: 0 0 auto;
  gap: var(--space-1);
  margin-bottom: var(--space-3);
  padding: 3px;
  background-color: var(--tint-navy-06);
  border-radius: var(--radius-md);
}

.eos-cycle-tabs__tab {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-4);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  text-decoration: none;
  transition: background-color var(--transition-base), color var(--transition-base);
}

.eos-cycle-tabs__tab:hover {
  color: var(--color-primary-dark);
}

.eos-cycle-tabs__tab--current {
  background-color: var(--color-surface);
  color: var(--color-primary-dark);
  box-shadow: var(--shadow-sm), inset 0 -2px 0 var(--color-primary-green);
}

/* --- Progress bar -------------------------------------------------------- */
/* The number is spelled out beside the bar: the value is set by hand, so it is
   a figure somebody chose rather than a length to be estimated. */
.eos-progress {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 140px;
}

.eos-progress__track {
  flex: 1 1 auto;
  height: 8px;
  min-width: 72px;
  border-radius: var(--radius-full);
  background: var(--tint-navy-10);
  overflow: hidden;
}

.eos-progress__fill {
  height: 100%;
  border-radius: var(--radius-full);
  background: var(--color-primary-green);
}

.eos-progress__value {
  flex: 0 0 auto;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-variant-numeric: tabular-nums;
}

/* --- Dashboard tiles and mini lists -------------------------------------- */
.eos-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
}

.eos-stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  text-decoration: none;
  transition: box-shadow var(--transition-fast), border-color var(--transition-fast);
}

.eos-stat:hover {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-sm);
}

.eos-stat__value {
  font-size: var(--font-size-xxxlarge);
  font-weight: 600;
  line-height: 1.1;
  color: var(--color-primary-dark);
}

.eos-stat__label {
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
}

.eos-stat__note {
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
}

.eos-stat--danger .eos-stat__note {
  color: var(--color-danger);
}

.eos-mini-list {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

.eos-mini-list__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}

.eos-mini-list__row:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.eos-mini-list__main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}

.eos-mini-list__title,
.eos-mini-list__title a {
  color: var(--color-primary-dark);
  font-size: var(--font-size-medium);
  font-weight: 600;
  text-decoration: none;
}

.eos-mini-list__title a:hover {
  text-decoration: underline;
}

.eos-mini-list__meta {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  white-space: nowrap;
}

.eos-mini-list__meta--danger {
  color: var(--color-danger);
  font-family: var(--font-family-bold);
}

/* --- Record details ------------------------------------------------------ */
.eos-details {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-4);
  margin: 0;
}

.eos-details__pair {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.eos-details__pair dt {
  font-size: var(--font-size-small);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.eos-details__pair dd {
  margin: 0;
  color: var(--color-text);
  font-size: var(--font-size-medium);
}

.eos-details__value--danger {
  color: var(--color-danger);
  font-family: var(--font-family-bold);
}

.eos-details__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* --- Meetings ------------------------------------------------------------ */
.eos-start-meeting {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

/* The custom select is `width: 100%` by default, which on a flex row of two
   controls takes the whole line and pushes the button under it. Here it is one
   of a pair, so it is given a width of its own and told not to grow. */
.eos-start-meeting__select {
  flex: 0 0 auto;
  width: 220px;
}

.eos-agenda {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
}

.eos-agenda__item {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}

.eos-agenda__head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}

.eos-agenda__position {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-full);
  background: var(--tint-navy-10);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
}

.eos-agenda__heading {
  flex: 1 1 auto;
  min-width: 0;
}

.eos-agenda__title {
  margin: 0;
  font-size: var(--font-size-medium);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.eos-agenda__details {
  margin: var(--space-1) 0 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  line-height: 1.6;
}

.eos-agenda__slot {
  flex-shrink: 0;
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
}

/* --- Agenda cards on the settings page ----------------------------------- */
.eos-agenda-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-4);
}

.eos-agenda-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}

.eos-agenda-card__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}

.eos-agenda-card__title {
  margin: 0;
  font-size: var(--font-size-large);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.eos-agenda-card__total {
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  white-space: nowrap;
}

.eos-agenda-card__blurb,
.eos-agenda-card__empty {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  line-height: 1.6;
}

.eos-agenda-card__empty {
  color: var(--color-text-faint);
}

.eos-agenda-card__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
  padding-left: var(--space-5);
  color: var(--color-text);
  font-size: var(--font-size-medium);
}

.eos-agenda-card__item-slot {
  margin-left: var(--space-2);
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
}

.eos-agenda-card__actions {
  margin-top: auto;
  padding-top: var(--space-2);
}

/* --- Forms and the list builders ----------------------------------------- */
.eos-form__section {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

.eos-form__section:first-of-type {
  padding-top: 0;
  border-top: 0;
}

.eos-form__section-title {
  margin: 0;
  font-size: var(--font-size-medium);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.eos-form__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-4);
}

.eos-form__hint {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  line-height: 1.5;
}

.eos-form__field-error {
  margin: var(--space-1) 0 0;
  color: var(--color-danger);
  font-size: var(--font-size-small);
}

.eos-form__errors {
  padding: var(--space-4);
  border: 1px solid var(--tint-danger-16);
  border-radius: var(--radius-md);
  background: var(--tint-danger-10);
  color: var(--color-danger);
}

.eos-form__errors-title {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-medium);
  color: var(--color-danger);
}

.eos-form__errors ul {
  margin: 0;
  padding-left: var(--space-5);
  font-size: var(--font-size-medium);
}

.eos-builder {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.eos-builder--stacked {
  gap: var(--space-3);
}

.eos-builder__row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}

.eos-builder__row--stacked {
  flex-direction: column;
  gap: var(--space-3);
}

.eos-builder__row--dragging {
  opacity: 0.5;
  border-color: var(--color-primary-green);
}

.eos-builder__row-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
}

.eos-builder__row-label {
  flex: 1 1 auto;
  font-size: var(--font-size-small);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.eos-builder__row-fields {
  display: flex;
  gap: var(--space-3);
  width: 100%;
}

.eos-builder__field {
  flex: 1 1 auto;
  min-width: 0;
}

.eos-builder__field--narrow {
  flex: 0 0 110px;
}

.eos-builder__handle {
  flex-shrink: 0;
  margin-top: var(--space-1);
  padding: 0 var(--space-1);
  border: 0;
  background: none;
  color: var(--color-text-faint);
  font-size: var(--font-size-large);
  line-height: 1;
  cursor: grab;
}

.eos-builder__row--stacked .eos-builder__handle {
  margin-top: 0;
}

.eos-builder__handle:active {
  cursor: grabbing;
}

/* --- Empty states -------------------------------------------------------- */
.eos-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-10) var(--space-6);
  text-align: center;
}

.eos-empty__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--radius-lg);
  background: var(--tint-green-16);
  color: var(--color-primary-green);
}

.eos-empty__title {
  margin: 0;
  font-size: var(--font-size-large);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.eos-empty__blurb {
  margin: 0;
  max-width: 44ch;
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  line-height: 1.6;
}

/* Every page of the EOS record fills the viewport rather than growing past it,
   the way a firm record's does: the breadcrumb, page header and subnav stay put
   and only the body scrolls.

   A record-table page hands that scroll on to the table, so its search and
   pagination stay put and only the rows move — which is what `fill` opts into
   (see eos/shared/_shell).

   Wide screens only: below 1024px the shell stacks into a single column with
   the subnav above the content, which has no room to pin anything. */
@media (min-width: 1025px) {
  turbo-frame#main_content:has(> .eos-show) {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
  }

  .eos-show {
    flex: 1 1 auto;
    min-height: 0;
    align-items: stretch;
    grid-template-rows: minmax(0, 1fr);
  }

  .eos-show__nav {
    min-height: 0;
  }

  /* Sticky is pointless once the page itself no longer scrolls: the panel takes
     the column's height and scrolls its own list. */
  .eos-subnav {
    position: static;
    display: flex;
    flex-direction: column;
    max-height: 100%;
  }

  .eos-subnav__list {
    min-height: 0;
    overflow-y: auto;
  }

  .eos-subnav__footer {
    flex: 0 0 auto;
  }

  .eos-show__main {
    display: flex;
    flex-direction: column;
    min-height: 0;
  }

  .eos-show__header {
    flex: 0 0 auto;
  }

  .eos-show__body {
    flex: 1 1 auto;
    min-height: 0;
    /* Only ever vertically: a card's shadow must not put a scrollbar under it. */
    overflow: hidden auto;
  }

  .eos-show--fill .eos-show__body,
  .eos-show--fill .eos-records {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
  }

  /* The frame, and the bulk-select form every one of these tables is wrapped in
     (see shared/_bulk_deletion_form) — which sits between the frame and the
     scroller exactly as it does on an index page (see .index-page in
     table.css). Both have to pass the height on. Left out, the form grows to
     the full height of the table and the shell's `overflow: hidden` clips it:
     no scrollbar, and the rows past the fold and the pagination under them out
     of reach. The :has() keeps a form with no table in it from claiming any. */
  .eos-show--fill .eos-records > turbo-frame,
  .eos-show--fill .eos-records form:has(.table-container) {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
  }

  .eos-show--fill .eos-records .table-container {
    flex: 1 1 auto;
    min-height: 180px;
  }

  .eos-show--fill .eos-records .table-pagination {
    flex: 0 0 auto;
  }
}

@media (max-width: 1024px) {
  .eos-show {
    grid-template-columns: minmax(0, 1fr);
  }

  .eos-subnav {
    position: static;
  }

  .eos-subnav__list {
    flex-direction: row;
    flex-wrap: wrap;
  }

  .eos-vto,
  .eos-dashboard {
    grid-template-columns: minmax(0, 1fr);
  }

  .eos-stats {
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  }
}


/* ===== components/error_modal.css ===== */
/* ==========================================================================
   Error Modal — floating validation toast
   ========================================================================== */
.error-modal {
  position: fixed;
  top: calc(var(--topbar-height) + var(--space-5));
  right: calc(40% + var(--space-6));
  z-index: var(--z-modal);
  /* min-width keeps single, short messages from collapsing to their longest
     word; max-width caps it so it stays a compact toast. */
  min-width: 20rem;
  max-width: min(400px, calc(100vw - var(--space-8)));
  animation: error-modal-slide-in var(--transition-slow);
}

.drawer-host .error-modal {
  right: calc(40% + var(--space-6));
}

.error-modal__content {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-danger);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

.error-modal__header {
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.error-modal__title {
  margin: 0;
  font-family: var(--font-family-bold);
  font-size: var(--font-size-large);
  color: var(--color-danger);
}

.error-modal__close {
  background: none;
  border: none;
  font-size: 20px;
  color: var(--color-text-faint);
  cursor: pointer;
  transition: color var(--transition-base), background-color var(--transition-base);
  line-height: 1;
  padding: 0;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
}

.error-modal__close:hover {
  color: var(--color-danger);
  background-color: var(--tint-danger-10);
}

.error-modal__body {
  padding: var(--space-3) var(--space-5);
}

.error-modal__list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.error-modal__item {
  display: flex;
  align-items: flex-start;
  padding: var(--space-2) 0;
  color: var(--color-text-muted);
}

.error-modal__item:not(:last-child) {
  border-bottom: 1px solid var(--color-border);
}

.error-modal__icon {
  flex-shrink: 0;
  color: var(--color-danger);
  margin-right: var(--space-3);
  width: 20px;
  height: 20px;
}

.error-modal__message {
  font-family: var(--font-family-base);
  font-size: var(--font-size-medium);
}

@keyframes error-modal-slide-in {
  from {
    opacity: 0;
    transform: translateX(30px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@media (max-width: 1200px) {
  .error-modal {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    top: calc(var(--topbar-height) + var(--space-5));
  }
}


/* ===== components/error_page.css ===== */
/* ==========================================================================
   Error Page — the full-screen takeover for a failed request (404/403/422/500)

   Shares the auth screens' backdrop deliberately: both are the application
   speaking for itself, outside the shell. Kept free of any dependency on the
   layout tokens the dashboard sets up, since the page has to render when the
   rest of the app could not.
   ========================================================================== */
.error-page-body {
  overflow-y: auto;
}

.error-page {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-6);
  padding: var(--space-6);
  overflow-y: auto;
  background:
    radial-gradient(ellipse at top right, var(--tint-green-16), transparent 55%),
    radial-gradient(ellipse at bottom left, var(--tint-white-10), transparent 60%),
    linear-gradient(160deg, var(--color-primary-dark), var(--color-secondary-dark));
}

/* == card == */
.error-page__card {
  width: 100%;
  max-width: 520px;
  padding: var(--space-8);
  text-align: center;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
}

/* == icon == */
.error-page__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  margin: 0 auto var(--space-5);
  color: var(--color-danger);
  background-color: var(--tint-danger-10);
  border-radius: var(--radius-full);
}

.error-page__icon svg {
  width: 26px;
  height: 26px;
}

/* == copy == */
.error-page__status {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}

.error-page__title {
  font-size: var(--font-size-xxlarge);
  color: var(--color-primary-dark);
  margin-bottom: var(--space-4);
}

.error-page__message {
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
  line-height: 1.6;
  margin-bottom: var(--space-3);
}

.error-page__advice {
  font-size: var(--font-size-medium);
  color: var(--color-text);
  line-height: 1.6;
}

/* == reference == */
.error-page__reference {
  margin-top: var(--space-6);
  padding: var(--space-4);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.error-page__reference-label {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}

.error-page__reference-code {
  display: block;
  /* The id is a long unbroken string; let it wrap rather than widen the card. */
  overflow-wrap: anywhere;
  font-family: ui-monospace, "SFMono-Regular", "Menlo", monospace;
  font-size: var(--font-size-small);
  color: var(--color-primary-dark);
  user-select: all;
}

.error-page__reference-hint {
  margin-top: var(--space-2);
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
  line-height: 1.5;
}

/* == actions == */
.error-page__actions {
  display: flex;
  justify-content: center;
  margin-top: var(--space-6);
}

.error-page__action {
  text-decoration: none;
}

/* == footer == */
.error-page__footer {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--tint-white-24);
}


/* ===== components/feedback.css ===== */
/* ==========================================================================
   Feedback — the firm record's satisfaction rating card plus the shared bits
   of the feedback and service-improvement tables (both the firm-scoped and the
   tenant-wide versions).
   ========================================================================== */

/* --- Satisfaction rating -------------------------------------------------- */
.satisfaction__current {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--color-border);
}

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

.satisfaction__face {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  font-size: var(--font-size-xlarge);
  line-height: 1;
}

/* The firm's current score. Filled rather than outlined so it reads as the one
   answer among five rather than as five equal options. */
.satisfaction__face--selected {
  background: var(--color-primary-green);
  border-color: var(--color-primary-green);
  box-shadow: var(--shadow-glow-green);
}

.satisfaction__score {
  min-width: 0;
}

.satisfaction__score-value {
  margin: 0;
  font-size: var(--font-size-xxlarge);
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
  line-height: 1.2;
}

.satisfaction__score-meta {
  margin: 0;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* A firm nobody has asked yet has no score, which is not the same as a bad
   one — so the readout withholds the number rather than showing a zero. */
.satisfaction__score-value--empty {
  color: var(--color-text-faint);
}

/* Pushed to the far edge, away from the score it has nothing to do with. */
.satisfaction__send {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-2);
  margin-left: auto;
  flex-shrink: 0;
}

/* `button_to` wraps its button in a form; dissolve it so the button sits on
   the column's own gap. */
.satisfaction__send form {
  display: contents;
}

/* Who the survey goes to, or why it cannot go — a greyed-out button on its own
   says neither. Capped so a long contact name wraps rather than stretching the
   card's first row. */
.satisfaction__send-meta {
  margin: 0;
  max-width: 260px;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  text-align: right;
}

.satisfaction__history-label {
  margin: 0 0 var(--space-4);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.satisfaction__chart {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  align-items: end;
  gap: var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.satisfaction__column {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
}

.satisfaction__bar-value {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
}

/* Fixed-height track so every bar is measured against the same 5, and the
   month labels sit on one line. */
.satisfaction__bar-track {
  display: flex;
  align-items: flex-end;
  width: 34px;
  height: 96px;
}

.satisfaction__bar {
  width: 100%;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

.satisfaction__bar--good {
  background: #4caf7d;
}

.satisfaction__bar--fair {
  background: var(--color-warning);
}

.satisfaction__bar-month {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* --- Section blurbs ------------------------------------------------------ */
/* The header's left column is a heading plus a line of guidance, so it stacks
   rather than sitting on the row's centre line. */
.firm-records__header:has(.firm-records__blurb) {
  align-items: flex-start;
}

.firm-records__blurb {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* --- Feedback & suggestion tables ---------------------------------------- */
/* Free text is the point of both tables, so those columns take the slack and
   wrap; everything else stays on one line. */
.feedback-table__body-cell,
.suggestion-table__description-cell {
  min-width: 260px;
  white-space: normal;
}

.feedback-table__firm-cell {
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.feedback-table__recipients-header {
  min-width: 140px;
}

.feedback-recipients {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: flex-start;
}

.feedback-recipients__avatars {
  display: flex;
  align-items: center;
}

/* Overlap the avatars so a long list stays inside the column. */
.feedback-recipients__avatars .profile-picture + .profile-picture {
  margin-left: -10px;
}

.feedback-recipients__names {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  white-space: normal;
}


/* ===== components/filters.css ===== */
/* ==========================================================================
   Page header ("index header")
   ========================================================================== */
.index-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.index-header__title {
  margin: 0;
  font-size: var(--font-size-xxlarge);
  color: var(--color-primary-dark);
  letter-spacing: -0.01em;
}

/* Title with a line under it saying what the page is for. For the listings whose
   purpose is not obvious from a two-word title — the recruitment pipeline spans
   several roles and sources, and the subtitle is what says so. */
.index-header__heading {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.index-header__subtitle {
  margin: 0;
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}

/* Wraps onto a second line rather than pushing a control off the page. Inert
   while everything fits. */
.index-header__controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* ==========================================================================
   Toolbar row — tab bar on the left, state toggles on the right
   The page header is full at a laptop width once a table has more than a
   toggle or two, so the toggles sit on the tab row instead, where the space
   is. The group wraps as a whole rather than scattering its switches.
   ========================================================================== */
.index-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  flex: 0 0 auto;
}

.index-toolbar__toggles {
  margin-left: auto;
}

.index-toolbar__toggles-form {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* First in the row, so there is nothing for its divider to divide. */
.index-toolbar__toggles-form .index-filters__switch:first-of-type {
  margin-left: 0;
  padding-left: 0;
  border-left: none;
}

/* The tab bar carries its own bottom margin for pages that use it alone. */
.index-toolbar .cases-index-tabs {
  margin-bottom: 0;
}

/* ==========================================================================
   Tab bar
   ========================================================================== */
.cases-index-tabs {
  display: inline-flex;
  gap: var(--space-1);
  margin-bottom: var(--space-4);
  padding: 3px;
  background-color: var(--tint-navy-06);
  border-radius: var(--radius-md);
  /* The tab bar is a flex child of .index-page, which blockifies inline-flex and
     would otherwise stretch it into a full-width banner. Shrink to the tabs and
     stay put vertically; both properties are inert outside a flex parent. */
  align-self: flex-start;
  flex: 0 0 auto;
}

.cases-index-tabs__tab {
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  text-decoration: none;
  font-family: var(--font-family-bold);
  font-size: var(--font-size-medium);
  transition: background-color var(--transition-base), color var(--transition-base);
}

.cases-index-tabs__tab:hover {
  color: var(--color-primary-dark);
}

.cases-index-tabs__tab--active {
  background-color: var(--color-surface);
  color: var(--color-primary-dark);
  box-shadow: var(--shadow-sm), inset 0 -2px 0 var(--color-primary-green);
}

/* Twelve months and an All tab is more than a tab bar's usual handful: the tabs
   tighten up, and the row scrolls sideways on a narrow window rather than
   pushing the table out of the page. */
.cases-index-tabs--months {
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: thin;
}

.cases-index-tabs--months .cases-index-tabs__tab {
  padding: var(--space-2) var(--space-3);
  white-space: nowrap;
}

/* ==========================================================================
   Index filters
   ========================================================================== */
.index-filters {
  display: flex;
  align-items: center;
}

.index-filters__form {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.index-filters__search {
  position: relative;
  display: flex;
  align-items: center;
}

.index-filters__search-icon {
  position: absolute;
  left: var(--space-3);
  width: 16px;
  height: 16px;
  color: var(--color-text-faint);
  pointer-events: none;
}

.index-filters__search-input {
  width: 220px;
  height: 40px;
  padding: 0 var(--space-3) 0 var(--space-8);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-base);
  color: var(--color-text);
  background-color: var(--color-surface);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.index-filters__search-input::placeholder {
  color: var(--color-text-faint);
}

.index-filters__search-input:hover {
  border-color: var(--color-border-strong);
}

.index-filters__search-input:focus {
  outline: none;
  border-color: var(--color-primary-green);
  box-shadow: var(--focus-ring);
}

.index-filters__switch {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-left: var(--space-2);
  padding-left: var(--space-3);
  border-left: 1px solid var(--color-border);
  white-space: nowrap;
}

.index-filters__switch-label {
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  white-space: nowrap;
}

/* ==========================================================================
   Filter panel (dropdown)
   ========================================================================== */
.filter-panel {
  position: relative;
  display: inline-block;
}

.filter-panel__trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-4);
  height: 40px;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-base);
  color: var(--color-primary-dark);
  cursor: pointer;
  transition: all var(--transition-base);
  box-shadow: var(--shadow-xs);
}

.filter-panel__trigger:hover {
  background-color: var(--color-surface-sunken);
  border-color: var(--color-border-strong);
}

.filter-panel__trigger--active {
  background-color: var(--color-primary-dark);
  color: var(--color-white);
  border-color: var(--color-primary-dark);
}

.filter-panel__trigger--active:hover {
  background-color: var(--color-secondary-dark);
}

.filter-panel__trigger-icon {
  width: 18px;
  height: 18px;
  transition: transform var(--transition-base);
}

.filter-panel__trigger--active .filter-panel__trigger-icon {
  color: var(--color-white);
}

.filter-panel__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  background-color: var(--color-primary-green);
  color: var(--color-white);
  font-size: 11px;
  font-weight: 600;
  border-radius: var(--radius-full);
  transition: opacity var(--transition-base);
}

.filter-panel__badge--hidden {
  opacity: 0;
  width: 0;
  min-width: 0;
  padding: 0;
  overflow: hidden;
}

.filter-panel__content {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  z-index: 100;
  min-width: 360px;
  max-width: 500px;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.filter-panel__content--open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.filter-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
}

.filter-panel__title {
  font-size: var(--font-size-large);
  font-weight: 600;
  color: var(--color-primary-dark);
  margin: 0;
}

.filter-panel__clear {
  padding: var(--space-1) var(--space-3);
  background: none;
  border: none;
  font-size: var(--font-size-small);
  color: var(--color-danger);
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition: background-color var(--transition-fast);
}

.filter-panel__clear:hover {
  background-color: var(--tint-danger-10);
}

.filter-panel__body {
  padding: var(--space-5);
}

.filter-panel__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
}

.filter-panel__field--wide {
  grid-column: 1 / -1;
}

.filter-panel__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.filter-panel__field--full {
  grid-column: 1 / -1;
}

.filter-panel__label {
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
}

.filter-panel__input,
.filter-panel__select {
  width: 100%;
  height: 40px;
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-base);
  color: var(--color-text);
  background-color: var(--color-surface-sunken);
  transition: all var(--transition-fast);
}

.filter-panel__input:hover,
.filter-panel__select:hover {
  border-color: var(--color-border-strong);
  background-color: var(--color-surface);
}

.filter-panel__input:focus,
.filter-panel__select:focus {
  outline: none;
  border-color: var(--color-primary-green);
  background-color: var(--color-surface);
  box-shadow: var(--focus-ring);
}

.filter-panel__select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%2364748b' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
  background-position: right var(--space-2) center;
  background-repeat: no-repeat;
  background-size: 1.5em 1.5em;
  padding-right: var(--space-8);
  cursor: pointer;
}

/* Native date input tuned to match the brand */
.filter-panel__input--date {
  cursor: pointer;
  color: var(--color-text);
}

.filter-panel__input--date::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: 0.6;
  transition: opacity var(--transition-fast);
}

.filter-panel__input--date:hover::-webkit-calendar-picker-indicator {
  opacity: 1;
}

/* Responsive adjustments */
@media (max-width: 768px) {
  .index-header {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-4);
  }

  .index-header__controls {
    width: 100%;
    flex-wrap: wrap;
  }

  .index-filters__search-input {
    width: 100%;
    min-width: 180px;
  }

  .filter-panel__content {
    position: fixed;
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    max-width: none;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    transform: translateY(100%);
  }

  .filter-panel__content--open {
    transform: translateY(0);
  }

  .filter-panel__grid {
    grid-template-columns: 1fr;
  }
}


/* ===== components/firm_pill.css ===== */
/* ==========================================================================
   Firm Pill — sharp, scannable firm card used in the firm directory list.
   Layout: colored status spine + header (name / status) + a three-column
   grid of facts and contact rows.
   ========================================================================== */
.firm-pill {
  position: relative;
  display: block;
  width: 100%;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  transition: border-color var(--transition-base), box-shadow var(--transition-base),
    transform var(--transition-fast);
}

.firm-pill:hover {
  transform: translateY(-2px);
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-md);
}

/* A firm needing a service plan renewal, tinted to match an overdue complaint's
   row (see .table-row--warning). The pill already carries a status spine on its
   left edge, so the flag is the tint plus the border rather than a second bar. */
.firm-pill--warning {
  background-color: rgba(245, 158, 11, 0.07);
  border-color: var(--color-warning);
}

.firm-pill--warning:hover {
  background-color: rgba(245, 158, 11, 0.13);
  border-color: var(--color-warning);
}

.firm-pill:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-color: var(--color-primary-green);
}

/* == status spine == */
.firm-pill__spine {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 4px;
  background-color: var(--color-border-strong);
}

.firm-pill__spine--green {
  background-color: var(--color-primary-green);
}

.firm-pill__spine--red {
  background-color: var(--color-danger);
}

.firm-pill__body {
  padding: var(--space-5) var(--space-6) var(--space-5) calc(var(--space-6) + 4px);
}

/* == header == */
.firm-pill__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: var(--space-4);
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.firm-pill__name {
  margin: 0;
  font-size: var(--font-size-xlarge);
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
  line-height: 1.2;
  overflow-wrap: anywhere;
}

/* == status pill (solid tinted chip, no dot — matches directory design) == */
.firm-pill__status {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  padding: 5px 14px;
  border-radius: var(--radius-sm);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
}

.firm-pill__status--green {
  background-color: rgba(93, 207, 162, 0.32);
  color: var(--color-primary-dark);
}

.firm-pill__status--red {
  background-color: rgba(245, 69, 92, 0.26);
  color: var(--color-primary-dark);
}

.firm-pill__status--gray {
  background-color: #e6e9ee;
  color: var(--color-secondary-dark);
}

/* == three-column body grid == */
.firm-pill__grid {
  display: grid;
  grid-template-columns: minmax(200px, 260px) 1fr 1fr;
  gap: var(--space-5) var(--space-6);
  align-items: start;
}

/* == facts (Authorisation / FCA Number) == */
.firm-pill__facts {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
}

.firm-pill__fact {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.firm-pill__label {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.firm-pill__value {
  margin: 0;
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
  overflow-wrap: anywhere;
}

/* == contact rows == */
.firm-pill__contacts {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.firm-pill__contact {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}

.firm-pill__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border-radius: var(--radius-sm);
  background-color: var(--tint-navy-06);
  color: var(--color-primary-dark);
  transition: background-color var(--transition-base), color var(--transition-base);
}

.firm-pill:hover .firm-pill__icon {
  background-color: var(--tint-green-16);
  color: var(--color-primary-dark);
}

.firm-pill__icon-svg {
  width: 16px;
  height: 16px;
}

.firm-pill__contact-text {
  min-width: 0;
  font-size: var(--font-size-medium);
  color: var(--color-text);
  overflow-wrap: anywhere;
}

.firm-pill__contact-text--link {
  color: var(--color-primary-green);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* == responsive == */
@media (max-width: 992px) {
  .firm-pill__grid {
    grid-template-columns: 1fr 1fr;
  }

  .firm-pill__facts {
    grid-column: 1 / -1;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-5);
  }
}

@media (max-width: 640px) {
  .firm-pill__grid {
    grid-template-columns: 1fr;
  }
}

/* == the row a pill sits in ==
   The card itself is one big link, so the select box and the row's own action
   cannot live inside it — a checkbox nested in an anchor is a click on the
   anchor. They are laid over the card's own padding instead, which keeps the
   card full width and reading as one thing rather than as a middle column with
   controls bolted either side. See firms/index/_index_list. */
.firm-row {
  position: relative;
  transition: transform var(--transition-fast);
}

/* Room in the card for the two of them. */
.firm-row .firm-pill__body {
  padding-left: calc(var(--space-6) + 30px);
  padding-right: calc(var(--space-6) + 28px);
}

.firm-row--deleted .firm-pill__body {
  padding-right: calc(var(--space-6) + 190px);
}

/* The hover state moves up to the row, so the box and the button ride with the
   card instead of the card sliding out from under them — and so it holds while
   the pointer is over either of those rather than over the link. */
.firm-row:hover {
  transform: translateY(-2px);
}

.firm-row:hover .firm-pill {
  transform: none;
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-md);
}

.firm-row__select {
  position: absolute;
  top: 50%;
  left: calc(var(--space-5) + 4px);
  transform: translateY(-50%);
}

.firm-row__actions {
  position: absolute;
  top: 50%;
  right: var(--space-5);
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

/* Deleting a firm is the heaviest thing this page can do and the least often
   wanted, so the button is quiet rather than hidden — it goes red under the
   pointer and picks up when the row does. Quiet rather than hidden because a
   control revealed on hover is one a keyboard, a touchscreen and a screen
   reader all have to work around; the earlier version faded to opacity 0, which
   even Selenium reports as not displayed. */
.firm-row__delete {
  color: var(--color-text-faint);
  transition: color var(--transition-base), background-color var(--transition-base);
}

.firm-row:hover .firm-row__delete {
  color: var(--color-danger);
}

.firm-row__delete:hover,
.firm-row__delete:focus-visible {
  color: var(--color-danger);
  background-color: var(--tint-danger-10);
}

.firm-row__deleted {
  margin: 0;
  text-align: right;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  line-height: 1.4;
  white-space: nowrap;
}

.firm-row__deleted-until {
  color: var(--color-text-faint);
}

/* The directory scrolls inside itself, so the bulk bar and its tabs have to keep
   their own height while the list takes the rest. */
.firm-directory-form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}


/* ===== components/firm_record.css ===== */
/* ==========================================================================
   Firm Record — firm show page: stacked cards for details, contacts,
   recent activity and notes
   ========================================================================== */
.firm-record {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* == section cards == */
.firm-record__section {
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.firm-record__section-title {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

.firm-record__section-content {
  min-height: 80px;
}

/* == side-by-side rows == */
.firm-record__row {
  display: flex;
  gap: var(--space-5);
}

/* == overview columns == */
.firm-record__columns {
  display: grid;
  grid-template-columns: minmax(240px, 320px) 1fr minmax(280px, 360px);
  gap: var(--space-6);
}

.firm-record__column {
  min-width: 0;
}

.firm-record__logo {
  height: 80px;
  max-width: 320px;
  margin-bottom: var(--space-4);
}

.firm-record__logo img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.firm-record__detail {
  font-size: var(--font-size-medium);
  color: var(--color-text);
  margin-bottom: var(--space-2);
}

.firm-record__detail strong {
  color: var(--color-primary-dark);
}

/* == contact column == */
.firm-record__column--contact {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-3);
}

.firm-record__column--contact p {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-medium);
  color: var(--color-text);
  overflow-wrap: anywhere;
}

.firm-record__contact-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  color: var(--color-primary-dark);
}

/* == attributes column == */
.firm-record__column--attributes {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.firm-record__attributes {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.firm-record__attribute {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.firm-record__attribute-label {
  font-family: var(--font-family-bold);
  font-weight: 600;
  font-size: var(--font-size-medium);
  color: var(--color-primary-dark);
}

/* == recent reviews / cases tables == */
.firm-record__table {
  flex: 1 1 0;
  min-width: 0;
  margin-bottom: 0;
}

.firm-record__table-title {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  margin: 0;
}

/* == important notes placeholder == */
.firm-record__notes {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  padding: var(--space-8) var(--space-4);
  text-align: center;
  background-color: var(--color-surface-sunken);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
}

.firm-record__notes-empty {
  font-family: var(--font-family-bold);
  font-weight: 600;
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}

.firm-record__notes-hint {
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
}

/* == responsive == */
@media (max-width: 992px) {
  .firm-record__columns {
    grid-template-columns: 1fr;
  }

  .firm-record__row {
    flex-direction: column;
  }
}


/* ===== components/firm_show.css ===== */
/* ==========================================================================
   Firm record — nested subnav, page shell, widgets and Activity slide-out.
   UI scaffolding; all data is placeholder for now.
   ========================================================================== */

/* --- Shell layout -------------------------------------------------------- */
.firm-show {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: var(--space-8);
  align-items: start;
}

.firm-show__main {
  min-width: 0;
}

.firm-show__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

/* The firm's logo beside its name, on every tab of the record. On the same dark
   plate the upload field previews it on, so a firm whose mark is white-on-
   transparent is readable here rather than invisible (see shared/_logo_field). */
.firm-show__logo {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  height: 34px;
  max-width: 140px;
  padding: 4px 8px;
  background: var(--color-secondary-dark);
  border-radius: var(--radius-md);
}

.firm-show__logo img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.firm-show__heading {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.firm-show__title {
  margin: 0;
  font-size: var(--font-size-xxlarge);
  font-weight: 600;
  color: var(--color-primary-dark);
}

/* The bookmark star and the Activity button, on the end of the header row. */
.firm-show__header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

.firm-show__activity-btn {
  flex-shrink: 0;
}

.firm-show__body {
  min-width: 0;
}

/* --- Subnav (distinct card panel with icons) ----------------------------- */
.firm-subnav {
  position: sticky;
  top: calc(var(--topbar-height) + var(--space-4));
  padding: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.firm-subnav__heading {
  margin: 0 0 var(--space-2);
  padding: var(--space-1) var(--space-3);
  font-size: var(--font-size-small);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.firm-subnav__list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.firm-subnav__link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  font-weight: 500;
  text-decoration: none;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.firm-subnav__link:hover {
  background: var(--tint-navy-04);
  color: var(--color-primary-dark);
}

.firm-subnav__link:hover .firm-subnav__icon {
  color: var(--color-primary-dark);
}

.firm-subnav__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  background: var(--tint-navy-06);
  color: var(--color-text-muted);
  transition: background var(--transition-fast), color var(--transition-fast);
}

.firm-subnav__icon .minor-icon {
  width: 16px;
  height: 16px;
}

.firm-subnav__label {
  min-width: 0;
}

.firm-subnav__link--active {
  background: var(--tint-green-16);
  color: var(--color-primary-dark);
  font-weight: 600;
}

.firm-subnav__link--active .firm-subnav__icon {
  background: var(--color-primary-green);
  color: var(--color-white);
}

/* Sign out, for a firm-scoped user whose only nav this is. Set apart from the
   record's pages by a rule, since it leaves the application rather than moving
   around inside it. */
.firm-subnav__footer {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-border);
}

.firm-subnav__signout {
  width: 100%;
  border: 0;
  background: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

/* --- Body layouts -------------------------------------------------------- */
.firm-dashboard {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: var(--space-5);
  align-items: start;
}

.firm-dashboard__col {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}

.firm-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.firm-stack--narrow {
  max-width: 560px;
}

.firm-toolbar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: var(--space-5);
}

/* --- Card primitive ------------------------------------------------------ */
.firm-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.firm-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.firm-card__title {
  margin: 0;
  font-size: var(--font-size-large);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.firm-card__blurb {
  margin: 0;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* A card whose title carries a line of explanation under it, rather than a
   control beside it. */
.firm-card__header--stacked {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
}

.firm-card__edit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast),
    border-color var(--transition-fast), transform var(--transition-fast);
}

.firm-card__edit:hover {
  background: var(--tint-navy-04);
  border-color: var(--color-border);
  color: var(--color-primary-dark);
}

/* The card it opens takes a round trip to arrive, so the button answers the
   click on its own first. */
.firm-card__edit:active {
  transform: scale(0.92);
}

/* --- Card swap (values ⇄ edit form) -------------------------------------- */
/* Each editable card is its own turbo frame, so switching to its form is a
   navigation, and the form is most of a card taller than the values it replaces.
   Two things used to make that ugly:

   The height was never animated, so the card doubled in size between one frame
   and the next while only its opacity was easing — the change everyone actually
   sees was the one thing that snapped. It is animated from JS now, because the
   height being left and the height being arrived at are only both known there
   (see section_swap_controller).

   And the opacity was ramped twice, in opposite directions: `busy` started
   fading the card out, the swap interrupted that a frame or two later, opacity
   sprang back towards 1, and then the entering animation slammed it to 0 and
   faded it up again. On a local request all of that happened inside ~200ms,
   which is what read as a flash. Now the dim is held back long enough that a
   quick swap never shows it at all, and the arriving half fades up from part
   way rather than from nothing. */
.firm-card-frame {
  display: block;
  transition: opacity var(--transition-fast), height var(--transition-slow);
}

/* Held back deliberately. The swap usually lands in a few tens of milliseconds,
   and a dim that comes and goes inside that is a flicker, not feedback — the
   button's own :active answers the click meanwhile. This is here for the request
   that is genuinely slow enough to be worth reporting. */
.firm-card-frame[busy] {
  opacity: 0.6;
  transition: opacity var(--transition-base) 0.25s;
  /* Nothing in a card that is on its way out is worth clicking. */
  pointer-events: none;
}

.firm-card-frame--entering {
  /* Its new contents are taller than the box they are growing into. */
  overflow: hidden;
  /* --transition-slow carries its own easing, so no timing function is added
     here — a second one makes the shorthand invalid and the whole declaration is
     dropped, which is what the swap spec's animation events really check. */
  animation: firm-card-swap var(--transition-slow);
}

@keyframes firm-card-swap {
  from {
    /* Not from zero. The outgoing half was on screen a frame ago, so starting
       from nothing reads as a blink; starting part way reads as a change. */
    opacity: 0.45;
    transform: translateY(-4px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .firm-card__edit,
  .firm-card-frame,
  .firm-card-frame--entering {
    transition: none;
    animation: none;
  }
}

.firm-card__edit--danger:hover {
  background: var(--tint-danger-10);
  border-color: var(--color-danger);
  color: var(--color-danger);
}

.firm-card__edit .minor-icon {
  width: 16px;
  height: 16px;
}

/* --- Contact list (address / phone / email / web) ------------------------ */
.firm-contact {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.firm-contact__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font-size: var(--font-size-medium);
  color: var(--color-text);
  line-height: 1.5;
}

.firm-contact__icon {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  margin-top: 1px;
  color: var(--color-primary-green);
}

.firm-contact__icon svg {
  width: 18px;
  height: 18px;
}

/* --- Field / value pairs ------------------------------------------------- */
.firm-fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
}

.firm-field {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.firm-field--inline {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.firm-field__label {
  margin: 0;
  font-size: var(--font-size-small);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.firm-field__value {
  margin: 0;
  font-size: var(--font-size-medium);
  color: var(--color-text);
}

.firm-field__value--empty {
  color: var(--color-text-faint);
}

.firm-field--inline .firm-field__label {
  text-transform: none;
  letter-spacing: normal;
  font-size: var(--font-size-medium);
  font-weight: 500;
  color: var(--color-text-muted);
}

.firm-field__hint {
  display: block;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* Field pairs in one grid that flows row by row, so each field lands opposite
   its counterpart rather than under whatever the column happened to reach. */
.firm-field-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-5) var(--space-6);
  margin: 0;
}

/* --- Inline link value (e.g. "Full Service") ----------------------------- */
.firm-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--color-primary-green);
  font-weight: 600;
  text-decoration: none;
}

.firm-link:hover {
  text-decoration: underline;
}

.firm-link__icon {
  width: 14px;
  height: 14px;
  color: var(--color-text-faint);
}

/* --- Service information -------------------------------------------------- */
.firm-service--expanded {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-6);
}

.firm-fields--attributes {
  gap: var(--space-4);
}

.firm-coordination {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-medium);
  color: var(--color-text);
}

/* --- Yes / No toggle (static) -------------------------------------------- */
.firm-toggle {
  display: inline-flex;
  padding: 2px;
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
}

.firm-toggle__option {
  padding: 2px var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-text-faint);
}

.firm-toggle__option.is-active.firm-toggle__option--yes {
  background: var(--color-primary-green);
  color: var(--color-white);
}

.firm-toggle__option.is-active.firm-toggle__option--no {
  background: var(--color-danger);
  color: var(--color-white);
}

/* --- Small tag pill (e.g. Delivery Model "UK") --------------------------- */
.firm-tag {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--font-size-small);
  font-weight: 600;
}

.firm-tag--green {
  background: var(--tint-green-16);
  color: var(--color-success-dark);
}

/* --- Key contact cards --------------------------------------------------- */
.firm-contact-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.firm-contact-card {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding: var(--space-4);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.firm-contact-card__group {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 160px;
}

.firm-contact-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  flex: 1;
  min-width: 0;
}

.firm-contact-card__meta-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-medium);
  color: var(--color-text);
}

.firm-contact-card__meta-icon {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  color: var(--color-text-faint);
}

.firm-contact-card__actions {
  display: flex;
  gap: var(--space-1);
  margin-left: auto;
}

/* --- Tasks table --------------------------------------------------------- */
.firm-tasks {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.firm-table-user {
  display: inline-flex;
  align-items: center;
}

.firm-table-updated {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}

.firm-table-updated__at {
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
}

/* --- Feedback gauge ------------------------------------------------------ */
.firm-gauge {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding-top: var(--space-2);
}

.firm-gauge__label {
  font-size: var(--font-size-small);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.firm-gauge__svg {
  width: 200px;
  max-width: 100%;
  height: auto;
}

.firm-gauge__track {
  fill: none;
  stroke: var(--color-border);
  stroke-width: 14;
  stroke-linecap: round;
}

.firm-gauge__value {
  fill: none;
  stroke: var(--color-primary-green);
  stroke-width: 14;
  stroke-linecap: round;
}

.firm-gauge__needle {
  stroke: var(--color-primary-dark);
  stroke-width: 3;
  stroke-linecap: round;
}

.firm-gauge__hub {
  fill: var(--color-primary-dark);
}

/* No survey answered yet: the needle rests at the foot of the scale, greyed so
   it reads as "nothing to point at" rather than as a score of zero. */
.firm-gauge__needle--empty {
  stroke: var(--color-border-strong);
}

.firm-gauge__readout {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: calc(var(--space-4) * -1);
}

.firm-gauge__score {
  font-size: var(--font-size-xxxlarge);
  font-weight: 600;
  color: var(--color-primary-dark);
  line-height: 1;
}

.firm-gauge__score--empty {
  color: var(--color-text-faint);
}

.firm-gauge__caption {
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}

/* --- Service notes / checklist ------------------------------------------- */
.firm-note-text {
  margin: 0;
  font-size: var(--font-size-medium);
  line-height: 1.6;
  color: var(--color-text);
}

.firm-checklist {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.firm-checklist__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--font-size-medium);
  color: var(--color-text);
}

.firm-checklist__box {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  border: 1.5px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  color: transparent;
}

.firm-checklist__item.is-checked .firm-checklist__box {
  background: var(--color-primary-green);
  border-color: var(--color-primary-green);
  color: var(--color-white);
}

.firm-checklist__box .minor-icon {
  width: 14px;
  height: 14px;
}

/* --- Record tables (cases / reviews / tasks / complaints) ----------------- */
.firm-records__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.firm-records__title {
  margin: 0;
  font-size: var(--font-size-large);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.firm-records__controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.firm-records .table-container {
  margin-bottom: 0;
}

/* Every page of a firm record fills the viewport rather than growing past it:
   the warning banner, breadcrumb, page header and subnav stay where they are and
   only the tab's own content scrolls — the same shell the index pages use (see
   .index-page in table.css).

   A record-table page goes one step further and hands that scroll to the table,
   so its search, filters and pagination stay put and only the rows move. That is
   what `fill` opts into (see firms/show/_shell).

   Wide screens only: below 1024px the shell stacks into a single column with the
   subnav as a row above the content (see the responsive block at the bottom of
   this file), which has no room to pin anything. There the page scrolls as it
   always did. */
@media (min-width: 1025px) {
  turbo-frame#main_content:has(> .firm-show) {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
  }

  .firm-show {
    flex: 1 1 auto;
    min-height: 0;
    align-items: stretch;
    /* One row bounded by the shell rather than by its tallest child, so a subnav
       longer than the viewport scrolls itself instead of stretching the page. */
    grid-template-rows: minmax(0, 1fr);
  }

  .firm-show__nav {
    min-height: 0;
  }

  /* Sticky is pointless once the page itself no longer scrolls. The card takes
     its natural height, or the column's if that is shorter, and scrolls its own
     list — so on a short viewport the panel still ends in a border rather than
     running off the bottom of the screen. */
  .firm-subnav {
    position: static;
    display: flex;
    flex-direction: column;
    max-height: 100%;
  }

  .firm-subnav__list {
    min-height: 0;
    overflow-y: auto;
  }

  /* Whatever the list does, the way out stays on screen. */
  .firm-subnav__footer {
    flex: 0 0 auto;
  }

  .firm-show__main {
    display: flex;
    flex-direction: column;
    min-height: 0;
  }

  /* Neither the warnings nor the page header scroll: they are the fixed top of
     the column, and the tab's own content moves underneath them. */
  #firm_warning_banner,
  .firm-show__header {
    flex: 0 0 auto;
  }

  /* The one part of the page that moves. */
  .firm-show__body {
    flex: 1 1 auto;
    min-height: 0;
    /* Only ever vertically: a card's shadow must not put a scrollbar under it. */
    overflow: hidden auto;
  }

  /* Except on a record-table page, where the body passes its height down to the
     table and the rows scroll inside it instead. */
  .firm-show--fill .firm-show__body,
  .firm-show--fill .firm-records {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
  }

  .firm-show--fill .firm-records > turbo-frame {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
  }

  .firm-show--fill .firm-records .table-container {
    flex: 1 1 auto;
    min-height: 180px;
  }

  .firm-show--fill .firm-records .table-pagination {
    flex: 0 0 auto;
  }
}

/* --- Placeholder pages (no design yet) ----------------------------------- */
.firm-placeholder {
  align-items: center;
  text-align: center;
  gap: var(--space-3);
  padding: var(--space-10) var(--space-6);
}

.firm-placeholder__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--radius-lg);
  background: var(--tint-green-16);
  color: var(--color-primary-dark);
}

.firm-placeholder__icon svg {
  width: 26px;
  height: 26px;
}

.firm-placeholder__title {
  margin: 0;
  font-size: var(--font-size-large);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.firm-placeholder__blurb {
  margin: 0;
  max-width: 420px;
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}

.firm-placeholder__badge {
  padding: 2px var(--space-3);
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-text-faint);
}

/* --- Activity slide-out (reuses .drawer + .audit-history design) ---------- */
/* Everything inside is fixed to the viewport, so the wrapper is a grouping for
   the controller and the `pointer-events` above — not a box. Without
   `display: contents` it is still a child of the .firm-show grid, and a grid
   child it must place somewhere: it would take a row of its own and push the
   nav and the page down by the grid's gap on every tab that has one. */
.firm-activity {
  display: contents;
  pointer-events: none;
}

.firm-show.is-activity-open .firm-activity {
  pointer-events: auto;
}

.firm-activity .drawer__overlay {
  opacity: 0;
  transition: opacity var(--transition-slow);
}

.firm-show.is-activity-open .firm-activity .drawer__overlay {
  opacity: 1;
}

.firm-activity .drawer__content {
  transform: translateX(100%);
  transition: transform var(--transition-slow);
}

.firm-show.is-activity-open .firm-activity .drawer__content {
  transform: translateX(0);
}

.firm-activity .audit-history__action strong {
  color: var(--color-primary-dark);
}

/* --- Responsive ---------------------------------------------------------- */
@media (max-width: 1024px) {
  .firm-show {
    grid-template-columns: 1fr;
    gap: var(--space-5);
  }

  .firm-subnav {
    position: static;
  }

  .firm-subnav__list {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-2);
  }

  .firm-dashboard,
  .firm-service--expanded {
    grid-template-columns: 1fr;
  }
}

/* --- Service plan (Service Information tab) ------------------------------ */
/* Field pairs sit in one grid that flows row by row, so each field lands
   opposite its counterpart (status / manager, review / payment schedule). */
.firm-service-plan__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-5) var(--space-6);
  margin: 0;
}

.firm-service-plan__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

/* A plan past its renewal kick-off date is flagged on the card itself, not just
   in its status pill — it is the one state that needs acting on. */
.firm-service-plan--renewal-due {
  border-color: var(--color-warning);
  box-shadow: var(--shadow-xs), 0 0 0 3px rgba(245, 158, 11, 0.12);
}

.firm-service-plan__flag {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: rgba(245, 158, 11, 0.1);
  color: var(--color-warning-dark);
  font-size: var(--font-size-medium);
  line-height: 1.5;
}

.firm-service-plan__flag-icon {
  flex-shrink: 0;
  /* Nudged onto the first line's baseline rather than its box top. */
  margin-top: 2px;
}

.firm-service-plan__notes {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

.firm-note-text--boxed {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}

/* --- Client numbers ------------------------------------------------------ */
.firm-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.firm-metric {
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}

.firm-metric__value {
  margin: 0;
  font-size: var(--font-size-xxlarge);
  font-family: var(--font-family-bold);
  font-weight: 600;
  line-height: 1.1;
  color: var(--color-primary-dark);
}

.firm-metric__label {
  margin: 0;
  font-size: var(--font-size-small);
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* --- Service inclusions -------------------------------------------------- */
/* Columns rather than a grid: the list reads all the way down one side and then
   the other, as the design has it. */
.firm-inclusions {
  display: block;
  column-count: 2;
  column-gap: var(--space-6);
}

.firm-inclusions .firm-checklist__item {
  /* Column layout drops flex gaps, so each row carries its own spacing and is
     kept from breaking across the column boundary. */
  margin-bottom: var(--space-3);
  break-inside: avoid;
}

/* --- Firm preferences (cards, brand swatches, meeting-type choices) ------- */
/* The heading and its blurb stack together on the left, leaving the edit pencil
   on the header's right whether or not the card carries a blurb. */
.firm-card__heading {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

/* The brand palette's pills are the shared .colour-swatch, so the card and the
   picker that fills it show a colour the same way (see colour_picker.css). */

/* Documents on file: the shared checklist row with its state pill pushed to the
   far edge, as the design has it. */
.firm-preferences__documents {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

.firm-documents {
  gap: 0;
  margin-top: var(--space-2);
}

.firm-documents__item {
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}

.firm-documents__item:last-child {
  border-bottom: none;
}

.firm-documents__label {
  flex: 1;
  min-width: 0;
}

/* Fixed-list choices (preferred meeting types): every option is shown, so what
   the firm will not do is as plain as what they will. */
.firm-choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.firm-choice {
  padding: 3px 12px;
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-text-faint);
}

.firm-choice.is-chosen {
  background: var(--tint-green-16);
  color: var(--color-success-dark);
}

/* --- Warning notes ------------------------------------------------------- */
.firm-warnings {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.firm-warning {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-danger);
  border-radius: var(--radius-md);
  background: var(--tint-danger-10);
}

.firm-warning__body {
  flex: 1;
  min-width: 0;
}

.firm-warning__text {
  margin: 0;
  font-size: var(--font-size-medium);
  line-height: 1.5;
  color: var(--color-danger);
}

.firm-warning__meta {
  margin: 2px 0 0;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* button_to wraps the control in a form, so the button is unwrapped back to a
   bare icon rather than inheriting any block layout. */
.firm-warning__dismiss {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-danger);
  cursor: pointer;
  transition: background var(--transition-fast);
}

.firm-warning__dismiss:hover {
  background: var(--tint-danger-10);
}

/* --- Other notes (Firm Preferences) -------------------------------------- */
/* Same note, without the alarm: read as part of the preferences rather than as
   something to stop and deal with. */
.firm-notes {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.firm-note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}

.firm-note__body {
  flex: 1;
  min-width: 0;
}

.firm-note__text {
  margin: 0;
  font-size: var(--font-size-medium);
  line-height: 1.5;
  color: var(--color-text);
}

.firm-note__meta {
  margin: 2px 0 0;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* As .firm-warning__dismiss: button_to wraps the control in a form, so the
   button is unwrapped back to a bare icon. */
.firm-note__dismiss {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.firm-note__dismiss:hover {
  background: var(--color-surface);
  color: var(--color-text);
}

/* --- Note composer (both cards) ------------------------------------------ */
.firm-note-composer__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.firm-note-composer__row .form__input {
  flex: 1;
  min-width: 0;
}

.firm-note-composer__row input[type="submit"] {
  flex-shrink: 0;
}

@media (max-width: 720px) {
  .firm-service-plan__grid,
  .firm-field-grid {
    grid-template-columns: 1fr;
  }

  .firm-inclusions {
    column-count: 1;
  }

  .firm-note-composer__row {
    flex-direction: column;
    align-items: stretch;
  }
}


/* ===== components/flash.css ===== */
/* ==========================================================================
   Flash messages — what the application says back after a redirect

   Rendered at the top of the main content frame (see shared/_flash), so they
   sit above whatever page the user has landed on. Two kinds: an alert, for
   being turned away from something, and a notice for everything else.
   ========================================================================== */
.flash-messages {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.flash-message {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
}

.flash-message__text {
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-medium);
  font-weight: 600;
  line-height: 1.5;
}

.flash-message__dismiss {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  background: transparent;
  color: inherit;
  cursor: pointer;
}

.flash-message--alert {
  border-color: var(--color-danger);
  background: var(--tint-danger-10);
  color: var(--color-danger);
}

.flash-message--notice {
  border-color: var(--color-primary-green);
  background: var(--tint-green-10);
  color: var(--color-primary-dark);
}


/* ===== components/form.css ===== */
/* ==========================================================================
   Forms
   ========================================================================== */
.form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.form__section {
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-xs);
}

.form__section-title {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

.form__row {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  gap: var(--space-4);
}

.form__field {
  display: flex;
  flex-direction: column;
  white-space: nowrap;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  font-size: var(--font-size-small);
  width: 100%;
}

.form__field > textarea {
  min-height: 100px;
  resize: vertical;
}

.form__field--inline {
  display: flex;
  flex-direction: row;
  gap: var(--space-4);
}

.form__field--centered {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.form__label {
  display: block;
  font-family: var(--font-family-bold);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.form__input,
.form__select {
  width: 100%;
  height: 40px;
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-base);
  color: var(--color-text);
  background-color: var(--color-surface-sunken);
  transition: border-color var(--transition-fast), background-color var(--transition-fast),
    box-shadow var(--transition-fast);
}

.form__field > textarea.form__input,
textarea.form__input {
  height: auto;
  padding: var(--space-2) var(--space-3);
}

.form__input:hover,
.form__select:hover {
  border-color: var(--color-border-strong);
}

.form__input:focus,
.form__select:focus {
  outline: none;
  background-color: var(--color-surface);
  border-color: var(--color-primary-green);
  box-shadow: var(--focus-ring);
}

/* Auto-generated values (e.g. a complaint id or a computed due date) — shown
   for reference, not editable. */
.form__input--readonly,
.form__input--readonly:hover,
.form__input--readonly:focus {
  border-color: var(--color-border);
  background-color: var(--tint-navy-04);
  color: var(--color-text-muted);
  box-shadow: none;
  cursor: default;
}

.form__select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%2364748b' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
  background-position: right var(--space-2) center;
  background-repeat: no-repeat;
  background-size: 1.5em 1.5em;
  padding-right: var(--space-8);
  cursor: pointer;
}

.form__checkbox {
  margin-right: var(--space-2);
  width: 16px;
  height: 16px;
  accent-color: var(--color-primary-green);
}

.form__hint {
  margin-bottom: var(--space-2);
  font-size: var(--font-size-small);
  color: var(--color-text-muted, #64748b);
}

/* Something the form needs to say before it is filled in, rather than about one
   field: that a firm's own adviser is sending their edits for review, say. */
.form__notice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  line-height: 1.5;
}

.form__notice-icon {
  flex-shrink: 0;
  margin-top: 2px;
}

/* A field the user can read but not set — the person a firm's own adviser is
   logging feedback as, say. Sits on the input's line so the form still reads as
   a column of fields rather than a paragraph dropped into one. */
.form__static-value {
  display: flex;
  align-items: center;
  height: 40px;
  font-size: var(--font-size-medium);
  color: var(--color-text);
}

.form__checkbox-group {
  display: grid;
  /* `min(100%, 200px)` rather than a bare 200px: in a drawer narrower than the
     track the column would otherwise overflow the form rather than the grid
     dropping to one column. */
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr));
  gap: var(--space-2);
}

.form__checkbox-option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  /* A grid track is `minmax(200px, 1fr)`, so an option whose label runs longer
     than that — "Annual Suitability Report (ASR)", and the checklist note under
     it — has to be allowed to wrap rather than push its box open. Flex items
     refuse to shrink below their content width without this. */
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border, #e2e8f0);
  border-radius: var(--radius-md);
  cursor: pointer;
  font-size: var(--font-size-small);
  transition: border-color 0.12s ease, background-color 0.12s ease;
}

.form__checkbox-option:hover {
  border-color: var(--color-primary-green);
}

.form__checkbox-option:has(.form__checkbox:checked) {
  border-color: var(--color-primary-green);
  background-color: var(--tint-primary-10, rgba(16, 185, 129, 0.08));
}

.form__checkbox-option .form__checkbox {
  margin-right: 0;
  /* The box keeps its size while the label beside it wraps. */
  flex-shrink: 0;
}

/* A recommendation and the checklist it brings with it, stacked so the option
   still reads as one line of list (see cases/_case_type_checkboxes). */
.form__checkbox-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* As above: without `min-width: 0` this refuses to be narrower than its
     longest line, and the text runs out of the option instead of wrapping. */
  min-width: 0;
  overflow-wrap: anywhere;
}

.form__checkbox-note {
  color: var(--color-text-muted);
  font-size: 11px;
  line-height: 1.3;
}

.form__actions {
  margin-top: var(--space-6);
  display: flex;
  gap: var(--space-3);
}

/* --- Validation error summary --- */
.form__error-summary {
  border: 1px solid var(--tint-danger-16);
  border-left: 3px solid var(--color-danger);
  border-radius: var(--radius-md);
  background-color: var(--tint-danger-10);
  color: var(--color-danger);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}

.form__error-summary h3 {
  font-size: var(--font-size-medium);
  color: var(--color-danger);
  margin-bottom: var(--space-2);
}

.form__error-summary ul {
  margin: 0;
  padding-left: var(--space-4);
  font-size: var(--font-size-small);
}

/* --- Yes/No radio switch --- */
.form__radio-switch {
  position: relative;
  width: 100%;
}

.form__radio-group {
  display: flex;
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 3px;
  position: relative;
  width: 120px;
}

.form__radio-input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.form__radio-label {
  flex: 1;
  text-align: center;
  padding: var(--space-1) var(--space-3);
  cursor: pointer;
  border-radius: var(--radius-sm);
  font-weight: 500;
  font-size: var(--font-size-small);
  transition: all var(--transition-base);
  user-select: none;
  z-index: 1;
  color: var(--color-text-muted);
}

.form__radio-label:hover {
  background-color: var(--tint-navy-06);
}

.form__radio-label--yes.selected,
.form__radio-input:checked + .form__radio-label--yes {
  background-color: var(--color-success) !important;
  color: var(--color-white) !important;
}

.form__radio-label--no.selected,
.form__radio-input:checked + .form__radio-label--no {
  background-color: var(--color-text-muted) !important;
  color: var(--color-white) !important;
}

.form__radio-input:focus-visible + .form__radio-label {
  box-shadow: var(--focus-ring);
}

.form__radio-label--yes.selected:hover,
.form__radio-input:checked + .form__radio-label--yes:hover {
  background-color: var(--color-success-dark) !important;
}

/* --- Grid helpers --- */
.form__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-3);
}

.form__field--full {
  grid-column: 1 / -1;
}

.form__field--date {
  width: 100%;
}

/* --- Duration inputs --- */
.form__duration-inputs {
  display: flex;
  gap: var(--space-2);
  align-items: flex-end;
}

.form__duration-inputs--labeled {
  flex-wrap: wrap;
}

.form__duration-input-group {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.form__duration-separator {
  color: var(--color-text-muted);
  font-weight: 500;
  padding-bottom: var(--space-2);
}

/* --- Currency / percentage affixes --- */
.form__input-wrapper {
  position: relative;
  display: inline-block;
}

.form__input-wrapper--currency::before {
  content: "£";
  position: absolute;
  left: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-muted);
}

.form__input-wrapper--percentage::after {
  content: "%";
  position: absolute;
  right: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-muted);
}

.form__input--currency {
  padding-left: var(--space-6);
}

.form__input--percentage {
  padding-right: var(--space-6);
}

/* --- File upload --- */
.form__file-upload {
  margin-bottom: var(--space-4);
}

.form__input--file {
  width: 100%;
  height: auto;
  padding: var(--space-3);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
  cursor: pointer;
  transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

.form__input--file:hover {
  border-color: var(--color-primary-green);
  background-color: var(--tint-green-10);
}

.form__preview {
  margin-top: var(--space-2);
}

.form__preview-image {
  max-width: 200px;
  max-height: 200px;
  object-fit: contain;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
}

/* --- Static (read-only) radio switch --- */
.form__radio-label--static {
  flex: 1;
  text-align: center;
  padding: var(--space-1) var(--space-3);
  cursor: default;
  border-radius: var(--radius-sm);
  font-weight: 500;
  user-select: none;
  z-index: 1;
  width: 50%;
}

.form__radio-switch--static {
  width: 120px;
}

.form__radio-switch--static .form__radio-label {
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-small);
  cursor: default;
}

.form__radio-label--yes.form__radio-label--selected {
  background-color: var(--color-success);
  color: var(--color-white);
}

.form__radio-label--no.form__radio-label--selected {
  background-color: var(--color-text-muted);
  color: var(--color-white);
}


/* ===== components/invoice_tracking.css ===== */
/* ==========================================================================
   Invoicing — the tracking listing

   Every invoice the practice has raised, of every kind, and what state each is
   in. The screen answers one question — what is outstanding — so the tiles get
   the weight and the table gets the detail.
   ========================================================================== */

/* --- The state tiles ----------------------------------------------------- */

/* Auto-fit rather than a fixed column count: a third kind of invoice is coming
   and may bring a state with it, and a grid that has to be recounted every time
   is a grid that will be wrong once. */
.invoice-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.invoice-summary__tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  /* The state's own colour, as a spine down the left rather than a fill. Five
     filled tiles side by side is a paint chart; a spine says which is which
     without any of them shouting. */
  border-left: 3px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
  text-decoration: none;
  color: inherit;
  transition: background-color 120ms ease, border-color 120ms ease;
}

.invoice-summary__tile:hover {
  background-color: var(--tint-navy-04);
}

/* The tile you are currently filtered to. Marked by weight rather than by
   colour, so it reads as "selected" and not as "this state is the bad one". */
.invoice-summary__tile--active {
  background-color: var(--tint-navy-06);
  border-color: var(--color-border-strong);
  box-shadow: inset 0 0 0 1px var(--color-border-strong);
}

.invoice-summary__tile--gray { border-left-color: var(--color-border-strong); }
.invoice-summary__tile--yellow { border-left-color: var(--color-warning); }
.invoice-summary__tile--blue { border-left-color: var(--color-primary-dark); }
.invoice-summary__tile--red { border-left-color: var(--color-danger); }
.invoice-summary__tile--green { border-left-color: var(--color-success); }

.invoice-summary__label {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* The money is the headline. It is the figure somebody came to this screen for. */
.invoice-summary__amount {
  font-family: var(--font-family-bold);
  font-size: var(--font-size-xlarge);
  font-weight: bold;
  color: var(--color-primary-dark);
  font-variant-numeric: tabular-nums;
}

.invoice-summary__count {
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
}

/* --- The table ----------------------------------------------------------- */

.invoice-row__number {
  font-family: var(--font-family-bold);
  font-weight: bold;
  white-space: nowrap;
}

/* The one free-text column, and the one that varies most in length: a case
   reference runs to four names joined by dashes, a retainer's is a month. */
.invoice-row__subject {
  max-width: 34ch;
}

.invoice-row__amount {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.invoice-row__late {
  display: block;
  margin-top: var(--space-1);
  color: var(--color-danger);
  font-size: var(--font-size-small);
}

.invoice-row__actions {
  text-align: right;
  white-space: nowrap;
}


/* ===== components/invoicing.css ===== */
/* ==========================================================================
   Case invoicing

   Two things: the Invoicing card on the case record, and the builder modal it
   opens. The invoice *document* is styled somewhere else entirely and on
   purpose — it is a client-facing PDF printed from one self-contained string of
   HTML (see app/views/case_invoices/pdf/_styles.html.erb). Nothing here reaches
   it, and nothing there reaches this.
   ========================================================================== */

/* --- The card on the case record ----------------------------------------- */

.invoicing__status {
  display: flex;
  gap: var(--space-6);
  margin-bottom: var(--space-3);
}

.invoicing__field + .invoicing__field {
  margin-top: 0;
}

.invoicing__field {
  margin-bottom: var(--space-3);
}

.invoicing__empty {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.invoicing__document {
  display: flex;
  align-items: baseline;
  gap: var(--space-1);
  flex-wrap: wrap;
}

.invoicing__link {
  font-weight: 600;
  color: var(--color-primary-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
  word-break: break-all;
}

.invoicing__amount {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* Everything superseded by the current invoice. Collapsed, because on most
   cases there is nothing in it and on the rest it is history rather than
   something to act on. */
.invoicing__history {
  margin-top: var(--space-2);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.invoicing__history summary {
  cursor: pointer;
}

.invoicing__history ul {
  margin: var(--space-2) 0 0;
  padding-left: var(--space-4);
}

/* Only while an invoice is with a reviewer. Amber, because it is a hold rather
   than a fault — the same colour the builder's service-plan warning uses. */
.invoicing__review-note {
  margin-bottom: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-warning);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-small);
}

.invoicing__review-note form {
  margin-top: var(--space-2);
}

.invoicing__action {
  width: 100%;
  justify-content: center;
}

/* Who the invoice was emailed to, from the latest attempt (see
   Invoicing::Delivery). Red only when that attempt failed. */
.invoicing__delivery {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.invoicing__delivery--failed {
  color: var(--color-danger);
}

/* --- The builder modal ---------------------------------------------------- */

.invoice-modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
}

.invoice-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, 0.45);
}

/* Wide, because it is two panels side by side: choosing on the left and the
   consequence on the right. Capped at the viewport so the body scrolls inside
   it rather than the page scrolling behind it. */
.invoice-modal__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(1180px, 100%);
  max-height: min(880px, 92vh);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: 0 24px 60px rgba(15, 23, 42, 0.28);
  overflow: hidden;
}

/* The form wraps the body and the footer, so it is the flex column that divides
   the panel's remaining height between them. A plain block here grows to its
   content instead, and pushes the footer out of the panel's overflow — a send
   button nobody can reach on a short screen. */
.invoice-modal__form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

/* The fixed bands — header, warning, footer — keep their height and the body
   absorbs whatever is left. */
.invoice-modal__header {
  flex: none;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border-bottom: 1px solid var(--color-border);
}

.invoice-modal__eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.invoice-modal__title {
  font-size: var(--font-size-xlarge);
  color: var(--color-primary-dark);
}

.invoice-modal__subtitle {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.invoice-modal__close {
  border: 0;
  background: none;
  cursor: pointer;
  color: var(--color-text-muted);
  padding: var(--space-1);
}

.invoice-modal__close:hover {
  color: var(--color-primary-dark);
}

.invoice-modal__warning {
  flex: none;
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-6);
  border-bottom: 1px solid var(--color-border);
  background: #fdf4e9;
  font-size: var(--font-size-small);
  color: var(--color-warning-dark);
}

.invoice-modal__warning svg {
  flex: none;
  margin-top: 2px;
}

.invoice-modal__body {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(320px, 1fr);
  /* `min-height: 0` is what lets the two panels scroll instead of the whole
     modal growing past the screen — a grid item's default minimum is its
     content. */
  min-height: 0;
  flex: 1 1 auto;
}

.invoice-modal__services {
  padding: var(--space-4) var(--space-6);
  overflow-y: auto;
}

/* A column of its own: the lines scroll and the totals sit under them as a
   band that does not move. Not `position: sticky` on the totals — a sticky block
   inside a short panel ends up painted over the line controls beneath it, and
   the thing it covers is a checkbox somebody was trying to tick. */
.invoice-modal__preview {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-left: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
}

.invoice-modal__footer {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--color-border);
  flex-wrap: wrap;
}

.invoice-modal__reviewer {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.invoice-modal__reviewer .form__label {
  margin: 0;
  white-space: nowrap;
}

.invoice-modal__buttons {
  display: flex;
  gap: var(--space-3);
  margin-left: auto;
}

/* --- People tabs ---------------------------------------------------------- */

.invoice-people {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.invoice-people__tab,
.invoice-people__add {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-surface);
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-text);
  cursor: pointer;
}

.invoice-people__tab.is-active {
  border-color: var(--color-primary-dark);
  background: var(--color-primary-dark);
  color: #fff;
}

/* A tab somebody added and has not named. Not an error — they may be halfway
   through typing — so it is marked rather than flagged. */
.invoice-people__tab.is-unnamed {
  font-style: italic;
  color: var(--color-text-muted);
}

.invoice-people__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--tint-green-16);
  color: var(--color-primary-dark);
  font-size: 11px;
}

.invoice-people__tab.is-active .invoice-people__count {
  background: var(--tint-white-24);
  color: #fff;
}

/* --- The service list ----------------------------------------------------- */

.invoice-person__name-field {
  margin-bottom: var(--space-4);
}

.invoice-group {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-3);
}

.invoice-group__summary {
  padding: var(--space-3);
  font-weight: 600;
  color: var(--color-primary-dark);
  cursor: pointer;
}

.invoice-group__list {
  border-top: 1px solid var(--color-border);
}

.invoice-line {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-top: 1px solid var(--color-border);
}

.invoice-line:first-child {
  border-top: 0;
}

.invoice-line.is-selected {
  background: var(--tint-green-10);
}

.invoice-line__toggle {
  flex: none;
}

.invoice-line__name {
  flex: 1;
  font-size: var(--font-size-small);
  cursor: pointer;
  margin: 0;
}

/* The catalogue's own exemption, said on the row rather than only in the
   preview: it changes what selecting the row will cost. */
.invoice-line__tag {
  padding: 1px 6px;
  border-radius: 999px;
  background: #fdf4e9;
  color: var(--color-warning-dark);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.invoice-line__qty {
  width: 62px;
  padding: 3px 6px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-small);
}

.invoice-line__price {
  min-width: 72px;
  text-align: right;
  font-size: var(--font-size-small);
  font-variant-numeric: tabular-nums;
}

/* --- Custom lines --------------------------------------------------------- */

.invoice-custom {
  margin-top: var(--space-4);
}

.invoice-custom__title {
  font-size: var(--font-size-small);
  font-weight: 700;
  color: var(--color-primary-dark);
  margin-bottom: var(--space-2);
}

.invoice-custom__row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) 0;
}

.invoice-custom__description {
  flex: 1;
}

.invoice-custom__fee {
  display: flex;
  align-items: center;
  gap: 4px;
  width: 110px;
}

/* Which side of VAT a typed price is on (see case_submission_queue/_request_line). */
.invoice-custom__vat {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  white-space: nowrap;
}

.submission-request__price .invoice-custom__fee:has(.invoice-custom__vat) {
  width: auto;
}

.invoice-custom__full-rate {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: var(--font-size-small);
  white-space: nowrap;
}

.invoice-custom__remove,
.invoice-preview__remove {
  border: 0;
  background: none;
  cursor: pointer;
  color: var(--color-text-muted);
  padding: 2px;
}

.invoice-custom__remove:hover,
.invoice-preview__remove:hover {
  color: var(--color-danger);
}

.invoice-custom__add {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  background: none;
  font-size: var(--font-size-small);
  color: var(--color-primary-dark);
  cursor: pointer;
}

/* --- The preview ---------------------------------------------------------- */

.invoice-preview {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1 1 auto;
  padding: var(--space-4) var(--space-5) 0;
}

.invoice-preview__title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-3);
}

.invoice-preview__empty {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* The only part that scrolls. */
.invoice-preview__lines {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.invoice-preview__person {
  margin: var(--space-3) 0 var(--space-1);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.invoice-preview__line {
  padding: var(--space-2) 0;
  border-top: 1px solid var(--color-border);
}

.invoice-preview__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
}

.invoice-preview__name {
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.invoice-preview__tag {
  margin-left: 4px;
  padding: 1px 5px;
  border-radius: 999px;
  background: var(--tint-navy-06);
  color: var(--color-text-muted);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
}

.invoice-preview__meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: 2px;
}

/* The three treatments, coloured so a line's story is legible without reading
   it: green for the one charged in full because it is the most expensive, grey
   for one charged in full because it is exempt, navy for a discounted one. */
.invoice-preview__badge {
  font-size: 11px;
  font-weight: 700;
}

.invoice-preview__badge--top {
  color: var(--color-success-dark);
}

.invoice-preview__badge--full {
  color: var(--color-text-muted);
}

.invoice-preview__badge--discounted {
  color: var(--color-primary-dark);
}

.invoice-preview__amount {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
}

.invoice-preview__controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: var(--space-2);
  font-size: 11px;
  color: var(--color-text-muted);
}

.invoice-preview__controls label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.invoice-preview__controls select {
  padding: 2px 4px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: 11px;
}

/* Under the lines and outside the scroll, so the total is always in view and
   never over anything. */
.invoice-preview__totals {
  flex: none;
  margin-top: var(--space-3);
  padding: var(--space-3) 0 var(--space-4);
  border-top: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
}

.invoice-total {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 3px 0;
  font-size: var(--font-size-small);
  font-variant-numeric: tabular-nums;
}

.invoice-total--reduction {
  color: var(--color-text-muted);
}

.invoice-total--split {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-border);
}

.invoice-total--grand {
  margin-top: var(--space-2);
  padding: var(--space-2) 0 var(--space-3);
  font-size: var(--font-size-medium);
  font-weight: 700;
  color: var(--color-primary-dark);
}

/* --- Adviser case submissions --------------------------------------------- */

/* The submission builder is the invoice builder's markup with the pricing taken
   out, so it inherits nearly all of the above. These are the few pieces it has
   that an invoice does not. */

/* Choosing the client, above the builder proper. Its own band because it is
   navigation rather than part of the form — picking a different one reloads the
   modal. */
.submission-chooser {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-6);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
}

.submission-chooser__field {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.submission-chooser .form__label,
.submission-chooser .form__hint {
  margin: 0;
  white-space: nowrap;
}

/* The name of a client the firm has just taken on, typed into the submission.

   Inside the builder's own form rather than in the chooser band above it: it is
   part of what is being sent, and the chooser reloads the modal on every change
   (see case_submissions/_new_client_fields). */
.submission-new-client {
  flex: none;
  margin: 0;
  padding: var(--space-4) var(--space-6);
  border: 0;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface-sunken);
}

.submission-new-client__legend {
  padding: 0;
  margin-bottom: var(--space-3);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.submission-new-client .form__hint {
  margin-top: var(--space-3);
  margin-bottom: 0;
}

.submission-modal__empty {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-8) var(--space-6);
  color: var(--color-text-muted);
}

/* An item the adviser has asked for and nobody has priced. Said on the row
   itself as well as in the estimate, because the row is where they typed it. */
.invoice-custom__unpriced {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.invoice-preview__badge--pending {
  color: var(--color-warning-dark);
}

.invoice-preview__amount--pending {
  color: var(--color-text-muted);
  font-weight: 400;
}

/* The caveat under the estimate. The whole reason the panel is called an
   estimate rather than a quote, so it is amber and it is not small print. */
.submission-caveat {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: #fdf4e9;
  font-size: var(--font-size-small);
  color: var(--color-warning-dark);
}

.submission-caveat svg {
  flex: none;
  margin-top: 2px;
}

.submission-footer__note {
  margin: 0;
  max-width: 42ch;
}

/* --- The submission record, both sides ------------------------------------ */

.submission-detail {
  gap: var(--space-4);
}

/* What the state means, said in words above the figures. Coloured by state so
   the page reads at a glance. */
.submission-note {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.submission-note--own {
  background: var(--color-surface-sunken);
}

.submission-note__title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-1);
}

.submission-summary__person + .submission-summary__person {
  margin-top: var(--space-4);
}

.submission-summary__name {
  font-size: var(--font-size-medium);
  font-weight: 700;
  color: var(--color-primary-dark);
  margin-bottom: var(--space-1);
}

/* The lines, on both sides' record screens. Its own small table rather than the
   index table's: this is three columns inside a card, not a listing. */
.submission-summary__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-small);
}

.submission-summary__table th,
.submission-summary__table td {
  padding: var(--space-2) var(--space-1);
  border-bottom: 1px solid var(--color-border);
  text-align: right;
  vertical-align: top;
}

.submission-summary__table th:first-child,
.submission-summary__table td:first-child {
  text-align: left;
  width: 100%;
}

.submission-summary__table thead th {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.submission-summary__table .num {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.submission-summary__treatment {
  font-size: 11px;
  color: var(--color-text-muted);
}

.submission-summary__totals {
  margin: var(--space-4) 0 0 auto;
  width: min(320px, 100%);
}

.invoice-preview .submission-summary__totals {
  width: 100%;
  margin: 0;
}

.submission-summary__estimate {
  margin-top: var(--space-2);
  font-size: 11px;
  color: var(--color-text-muted);
  text-align: right;
}

/* The adviser's decision. Accept is a button and decline is a small form,
   because declining takes a reason and accepting does not. */
.submission-tabs {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin: var(--space-4) 0;
}

.submission-tabs__tab {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-text);
}

.submission-tabs__tab.is-active {
  border-color: var(--color-primary-dark);
  background: var(--color-primary-dark);
  color: #fff;
}

.submission-tabs__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--tint-green-16);
  color: var(--color-primary-dark);
  font-size: 11px;
}

.submission-tabs__tab.is-active .submission-tabs__count {
  background: var(--tint-white-24);
  color: #fff;
}

/* --- Pricing a submission -------------------------------------------------- */

/* The invoice builder's two panels, on a page rather than in a modal: what was
   asked for on the left, what it currently comes to on the right. */
.submission-pricer__body {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(320px, 1fr);
  gap: var(--space-4);
  align-items: start;
}

.submission-pricer__preview {
  position: sticky;
  top: var(--space-4);
  display: flex;
  flex-direction: column;
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

/* Under both panels rather than beside one: it acts on the whole form. */
.submission-pricer__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface-sunken);
}

.submission-pricer__lead {
  flex: 1 1 320px;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  margin: 0;
}

.submission-pricer__meta {
  margin-top: var(--space-4);
  max-width: 480px;
}

/* --- The request, on the left --------------------------------------------- */

.submission-request__person + .submission-request__person {
  margin-top: var(--space-4);
}

.submission-request__name {
  font-size: var(--font-size-small);
  font-weight: 700;
  color: var(--color-primary-dark);
  margin-bottom: var(--space-2);
}

.submission-request__line {
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
}

.submission-request__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}

.submission-request__label {
  font-size: var(--font-size-small);
  color: var(--color-primary-dark);
}

.submission-request__rate {
  font-size: var(--font-size-small);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
  white-space: nowrap;
}

/* Only a custom line has one: everything else is priced by the catalogue. */
.submission-request__price {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: var(--space-2);
}

.submission-request__price .invoice-custom__fee {
  flex: 0 1 160px;
}

.submission-request__check {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.submission-request__pending {
  margin-top: 2px;
  font-size: 11px;
  color: var(--color-warning-dark);
}

.submission-meta {
  display: grid;
  gap: var(--space-2);
}

.submission-meta div {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--font-size-small);
}

.submission-meta dt {
  color: var(--color-text-muted);
}

.submission-pricer__section + .submission-pricer__section {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

.submission-pricer__heading {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}

.submission-pricer__discount {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.submission-pricer__discount .form__select {
  flex: 1 1 140px;
}

.submission-pricer__discount .form__input {
  flex: 1 1 80px;
  min-width: 0;
}

.firm-records__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.firm-records__lead,
.firm-records__empty {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  max-width: 60ch;
}

/* --- A discount on the whole invoice --------------------------------------- */

/* Under the services rather than in the preview: the preview is replaced on
   every tick, and these are boxes somebody types into. */
.invoice-modal__discount {
  margin-top: var(--space-4);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}

.invoice-modal__discount-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}

.invoice-modal__discount-fields {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.invoice-modal__discount-fields .form__select {
  flex: 1 1 140px;
}

.invoice-modal__discount-fields .form__input {
  flex: 1 1 80px;
  min-width: 0;
}

/* The list price beside what was actually charged, wherever a subscription or a
   tier took something off. Struck through rather than labelled: the pair reads
   as "was / is" at a glance, and there is no room on a line for two headings. */
.invoice-preview__was {
  margin-right: 5px;
  font-weight: 400;
  color: var(--color-text-muted);
  text-decoration: line-through;
}

/* --- An adviser reading their quote ---------------------------------------- */

/* The figure first. A quote is opened to answer "what does it cost and do I say
   yes"; the breakdown underneath is there for "why that much", afterwards. */
.quote-headline {
  display: grid;
  grid-template-columns: minmax(200px, 260px) minmax(0, 1fr);
  gap: var(--space-4);
  align-items: center;
  margin-top: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.quote-headline__figure {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-right: var(--space-4);
  border-right: 1px solid var(--color-border);
}

.quote-headline__label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.quote-headline__amount {
  font-size: 32px;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--color-primary-dark);
}

.quote-headline__vat {
  font-size: 11px;
  color: var(--color-text-muted);
}

.quote-headline__state h3 {
  font-size: var(--font-size-base);
  font-weight: 700;
  color: var(--color-primary-dark);
}

.quote-headline__state p {
  margin-top: 2px;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  max-width: 60ch;
}

/* A quote waiting on the adviser is the one state worth colouring: it is the
   only one asking them for something. */
.quote-headline--quoted {
  border-color: var(--color-primary-green);
  box-shadow: inset 3px 0 0 var(--color-primary-green);
}

.quote-headline--declined {
  opacity: 0.75;
}

.quote-breakdown {
  margin-top: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

/* Lines and totals side by side where there is room. Stacked, a four-row table
   leaves a wide empty gap beside a narrow totals column. */
@media (min-width: 1100px) {
  .quote-breakdown .submission-summary {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(260px, 300px);
    gap: var(--space-5);
    align-items: start;
  }

  .quote-breakdown .submission-summary__totals {
    width: 100%;
    margin: 0;
    padding-top: 0;
    border-top: 0;
  }

  .quote-breakdown .submission-caveat {
    grid-column: 1 / -1;
  }
}

.quote-breakdown__title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-3);
}

/* Accepting is one button; declining is behind a toggle. They are not two equal
   choices on a quote the adviser asked us for. */
.quote-decision {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface-sunken);
}

.quote-decision__accept .button {
  white-space: nowrap;
}

.quote-decision__decline {
  flex: 1 1 320px;
  min-width: 0;
}

.quote-decision__decline summary {
  cursor: pointer;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  list-style: none;
}

.quote-decision__decline summary::-webkit-details-marker {
  display: none;
}

.quote-decision__decline summary::after {
  content: " ›";
}

.quote-decision__decline[open] summary::after {
  content: " ⌄";
}

.quote-decision__decline summary:hover {
  color: var(--color-primary-dark);
}

.quote-decision__decline .submission-decline {
  margin-top: var(--space-3);
}

.quote-decision__decline .button {
  margin-top: var(--space-2);
}

/* The two payment buttons on the case record's invoicing card. Below the pill
   rather than beside it: the pill is read on every case, and the buttons are
   pressed once each in the life of an invoice. */
.invoicing__payment-actions {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-3);
}


/* ===== components/key_contacts.css ===== */
/* ==========================================================================
   Key Contacts — compact contact grid shown on firm directory cards and
   the firm record page
   ========================================================================== */
.key-contacts {
  width: 100%;
}

/* == header == */
.key-contacts__header {
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

.key-contacts__title {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  margin: 0;
}

/* == layout == */
.key-contacts__container {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.key-contacts__container--wide {
  gap: var(--space-5);
}

.key-contacts__row {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.key-contacts__column {
  flex: 1 1 0;
  min-width: 0;
}

/* == contact identity == */
.key-contacts__primary-details {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.key-contacts__avatar {
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  background-color: var(--tint-navy-06);
  border: 1px solid var(--color-border-strong);
}

.key-contacts__details {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.key-contacts__name {
  font-family: var(--font-family-bold);
  font-size: var(--font-size-medium);
  color: var(--color-primary-dark);
  margin: 0 0 var(--space-1) 0;
}

.key-contacts__role {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  margin: 0;
}

/* == contact details == */
.key-contacts__secondary-details {
  display: flex;
  flex-direction: column;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.key-contacts__secondary-details p {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
  white-space: nowrap;
}

.key-contacts__icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: var(--color-text-faint);
}

/* --- Principal contact ---------------------------------------------------
   The one contact who speaks for the firm — the one the monthly satisfaction
   survey goes to. The badge reads the same wherever contacts are listed, so a
   glance at the table and a glance at the dashboard card agree. */
.principal-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--tint-green-16);
  border: 1px solid var(--color-primary-green);
  color: var(--color-primary-dark);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
}

.principal-badge__icon {
  width: 12px;
  height: 12px;
  fill: var(--color-primary-green);
  stroke: var(--color-primary-green);
}

/* Tinted so the principal is still findable once the table is scrolled and the
   badge has gone off the top. Same treatment an overdue complaint's row gets,
   in the affirmative colour. */
.key-contact-row--principal > td {
  background: var(--tint-green-10);
}

/* The badge sits beside the name, so the name stops wrapping to make room for
   it — the column widens instead. */
.key-contact-row--principal .team-member__name-cell {
  white-space: nowrap;
}

/* The dashboard card's version: a left edge rather than a wash, because the
   cards already sit on a tinted panel. */
.firm-contact-card--principal {
  border-left: 3px solid var(--color-primary-green);
  background: var(--tint-green-10);
}


/* ===== components/legal.css ===== */
/* ==========================================================================
   Legal — the documents, their index, and the acceptance gate

   Long-form prose, which the rest of the application has none of: the type is
   larger and the measure narrower than anywhere else on purpose, because these
   are pages somebody has to actually read.
   ========================================================================== */
/* The application's base stylesheet gives html and body `height: 100%` and
   `overflow: hidden`, because every other screen scrolls a pane inside a fixed
   shell. A legal document is the page, so something here has to scroll — and it
   has to be the body.

   Releasing html instead is the obvious way and is the one that cannot work.
   These pages are reached from inside the application by an ordinary Turbo visit
   — the Legal item in the user menu, a link in the middle of another document —
   and a Turbo visit swaps the body and leaves html's attributes exactly as the
   page before it left them. So a class on html is present on a full page load and
   absent on every navigation: the document lays out four thousand pixels tall
   inside an html still locked to the viewport, and nothing scrolls at all. It
   leaks the other way too, releasing the application's own shell on the way back
   in.

   The body is replaced on every visit, so the body is where this belongs. It
   keeps the base's `height: 100%`, which is what makes it a scrollport rather
   than a box that simply grows — and a scrollport is what the sticky header
   below needs in order to have anything to stick to. Give the body `height: auto`
   and the header silently loses its stickiness, which is what happened the first
   time this was tried. */
.legal-body {
  overflow-y: auto;
  background-color: var(--color-canvas);
}

/* == header == */
/* Sticky rather than static: a reader four screens into the privacy notice needs
   the way back where they are, not where they started. */
.legal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  background-color: var(--color-primary-dark);
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
}

.legal-header__brand {
  display: inline-flex;
}

.legal-header__logo {
  width: 120px;
  height: auto;
}

.legal-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.legal-header__link {
  font-size: var(--font-size-medium);
  font-weight: 600;
  color: var(--color-white);
  text-decoration: none;
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--tint-white-24);
  border-radius: var(--radius-full);
  transition: background-color var(--transition-base);
}

.legal-header__link:hover {
  background-color: var(--tint-white-10);
}

/* button_to wraps its button in a form, which would otherwise break the
   header's flex row. */
.legal-header__link--button {
  font-family: inherit;
  background: none;
  cursor: pointer;
}

/* The way back into the application — the primary action on these pages, so it
   is filled rather than outlined. */
.legal-header__link--back {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background-color: var(--color-primary-green);
  border-color: var(--color-primary-green);
}

.legal-header__link--back:hover {
  background-color: var(--color-primary-green);
  filter: brightness(0.95);
}

.legal-header__link-icon {
  flex-shrink: 0;
  color: currentColor;
}

/* == the document page == */
.legal-doc {
  max-width: 820px;
  margin: 0 auto;
  padding: var(--space-8) var(--space-6) var(--space-10);
}

.legal-doc__paper {
  padding: var(--space-10);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm);
}

.legal-doc__masthead {
  padding-bottom: var(--space-6);
  margin-bottom: var(--space-6);
  border-bottom: 1px solid var(--color-border);
}

.legal-doc__eyebrow {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}

.legal-doc__title {
  font-size: var(--font-size-xxxlarge);
  color: var(--color-primary-dark);
  margin-bottom: var(--space-3);
}

.legal-doc__lede {
  font-size: var(--font-size-large);
  color: var(--color-text-muted);
  line-height: 1.6;
}

.legal-doc__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
  margin-top: var(--space-5);
}

.legal-doc__meta-item dt {
  font-size: var(--font-size-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-faint);
  margin-bottom: var(--space-1);
}

.legal-doc__meta-item dd {
  font-size: var(--font-size-medium);
  color: var(--color-text);
}

/* == the prose itself == */
.legal-doc__body {
  font-size: var(--font-size-large);
  line-height: 1.7;
  color: var(--color-text);
}

.legal-doc__section + .legal-doc__section {
  margin-top: var(--space-8);
}

.legal-doc__section h2 {
  font-size: var(--font-size-xlarge);
  color: var(--color-primary-dark);
  margin-bottom: var(--space-3);
}

.legal-doc__section p + p,
.legal-doc__section ul + p,
.legal-doc__section p + ul {
  margin-top: var(--space-3);
}

.legal-doc__section ul {
  padding-left: var(--space-5);
}

.legal-doc__section li + li {
  margin-top: var(--space-2);
}

.legal-doc__section a {
  color: var(--color-primary-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.legal-doc__section code {
  padding: 2px var(--space-1);
  font-family: ui-monospace, "SFMono-Regular", "Menlo", monospace;
  font-size: 0.9em;
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}

/* The clause the reader most needs to notice — the precedence clause on the
   adviser terms, and the controller/processor split on the privacy notice. */
.legal-doc__section--emphasis {
  padding: var(--space-5);
  background-color: var(--tint-green-10);
  border-left: 3px solid var(--color-primary-green);
  border-radius: var(--radius-md);
}

/* A company detail nobody has filled in yet (see LegalHelper#legal_detail).
   Loud on purpose. */
.legal-doc__placeholder {
  padding: 0 var(--space-1);
  font-family: ui-monospace, "SFMono-Regular", "Menlo", monospace;
  font-size: 0.85em;
  color: var(--color-warning-dark);
  background-color: var(--color-yellow-100);
  border: 1px dashed var(--color-warning);
  border-radius: var(--radius-sm);
}

/* == the cookie table == */
.legal-doc__table-wrapper {
  margin: var(--space-4) 0;
  overflow-x: auto;
}

.legal-doc__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-medium);
}

.legal-doc__table th,
.legal-doc__table td {
  padding: var(--space-3);
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--color-border);
}

.legal-doc__table th {
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  white-space: nowrap;
}

/* == the index == */
.legal-index {
  list-style: none;
  padding: 0;
}

.legal-index__item + .legal-index__item {
  margin-top: var(--space-3);
}

.legal-index__link {
  display: block;
  padding: var(--space-5);
  text-decoration: none;
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.legal-index__link:hover {
  border-color: var(--color-primary-green);
  box-shadow: var(--shadow-sm);
}

.legal-index__title {
  display: block;
  font-family: var(--font-family-bold);
  font-weight: 600;
  font-size: var(--font-size-xlarge);
  color: var(--color-primary-dark);
  margin-bottom: var(--space-2);
}

.legal-index__summary {
  display: block;
  font-size: var(--font-size-medium);
  line-height: 1.6;
  color: var(--color-text-muted);
}

.legal-index__meta {
  display: block;
  margin-top: var(--space-2);
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
}

/* ==========================================================================
   The acceptance gate
   ========================================================================== */
.legal-gate {
  max-width: 820px;
  margin: 0 auto;
  padding: var(--space-8) var(--space-6) var(--space-10);
}

.legal-gate__intro {
  margin-bottom: var(--space-6);
}

.legal-gate__title {
  font-size: var(--font-size-xxxlarge);
  color: var(--color-primary-dark);
  margin-bottom: var(--space-3);
}

.legal-gate__lede {
  font-size: var(--font-size-large);
  line-height: 1.6;
  color: var(--color-text-muted);
}

.legal-gate__flash {
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-5);
  font-size: var(--font-size-medium);
  color: var(--color-danger);
  background-color: var(--tint-danger-10);
  border-radius: var(--radius-md);
}

/* == one document == */
.legal-gate__document {
  margin-bottom: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.legal-gate__document-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5);
  border-bottom: 1px solid var(--color-border);
}

.legal-gate__document-title {
  font-size: var(--font-size-xlarge);
  color: var(--color-primary-dark);
}

.legal-gate__document-meta {
  margin-top: var(--space-1);
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
}

.legal-gate__document-link {
  flex-shrink: 0;
  font-size: var(--font-size-medium);
  font-weight: 600;
  color: var(--color-primary-dark);
  white-space: nowrap;
}

/* Capped so the tick box stays reachable on a page holding two full documents;
   tall enough that the reader is not scrolling a letterbox. */
.legal-gate__document-body {
  max-height: 380px;
  padding: var(--space-5);
  overflow-y: auto;
  font-size: var(--font-size-medium);
}

.legal-gate__document-body:focus-visible {
  outline: none;
  box-shadow: inset var(--focus-ring);
}

/* == the tick box == */
.legal-gate__form {
  padding: var(--space-6);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.legal-gate__confirm {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  cursor: pointer;
}

.legal-gate__checkbox {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 3px;
  accent-color: var(--color-primary-green);
  cursor: pointer;
}

.legal-gate__confirm-text {
  font-size: var(--font-size-large);
  line-height: 1.5;
  color: var(--color-text);
}

.legal-gate__actions {
  margin-top: var(--space-5);
}

.legal-gate__footnote {
  margin-top: var(--space-4);
  font-size: var(--font-size-small);
  line-height: 1.5;
  color: var(--color-text-faint);
}

@media (max-width: 640px) {
  .legal-doc__paper {
    padding: var(--space-5);
  }

  .legal-gate__document-header {
    flex-direction: column;
  }
}


/* ===== components/login_form.css ===== */
/* ==========================================================================
   Login Form — auth screens (log in, 2FA, password reset, setup, invitation)
   ========================================================================== */

/* == backdrop == */
.login-form {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--space-6);
  overflow-y: auto;
  background:
    radial-gradient(ellipse at top right, var(--tint-green-16), transparent 55%),
    radial-gradient(ellipse at bottom left, var(--tint-white-10), transparent 60%),
    linear-gradient(160deg, var(--color-primary-dark), var(--color-secondary-dark));
}

/* == logo == */
.login-form__logo {
  position: fixed;
  top: var(--space-10);
  left: var(--space-10);
  z-index: var(--z-sticky);
}

.login-form__logo-image {
  width: 150px;
  height: auto;
}

/* == card == */
.login-form__card {
  width: 100%;
  max-width: 420px;
  margin: auto;
  padding: var(--space-8);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
}

/* == headings == */
.login-form__eyebrow {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}

.login-form__title {
  font-size: var(--font-size-xxlarge);
  color: var(--color-primary-dark);
  margin-bottom: var(--space-6);
}

.login-form__intro {
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
  line-height: 1.5;
  margin-top: calc(-1 * var(--space-4));
  margin-bottom: var(--space-6);
}

/* == flash messages == */
.login-form__flash {
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-5);
  border-radius: var(--radius-md);
  font-size: var(--font-size-medium);
  line-height: 1.4;
}

.login-form__flash--alert {
  background-color: var(--tint-danger-10);
  border: 1px solid var(--tint-danger-16);
  color: var(--color-danger);
}

.login-form__flash--notice {
  background-color: var(--tint-green-10);
  border: 1px solid var(--tint-green-28);
  color: var(--color-primary-dark);
}

/* == form == */
.login-form__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.login-form__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.login-form__label {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.login-form__input {
  width: 100%;
  height: 44px;
  padding: 0 var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-base);
  color: var(--color-text);
  background-color: var(--color-surface-sunken);
  transition: border-color var(--transition-fast), background-color var(--transition-fast),
    box-shadow var(--transition-fast);
}

.login-form__input:hover {
  border-color: var(--color-border-strong);
}

.login-form__input:focus {
  outline: none;
  background-color: var(--color-surface);
  border-color: var(--color-primary-green);
  box-shadow: var(--focus-ring);
}

.login-form__input--otp {
  text-align: center;
  font-size: var(--font-size-xlarge);
  font-family: var(--font-family-bold);
  letter-spacing: var(--space-2);
  font-variant-numeric: tabular-nums;
}

/* == static (read-only) value == */
.login-form__static {
  display: flex;
  align-items: center;
  height: 44px;
  padding: 0 var(--space-3);
  margin: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}

/* == password requirements == */
.login-form__requirements {
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--tint-navy-04);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.login-form__requirements-title {
  font-family: var(--font-family-bold);
  font-weight: 600;
  margin-bottom: var(--space-2);
}

.login-form__requirements-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
  padding-left: var(--space-5);
}

/* == actions == */
.login-form__actions {
  margin-top: var(--space-2);
}

.login-form__submit {
  width: 100%;
}

/* == footer links == */
.login-form__links {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}

.login-form__link {
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
  text-decoration: none;
  transition: color var(--transition-fast);
}

.login-form__link:hover {
  color: var(--color-primary-dark);
  text-decoration: underline;
}

.login-form__link-form {
  display: contents;
}

.login-form__link-button {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font-size: var(--font-size-medium);
  font-family: var(--font-family-base);
  color: var(--color-text-muted);
  transition: color var(--transition-fast);
}

.login-form__link-button:hover {
  color: var(--color-primary-dark);
  text-decoration: underline;
}

/* == accepting the terms, on the invitation form == */
.login-form__consent {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  margin-bottom: var(--space-5);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  cursor: pointer;
}

.login-form__consent-box {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  margin-top: 2px;
  accent-color: var(--color-primary-green);
  cursor: pointer;
}

.login-form__consent-text {
  font-size: var(--font-size-medium);
  line-height: 1.5;
  color: var(--color-text);
}

/* A link sitting inside a sentence rather than on its own row, so it drops the
   block layout `.login-form__link` gives the links under the card. */
.login-form__link--inline {
  display: inline;
  color: var(--color-primary-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* == responsive == */
@media (max-width: 720px) {
  .login-form__logo {
    position: static;
    margin-bottom: var(--space-6);
    flex-shrink: 0;
  }

  .login-form__card {
    margin-top: 0;
  }
}


/* ===== components/mandatory_training.css ===== */
/* Mandatory Training (see training_courses/index/_index_table).

   Not one table but a stack of them: a course is a header saying whether it is
   in order, with the team's own rows underneath. The header is what the page is
   read for, so it carries the weight — the rows below it are an ordinary table. */
.mandatory-training {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.mandatory-training__course {
  border: 1px solid var(--color-border, #e2e8f0);
  border-radius: var(--radius-lg, 12px);
  background-color: var(--color-surface, #ffffff);
  overflow: hidden;
}

.mandatory-training__header {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-4);
  border-bottom: 1px solid var(--color-border, #e2e8f0);
}

/* The name and what the course covers take the room that is going; the status
   and the row actions keep to their own width on the right. */
.mandatory-training__toggle {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0;
  background: none;
  border: none;
  font: inherit;
  text-align: left;
  color: inherit;
  cursor: pointer;
}

.mandatory-training__chevron {
  display: flex;
  flex-shrink: 0;
  color: var(--color-text-muted);
  transition: transform var(--transition-base);
}

.mandatory-training__course.is-open .mandatory-training__chevron {
  transform: rotate(180deg);
}

.mandatory-training__heading {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.mandatory-training__title {
  margin: 0;
  font-size: var(--font-size-large);
  font-weight: 600;
  color: var(--color-text);
}

.mandatory-training__description {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* The header keeps its bottom rule only while there is something under it. */
.mandatory-training__header {
  border-bottom: none;
}

.mandatory-training__course.is-open .mandatory-training__header {
  border-bottom: 1px solid var(--color-border, #e2e8f0);
}

.mandatory-training__status {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* "3 of 11 in date", so the pill beside it can be checked against the thing it
   was worked out from. */
.mandatory-training__summary {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  white-space: nowrap;
}

.mandatory-training__renewal-period {
  margin: 0;
  padding: var(--space-2) var(--space-4);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.mandatory-training__certificate {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--color-text);
  text-decoration: none;
}

.mandatory-training__certificate:hover {
  text-decoration: underline;
}

@media (max-width: 900px) {
  .mandatory-training__header {
    flex-direction: column;
    align-items: stretch;
  }
}


/* ===== components/mi.css ===== */
/* ==========================================================================
   MI — the dashboard and its reports

   Sits on the EOS record's shell (see components/eos.css) rather than a second
   copy of it: the tabs are pages of one thing with a nav down the left, which
   is exactly what the EOS record is. Only what MI adds is here.
   ========================================================================== */

/* --- The headline figures ------------------------------------------------ */

.mi-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-3);
}

.mi-stat {
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
}

/* Reserved for the figure that means somebody has to do something. Never used
   for emphasis — a dashboard where three of four tiles are red is a dashboard
   nobody reads. */
.mi-stat--danger {
  border-left-color: var(--color-danger);
}

.mi-stat__label {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.mi-stat__value {
  margin-top: var(--space-1);
  font-family: var(--font-family-bold);
  font-size: var(--font-size-xxlarge);
  font-weight: bold;
  color: var(--color-primary-dark);
  font-variant-numeric: tabular-nums;
}

.mi-stat--danger .mi-stat__value {
  color: var(--color-danger);
}

.mi-stat__note {
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
}

/* --- The charts ---------------------------------------------------------- */

/* Two across where there is room. The charts are drawn at a fixed viewBox and
   scale to their column, so the breakpoint is about reading width rather than
   about the drawings. */
.mi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
  gap: var(--space-4);
}

.mi-chart__plot {
  padding: var(--space-2) 0;
}

/* The SVG has a viewBox and no width, so the column decides how big it is and
   the geometry never has to know. */
.mi-chart__plot svg {
  width: 100%;
  height: auto;
  display: block;
}

/* What the chart actually measures, under it. Not decoration: every one of
   these has something a reader would otherwise get wrong. */
.mi-chart__note {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

/* Always present where two or more things have to be told apart, so identity
   never rests on colour alone. */
.mi-legend {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  list-style: none;
  margin: 0;
  padding: 0;
}

.mi-legend__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

/* The swatch carries the colour; the label beside it carries the identity. Text
   never wears the series colour. */
.mi-legend__swatch {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex: 0 0 auto;
}

/* --- The by-code table --------------------------------------------------- */

.mi-code-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-medium);
}

.mi-code-table th,
.mi-code-table td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  text-align: left;
}

.mi-code-table thead th {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.mi-code-table__value {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* --- The reports tab ----------------------------------------------------- */

.mi-run__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4);
}

.mi-reports__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-medium);
}

.mi-reports__table th,
.mi-reports__table td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  text-align: left;
  vertical-align: top;
}

.mi-reports__table thead th {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.mi-reports__files {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.mi-reports__actions {
  display: flex;
  gap: var(--space-2);
  justify-content: flex-end;
  flex-wrap: wrap;
}

/* A report the firm can see. Marked rather than coloured: it is a state of the
   record, not a warning. */
.mi-reports__row--shared {
  background-color: var(--tint-green-10);
}

/* --- The figure tabs ----------------------------------------------------- */

/* What the tab is about, in a line, under the header. */
.mi-blurb {
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  margin: 0;
}

/* A heading between groups of charts on a tab that has several. */
.mi-heading {
  margin: var(--space-2) 0 0;
  font-family: var(--font-family-bold);
  font-size: var(--font-size-large);
  color: var(--color-primary-dark);
}

/* How far back the tab looks: four links, the current one filled. */
.mi-period {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
}

.mi-period__option {
  padding: var(--space-1) var(--space-3);
  border-radius: calc(var(--radius-md) - 2px);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  text-decoration: none;
  white-space: nowrap;
}

.mi-period__option:hover {
  color: var(--color-primary-dark);
  background-color: var(--color-background);
}

.mi-period__option--current,
.mi-period__option--current:hover {
  color: #fff;
  background-color: var(--color-primary-dark);
}

/* The legend and the "open tab" link share the header's right-hand side. */
.mi-chart__aside {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.mi-chart__link {
  color: var(--color-primary);
  font-size: var(--font-size-small);
  white-space: nowrap;
}

/* --- The tables ---------------------------------------------------------- */

.mi-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-medium);
}

.mi-table th,
.mi-table td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  text-align: left;
  vertical-align: top;
}

.mi-table thead th {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.mi-table tbody th {
  font-weight: normal;
}

.mi-table tbody th .mi-stat__note {
  display: block;
}

.mi-table__number {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Reserved for a figure that means somebody has to do something. */
.mi-table__number--danger {
  color: var(--color-danger);
  font-weight: bold;
}

/* The team table has a dozen columns; it scrolls inside its card rather than
   squeezing them. */
.mi-table--wide {
  min-width: 960px;
}

/* --- Recent reports ------------------------------------------------------ */

.mi-recent__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.mi-recent__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
}

.mi-recent__row:last-child {
  border-bottom: 0;
}

.mi-recent__main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.mi-recent__title {
  font-size: var(--font-size-medium);
  color: var(--color-primary-dark);
}

.mi-recent__meta {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.mi-recent__heading {
  margin: var(--space-4) 0 var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* A group heading inside the subnav, under the section's own. */
.eos-subnav__heading--group {
  margin-top: var(--space-3);
  font-size: var(--font-size-xsmall, 0.7rem);
  opacity: 0.8;
}

/* --- Custom reports ------------------------------------------------------ */

/* The builder: the definition down the left, the fields it can draw on down
   the right, so the reference is beside the form that needs it. */
.mi-builder {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(260px, 2fr);
  gap: var(--space-4);
  align-items: start;
}

@media (max-width: 1100px) {
  .mi-builder {
    grid-template-columns: 1fr;
  }
}

.mi-builder__filters {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.mi-builder__filter {
  display: grid;
  grid-template-columns: 2fr 1.4fr 2fr auto;
  gap: var(--space-2);
  align-items: center;
}

.mi-builder__filter select,
.mi-builder__filter input {
  min-width: 0;
}

.mi-builder__filter-remove {
  white-space: nowrap;
}

.mi-builder__pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}

/* The fields reference: one row per field, what it is and what it takes. */
.mi-fields {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--font-size-small);
}

.mi-fields__row {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
}

.mi-fields__row:last-child {
  border-bottom: 0;
}

.mi-fields__name {
  color: var(--color-primary-dark);
}

.mi-fields__type {
  margin-left: var(--space-2);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: var(--font-size-xsmall, 0.7rem);
}

.mi-fields__options {
  color: var(--color-text-muted);
}

/* The run: the period control and the exports share the header. */
.mi-run__controls {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.mi-run__controls .form__field {
  margin: 0;
}

/* A group heading between blocks of rows on the run. */
.mi-run__group {
  margin: var(--space-4) 0 var(--space-2);
  font-family: var(--font-family-bold);
  font-size: var(--font-size-medium);
  color: var(--color-primary-dark);
}

.mi-run__group:first-child {
  margin-top: 0;
}

.mi-run__subtotal td,
.mi-run__subtotal th {
  font-weight: bold;
  background-color: var(--color-background);
}

/* The saved definitions, as a list of cards. */
.mi-definitions {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--space-3);
}

.mi-definition__summary {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}


/* ===== components/notes.css ===== */
/* ==========================================================================
   Notes — composer + threaded notes list (cases, reviews, firms, complaints…)
   ========================================================================== */
.notes-form {
  margin-bottom: var(--space-4);
}

.notes-form__editor {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-2);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.notes-form__editor:focus-within {
  border-color: var(--color-primary-green);
  box-shadow: var(--focus-ring);
}

.notes-form__error {
  margin-bottom: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background-color: var(--tint-danger-10);
  color: var(--color-danger);
  font-size: var(--font-size-small);
}

.notes-form__textarea {
  min-height: 80px;
  padding: var(--space-2);
  border: none;
  outline: none;
  font-family: var(--font-family-base);
  font-size: var(--font-size-medium);
  line-height: 1.55;
  color: var(--color-text);
}

.notes-form__textarea:empty:before {
  content: attr(placeholder);
  color: var(--color-text-faint);
}

.notes-form__textarea:focus {
  outline: none;
}

.notes-form__actions {
  display: flex;
  justify-content: flex-end;
  padding-top: var(--space-2);
}

.notes-form__submit {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

/* Highlight (mark) styling for the editor and rendered notes */
.notes-form__textarea mark,
.note__text mark {
  background-color: var(--tint-yellow-28, #fff1a8);
  color: inherit;
  padding: 0 2px;
  border-radius: var(--radius-sm);
}

.trix-button.trix-button--highlight {
  width: auto;
  padding: 0 var(--space-2);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
}

/* --- Firm record's Notes page --- */
/* The composer and thread sit in a card of their own there, so the gap between
   them is set here rather than by the panel around them (as on a case). */
.firm-notes-thread {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.firm-notes-thread__empty {
  padding: var(--space-6) var(--space-4);
  color: var(--color-text-muted);
  text-align: center;
}

/* --- Threaded list --- */
.notes-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.note {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.note:first-child {
  border-color: var(--color-primary-green);
}

.note__avatar {
  flex-shrink: 0;
}

.note__avatar-circle {
  width: 30px;
  height: 30px;
  border-radius: var(--radius-full);
}

.note__content {
  flex: 1;
  min-width: 0;
}

.note__header {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin-bottom: 2px;
}

.note__author {
  font-family: var(--font-family-bold);
  font-size: var(--font-size-small);
  color: var(--color-primary-dark);
}

.note__timestamp {
  font-size: var(--font-size-xsmall, 0.72rem);
  color: var(--color-text-faint);
}

.note__text {
  font-size: var(--font-size-small);
  color: var(--color-text);
  line-height: 1.5;
  word-wrap: break-word;
}

.note__text p {
  margin: 0 0 var(--space-1) 0;
}

.note__text p:last-child {
  margin-bottom: 0;
}


/* ===== components/notifications.css ===== */
/* ==========================================================================
   Notifications — index table with unread emphasis
   ========================================================================== */

/* == bulk actions == */
.notifications-bulk-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* == table form == */
.notifications-table-form {
  width: 100%;
}

/* == column sizing == */
.notifications-table__cell--checkbox {
  width: 48px;
  vertical-align: middle;
}

.notifications-table__cell--status {
  width: 96px;
}

.notifications-table__cell--date {
  width: 160px;
}

.notifications-table__cell--actions {
  width: 192px;
}

/* == checkboxes == */
.notifications-table__select-all,
.notifications-table__checkbox {
  width: 16px;
  height: 16px;
  accent-color: var(--color-primary-green);
  cursor: pointer;
}

/* == unread emphasis == */
.notifications-table__row--unread {
  background-color: var(--tint-green-10);
  box-shadow: inset 3px 0 0 var(--color-primary-green);
}

.table-container .notifications-table__row--unread:hover {
  background-color: var(--tint-green-16);
}

.notifications-table__row--unread .notifications-table__message {
  font-weight: 600;
}

/* == message == */
.notifications-table__message {
  max-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (min-width: 768px) {
  .notifications-table__message {
    max-width: none;
    white-space: normal;
  }
}

.notifications-table__message-link {
  color: var(--color-primary-dark);
  text-decoration: none;
  transition: color var(--transition-fast);
}

.notifications-table__message-link:hover {
  text-decoration: underline;
}

/* == timestamp == */
.table-container .notifications-table__date {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  white-space: nowrap;
}


/* ===== components/pending_changes.css ===== */
/* ==========================================================================
   Adviser-proposed preference changes waiting for review
   ========================================================================== */

/* The banner at the top of the Firm Preferences page */
.pending-changes {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-warning);
  border-radius: var(--radius-lg);
  background-color: var(--color-surface);
}

.pending-changes__header {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}

.pending-changes__icon {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--color-warning);
}

.pending-changes__title {
  margin: 0;
  font-family: var(--font-family-bold);
  font-size: var(--font-size-medium);
  color: var(--color-primary-dark);
}

.pending-changes__blurb {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  line-height: 1.5;
}

/* One card's worth of proposed changes */
.pending-change {
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
}

.pending-change__header {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.pending-change__section {
  margin: 0;
  font-family: var(--font-family-bold);
  font-size: var(--font-size-medium);
  color: var(--color-primary-dark);
}

.pending-change__meta {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.pending-change__fields {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.pending-change__field {
  display: grid;
  grid-template-columns: minmax(12rem, 1fr) 2fr;
  align-items: start;
  gap: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

.pending-change__field:last-child {
  padding-bottom: 0;
  border-bottom: none;
}

.pending-change__accept {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
}

.pending-change__label {
  font-size: var(--font-size-small);
  color: var(--color-text);
}

/* Old value, arrow, new value — the arrow drops out on narrow screens and the
   two values stack, which still reads in the right order. */
.pending-change__values {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--font-size-small);
  min-width: 0;
}

.pending-change__from {
  color: var(--color-text-faint);
  text-decoration: line-through;
  overflow-wrap: anywhere;
}

.pending-change__arrow {
  color: var(--color-text-faint);
  flex-shrink: 0;
}

.pending-change__to {
  font-family: var(--font-family-bold);
  color: var(--color-primary-dark);
  overflow-wrap: anywhere;
}

.pending-change__actions {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.pending-change__awaiting {
  margin: var(--space-3) 0 0;
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
  font-style: italic;
}

/* Card header: the pending pill sits beside the edit pencil */
.firm-card__header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* Count beside "Firm Preferences" in the firm record's own nav */
.firm-subnav__badge {
  margin-left: auto;
  min-width: 20px;
  padding: 0 var(--space-1);
  border-radius: var(--radius-full);
  background-color: var(--color-danger);
  color: var(--color-surface);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  line-height: 20px;
  text-align: center;
}

/* Count inside the directory's Pending Changes tab */
.cases-index-tabs__count {
  display: inline-block;
  margin-left: var(--space-1);
  min-width: 18px;
  padding: 0 var(--space-1);
  border-radius: var(--radius-full);
  background-color: var(--color-danger);
  color: var(--color-surface);
  font-size: var(--font-size-small);
  line-height: 18px;
  text-align: center;
}

/* Directory row for a firm with changes waiting. Tinted the way the
   renewal-due row is, but in the danger colour: a renewal is a date passing,
   this is somebody outside the practice waiting on an answer from us. */
.firm-pill--attention {
  background-color: var(--tint-danger-10);
  border-color: var(--color-danger);
}

.firm-pill--attention:hover {
  background-color: var(--tint-danger-16);
  border-color: var(--color-danger);
}


/* ===== components/profile_picture.css ===== */
/* ==========================================================================
   Profile Picture / Avatar

   Two things wear the same circle: somebody's uploaded picture, and the two
   letters that stand in for it when there is none (see
   shared/_profile_picture). The size lives on the wrapper so that the two are
   always the same size as each other, whichever the row happens to get — a
   table where a face is a pixel wider than a set of initials reads as broken.
   ========================================================================== */
.profile-picture {
  /* The size the circle is, in one place. The modifiers below change this and
     nothing else. */
  --profile-picture-size: 34px;

  display: inline-block;
  flex: 0 0 auto;
  line-height: 0;
}

.profile-picture__placeholder,
.profile-picture__image {
  width: var(--profile-picture-size);
  height: var(--profile-picture-size);
  border: 2px solid var(--color-primary-green);
  border-radius: var(--radius-full);
}

.profile-picture__placeholder {
  background-color: var(--color-secondary-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-white);
  font-size: var(--font-size-small);
  font-weight: bold;
  letter-spacing: 0.02em;
}

.profile-picture__placeholder span {
  color: var(--color-white);
  font-size: var(--font-size-small);
  font-weight: 600;
}

/* `cover` rather than `contain`: the image is already a square cropped in the
   browser, so this only has to survive the odd one stored before that was true
   (and an image that has not loaded yet). */
.profile-picture__image {
  object-fit: cover;
  /* Behind a transparent PNG, so a face is never cut out of the page itself. */
  background-color: var(--color-secondary-dark);
}

/* == Sizes ==
   Small for the dense rows — a stack of overlapping recipients. Large for the
   places the picture is the subject rather than a label: the account menu, and
   the settings section that sets it. */
.profile-picture--small {
  --profile-picture-size: 26px;
}

.profile-picture--large {
  --profile-picture-size: 64px;
}

.profile-picture--large .profile-picture__placeholder span {
  font-size: var(--font-size-large);
}

/* ==========================================================================
   The field that sets it
   ========================================================================== */
.avatar-field__row {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
}

.avatar-field__figure {
  position: relative;
  flex: 0 0 auto;
  width: 80px;
  height: 80px;
}

.avatar-field__preview,
.avatar-field__placeholder {
  width: 80px;
  height: 80px;
  border: 2px solid var(--color-primary-green);
  border-radius: var(--radius-full);
}

.avatar-field__preview {
  object-fit: cover;
  background-color: var(--color-secondary-dark);
}

.avatar-field__placeholder {
  background-color: var(--color-secondary-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-white);
  font-size: var(--font-size-large);
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* `[hidden]` needs saying because the two above are flex. */
.avatar-field__preview[hidden],
.avatar-field__placeholder[hidden] {
  display: none;
}

.avatar-field__controls {
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

/* The choose control is a <label> around a file input, because a file input
   cannot be made to look like the rest of the buttons on the form. The input
   itself is taken out of the layout rather than hidden with `display: none`,
   which would take it out of the keyboard order with it. */
.avatar-field__choose {
  position: relative;
  overflow: hidden;
  cursor: pointer;
}

.avatar-field__input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Focus has to be drawn on the label, since that is what is visible. */
.avatar-field__input:focus-visible + span,
.avatar-field__choose:focus-within {
  outline: 2px solid var(--color-primary-green);
  outline-offset: 2px;
}

/* Both take the full width so the hint and any error read as lines under the
   controls rather than as another column beside them. */
.avatar-field__controls .form__hint,
.avatar-field__error {
  flex: 1 0 100%;
  margin: 0;
}

.avatar-field__error {
  color: var(--color-danger);
  font-size: var(--font-size-small);
}

.avatar-field__error[hidden] {
  display: none;
}

/* ==========================================================================
   The firm logo field

   Beside the profile picture field because they are the same control with a
   different shape — a logo is fitted inside a box rather than cropped square
   (see shared/_logo_field).
   ========================================================================== */
/* Wraps, because this field lives in the firm's edit drawer and a drawer is
   narrow. Without it the preview and the buttons sit on one line that is wider
   than the drawer, and "Choose logo" ends up off the edge of it. */
.logo-field__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: flex-start;
}

/* Dark, because that is what the logo sits on where it matters most: the
   masthead of a generated report is the firm's own navy. A mark that vanishes
   against this will vanish there, which is worth finding out here. */
.logo-field__figure {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 172px;
  height: 64px;
  padding: var(--space-2);
  background: var(--color-secondary-dark);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

/* Fitted, never filled: the whole point of the shape is that the mark is not
   cropped. */
.logo-field__preview {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.logo-field__placeholder {
  color: var(--color-white);
  font-size: var(--font-size-small);
  opacity: 0.7;
}

.logo-field__preview[hidden],
.logo-field__placeholder[hidden] {
  display: none;
}

/* `1 1 200px` rather than `1 1 auto`: below 200px of its own the whole block
   drops onto the line under the preview rather than being squeezed. */
.logo-field__controls {
  display: flex;
  flex: 1 1 200px;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

/* As the avatar's: a <label> around a file input, with the input taken out of
   the layout rather than hidden, so it keeps its place in the keyboard order. */
.logo-field__choose {
  position: relative;
  overflow: hidden;
  cursor: pointer;
}

.logo-field__input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.logo-field__choose:focus-within {
  outline: 2px solid var(--color-primary-green);
  outline-offset: 2px;
}

.logo-field__controls .form__hint,
.logo-field__error {
  flex: 1 0 100%;
  margin: 0;
}

.logo-field__error {
  color: var(--color-danger);
  font-size: var(--font-size-small);
}

.logo-field__error[hidden] {
  display: none;
}


/* ===== components/quick_search.css ===== */
/* ==========================================================================
   Quick Search — topbar dropdown results panel
   Anchored to .topbar__search (which is position: relative).
   ========================================================================== */
.quick-search {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  width: 380px;
  max-width: 90vw;
  max-height: min(70vh, 520px);
  overflow-y: auto;
  padding: var(--space-2);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  z-index: var(--z-topbar);
}

.quick-search[hidden] {
  display: none;
}

.quick-search__group {
  padding: var(--space-2) 0;
}

.quick-search__group:not(:last-child) {
  border-bottom: 1px solid var(--color-border);
}

.quick-search__group:empty {
  display: none;
}

.quick-search__group-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 0 var(--space-2) var(--space-1);
}

.quick-search__group-title {
  font-size: var(--font-size-small);
  font-weight: 700;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.quick-search__see-all {
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-primary-green);
  text-decoration: none;
  white-space: nowrap;
}

.quick-search__see-all:hover {
  text-decoration: underline;
}

.quick-search__results {
  list-style: none;
  margin: 0;
  padding: 0;
}

.quick-search__result {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background-color var(--transition-fast);
}

.quick-search__result:hover {
  background-color: var(--color-surface-sunken);
}

.quick-search__result-title {
  font-size: var(--font-size-medium);
  font-weight: 600;
  color: var(--color-text);
}

.quick-search__result-subtitle {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.quick-search__empty {
  padding: var(--space-1) var(--space-2) var(--space-2);
  font-size: var(--font-size-small);
  color: var(--color-text-faint);
}

/* --- Skeleton loaders --- */
.quick-search__skeletons {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.quick-search__skeleton-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: var(--space-2);
}

.quick-search__skeleton {
  display: block;
  height: 10px;
  border-radius: var(--radius-full);
  background: linear-gradient(
    90deg,
    var(--color-surface-sunken) 25%,
    var(--color-border) 37%,
    var(--color-surface-sunken) 63%
  );
  background-size: 400% 100%;
  animation: quick-search-shimmer 1.4s ease infinite;
}

.quick-search__skeleton--title {
  width: 60%;
}

.quick-search__skeleton--subtitle {
  width: 40%;
  height: 8px;
}

@keyframes quick-search-shimmer {
  0% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0 50%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .quick-search__skeleton {
    animation: none;
  }
}


/* ===== components/record_page.css ===== */
/* ==========================================================================
   Record page shell — breadcrumb and header pinned, only the body scrolls
   The same bargain the index tables strike (see .index-page in table.css): the
   page itself never scrolls, so the scroller has to be handed a bounded height.
   Each ancestor from the main-content frame down is a flex column that passes
   its height on, and min-height: 0 lets the body shrink below the intrinsic
   height of a long record instead of overflowing.
   ========================================================================== */
turbo-frame#main_content:has(> .record-page) {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

.record-page {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.record-page__header {
  flex: 0 0 auto;
}

/* The scroller. The small right-hand padding keeps a card's shadow off the
   scrollbar; the bottom padding stops the last card sitting flush on the edge. */
.record-page__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: var(--space-2);
  padding-bottom: var(--space-5);
}

/* --- Page heading -------------------------------------------------------- */
/* The record says what it is (its client, its firm), so the title is the
   record's own label with the rest of what identifies it underneath. */
.record-page__heading {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.record-page__subtitle {
  margin: 0;
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}

/* ==========================================================================
   Record card
   The box a record's page is built from — details, quick actions, whatever a
   record keeps beside them. Shared by the case and review records so the two
   read the same way; .review-record__card is the review record's original name
   for it and is kept so its markup does not have to change.
   ========================================================================== */
.record-card,
.review-record__card {
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.record-card__title,
.review-record__card-title {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

/* Title plus whatever acts on the card — the edit affordance that opens its
   form, most often. */
.record-card__header,
.review-record__card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

/* The header row owns the rule and the spacing under it, so the title inside
   one drops both. */
.record-card__title--flush,
.review-record__card-title--flush {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}

/* The row of buttons a Quick Actions card holds. */
.record-card__actions,
.case-record__actions,
.review-record__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* ==========================================================================
   Warning banner
   Standing warnings about a record, at the top of its page — the firm record's
   original treatment, now shared by every record that keeps them (see
   shared/_warning_banner).
   ========================================================================== */
.record-warning-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  padding: var(--space-3) var(--space-5);
  border: 1px solid var(--color-danger);
  border-radius: var(--radius-md);
  background: var(--tint-danger-10);
}

.record-warning-banner__dot {
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  /* Nudged onto the first line's baseline rather than its box top. */
  margin-top: 7px;
  border-radius: var(--radius-full);
  background: var(--color-danger);
}

.record-warning-banner__text {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: var(--font-size-medium);
  font-weight: 600;
  line-height: 1.5;
  color: var(--color-danger);
}

.record-warning-banner__dismiss {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--color-danger);
  cursor: pointer;
}


/* ===== components/record_status.css ===== */
/* ==========================================================================
   Record Status — the inline status dropdown a case and a review share
   ========================================================================== */
.record-status {
  position: relative;
  display: inline-block;
}

.record-status__trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
  font: inherit;
  transition: opacity var(--transition-base);
}

.record-status__trigger:hover {
  opacity: 0.85;
}

.record-status__chevron {
  font-size: 0.6em;
  opacity: 0.8;
}

.record-status__menu {
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: var(--space-1);
  min-width: 180px;
  padding: var(--space-1);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  z-index: 50;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.record-status__menu.hidden {
  display: none;
}

.record-status__option {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  text-align: left;
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font: inherit;
  color: var(--color-text);
  transition: background-color var(--transition-base);
}

.record-status__option:hover {
  background: var(--tint-navy-06);
}

.record-status__actions {
  position: absolute;
  top: 50%;
  left: calc(100% + var(--space-3));
  transform: translateY(-50%) scale(0.95);
  transform-origin: left center;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition-base), transform var(--transition-base);
  z-index: 60;
}

.record-status__actions--visible {
  transform: translateY(-50%) scale(1);
  opacity: 1;
  pointer-events: auto;
}


/* ===== components/record_tabs.css ===== */
/* ==========================================================================
   Record Tabs — the tabbed panels beneath a record's details
   The shared version of the per-record tabulation blocks (see
   components/task_tabulation, which the case, review and task records each keep
   a copy of). Named for what it is rather than for one record, so the next
   record page to want tabs does not add a fourth copy.
   ========================================================================== */
.record-tabs {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.record-tabs__tabs {
  display: flex;
  gap: var(--space-1);
  border-bottom: 1px solid var(--color-border);
}

.record-tabs__tab {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  color: var(--color-text-muted);
  cursor: pointer;
  transition: color var(--transition-base), border-color var(--transition-base);
}

.record-tabs__tab:hover {
  color: var(--color-primary-dark);
}

.record-tabs__tab--active {
  color: var(--color-primary-dark);
  border-bottom-color: var(--color-primary-green);
}

.record-tabs__tab-icon {
  width: 1.15rem;
  height: 1.15rem;
  fill: currentColor;
}

.record-tabs__content {
  position: relative;
  min-height: 200px;
}

.record-tabs__panel {
  display: none;
  flex-direction: column;
  gap: var(--space-4);
}

.record-tabs__panel--active {
  display: flex;
}

/* The note thread sits on a sunken panel, as it does on every other record. */
.record-tabs__thread {
  padding: var(--space-4);
  background-color: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  min-height: 200px;
}

.record-tabs__empty-state {
  color: var(--color-text-muted);
  text-align: center;
  padding: var(--space-8) var(--space-4);
}


/* ===== components/recruitment.css ===== */
/* ==========================================================================
   Recruitment — the applicant record page
   The pipeline itself needs nothing of its own: it is an index table with a tab
   bar and a filter panel, all of which are shared (see components/table and
   components/filters). This is the record you open from a row.
   ========================================================================== */
.applicant-record {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* What we know about an applicant, as label-over-value pairs that wrap into as
   many columns as the card is wide. A grid rather than two fixed columns, so a
   narrow window reads as one list instead of two cramped ones. */
.applicant-details {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-4);
  margin: 0;
}

.applicant-details__pair {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.applicant-details__pair dt {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.applicant-details__pair dd {
  margin: 0;
  font-size: var(--font-size-medium);
  color: var(--color-text);
  overflow-wrap: anywhere;
}

.applicant-details__link {
  color: var(--color-primary-dark);
  font-family: var(--font-family-bold);
  text-decoration: none;
}

.applicant-details__link:hover {
  text-decoration: underline;
}


/* ===== components/reports.css ===== */
/* ==========================================================================
   Report generator

   The screens the firm record's Reports tab is made of: setting a run up in
   three steps, the run itself, one client's report and its figures, and the
   template all of it is generated from.

   The report *document* is styled somewhere else entirely and on purpose — it
   is a client-facing PDF with a palette of its own, rendered from one
   self-contained string of HTML (see app/views/reports/pdf/_styles.html.erb).
   Nothing here reaches it, and nothing there reaches this.
   ========================================================================== */

/* --- The three steps of setting a run up ---------------------------------- */

.report-wizard {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.report-wizard__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-6);
  flex-wrap: wrap;
}

.report-wizard__title {
  font-size: var(--font-size-xxlarge);
  color: var(--color-primary-dark);
}

.report-wizard__lead {
  margin-top: var(--space-1);
  max-width: 62ch;
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}

/* The blank intake workbook, offered beside the lead on the step that asks for
   filled-in ones. Set apart from the paragraph above it rather than beside the
   step markers, because it is something to do before this step rather than a
   way through it. */
.report-wizard__aside {
  margin-top: var(--space-3);
}

.report-wizard__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.report-wizard__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  padding-top: var(--space-2);
}

.report-steps {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  list-style: none;
}

.report-steps__step {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* The number in front of a step. Filled when it is the one open, ticked-off
   green when it is behind, and outlined when it is still ahead. */
.report-steps__marker {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  font-size: var(--font-size-small);
  font-weight: 600;
}

.report-steps__step--current .report-steps__marker {
  background: var(--color-primary-dark);
  border-color: var(--color-primary-dark);
  color: #fff;
}

.report-steps__step--current .report-steps__label {
  color: var(--color-primary-dark);
  font-weight: 600;
}

.report-steps__step--done .report-steps__marker {
  background: var(--tint-green-16);
  border-color: var(--color-primary-green);
  color: var(--color-primary-dark);
}

/* --- Picking advisers, then their clients --------------------------------- */

.report-picker {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  background: var(--color-surface);
}

.report-picker + .report-picker {
  margin-top: var(--space-4);
}

.report-picker__legend {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-2);
  font-weight: 600;
  color: var(--color-primary-dark);
}

/* Two columns where there is room. A firm with forty clients under one adviser
   is a very long single column otherwise. */
.report-picker__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.report-picker__row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  cursor: pointer;
}

.report-picker__row:hover {
  border-color: var(--color-border-strong);
  background: var(--color-surface-sunken);
}

.report-picker__row:has(.report-picker__check:checked) {
  border-color: var(--color-primary-green);
  background: var(--tint-green-10);
}

.report-picker__check {
  margin-top: 2px;
  flex: none;
}

.report-picker__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.report-picker__name {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 600;
  color: var(--color-text);
}

.report-picker__meta {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  font-weight: 400;
}

/* The report type step picks between paragraphs rather than names, so its rows
   need the line height a sentence wants. */
.report-picker__row .report-picker__meta {
  line-height: 1.45;
}

/* The blank workbook for one option, inside its row. A link rather than a
   button: the row is already one large click target for choosing this report,
   and a second button in it would compete with that. Given its own line so it
   is obviously not part of the sentence above it. */
.report-picker__download {
  align-self: flex-start;
  margin-top: var(--space-2);
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-primary-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.report-picker__download:hover {
  text-decoration-thickness: 2px;
}

/* What choosing a different report type would cost, on the step that offers it. */
.report-notice {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-warning);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* --- Uploading the workbooks ---------------------------------------------- */

.report-upload {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.report-upload__input {
  max-width: 210px;
  font-size: var(--font-size-small);
}

/* The submit button is hidden once auto-submit takes over (see
   auto_submit_controller). The `hidden` attribute alone is not enough: the
   button's own display rule outranks the browser's [hidden] { display: none },
   so the button has to be told again here. */
.report-upload__submit[hidden] {
  display: none;
}

.report-upload__filename,
.report-upload__status {
  margin-top: var(--space-1);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

/* What reading a workbook turned up. Errors stop the run; warnings do not, and
   the two have to be told apart at a glance or the distinction is worthless. */
.report-issues {
  margin-top: var(--space-2);
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  max-width: 52ch;
}

.report-issues__item {
  padding-left: var(--space-3);
  border-left: 2px solid var(--color-border-strong);
  font-size: var(--font-size-small);
  line-height: 1.45;
  color: var(--color-text-muted);
}

.report-issues__item--error {
  border-left-color: var(--color-danger);
  color: var(--color-danger);
}

.report-issues__item--warning {
  border-left-color: var(--color-warning);
  color: var(--color-warning-dark);
}

.report-issues__where {
  display: block;
  font-size: var(--font-size-small);
  opacity: 0.75;
}

/* --- A run, and one report in it ------------------------------------------ */

.report-run__heading {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.report-run__meta {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.report-run__meta-line {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.report-run__failed {
  margin-left: var(--space-2);
  color: var(--color-danger);
  font-size: var(--font-size-small);
}

.report-run__progress {
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-primary-green);
  border-radius: var(--radius-md);
  background: var(--tint-green-10);
  font-size: var(--font-size-medium);
}

.report-detail {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.report-detail__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-6);
  flex-wrap: wrap;
}

.report-detail__title {
  font-size: var(--font-size-xxlarge);
  color: var(--color-primary-dark);
}

/* The figures on the left, the versions and the source file on the right. Falls
   to one column before the side panel gets too narrow to read. */
.report-detail__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: var(--space-5);
  align-items: start;
}

@media (max-width: 1100px) {
  .report-detail__grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.report-detail__col,
.report-detail__side {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}

.report-card {
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.report-card + .report-card {
  margin-top: var(--space-4);
}

.report-card__header {
  margin-bottom: var(--space-3);
}

.report-card__title {
  font-size: var(--font-size-large);
  color: var(--color-primary-dark);
}

.report-card__description {
  margin-top: var(--space-1);
  max-width: 68ch;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.report-values__row {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-top: 1px solid var(--color-border);
  font-size: var(--font-size-medium);
}

.report-values__row:first-child {
  border-top: 0;
}

.report-values__row dt {
  color: var(--color-text-muted);
}

.report-versions {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.report-versions__item {
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

.report-versions__item:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}

.report-versions__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.report-versions__label {
  font-weight: 700;
  color: var(--color-primary-dark);
}

.report-versions__meta,
.report-versions__pending {
  margin-top: var(--space-1);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  line-height: 1.5;
}

.report-versions__sent {
  margin-top: var(--space-1);
  font-size: var(--font-size-small);
  color: var(--color-success-dark);
}

.report-empty {
  padding: var(--space-4);
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}

/* --- Editing a report's figures ------------------------------------------- */

.report-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.report-form__actions {
  position: sticky;
  bottom: 0;
  padding: var(--space-3) 0;
  background: var(--color-canvas);
  border-top: 1px solid var(--color-border);
}

/* A report is around a hundred and fifty fields. Laid out in a grid so a form
   section is scanned rather than scrolled, with the long ones — a conclusion, a
   risk blurb — spanning the row. */
.report-fields {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--space-3) var(--space-4);
}

.report-field--wide {
  grid-column: 1 / -1;
}

/* A grid item is sized by its content unless it is told otherwise, so a long
   hint under a short field pushes out over its neighbour instead of wrapping. */
.report-field {
  min-width: 0;
}

/* The app's form fields hold their text on one line, which is right for a label
   and wrong here: nearly every field on this form carries a sentence explaining
   what the intake workbook asks for, and the grid puts them in columns barely
   wider than an input. */
.report-field .form__label,
.report-field .form__hint {
  white-space: normal;
}

.report-field__check {
  width: 18px;
  height: 18px;
}

/* A figure that no longer says what the client's own file said. The whole point
   of tracking where a value came from, so it is worth being visible. */
.report-field__edited {
  display: inline-block;
  margin-left: var(--space-1);
  padding: 1px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-yellow-100);
  color: var(--color-warning-dark);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.report-rows {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.report-rows__row {
  position: relative;
  padding: var(--space-3);
  padding-right: var(--space-8);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
}

.report-rows__remove {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text-muted);
  cursor: pointer;
}

.report-rows__remove:hover {
  border-color: var(--color-danger);
  color: var(--color-danger);
}

/* --- Template configuration ----------------------------------------------- */

/* One block per kind of report, each with its own drafts and published
   versions. Ruled off from the next so the two lines of template do not read as
   one long list. */
.report-kind + .report-kind {
  margin-top: var(--space-6);
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-border);
}

.report-kind__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}

.report-kind__title {
  font-size: var(--font-size-large);
  font-weight: 600;
  color: var(--color-text);
}

.report-kind__blurb {
  max-width: 62ch;
  margin-top: var(--space-1);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.report-effective {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  font-size: var(--font-size-medium);
}

.report-section-config {
  padding: var(--space-4) 0;
  border-top: 1px solid var(--color-border);
}

.report-section-config:first-of-type {
  border-top: 0;
}

.report-section-config__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-3);
}

.report-section-config__toggle {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 600;
  color: var(--color-primary-dark);
  cursor: pointer;
}

.report-section-config__position {
  width: 90px;
}

/* A section switched off is left out of the report entirely, so it reads as
   switched off rather than merely unticked. */
.report-section-config:has(input[type="checkbox"]:not(:checked)) .report-fields {
  opacity: 0.5;
}

/* --- Previewing a template ------------------------------------------------ */

/* The report has a stylesheet of its own and a palette that is the firm's
   rather than the application's, so a preview of it is shown in a frame. That
   is also the only way to be sure the picture on this screen is the report
   itself rather than a mock-up of it that has quietly drifted. */
.report-preview-frame {
  display: block;
  width: 100%;
  height: 320px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.report-preview-frame--full {
  height: 640px;
}

.report-preview-frame[hidden] {
  display: none;
}

.report-preview__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.report-preview__modes {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.report-section-config__identity {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.report-section-config__head-right {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* What the card draws, in words. Beside the toggle so the list can be read
   without opening a dozen frames. */
.report-section-config__draws {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.report-section-config__preview {
  margin-bottom: var(--space-3);
}

.report-colour {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.report-colour__swatch {
  width: 42px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: none;
  cursor: pointer;
}

.report-colour__code {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}


/* ===== components/retainer.css ===== */
/* ==========================================================================
   Retainers, billed time and bills to a firm

   The screens here share one idea worth getting right: a quarter's credit only
   means anything against the budget it started at, so the bar carries the
   proportion and the figures carry the amounts. Aqua inside the budget, amber
   at 90% used, coral over it — the same thresholds the alerts are raised on,
   because a screen and an alert that disagree are worse than neither (see
   RetainerQuarter).
   ========================================================================== */

.firm-retainer__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.firm-retainer__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4) var(--space-6);
}

@media (max-width: 960px) {
  .firm-retainer__grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --- The summary card ----------------------------------------------------- */

.retainer-summary__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  margin: var(--space-1) 0 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.retainer-summary__note {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
}

/* --- The meter ------------------------------------------------------------ */

.retainer-meter {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--tint-navy-04);
}

.retainer-meter__kpis {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  margin: 0;
}

.retainer-meter__kpi dt {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.retainer-meter__kpi dd {
  margin: var(--space-1) 0 0;
  font-family: var(--font-family-bold);
  font-size: var(--font-size-xlarge);
  font-weight: bold;
  color: var(--color-primary-dark);
  font-variant-numeric: tabular-nums;
}

.retainer-meter__kpi--left dd {
  color: var(--color-success-dark);
}

.retainer-meter__kpi--over dd {
  color: var(--color-danger);
}

.retainer-meter__kpi--expired dd {
  color: var(--color-text-muted);
}

.retainer-meter__kpi-note {
  margin: var(--space-1) 0 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.retainer-meter__track {
  position: relative;
  height: 14px;
  border-radius: 7px;
  background-color: var(--color-border);
  overflow: hidden;
}

.retainer-meter__fill {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: 7px;
  background-color: var(--color-primary-green);
}

.retainer-meter--running_out .retainer-meter__fill {
  background-color: var(--color-warning);
}

/* Spend past the budget, striped so it reads as "beyond" rather than as more
   of the same. */
.retainer-meter__over {
  position: absolute;
  top: 0;
  bottom: 0;
  background: repeating-linear-gradient(
    -45deg,
    var(--color-danger) 0 6px,
    var(--color-danger-light) 6px 12px
  );
}

/* Where today falls in the quarter, so spend running ahead of time shows. */
.retainer-meter__today {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 3px;
  border-radius: 2px;
  background-color: var(--color-primary-dark);
}

.retainer-meter__legend {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

@media (max-width: 720px) {
  .retainer-meter__kpis {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --- Alerts --------------------------------------------------------------- */

.retainer-alert {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border-left: 4px solid var(--color-warning);
  background-color: var(--color-yellow-100);
  font-size: var(--font-size-medium);
}

.retainer-alert p {
  margin: var(--space-1) 0 0;
  color: var(--color-text-muted);
}

.retainer-alert--over {
  border-left-color: var(--color-danger);
  background-color: var(--tint-danger-10);
}

.retainer-alert--settled {
  border-left-color: var(--color-primary-green);
  background-color: var(--tint-green-10);
}

.retainer-alert--expired {
  border-left-color: var(--color-border-strong);
  background-color: var(--color-surface-sunken);
}

/* --- Spend log, quarters, schedule, overspend ------------------------------ */

.retainer-spend__scroll {
  overflow-x: auto;
}

.retainer-spend__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-medium);
}

.retainer-spend__table th,
.retainer-spend__table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border);
  text-align: left;
  vertical-align: top;
}

.retainer-spend__table thead th {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.retainer-spend__table tfoot td {
  border-bottom: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.retainer-spend__numeric {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The running total once it has passed the budget. */
.retainer-spend__numeric--over {
  color: var(--color-danger);
  font-weight: bold;
}

.retainer-spend__source {
  display: block;
  margin-top: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.retainer-spend__description {
  max-width: 28rem;
}

.retainer-spend__row--adjustment {
  background-color: var(--tint-navy-04);
}

.retainer-spend__empty {
  padding: var(--space-4);
  text-align: center;
  color: var(--color-text-muted);
}

.retainer-quarters__row--selected {
  background-color: var(--tint-green-10);
}

.retainer-quarters__now {
  margin-left: var(--space-2);
  padding: 0 var(--space-2);
  border-radius: 999px;
  background-color: var(--tint-green-16);
  font-size: var(--font-size-small);
}

.retainer-schedule__status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.retainer-schedule__status form {
  display: inline;
}

/* The quarterly budgets the retainer form previews before it is saved. */
.retainer-form__budget .retainer-spend__table td {
  padding: var(--space-1) var(--space-2);
}

/* --- Service Information's empty state ------------------------------------ */

.firm-placeholder__choices {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
}

.firm-placeholder__note {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2) var(--space-5);
  margin: var(--space-3) 0 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

/* --- The marker on a firm's directory card -------------------------------- */

/* A badge rather than another chip. The header already carries up to three
   chips that mean something has gone wrong, and a fourth saying "this is how
   they pay" would compete with them for the same glance (see
   firms/index/_index_list). */
.firm-pill__retainer {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background-color: var(--tint-green-16);
  color: var(--color-primary-dark);
}

/* The firm's name and its marker, as one thing. */
.firm-pill__heading {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.firm-pill__retainer-icon {
  width: 15px;
  height: 15px;
}

/* --- The time log's Billing panel ----------------------------------------- */

.time-entry-billing__choice {
  margin: 0 0 var(--space-4);
  padding: 0;
  border: 0;
}

.time-entry-billing__options {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}

.time-entry-billing__option {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  cursor: pointer;
}

.time-entry-billing__option:has(input:checked) {
  border-color: var(--color-primary-dark);
  background-color: var(--tint-navy-04);
}

.time-entry-billing__option--billed:has(input:checked) {
  border-color: var(--color-danger);
  background-color: var(--tint-danger-10);
}

.time-entry-billing__option span {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.time-entry-billing__option small {
  color: var(--color-text-muted);
}

.time-entry-billing__billed {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.time-entry-billing__billed.hidden {
  display: none;
}

/* The client's red warning, with the tick that has to be given. */
.time-entry-billing__warning {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-danger);
  border-radius: var(--radius-md);
  background-color: var(--tint-danger-10);
  font-size: var(--font-size-medium);
}

.time-entry-billing__warning p {
  margin: 0 0 var(--space-2);
}

.time-entry-billing__warning-title {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  color: var(--color-danger);
  font-weight: bold;
}

.time-entry-billing__confirm {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  font-weight: bold;
  cursor: pointer;
}

.time-entry-billing__preview {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.time-entry-billing__note {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
}

.time-entry-billing__cost {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.time-entry-billing__cost-line {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  align-items: baseline;
}

.time-entry-billing__cost-line strong {
  font-size: var(--font-size-xlarge);
  font-variant-numeric: tabular-nums;
}

.time-entry-billing__cost-vat,
.time-entry-billing__muted {
  margin: var(--space-1) 0 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.time-entry-billing__destination {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border-left: 4px solid var(--color-border-strong);
  background-color: var(--color-surface-sunken);
  font-size: var(--font-size-medium);
}

.time-entry-billing__destination p {
  margin: 0;
}

.time-entry-billing__destination--retainer {
  border-left-color: var(--color-primary-green);
  background-color: var(--tint-green-10);
}

.time-entry-billing__destination--over {
  border-left-color: var(--color-warning);
  background-color: var(--color-yellow-100);
}

.time-entry-billing__destination--month-end {
  border-left-color: var(--color-primary-dark);
  background-color: var(--tint-navy-06);
}

.time-entry-billing__meter {
  position: relative;
  height: 8px;
  margin-top: var(--space-2);
  border-radius: 4px;
  background-color: var(--color-border);
  overflow: hidden;
}

.time-entry-billing__meter i {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  background-color: var(--color-primary-green);
}

.time-entry-billing__meter .time-entry-billing__meter-add {
  background-color: var(--color-primary-dark);
}

/* The firm a billed hour was charged to, under its record on the time log. */
.time-entry__firm {
  display: block;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.time-entry__locked {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

/* --- The time log's two views ---------------------------------------------- */

.time-log-tabs {
  display: flex;
  gap: var(--space-1);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-3);
}

.time-log-tabs__tab {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-bottom: 2px solid transparent;
  color: var(--color-text-muted);
  text-decoration: none;
  font-weight: bold;
}

.time-log-tabs__tab--current {
  border-bottom-color: var(--color-primary-dark);
  color: var(--color-primary-dark);
}

.time-log-tabs__count {
  min-width: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background-color: var(--color-danger);
  color: var(--color-white);
  font-size: var(--font-size-small);
  text-align: center;
}

/* --- Month-end billing ------------------------------------------------------ */

.month-end-billing__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  overflow-y: auto;
}

.month-end-billing__intro,
.month-end-billing__empty {
  margin: 0;
  color: var(--color-text-muted);
}

.month-end-billing__when {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

/* --- A firm's Invoices tab --------------------------------------------------- */

.firm-invoices__recipients {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  margin: 0;
  font-size: var(--font-size-medium);
}

.firm-invoices__recipients--missing {
  color: var(--color-danger);
}

.invoice-row__sent-to {
  max-width: 14rem;
  font-size: var(--font-size-small);
  overflow-wrap: anywhere;
}

/* A case invoice's reference is built from names and runs long; two lines of
   it is enough to know which case. */
.invoice-row__subject {
  max-width: 16rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* The bill actions wrap rather than push the table past the screen. */
.invoice-row__actions .table-actions {
  flex-wrap: wrap;
  justify-content: flex-end;
  min-width: 9rem;
}

.invoice-row__when {
  display: block;
  color: var(--color-text-muted);
}

/* --- Invoices — Scheduled --------------------------------------------------- */

.scheduled-invoices__horizon {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.scheduled-invoices__horizon-label {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.scheduled-invoices__note {
  margin-left: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}


/* ===== components/review_record.css ===== */
/* ==========================================================================
   Review Record — review show page layout
   Card-based two-column layout: details + important notes on the left,
   quick actions + client details on the right, tabulation below.
   ========================================================================== */
.review-record {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* Cards themselves are shared with the other records (see .record-card in
   record_page.css); what follows is what a review puts inside them. */

/* == Layout grid == */
.review-record__grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-5);
  align-items: start;
}

.review-record__column {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}

@media (max-width: 1024px) {
  .review-record__grid {
    grid-template-columns: 1fr;
  }
}

/* == Detail grid == */
.review-record__details {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5);
}

.review-record__details--stacked {
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

.review-record__details-column {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}

.review-record__detail {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.review-record__detail-label {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.review-record__detail-value {
  margin: 0;
  font-size: var(--font-size-medium);
  color: var(--color-text);
  overflow-wrap: anywhere;
}

/* A date the record is behind on, coloured as the table colours its row: amber
   for a pack still to come, red for one that went out late. */
.review-record__detail-value--warning {
  color: var(--color-warning);
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.review-record__detail-value--danger {
  color: var(--color-danger);
  font-family: var(--font-family-bold);
  font-weight: 600;
}

/* == Important notes == */
.review-record__hint {
  margin-bottom: var(--space-4);
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}

.review-record__textarea-wrapper {
  position: relative;
}

.review-record__textarea {
  width: 100%;
  min-height: 120px;
  padding: var(--space-3);
  padding-bottom: var(--space-10);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-sunken);
  font-family: var(--font-family-base);
  font-size: var(--font-size-medium);
  color: var(--color-text);
  resize: vertical;
  transition: border-color var(--transition-fast), background-color var(--transition-fast),
    box-shadow var(--transition-fast);
}

/* The warning composer in the side column: a warning is a line or two, written
   once and read from the banner, so the box need not be a page deep. */
.review-record__textarea--compact {
  min-height: 76px;
  padding-bottom: var(--space-8);
  font-size: var(--font-size-small);
}

.review-record__textarea:hover {
  border-color: var(--color-border-strong);
}

.review-record__textarea:focus {
  outline: none;
  background-color: var(--color-surface);
  border-color: var(--color-primary-green);
  box-shadow: var(--focus-ring);
}

.review-record__update-button {
  position: absolute;
  bottom: var(--space-3);
  right: var(--space-3);
}


/* Why a pack date is what it is, under the date itself: set by hand, or the
   firm's own lead time rather than the practice's standard (see
   reviews/show/_details). Quiet — it explains a figure, it is not one. */
.review-record__detail-note {
  margin-top: var(--space-1);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  font-style: italic;
}


/* ===== components/review_tabulation.css ===== */
/* ==========================================================================
   Review Tabulation — tabbed checklist / updates card on the review record
   Active-state class names are toggled by review_tabulation_controller.js.
   ========================================================================== */
.review-tabulation {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

/* == Tab bar == */
.review-tabulation__tabs {
  display: flex;
  gap: var(--space-1);
  border-bottom: 1px solid var(--color-border);
}

.review-tabulation__tab {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  margin-bottom: -1px;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  font-family: var(--font-family-bold);
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
  cursor: pointer;
  transition: color var(--transition-base), background-color var(--transition-base),
    border-color var(--transition-base);
}

.review-tabulation__tab:hover {
  color: var(--color-primary-dark);
  background-color: var(--tint-navy-04);
}

.review-tabulation__tab--active {
  color: var(--color-primary-dark);
  border-bottom-color: var(--color-primary-green);
  background-color: var(--tint-green-10);
}

.review-tabulation__tab--updates.review-tabulation__tab--active {
  color: var(--color-primary-pink);
  border-bottom-color: var(--color-primary-pink);
  background-color: var(--tint-danger-10);
}

.review-tabulation__tab-icon {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

/* == Panels == */
.review-tabulation__content {
  position: relative;
  min-height: 200px;
}

.review-tabulation__panel {
  display: none;
  flex-direction: column;
  gap: var(--space-4);
}

.review-tabulation__panel--active {
  display: flex;
}

.review-tabulation__updates {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-4);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.review-tabulation__empty-state {
  padding: var(--space-8) var(--space-4);
  text-align: center;
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}


/* ===== components/scrolling_cards.css ===== */
/* ==========================================================================
   Scrolling Cards — vertical scroll list of record cards (firms, cases, reviews)
   ========================================================================== */
.scrolling-cards {
  position: relative;
  width: 100%;
  height: calc(3 * (200px + var(--space-4)));
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--space-2) 0;
  border-radius: var(--radius-lg);
}

/* Fills the space left under the page header instead of stopping at a fixed
   three-card height, so the list uses the whole viewport. The offset is the
   main-content padding plus everything above the scroller. */
.scrolling-cards--fill {
  --scrolling-cards-offset: 140px;
  height: calc(100vh - var(--topbar-height) - var(--scrolling-cards-offset));
  min-height: 260px;
}

/* With a tab bar between the header and the list (the firm directory's All /
   Renewals Due), the scroller starts ~58px lower. */
.scrolling-cards--fill.scrolling-cards--tabbed {
  --scrolling-cards-offset: 198px;
}

.scrolling-cards__container {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: 0 var(--space-1);
}

/* Slightly tighter stacking so the taller scroller shows another card. */
.scrolling-cards--fill .scrolling-cards__container {
  gap: var(--space-3);
}

.scrolling-cards__card-link {
  text-decoration: none;
  color: inherit;
  display: block;
  width: 100%;
}

.scrolling-cards__card {
  position: relative;
  width: 100%;
  min-height: 120px;
  background-color: var(--color-surface);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-xs);
  padding: var(--space-5);
  transition: border-color var(--transition-base), box-shadow var(--transition-base),
    transform var(--transition-fast);
  display: flex;
  flex-direction: row;
  gap: var(--space-4);
  justify-content: space-between;
}

.scrolling-cards__card:hover {
  transform: translateY(-2px);
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-md);
}

.scrolling-cards__logo {
  width: 180px;
}

.scrolling-cards__logo-image {
  width: 100%;
  height: auto;
  object-fit: contain;
}

.scrolling-cards__card-column {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-right: var(--space-4);
}

.scrolling-cards__card-column--wide,
.scrolling-cards__card-column--extra-wide {
  flex: 1;
  min-width: 200px;
}

.scrolling-cards__card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-2);
}

.scrolling-cards__card-title {
  font-size: var(--font-size-large);
  font-family: var(--font-family-bold);
  color: var(--color-primary-dark);
  margin: 0;
}

.scrolling-cards__card-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  justify-content: space-between;
}

.scrolling-cards__card-content h4 {
  font-family: var(--font-family-bold);
  color: var(--color-text);
}

.scrolling-cards__card-content p {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
}

.scrolling-cards__card-content .sidenav__link-icon {
  min-width: 20px;
  width: 20px;
  height: 20px;
  margin-right: var(--space-2);
  flex-shrink: 0;
  color: var(--color-primary-green);
}

.scrolling-cards__card-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: var(--space-2);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.scrolling-cards__scroll-indicator {
  position: absolute;
  bottom: var(--space-2);
  right: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  padding: var(--space-1) var(--space-2);
  background-color: rgba(255, 255, 255, 0.85);
  border-radius: var(--radius-sm);
  opacity: 0.8;
}

.scrolling-cards__empty-state {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 160px;
  padding: var(--space-8);
  color: var(--color-text-muted);
  background-color: var(--color-surface);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
}

.scrolling-cards__edit-icon {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-full);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  transition: background-color var(--transition-base), transform var(--transition-fast);
  z-index: 1;
}

.scrolling-cards__edit-icon:hover {
  background-color: var(--color-surface-sunken);
  transform: scale(1.05);
}

.scrolling-cards__edit-icon-svg {
  color: var(--color-text-muted);
}

.scrolling-cards__edit-icon:hover .scrolling-cards__edit-icon-svg {
  color: var(--color-primary-dark);
}


/* ===== components/service_catalogue.css ===== */
/* ==========================================================================
   Service Catalogue — Business

   What the practice charges for: the sections on the invoice builder and the
   services under them. One scrolling page showing all of it at once, because
   this screen is read with a fee schedule beside it and a price list you have
   to page through is a price list nobody checks.

   Scrolls as a page rather than as a table filling the viewport, the way the
   bulk importer's hub does — it is panels and tables together rather than one
   listing (see components/bulk_import and components/table).
   ========================================================================== */
.service-catalogue__scroll {
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding-bottom: var(--space-6);
}

/* The standing note about what a price change does and does not touch, and the
   same note over the edit form. Informational rather than a warning: nothing
   here is dangerous, it is just the thing everybody wants confirming. */
.service-catalogue__note {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3) var(--space-4);
  background-color: var(--tint-navy-04);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-primary-dark);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
}

.service-catalogue__note .minor-icon {
  flex: 0 0 auto;
  margin-top: 2px;
  color: var(--color-primary-dark);
}

.service-catalogue__note strong {
  color: var(--color-text);
}

/* == A section == */
.service-catalogue__section {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  /* Anchored to after a change, so the browser must not park it under the
     sticky page header (see ServiceCatalogueSectionsController). */
  scroll-margin-top: var(--space-6);
}

.service-catalogue__section-header {
  display: flex;
  gap: var(--space-4);
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}

/* The whole heading is the fold's toggle: a header you can only open by hitting
   a chevron is a header most people never open. Stripped back to text so it
   reads as the heading it is rather than as a button. */
.service-catalogue__section-toggle {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 0;
  background: none;
  border: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.service-catalogue__section-toggle:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
}

.service-catalogue__section-chevron {
  display: flex;
  flex-shrink: 0;
  color: var(--color-text-muted);
  transition: transform var(--transition-base);
}

/* Points down when the section is open, right when it is folded — the direction
   it will move in rather than the state it is in. */
.service-catalogue__section:not(.is-open) .service-catalogue__section-chevron {
  transform: rotate(-90deg);
}

/* The gap between the header and the body belongs to the body, so a folded
   section is the header and nothing else rather than a header with a hole
   under it (see the section's own `gap`). */
.service-catalogue__section-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.service-catalogue__section-body[hidden] {
  display: none;
}

.service-catalogue__section-heading {
  display: flex;
  gap: var(--space-3);
  align-items: baseline;
  min-width: 0;
}

.service-catalogue__section-title {
  font-size: var(--font-size-large);
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
  margin: 0;
}

.service-catalogue__section-count,
.service-catalogue__section-empty {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  margin: 0;
}

.service-catalogue__section-actions {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  flex-wrap: wrap;
}

/* == The list of services == */
.service-catalogue__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-medium);
}

.service-catalogue__table th,
.service-catalogue__table td {
  padding: var(--space-3);
  text-align: left;
  border-bottom: 1px solid var(--color-border);
  vertical-align: middle;
}

.service-catalogue__table thead th {
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
  border-bottom: 1px solid var(--color-border);
}

.service-catalogue__table tbody tr:last-child th,
.service-catalogue__table tbody tr:last-child td {
  border-bottom: none;
}

.service-catalogue__row:hover {
  background-color: var(--tint-navy-04);
}

.service-catalogue__row {
  scroll-margin-top: var(--space-6);
}

.service-catalogue__name {
  font-weight: 500;
  color: var(--color-text);
}

/* The one column anybody scans down. Tabular figures so the decimal points line
   up, which is the whole reason to right-align a price at all. */
.service-catalogue__price-column {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.service-catalogue__table th.service-catalogue__price-column {
  text-align: right;
}

.service-catalogue__treatment-none {
  color: var(--color-text-muted);
}

.service-catalogue__tag {
  display: inline-block;
  padding: 2px var(--space-2);
  margin-right: var(--space-1);
  font-size: var(--font-size-small);
  color: var(--color-primary-dark);
  background-color: var(--tint-navy-06);
  border-radius: var(--radius-full);
  cursor: help;
}

.service-catalogue__row-actions {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
}

/* `button_to` wraps each button in a form, which is a block element and would
   otherwise break the row of actions onto its own line. */
.service-catalogue__row-actions form,
.service-catalogue__section-actions form {
  display: inline-flex;
  margin: 0;
}

/* == Up and down == */
.service-catalogue__move {
  display: inline-flex;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.service-catalogue__move-form {
  display: inline-flex;
  margin: 0;
}

.service-catalogue__move-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  background-color: var(--color-surface);
  color: var(--color-primary-dark);
  cursor: pointer;
}

.service-catalogue__move-form + .service-catalogue__move-form .service-catalogue__move-button {
  border-left: 1px solid var(--color-border);
}

.service-catalogue__move-button:hover:not(:disabled) {
  background-color: var(--tint-navy-10);
}

.service-catalogue__move-button:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* The end of the list keeps its buttons and greys them, rather than dropping
   one — a row of actions that changes width as you move down the table takes
   the next button out from under the pointer. */
.service-catalogue__move-button:disabled {
  color: var(--color-text-muted);
  opacity: 0.4;
  cursor: default;
}

/* == The retired drawer == */
.service-catalogue__archived {
  padding: var(--space-4) var(--space-5);
  background-color: var(--color-surface);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-lg);
}

.service-catalogue__archived-summary {
  cursor: pointer;
  font-size: var(--font-size-medium);
  font-weight: 500;
  color: var(--color-primary-dark);
}

.service-catalogue__archived-note {
  margin: var(--space-3) 0 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

/* == Empty catalogue, and the restore offer == */
.service-catalogue__empty {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-6);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.service-catalogue__empty h2 {
  font-size: var(--font-size-large);
  color: var(--color-primary-dark);
  margin: 0;
}

.service-catalogue__empty p,
.service-catalogue__restore p {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  max-width: 62ch;
}

.service-catalogue__empty-actions {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  margin-top: var(--space-2);
}

.service-catalogue__empty-actions form,
.service-catalogue__restore form {
  margin: 0;
}

.service-catalogue__restore {
  display: flex;
  gap: var(--space-4);
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  padding: var(--space-4) var(--space-5);
  background-color: var(--tint-navy-04);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-lg);
}

/* == The two forms == */
.service-catalogue__form {
  max-width: 640px;
}

.service-catalogue__flags {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  border: none;
  padding: 0;
  margin: 0;
}

/* The checkbox rows carry a title and an explanation rather than a single line,
   so they align to the top of the box instead of the middle of the block. */
.service-catalogue__flags .form__checkbox-option {
  align-items: flex-start;
}

.service-catalogue__flags .form__checkbox-option strong {
  display: block;
  color: var(--color-text);
}

.service-catalogue__flags .form__hint {
  margin-top: var(--space-1);
}


/* ===== components/settings.css ===== */
/* ==========================================================================
   Settings

   An accordion of sections, each a native <details>. There is one section today
   and there will be more, so the section is the unit: a heading that opens, and
   a body of cards inside it.
   ========================================================================== */
.settings {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-width: 1100px;
}

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

/* The default triangle is replaced by the chevron in the markup, which can then
   be turned with the section. */
.settings__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  cursor: pointer;
  list-style: none;
}

.settings__summary::-webkit-details-marker {
  display: none;
}

.settings__summary:hover {
  background-color: var(--color-surface-sunken);
  border-radius: var(--radius-md);
}

.settings__summary:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-md);
}

.settings__summary-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.settings__summary-title {
  color: var(--color-primary-dark);
  font-size: var(--font-size-large);
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.settings__summary-hint {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.settings__chevron {
  flex-shrink: 0;
  color: var(--color-text-muted);
  transition: transform var(--transition-base);
}

.settings__section[open] .settings__chevron {
  transform: rotate(180deg);
}

/* The rule divides the section from its heading, so it belongs to the body and
   spans it — on the note it would stop wherever the note's measure does. */
.settings__section-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin: 0 var(--space-5);
  padding: var(--space-4) 0 var(--space-5);
  border-top: 1px solid var(--color-border);
}

.settings__note {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  line-height: 1.6;
  max-width: 70ch;
}

/* ==========================================================================
   One table's card
   ========================================================================== */
.settings-card {
  display: block;
  padding: var(--space-4);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.settings-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-3);
}

.settings-card__title {
  margin: 0;
  color: var(--color-primary-dark);
  font-size: var(--font-size-medium);
  font-weight: 600;
}

.settings-card__where {
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
}

/* Whether this table is currently holding anything, and what just happened to
   it. Both sit in the same corner, because a save answers the same question. */
.settings-card__state,
.settings-card__message {
  flex-shrink: 0;
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
  white-space: nowrap;
}

.settings-card__state--set {
  background-color: var(--tint-navy-06);
  color: var(--color-text);
}

.settings-card__message {
  background-color: var(--tint-green-16);
  color: var(--color-success-dark);
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.settings-card__scoping {
  margin-bottom: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background-color: var(--color-yellow-100);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  line-height: 1.5;
  max-width: 70ch;
}

.settings-card__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.settings-card__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* ==========================================================================
   One control
   ========================================================================== */
.settings-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

/* The products multi-select needs the room its chips take. */
.settings-field--wide {
  grid-column: 1 / -1;
}

.settings-field__label {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
}

.settings-field__select,
.settings-field__input {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-family: var(--font-family-base);
  font-size: var(--font-size-medium);
}

.settings-field__select:focus,
.settings-field__input:focus {
  outline: none;
  border-color: var(--color-primary-green);
  box-shadow: var(--focus-ring);
}

@media (max-width: 768px) {
  .settings-card__grid {
    grid-template-columns: 1fr;
  }
}


/* ===== components/sidenav.css ===== */
/* ==========================================================================
   Side Navigation — a single rail that widens

   One element, two widths. Collapsed it is a 64px strip of icons; open it is
   240px with the labels showing. The rows do not move between the two, because
   the gutter is sized so that a collapsed row is a square with its icon on the
   rail's centre line.

   Open is driven by the `sidenav--open` class the controller sets on pointer
   enter, with `:hover` alongside it so the rail still works on a screen that
   loaded no JavaScript, and `:focus-within` so that tabbing in opens it too —
   a keyboard should not be left reading a column of unlabelled icons.
   `sidenav--pinned` is open that stays.

   Two themes. Everything below draws its colour from the rail's own custom
   properties, so a theme is the one block that redefines them and nothing else
   has to know which is on. Green is the default; `sidenav--dark` is the navy.
   ========================================================================== */
.sidenav {
  /* --- Green (default) --- */
  --rail-surface: var(--color-primary-green);
  /* Deepening towards the floor, so a full-height column of one colour does not
     read as a flat slab. */
  --rail-surface-deep: #46bd90;
  --rail-ink: var(--color-white);
  --rail-ink-soft: rgba(255, 255, 255, 0.75);
  --rail-hover: var(--tint-white-16);
  --rail-active: var(--tint-white-24);
  --rail-line: var(--tint-white-16);
  --rail-marker: var(--color-white);
  --rail-edge: var(--tint-navy-10);
  --rail-focus: 0 0 0 3px rgba(255, 255, 255, 0.5);
  --rail-scrollbar: var(--tint-white-24);

  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: var(--sidenav-width-collapsed);
  z-index: var(--z-sidenav);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: linear-gradient(
    180deg,
    var(--rail-surface) 0%,
    var(--rail-surface-deep) 100%
  );
  border-right: 1px solid var(--rail-edge);
  color: var(--rail-ink);
  transition: width var(--transition-slow), box-shadow var(--transition-slow),
    background var(--transition-base);
}

/* --- Navy (dark mode) ----------------------------------------------------- */
/* The rail becomes the left arm of the dark frame the top bar starts: same navy,
   flush to it. White has more room to work here than it does on green, so the
   ink can carry the hierarchy that the green theme puts into the fills. */
.sidenav--dark {
  --rail-surface: var(--color-primary-dark);
  --rail-surface-deep: #1b2c3e;
  --rail-ink: rgba(255, 255, 255, 0.92);
  --rail-ink-soft: rgba(255, 255, 255, 0.55);
  --rail-hover: rgba(255, 255, 255, 0.06);
  --rail-active: var(--tint-white-10);
  --rail-line: var(--tint-white-10);
  --rail-marker: var(--color-primary-green);
  --rail-edge: var(--tint-white-10);
  --rail-focus: 0 0 0 3px var(--tint-green-28);
}

.sidenav:is(:hover, :focus-within, .sidenav--open) {
  width: var(--sidenav-width-expanded);
  /* Unpinned, the widened rail floats over the page rather than pushing it, so
     it needs an edge. Pointing over a nav should not reflow a wide table. */
  box-shadow: var(--shadow-lg);
}

/* Pinned, the page has already made room for it (see layouts/dashboard), so it
   sits in the layout instead of over it and drops the shadow. */
.sidenav--pinned:is(:hover, :focus-within, .sidenav--open) {
  box-shadow: none;
}

/* The app's focus ring is a green glow, which is no ring at all on green. */
.sidenav :focus-visible {
  outline: none;
  box-shadow: var(--rail-focus);
}

/* --- The scrolling list -------------------------------------------------- */
/* Sixteen destinations and five groups is taller than a short window. The list
   takes the slack and scrolls inside itself; the footer below it does not move. */
.sidenav__scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--space-3) 0 var(--space-2);
  /* The app's scrollbar is drawn for a light surface — restate it for the rail. */
  scrollbar-color: var(--rail-scrollbar) transparent;
}

.sidenav__scroll::-webkit-scrollbar-thumb {
  background-color: var(--rail-scrollbar);
}

/* Collapsed, a scrollbar would be a stripe down a 64px strip of icons — so hide
   the bar, not the overflow. `overflow-y: hidden` here clips whatever the list
   has already scrolled past: on a short window the rail scrolls to keep the
   current page in view, and the rows above it then vanish with no way to reach
   them until you hover. */
.sidenav:not(:hover):not(:focus-within):not(.sidenav--open) .sidenav__scroll {
  scrollbar-width: none;
}

.sidenav:not(:hover):not(:focus-within):not(.sidenav--open) .sidenav__scroll::-webkit-scrollbar {
  width: 0;
  height: 0;
}

.sidenav__group + .sidenav__group {
  margin-top: var(--space-2);
}

.sidenav__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The gap between rows belongs to the item, not to the row inside it, so that
   the row's own top is the item's top — which is what the active marker below
   measures from. */
.sidenav__list > li {
  position: relative;
}

.sidenav__list > li + li {
  margin-top: 2px;
}

/* --- Group headings ------------------------------------------------------ */
/* Fixed height, whichever of its two forms is showing: the words when there is
   room for them, a short rule when there is not. Nothing below shifts. */
.sidenav__group-heading {
  position: relative;
  display: flex;
  align-items: center;
  height: 28px;
  margin: 0;
  padding: 0 var(--space-5);
}

.sidenav__group-heading-text {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--rail-ink-soft);
  /* See the note on .sidenav__link-text: transparent is not hidden. */
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--transition-fast), visibility var(--transition-fast);
}

.sidenav__group-heading::before {
  content: "";
  position: absolute;
  left: var(--space-5);
  width: 24px;
  height: 1px;
  background: var(--rail-line);
  transition: opacity var(--transition-fast);
}

.sidenav:is(:hover, :focus-within, .sidenav--open) .sidenav__group-heading-text {
  opacity: 1;
  visibility: visible;
  /* The fade is held back until the rail has most of its width, so the words
     arrive in place rather than smearing across the opening. Becoming visible
     is not held back with it — that would fade in from nothing twice. */
  transition: opacity var(--transition-fast) 0.12s, visibility 0s;
}

.sidenav:is(:hover, :focus-within, .sidenav--open) .sidenav__group-heading::before {
  opacity: 0;
}

/* --- Rows ---------------------------------------------------------------- */
.sidenav__link {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  box-sizing: border-box;
  /* 100% less both gutters — set explicitly so a <button> row (sign out, the
     rail toggle, the theme toggle) fills the same box an <a> row does. */
  width: calc(100% - 2 * var(--sidenav-gutter));
  height: var(--sidenav-row-height);
  margin: 0 var(--sidenav-gutter);
  padding: 0 10px;
  border: none;
  border-radius: var(--radius-md);
  background: none;
  color: var(--rail-ink);
  font-family: var(--font-family-base);
  font-size: var(--font-size-medium);
  font-weight: 500;
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  cursor: pointer;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.sidenav__link:hover {
  background-color: var(--rail-hover);
  color: var(--rail-ink);
}

.sidenav__link:hover .sidenav__link-icon {
  color: var(--rail-ink);
}

.sidenav__link-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  color: var(--rail-ink-soft);
  transition: color var(--transition-fast);
}

/* The app's own icons carry their own width and height and vary in proportion,
   so the box is the constant and each icon fits itself inside it. */
.sidenav__link-icon svg {
  width: 100%;
  height: 100%;
}

/* Hidden, not merely transparent. A narrow rail clips the labels but does not
   quite cut them off — the first few pixels of one still fall inside the 64px
   box — and a transparent thing that is still laid out is still a thing: it
   answers to hit testing, to a text selection dragged across it, and to
   anything asking the page what is on screen. The row carries its own
   aria-label (see shared/_sidenav) so hiding the words costs it no name. */
.sidenav__link-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--transition-fast), visibility var(--transition-fast);
}

.sidenav:is(:hover, :focus-within, .sidenav--open) .sidenav__link-text {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--transition-fast) 0.12s, visibility 0s;
}

/* --- Where you are ------------------------------------------------------- */
/* A brighter row and a full-strength icon, with a marker on the rail's own edge.
   Legible collapsed, where the marker and the icon are all there is to go on. */
.sidenav__link--active,
.sidenav__link--active:hover {
  background-color: var(--rail-active);
  color: var(--rail-ink);
  font-weight: 600;
}

.sidenav__link--active .sidenav__link-icon,
.sidenav__link--active:hover .sidenav__link-icon {
  color: var(--rail-ink);
}

/* The marker hangs off the list item rather than off the row: the row clips its
   own overflow — that is what hides a label while the rail is narrow — so a tab
   sitting outside it, flush on the rail's edge, would be clipped away with it. */
.sidenav__list > li:has(> .sidenav__link--active)::before {
  content: "";
  position: absolute;
  left: 0;
  top: calc(var(--sidenav-row-height) / 2);
  width: 3px;
  height: 20px;
  border-radius: var(--radius-full);
  background-color: var(--rail-marker);
  transform: translateY(-50%);
}

/* --- Footer -------------------------------------------------------------- */
.sidenav__footer {
  flex: 0 0 auto;
  padding: var(--space-2) 0 var(--space-3);
  border-top: 1px solid var(--rail-line);
}

.sidenav__footer-form {
  margin: 0;
}

.sidenav__link--rail-toggle,
.sidenav__link--signout {
  margin-top: 2px;
}

/* One icon or the other, never both. Each toggle shows where it will take you:
   the moon while the rail is green, the sun while it is navy; open-panel while
   the rail is only borrowing its width, close-panel once it has been pinned. */
.sidenav__link-icon--pinned,
.sidenav--pinned .sidenav__link-icon--unpinned,
.sidenav__link-icon--dark,
.sidenav--dark .sidenav__link-icon--light {
  display: none;
}

.sidenav--pinned .sidenav__link-icon--pinned,
.sidenav--dark .sidenav__link-icon--dark {
  display: inline-flex;
}

/* ==========================================================================
   Pointerless screens

   Widening on hover is a pointer's idiom. On a touch screen the same gesture
   is a tap that is also trying to follow a link, so the rail stays put and the
   footer's toggle is how it opens. The controller keeps its hover listeners off
   these screens for the same reason.
   ========================================================================== */
@media (hover: none) {
  .sidenav:hover:not(:focus-within):not(.sidenav--open) {
    width: var(--sidenav-width-collapsed);
  }

  .sidenav:hover:not(:focus-within):not(.sidenav--open) .sidenav__link-text,
  .sidenav:hover:not(:focus-within):not(.sidenav--open) .sidenav__group-heading-text {
    opacity: 0;
    visibility: hidden;
  }
}


/* ===== components/star_rating.css ===== */
/* ==========================================================================
   Star Rating — a mark out of five, to read in a table row or to set on a form
   Gold for the stars given, faint for the rest. Blank is a line of text rather
   than five empty stars, because "nobody has formed a view" and "somebody has
   formed a poor one" must not look alike (see shared/_star_rating).
   ========================================================================== */
.star-rating {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

.star-rating__star {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-border-strong);
  transition: color var(--transition-base);
}

.star-rating__star--filled {
  color: #f2b134;
}

.star-rating__icon {
  width: 15px;
  height: 15px;
}

.star-rating__empty {
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  white-space: nowrap;
}

/* --- The form control ---------------------------------------------------- */
.star-rating--input {
  gap: var(--space-1);
}

.star-rating__star--button {
  padding: 2px;
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.star-rating__star--button:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.star-rating--input .star-rating__icon {
  width: 22px;
  height: 22px;
}

/* Sits to the right of the row and says what is set — and that clicking the star
   a rating sits on is the way back to no rating at all, which a row of stars
   gives no hint of on its own. */
.star-rating__label {
  margin-left: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}


/* ===== components/status_pill.css ===== */
/* ==========================================================================
   Status Pill — tinted chip with status dot
   ========================================================================== */
.status-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 4px 12px;
  white-space: nowrap;
  border-radius: var(--radius-full);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  line-height: 1.6;
  border: 1px solid transparent;
}

.status-pill::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: var(--radius-full);
  background-color: currentColor;
  flex-shrink: 0;
}

.status-pill--green {
  background-color: var(--tint-green-16);
  color: #1e8e63;
  border-color: var(--tint-green-28);
}

.status-pill--red {
  background-color: rgba(231, 76, 60, 0.12);
  color: #e74c3c;
  border-color: rgba(231, 76, 60, 0.25);
}

.status-pill--yellow {
  background-color: rgba(245, 158, 11, 0.12);
  color: #b45309;
  border-color: rgba(245, 158, 11, 0.3);
}

.status-pill--blue {
  background-color: rgba(52, 152, 219, 0.12);
  color: #2980b9;
  border-color: rgba(52, 152, 219, 0.3);
}

.status-pill--gray {
  background-color: rgba(149, 165, 166, 0.15);
  color: #5d6d6e;
  border-color: rgba(149, 165, 166, 0.35);
}

.status-pill--purple {
  background-color: rgba(155, 89, 182, 0.12);
  color: #8e44ad;
  border-color: rgba(155, 89, 182, 0.3);
}

/* ==========================================================================
   Status pills, per status — the agreed colour system for cases and reviews.

   Everything else in the application draws its status from the six generic
   colours above: a task, a project, a complaint, an EOS rock, a candidate. A
   case and a review are the two records the practice reads all day, and they
   were the two asked for by name, so they get a colour each instead of sharing
   six between twenty-two states.

   The token is built by the model rather than written here — Case#status_color
   returns "case-ready-for-pp" — so a status added to the enum without a colour
   added here renders as an unstyled pill rather than as the wrong one. The
   border is the ink mixed a quarter of the way into the paper, which is how the
   generic pills are drawn and what keeps a pale chip from floating.
   ========================================================================== */

/* --- Case --- */

.status-pill--case-not-started {
  background-color: #FBE5E5;
  color: #DC2626;
  border-color: #F2B0B0;
}

.status-pill--case-with-adviser {
  background-color: #E5ECFD;
  color: #2563EB;
  border-color: #AFC6F8;
}

.status-pill--case-data-gathering {
  background-color: #E2F2F1;
  color: #0D9488;
  border-color: #A6D8D4;
}

.status-pill--case-ready-for-pp {
  background-color: #E4EAFA;
  color: #1D4ED8;
  border-color: #ACBEF0;
}

.status-pill--case-in-progress {
  background-color: #F9EBDD;
  color: #D97706;
  border-color: #F0CBA1;
}

.status-pill--case-in-checking {
  background-color: #FBE5EF;
  color: #DB2777;
  border-color: #F2B0CD;
}

.status-pill--case-compliance-pre-approval {
  background-color: #E2F4FC;
  color: #0EA5E9;
  border-color: #A7DEF7;
}

.status-pill--case-amends-required {
  background-color: #FCEBE2;
  color: #EA580C;
  border-color: #F7C2A6;
}

.status-pill--case-implementation {
  background-color: #F1EBFE;
  color: #8B5CF6;
  border-color: #D4C3FC;
}

.status-pill--case-complete {
  background-color: #E3F4E9;
  color: #16A34A;
  border-color: #AADDBC;
}

.status-pill--case-cancelled {
  background-color: #F3E3E7;
  color: #9F1239;
  border-color: #DBA8B6;
}

.status-pill--case-on-hold {
  background-color: #EDEEF0;
  color: #6B7280;
  border-color: #C9CBD1;
}

/* --- Review --- */

.status-pill--review-not-started {
  background-color: #FBE5E5;
  color: #DC2626;
  border-color: #F2B0B0;
}

.status-pill--review-client-contacted {
  background-color: #E5ECFD;
  color: #2563EB;
  border-color: #AFC6F8;
}

.status-pill--review-meeting-booked {
  background-color: #E2F2F1;
  color: #0D9488;
  border-color: #A6D8D4;
}

.status-pill--review-preparation-in-progress {
  background-color: #FAEFE1;
  color: #D97706;
  border-color: #F1CDA4;
}

.status-pill--review-in-checking {
  background-color: #FBE5EF;
  color: #DB2777;
  border-color: #F2B0CD;
}

.status-pill--review-review-pack-complete {
  background-color: #F1EBFE;
  color: #8B5CF6;
  border-color: #D4C3FC;
}

.status-pill--review-post-meeting-actions {
  background-color: #E2F4FC;
  color: #0EA5E9;
  border-color: #A7DEF7;
}

.status-pill--review-complete {
  background-color: #E3F4E9;
  color: #16A34A;
  border-color: #AADDBC;
}

.status-pill--review-deferred {
  background-color: #FCEBE2;
  color: #EA580C;
  border-color: #F7C2A6;
}

.status-pill--review-not-required {
  background-color: #EDEEF0;
  color: #6B7280;
  border-color: #C9CBD1;
}


/* ===== components/survey.css ===== */
/* ==========================================================================
   Satisfaction survey — the page a firm's principal contact answers.

   The only part of the app seen by someone with no account, on whatever device
   the email was opened on. So: one card, centred, no navigation, and a scale
   that stays usable when five 64px faces no longer fit across the screen.
   ========================================================================== */
/* The app locks `body { overflow: hidden }`, so this is the element that
   scrolls. It takes the viewport's height exactly — `min-height` would let it
   grow past the clip instead, putting the submit button somewhere unreachable
   on a short window. */
.survey-page {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  height: 100%;
  padding: var(--space-8) var(--space-4);
  background: var(--color-canvas);
  overflow-y: auto;
}

/* `overflow: hidden` so the header band takes the card's top corners with it. */
.survey-card {
  width: 100%;
  max-width: 560px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}

.survey-card--centred {
  text-align: center;
}

/* The logo is a white mark, so it needs a dark ground — the same gradient the
   sign-in page stands it on. Full-bleed rather than inset: it is the brand
   saying who is asking, not a heading. */
.survey-card__header {
  padding: var(--space-6);
  background: linear-gradient(160deg, var(--color-primary-dark), var(--color-secondary-dark));
  text-align: center;
}

.survey-card__logo {
  display: block;
  width: 120px;
  height: auto;
  margin: 0 auto;
}

.survey-card__body {
  padding: var(--space-8) var(--space-10) var(--space-10);
}

.survey-card__title {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-xxlarge);
  color: var(--color-primary-dark);
  text-align: center;
}

.survey-card__blurb {
  margin: 0 0 var(--space-6);
  font-size: var(--font-size-large);
  line-height: 1.6;
  color: var(--color-text);
  text-align: center;
}

/* The score, played back on the thank-you screen. Large enough to be the whole
   confirmation on its own — it is what they just clicked, made bigger. */
.survey-card__answer {
  margin: 0 0 var(--space-4);
  font-size: 64px;
  line-height: 1;
}

.survey-card__note {
  margin: var(--space-6) 0 0;
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}

/* --- The five faces ------------------------------------------------------ */
.survey-scale {
  margin: 0 0 var(--space-6);
  padding: 0;
  border: 0;
}

.survey-scale__legend {
  display: block;
  width: 100%;
  margin-bottom: var(--space-3);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  color: var(--color-text-muted);
  text-align: center;
}

/* Wraps rather than shrinking: five faces small enough to fit a narrow phone
   are five faces too small to tap accurately. */
.survey-scale__options {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
}

.survey-scale__option {
  flex: 0 0 auto;
}

/* The radio itself is the state; the label is the control. Kept in the
   document (rather than display: none) so it stays reachable by keyboard and
   announced by a screen reader. */
.survey-scale__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.survey-scale__face {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  width: 84px;
  padding: var(--space-3) var(--space-1);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
  transition: border-color var(--transition-base), background-color var(--transition-base),
    transform var(--transition-fast), box-shadow var(--transition-base);
}

.survey-scale__face:hover {
  border-color: var(--color-primary-green);
  transform: translateY(-2px);
  box-shadow: var(--shadow-sm);
}

.survey-scale__glyph {
  font-size: 32px;
  line-height: 1;
}

.survey-scale__label {
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
  text-align: center;
}

/* Filled rather than outlined, matching the firm record's card: the one answer
   among five, not five equal options. */
.survey-scale__input:checked + .survey-scale__face {
  border-color: var(--color-primary-green);
  background: var(--tint-green-16);
  box-shadow: var(--shadow-glow-green);
}

.survey-scale__input:checked + .survey-scale__face .survey-scale__label {
  color: var(--color-primary-dark);
  font-weight: 600;
}

/* The label carries the focus ring, since the input it belongs to is invisible
   — without this, tabbing through the scale shows nothing at all. */
.survey-scale__input:focus-visible + .survey-scale__face {
  outline: none;
  border-color: var(--color-primary-green);
  box-shadow: var(--focus-ring);
}

/* --- Comment and submit --------------------------------------------------- */
.survey-form__field {
  margin-bottom: var(--space-6);
}

.survey-form__label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
}

.survey-form__input {
  width: 100%;
  padding: var(--space-3);
  font-family: var(--font-family-base);
  font-size: var(--font-size-medium);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  resize: vertical;
}

.survey-form__input:focus {
  outline: none;
  border-color: var(--color-primary-green);
  box-shadow: var(--focus-ring);
}

.survey-form__hint {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.survey-form__error {
  margin: 0 0 var(--space-4);
  font-size: var(--font-size-medium);
  color: var(--color-danger);
  text-align: center;
}

.survey-form__submit {
  width: 100%;
}

@media (max-width: 480px) {
  .survey-card__body {
    padding: var(--space-6);
  }

  .survey-scale__face {
    width: 72px;
  }
}


/* ===== components/table.css ===== */
/* ==========================================================================
   Data Table — card-contained table with hairline dividers
   Bare th/td tags inside `.table-container` are styled deliberately so
   content markup stays lean; named cells use table-* modifier classes.
   ========================================================================== */
.table-container {
  width: 100%;
  overflow-y: auto;
  margin-bottom: var(--space-6);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.table-container--small {
  width: 50%;
}

.table-container__header {
  display: flex;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  align-items: center;
  border-bottom: 1px solid var(--color-border);
}

.table-container table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-medium);
}

.table-container thead {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background-color: var(--color-surface);
}

/* `border-collapse: collapse` drops the header's own bottom border once the
   thead is lifted out of flow, so the divider is redrawn as a shadow. */
.table-container thead::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  border-bottom: 1px solid var(--color-border);
}

/* A summary footer (the time log's "Total Time") pins to the bottom of the
   scroller, the way the column headers pin to the top. */
.table-container tfoot {
  position: sticky;
  bottom: 0;
  z-index: var(--z-sticky);
  background-color: var(--color-surface);
}

.table-container th {
  color: var(--color-text-muted);
  font-family: var(--font-family-bold);
  font-size: var(--font-size-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
}

.table-header--center {
  text-align: center !important;
}

.table-header--right {
  text-align: right !important;
}

.table-container tbody tr {
  transition: background-color var(--transition-fast);
}

.table-container tbody tr:not(:last-child) td {
  border-bottom: 1px solid var(--color-border);
}

.table-container tbody tr:hover {
  background-color: var(--tint-navy-04);
}

.table-container tbody tr[data-controller~="clickable-row"] {
  cursor: pointer;
}

.table-row--warning {
  box-shadow: inset 3px 0 0 var(--color-warning);
  background-color: rgba(245, 158, 11, 0.07);
}

.table-row--warning:hover {
  background-color: rgba(245, 158, 11, 0.13);
}

.table-row--danger {
  box-shadow: inset 3px 0 0 var(--color-danger);
  background-color: var(--tint-danger-10);
}

.table-row--danger:hover {
  background-color: var(--tint-danger-16);
}

/* A record added in the last 48 hours (see Case#recently_added?). Deliberately
   the faintest of these: it says "this one is new", not "do something about
   this one", so it is a tint with no edge marker to compete with the states
   above that do. */
.table-row--new {
  background-color: rgba(59, 130, 246, 0.06);
}

.table-row--new:hover {
  background-color: rgba(59, 130, 246, 0.12);
}

/* Cases with no assigned checklist ("No Recommendation"). Defined last so the
   data-quality flag stays visible even when a due-date state also applies. */
.table-row--no-checklist {
  box-shadow: inset 3px 0 0 #6366f1;
  background-color: rgba(99, 102, 241, 0.07);
}

.table-row--no-checklist:hover {
  background-color: rgba(99, 102, 241, 0.13);
}

.table-container td {
  padding: var(--space-3) var(--space-4);
  color: var(--color-text);
  vertical-align: middle;
}

.table-cell--danger {
  color: var(--color-danger);
  font-family: var(--font-family-bold);
}

/* Emphasised name cell — the row's primary identifier. */
.table-cell--primary {
  color: var(--color-primary-dark);
  font-family: var(--font-family-bold);
  font-weight: 600;
}

/* Row count under a table, e.g. "Showing 25 of 137 clients". */
.table-summary {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

/* --- Pagination footer --------------------------------------------------- */
.table-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-3);
}

.table-pagination__controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.table-pagination__page {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  white-space: nowrap;
}

/* A paging control with nowhere to go renders as a span, not a link. */
.table-pagination__controls span.button {
  opacity: 0.45;
  cursor: default;
  pointer-events: none;
}

/* ==========================================================================
   Index page shell — header/filters pinned, only the rows scroll
   Mirrors the firm directory: the breadcrumb, page header, search, filter and
   action buttons stay put while the table body scrolls under its sticky column
   headers. The page itself never scrolls, so the scroller has to be handed a
   bounded height: each ancestor from the main-content frame down to the table
   is a flex column that passes its height on (min-height: 0 lets it shrink
   below the intrinsic height of a long table instead of overflowing).
   ========================================================================== */
turbo-frame#main_content:has(> .index-page) {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

.index-page {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

/* Wrappers sitting between the page shell and the table scroller: the turbo
   frame when the page header lives outside it, and the bulk-select form every
   soft-deleting table is wrapped in — inside that frame on most of them, a
   direct child of the page on the case list, hence the descendant selector.
   They pass the height through instead of absorbing it. Forms that hold no
   table (the notifications bulk form is an empty element the checkboxes attach
   to by id) must not claim any, hence the :has().

   `min-height: 0` is what lets them shrink below the intrinsic height of a long
   table. That is also why the pagination goes inside the bulk form rather than
   beside it: a squeezed form overflows, and its footer has to overflow with the
   rows rather than be sat on by them. */
.index-page__body,
.index-page form:has(.table-container) {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

/* Breadcrumbs, page header, filters and toolbars keep their natural size; the
   scroller takes whatever is left, down to a floor of a few rows. */
.index-page .table-container {
  flex: 1 1 auto;
  min-height: 180px;
  margin-bottom: 0;
}

.index-page .table-pagination {
  flex: 0 0 auto;
  padding-bottom: var(--space-1);
}

/* Yes / No flags (e.g. Bespoke DFM): affirmative reads green, negative muted. */
.table-flag--yes {
  color: #1e8e63;
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.table-flag--no {
  color: var(--color-text-muted);
}

/* A listing with more columns than the shell has room for — the QA tracker's
   thirteen — given a floor to lay them out against so the cells stop cramming and
   the scroller does its job instead. Without it every name in every row wraps onto
   three lines and the table reads as a wall. */
.table-container table.table--wide {
  min-width: 1500px;
}

/* A value that is legitimately not set yet — an unowned applicant on the
   recruitment pipeline — as against missing data, which gets the louder alert
   (see ApplicationHelper#display_or_alert). */
.table-data--unset {
  color: var(--color-text-muted);
}

/* The cell that names the row — the applicant on the recruitment pipeline — set
   apart from the columns describing it. */
.table-data--strong {
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.table-data--center {
  text-align: center;
}

.table-data--right {
  text-align: right;
}

.table-empty-state {
  text-align: center;
  padding: var(--space-10) var(--space-4) !important;
  color: var(--color-text-muted);
}

/* Closing row of a populated table — see shared/_table_end_row. */
.table-end-row:hover {
  background-color: transparent;
}

.table-end-row__cell {
  text-align: center;
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
  background-color: var(--color-surface-sunken);
}

/* --- Sortable headers --- */
.table-header__content {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.table-header--center .table-header__content {
  justify-content: center;
}

.table-header__sort-link {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: color var(--transition-base);
}

.table-header__sort-link:hover,
.table-header__sort-link--active {
  color: var(--color-primary-dark);
}

.table-header__sort-icon {
  font-size: 0.625rem;
  margin-left: var(--space-1);
  color: var(--color-text-faint);
}

.table-header__clear-sort {
  color: var(--color-text-faint);
  display: flex;
  align-items: center;
  transition: color var(--transition-base);
}

.table-header__clear-sort:hover {
  color: var(--color-danger);
}

.table-header__clear-icon {
  width: 1rem;
  height: 1rem;
}

/* --- Missing data alert --- */
.missing-data-alert {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  color: var(--color-danger);
}

.missing-data-alert svg {
  width: 28px;
  height: 28px;
  fill: currentColor;
}

/* --- Table actions --- */
.table-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
}


/* --- Bulk selection --- */
.table-bulk {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.table-bulk__count {
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
}

.table-select-column {
  width: 48px;
}

.table-select-checkbox {
  width: 16px;
  height: 16px;
  accent-color: var(--color-primary-green);
  cursor: pointer;
}

/* --- Deleted records --- */

/* The Active / Deleted switch. The same tab bar the listings already use (see
   .cases-index-tabs), a size down: it is a way back to something deleted by
   mistake, not a second half of the page (see shared/_deletion_tabs). */
.deletion-tabs {
  display: inline-flex;
  align-self: flex-start;
  flex: 0 0 auto;
  gap: var(--space-1);
  margin-bottom: var(--space-3);
  padding: 3px;
  background-color: var(--tint-navy-06);
  border-radius: var(--radius-md);
}

.deletion-tabs__tab {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  text-decoration: none;
  transition: background-color var(--transition-base), color var(--transition-base);
}

.deletion-tabs__tab:hover {
  color: var(--color-primary-dark);
}

.deletion-tabs__tab--current {
  background-color: var(--color-surface);
  color: var(--color-primary-dark);
  box-shadow: var(--shadow-sm), inset 0 -2px 0 var(--color-primary-green);
}

.deletion-tabs__count {
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  background-color: var(--tint-navy-10);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}


/* When it was deleted and when it stops being recoverable, stacked so the
   deadline reads as a footnote to the date rather than a second fact. */
.table-deleted-cell {
  white-space: nowrap;
}

.table-deleted-cell__when {
  display: block;
  color: var(--color-text-muted);
}

.table-deleted-cell__until {
  display: block;
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
}

/* A select-all that has no header row to sit in — the firm directory's cards.
   It groups with the count and the button on the right rather than being pushed
   to the far side of a very wide bar, so the three read as one control. */
.table-bulk--cards {
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.table-bulk__select-all {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  cursor: pointer;
}

/* A cell that names another record and opens it (see RecordLinksHelper). The row
   underneath already opens the record the table is of, so these are underlined
   on hover to say they go somewhere else. */
.record-link {
  color: inherit;
  text-decoration: none;
}

.record-link:hover {
  text-decoration: underline;
  color: var(--color-primary-green);
}

/* ==========================================================================
   Row colour key — what a table's tinted rows mean (see shared/_row_highlight_key)
   ========================================================================== */
.row-key {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  margin-bottom: var(--space-3);
  font-size: var(--font-size-small);
  color: var(--color-text-muted);
}

.row-key__title {
  font-family: var(--font-family-bold);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
}

.row-key__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

/* The swatch carries the row's own class, so it is tinted by the same rule the
   row is. The border is what makes the faintest of them (the "just added" tint)
   visible at 14px square. */
.row-key__swatch {
  width: 14px;
  height: 14px;
  border-radius: var(--radius-small, 3px);
  border: 1px solid var(--color-border, #d6dbe0);
  flex-shrink: 0;
}


/* ===== components/tag_pill.css ===== */
/* ==========================================================================
   Tag Pill — flat, dotless counterpart to .status-pill, for categorising a row
   (client type, preferred contact) rather than reporting a live state.
   ========================================================================== */
.tag-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 3px 12px;
  border-radius: var(--radius-full);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  line-height: 1.6;
  white-space: nowrap;
}

.tag-pill--gray {
  background-color: rgba(149, 165, 166, 0.15);
  color: #5d6d6e;
}

.tag-pill--blue {
  background-color: rgba(52, 152, 219, 0.12);
  color: #2980b9;
}

.tag-pill--purple {
  background-color: rgba(155, 89, 182, 0.12);
  color: #8e44ad;
}

.tag-pill--amber {
  background-color: rgba(245, 158, 11, 0.14);
  color: #b45309;
}

.tag-pill--green {
  background-color: var(--tint-green-16);
  color: #1e8e63;
}

.tag-pill--pink {
  background-color: rgba(236, 72, 153, 0.12);
  color: #be185d;
}

/* Outlined rather than tinted, for the second categorising pill in a row: an
   applicant's source sits beside their role, and two tinted pills side by side
   read as two states rather than one fact and its context. */
.tag-pill--outline {
  background-color: var(--color-surface);
  border: 1.5px solid var(--color-border);
  color: var(--color-text-muted);
}

/* Outlined in the brand navy rather than in grey: the emphatic outline, for the
   value in a pair that means "somebody is still watching this". A full QA check
   beside a spot check is the case in point (see QaCheck#check_type_color). */
.tag-pill--outline-dark {
  background-color: var(--color-surface);
  border: 1.5px solid var(--color-primary-dark);
  color: var(--color-primary-dark);
}

/* Between amber and red, for a middle grading that has to read as worse than
   amber without being the loudest thing on the page. */
.tag-pill--orange {
  background-color: rgba(194, 101, 15, 0.14);
  color: #c2650f;
}

/* Solid rather than tinted — the one pill in the set that is meant to stop
   somebody scanning a table. Reserved for a critical QA failure. */
.tag-pill--critical {
  background-color: var(--color-danger-light);
  color: var(--color-white);
}


/* ===== components/task_tabulation.css ===== */
/* ==========================================================================
   Task Tabulation — tabbed panel (notes, documents) on a task record
   ========================================================================== */
.task-tabulation {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.task-tabulation__tabs {
  display: flex;
  gap: var(--space-1);
  border-bottom: 1px solid var(--color-border);
}

.task-tabulation__tab {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  color: var(--color-text-muted);
  cursor: pointer;
  transition: color var(--transition-base), border-color var(--transition-base);
  position: relative;
}

.task-tabulation__tab:hover {
  color: var(--color-primary-dark);
}

.task-tabulation__tab--active {
  color: var(--color-primary-dark);
  border-bottom-color: var(--color-primary-green);
}

.task-tabulation__tab-icon {
  width: 1.15rem;
  height: 1.15rem;
  fill: currentColor;
}

/* --- Panels --- */
.task-tabulation__content {
  position: relative;
  min-height: 200px;
}

.task-tabulation__panel {
  display: none;
  flex-direction: column;
  gap: var(--space-4);
}

.task-tabulation__panel--active {
  display: flex;
}

.task-tabulation__updates {
  padding: var(--space-4);
  background-color: var(--color-surface-sunken);
  border-radius: var(--radius-md);
  min-height: 200px;
}

.task-tabulation__empty-state {
  color: var(--color-text-muted);
  text-align: center;
  padding: var(--space-8) var(--space-4);
}

/* --- Record tag chips (firms / team members on the task record) --- */
.record-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.record-tags__tag {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  background-color: var(--tint-navy-06);
  border: 1px solid var(--color-border);
  color: var(--color-text);
  font-size: var(--font-size-small);
  line-height: 1.5;
  /* The row of tags wraps; a tag does not. "Missing Risk Assessment" broken over
     three lines inside its own pill reads as three tags rather than one. */
  white-space: nowrap;
}


/* ===== components/team_members.css ===== */
/* ==========================================================================
   Team Members — index table, activity table and drawer extras
   ========================================================================== */

/* == index table == */
.team-member__name-cell {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

/* == activity table == */
.team-member__activity-date {
  white-space: nowrap;
}

/* == drawer banners == */
.team-member__locked-banner {
  background-color: var(--tint-danger-10);
  border: 1px solid var(--tint-danger-16);
  border-left: 3px solid var(--color-danger);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin-bottom: var(--space-5);
}

.team-member__locked-banner p {
  margin: 0 0 var(--space-2) 0;
  font-size: var(--font-size-medium);
  color: var(--color-danger);
}

.team-member__locked-banner p:last-of-type {
  margin-bottom: var(--space-4);
}

/* Amber warning values mirror the core `.table-row--warning` treatment. */
.team-member__pending-banner {
  background-color: rgba(245, 158, 11, 0.07);
  border: 1px solid rgba(245, 158, 11, 0.3);
  border-left: 3px solid var(--color-warning);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin-bottom: var(--space-5);
}

.team-member__pending-banner p {
  margin: 0 0 var(--space-2) 0;
  font-size: var(--font-size-medium);
  color: var(--color-warning-dark);
}

.team-member__pending-banner p:last-of-type {
  margin-bottom: var(--space-4);
}

/* == lock account section == */
.team-member__lock-section {
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}

.team-member__lock-title {
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
  margin-bottom: var(--space-4);
}

.team-member__lock-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.team-member__lock-form .form__field {
  margin-bottom: 0;
}

/* == static (read-only) field text == */
.team-member__static-text {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 var(--space-3);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
}


/* ===== components/time_entry.css ===== */
/* ==========================================================================
   Time Entry — time log table accents and drawer form context
   ========================================================================== */

/* == Duration chip == */
.time-entry__duration {
  display: inline-block;
  font-family: var(--font-family-bold);
  font-weight: 600;
  font-size: var(--font-size-small);
  color: var(--color-primary-dark);
  background-color: var(--tint-green-10);
  border: 1px solid var(--tint-green-28);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  white-space: nowrap;
}

/* == Description cell == */
.time-entry__description {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  max-width: 300px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* == Totals row == */
.time-entry-table__total-row td {
  background-color: var(--color-surface-sunken);
  border-top: 1px solid var(--color-border);
}

.time-entry-table__total-label {
  font-family: var(--font-family-bold);
  font-size: var(--font-size-small);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.time-entry-table__total-value {
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
}

/* == Drawer form: selected record context == */
.time-entry-form__selected-item {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-primary-green);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-4);
}

.time-entry-form__selected-label {
  font-family: var(--font-family-bold);
  font-size: var(--font-size-small);
  text-transform: uppercase;
  letter-spacing: var(--label-letter-spacing);
  color: var(--color-text-muted);
}

.time-entry-form__selected-value {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-family-bold);
  font-weight: 600;
  color: var(--color-primary-dark);
}


/* ===== components/topbar.css ===== */
/* ==========================================================================
   Top Bar — slim, fixed app header
   ========================================================================== */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: 0 var(--space-5);
  background-color: var(--color-primary-dark);
  border-bottom: 1px solid var(--tint-white-10);
  box-shadow: var(--shadow-sm);
  height: var(--topbar-height);
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: var(--z-topbar);
}

.topbar__section {
  display: flex;
  align-items: center;
  min-width: 0;
}

.topbar__section--center {
  flex-grow: 1;
  margin: 0 var(--space-8);
}

.topbar__section--right {
  gap: var(--space-2);
}

.topbar__logo {
  height: 40px;
  width: auto;
  display: block;
}

/* Quick search — glassy field on the dark bar */
.topbar__search {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background-color: var(--tint-white-10);
  border: 1px solid var(--tint-white-16);
  border-radius: var(--radius-md);
  padding: 0 var(--space-3);
  height: 38px;
  width: 260px;
  max-width: 100%;
  transition: background-color var(--transition-base), border-color var(--transition-base);
}

.topbar__search:hover,
.topbar__search:focus-within {
  background-color: var(--tint-white-16);
  border-color: var(--tint-white-24);
}

.topbar__search-input {
  border: none;
  background: transparent;
  width: 100%;
  outline: none;
  font-size: var(--font-size-medium);
  font-family: var(--font-family-base);
  color: var(--color-white);
}

.topbar__search-input::placeholder {
  color: rgba(255, 255, 255, 0.55);
}

.topbar__search-icon {
  width: 18px;
  height: 18px;
  color: rgba(255, 255, 255, 0.65);
  flex-shrink: 0;
}

/* Icon actions */
.topbar__option {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 38px;
  width: 38px;
}

.topbar__option-icon {
  width: 22px;
  height: 22px;
  color: var(--color-white);
}

.topbar__settings-link,
.topbar__notifications-link {
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  color: var(--color-white);
  width: 38px;
  height: 38px;
  border-radius: var(--radius-md);
  transition: background-color var(--transition-base);
  position: relative;
}

.topbar__settings-link:hover,
.topbar__notifications-link:hover {
  background-color: var(--tint-white-16);
}

.topbar__notifications-icon-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.topbar__notifications-badge {
  position: absolute;
  top: -6px;
  right: -8px;
  min-width: 1.1rem;
  height: 1.1rem;
  padding: 0 0.3rem;
  font-size: 0.65rem;
  font-weight: 700;
  line-height: 1.1rem;
  color: var(--color-white);
  background-color: var(--color-danger);
  border: 2px solid var(--color-primary-dark);
  border-radius: var(--radius-full);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ==========================================================================
   The account menu — the avatar, and what hangs off it

   Hover-opened, like the sidenav's Business fly-out, and :focus-within opens it
   for a keyboard as well. No JavaScript, so it also works on the screens that
   load none.
   ========================================================================== */
.topbar__user {
  position: relative;
}

.topbar__user-trigger {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
  border-radius: var(--radius-full);
}

.topbar__user-trigger:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.topbar__user-menu {
  display: none;
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  min-width: 240px;
  padding: var(--space-2);
  background-color: var(--color-primary-green);
  border: 1px solid var(--tint-white-16);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  z-index: 1;
}

.topbar__user:hover .topbar__user-menu,
.topbar__user:focus-within .topbar__user-menu {
  display: block;
}

/* Bridges the gap between the avatar and the menu, so crossing it with the
   pointer does not close what you are reaching for. */
.topbar__user:hover::after {
  content: "";
  position: absolute;
  top: 100%;
  right: 0;
  width: 100%;
  height: var(--space-2);
}

.topbar__user-identity {
  padding: var(--space-2) var(--space-3) var(--space-3);
  margin-bottom: var(--space-2);
  border-bottom: 1px solid var(--tint-white-16);
}

.topbar__user-name {
  font-family: var(--font-family-bold);
  font-weight: 600;
  font-size: var(--font-size-medium);
  color: var(--color-white);
}

.topbar__user-email {
  font-size: var(--font-size-small);
  color: rgba(255, 255, 255, 0.7);
  overflow-wrap: anywhere;
}

.topbar__user-menu-link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  font-size: var(--font-size-medium);
  color: var(--color-white);
  text-decoration: none;
  border-radius: var(--radius-sm);
  transition: background-color var(--transition-base);
}

.topbar__user-menu-link:hover {
  background-color: var(--tint-white-16);
}

/* The tenant switcher: the tenant this is, then a form per other tenant. The
   buttons wear the link style, so they need the button's own chrome taken off. */
.topbar__user-tenants {
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-2);
  border-bottom: 1px solid var(--tint-white-16);
}

.topbar__user-tenant-current {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-family-bold);
  font-weight: 600;
  font-size: var(--font-size-medium);
  color: var(--color-white);
}

.topbar__user-menu-form {
  margin: 0;
}

button.topbar__user-menu-link {
  font-family: inherit;
  text-align: left;
  background: none;
  border: 0;
  cursor: pointer;
}

.topbar__user-menu-icon {
  flex-shrink: 0;
  color: var(--color-white);
}


/* ===== components/under_construction.css ===== */
/* ==========================================================================
   Under Construction placeholder
   ========================================================================== */
.under-construction {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: var(--space-10);
  background-color: var(--color-surface);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
  margin: var(--space-4) 0;
}

.under-construction__content {
  text-align: center;
}

.under-construction__icon {
  width: 48px;
  height: 48px;
  margin-bottom: var(--space-4);
  color: var(--color-text-faint);
}

.under-construction__title {
  font-size: var(--font-size-xxlarge);
  margin-bottom: var(--space-2);
  color: var(--color-primary-dark);
}

.under-construction__message {
  font-size: var(--font-size-medium);
  color: var(--color-text-muted);
}


/* ===== components/user_guides.css ===== */
/* ==========================================================================
   User Guides — the index of modules, one module's page, and the sign-off quiz
   at the foot of it.

   The index is a card grid grouped the way the rail is grouped. A module page
   is the firm and EOS records' arrangement — a nav down the left, the page
   beside it — at the same measurements, with its own classes so a change to a
   record's tabs does not restyle a page about how to use them. The prose is
   set larger and on a narrower measure than the rest of the application,
   because these are pages somebody has to actually read (see legal.css, which
   makes the same call for the same reason).
   ========================================================================== */

/* --- Index header: title on the left, the reader's progress on the right --- */
.guides-header {
  align-items: flex-start;
}

.guides-progress {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-2);
  flex-shrink: 0;
  min-width: 260px;
}

.guides-progress__role {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.guides-progress__role-label {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
}

/* The same shape as the EOS goal bar: a track, a fill, and the number spelled
   out beside it so nobody has to estimate a length. */
.guides-progress__meter {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
}

.guides-progress__track {
  flex: 1 1 auto;
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--tint-navy-10);
  overflow: hidden;
}

.guides-progress__fill {
  height: 100%;
  border-radius: var(--radius-full);
  background: var(--color-primary-green);
  transition: width var(--transition-slow);
}

.guides-progress__value {
  flex: 0 0 auto;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* --- Index body: groups of cards --------------------------------------- */
.guides {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  max-width: 1200px;
}

.guides__group-title {
  margin: 0 0 var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
}

.guides__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--space-4);
}

/* --- One module's card ---------------------------------------------------- */
.guide-card {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--transition-base), box-shadow var(--transition-base),
    transform var(--transition-fast);
}

.guide-card:hover {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.guide-card:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* A signed-off module wears a green rule down its edge, the way a firm card
   wears its status. */
.guide-card--complete {
  box-shadow: inset 4px 0 0 var(--color-primary-green), var(--shadow-xs);
}

.guide-card--complete:hover {
  box-shadow: inset 4px 0 0 var(--color-primary-green), var(--shadow-md);
}

.guide-card__icon,
.guide__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-md);
  background: var(--tint-green-16);
  color: var(--color-primary-dark);
}

.guide-card__icon svg,
.guide__icon svg {
  width: 24px;
  height: 24px;
}

.guide-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  flex: 1 1 auto;
  min-width: 0;
}

.guide-card__title {
  color: var(--color-primary-dark);
  font-size: var(--font-size-large);
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.guide-card__summary {
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  line-height: 1.5;
}

.guide-card__meta {
  margin-top: var(--space-1);
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
}

.guide-card__status {
  flex-shrink: 0;
}

/* --- A module's page: nav down the left, the guide beside it -------------- */
.guide-show {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: var(--space-8);
  align-items: start;
}

.guide-show__nav {
  position: sticky;
  top: 0;
  min-width: 0;
}

.guide-subnav {
  padding: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.guide-subnav__heading {
  margin: 0 0 var(--space-2);
  padding: var(--space-1) var(--space-3);
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
}

.guide-subnav__list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
  /* Fifteen modules is taller than a short window; the list scrolls itself so
     the way back out stays in view. */
  max-height: calc(100vh - var(--topbar-height) - var(--app-tabs-height) - 220px);
  overflow-y: auto;
}

.guide-subnav__link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  font-weight: 500;
  text-decoration: none;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.guide-subnav__link:hover {
  background: var(--tint-navy-04);
  color: var(--color-primary-dark);
}

.guide-subnav__link:hover .guide-subnav__icon {
  color: var(--color-primary-dark);
}

.guide-subnav__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  background: var(--tint-navy-06);
  color: var(--color-text-muted);
  transition: background var(--transition-fast), color var(--transition-fast);
}

.guide-subnav__icon svg {
  width: 16px;
  height: 16px;
}

/* Wraps rather than truncates, as the firm subnav's labels do: a module's
   title is the one thing the row has to say. */
.guide-subnav__label {
  flex: 1 1 auto;
  min-width: 0;
  line-height: 1.3;
}

.guide-subnav__link--active {
  background: var(--tint-green-16);
  color: var(--color-primary-dark);
  font-weight: 600;
}

.guide-subnav__link--active .guide-subnav__icon {
  background: var(--color-primary-green);
  color: var(--color-white);
}

.guide-subnav__tick {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  border-radius: var(--radius-full);
  background: var(--tint-green-28);
  color: var(--color-success-dark);
}

.guide-subnav__footer {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-border);
}

/* --- The guide itself ----------------------------------------------------- */
.guide {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
  max-width: 820px;
  padding-bottom: var(--space-8);
}

.guide__intro {
  display: flex;
  align-items: flex-start;
  gap: var(--space-5);
  padding: var(--space-6);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}

.guide__heading {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.guide__eyebrow {
  margin: 0;
  color: var(--color-text-faint);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
}

.guide__title {
  margin: 0;
  color: var(--color-primary-dark);
  font-size: var(--font-size-xxlarge);
  font-weight: 600;
  line-height: 1.2;
}

.guide__lede {
  margin: 0;
  color: var(--color-text);
  font-size: var(--font-size-large);
  line-height: 1.6;
}

.guide__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.guide__meta-complete {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--color-success-dark);
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.guide__meta-icon {
  color: var(--color-success-dark);
}

/* "In this guide": the section titles as jump links. */
.guide__contents {
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.guide__contents-title {
  margin: 0 0 var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
}

.guide__contents-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--space-1) var(--space-5);
  margin: 0;
  padding-left: var(--space-5);
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  line-height: 1.7;
}

.guide__contents-link {
  color: var(--color-primary-dark);
  font-weight: 500;
  text-decoration: none;
}

.guide__contents-link:hover {
  text-decoration: underline;
}

/* --- One section: numbered heading, then its steps ----------------------- */
.guide-section {
  padding: var(--space-6);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  /* Room under the pinned header when a contents link lands here. */
  scroll-margin-top: var(--space-4);
}

.guide-section__header {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.guide-section__number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-full);
  background: var(--color-primary-dark);
  color: var(--color-white);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.guide-section__heading {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.guide-section__title {
  margin: 0;
  color: var(--color-primary-dark);
  font-size: var(--font-size-xlarge);
  font-weight: 600;
  line-height: 1.3;
}

.guide-section__intro {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  line-height: 1.6;
}

.guide-steps {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  margin: 0;
  padding: 0;
  list-style: none;
}

.guide-step {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
}

/* A callout sits in the step column, indented to the steps' text, so it reads
   as a remark on the step above it rather than a step of its own. */
.guide-steps__aside {
  padding-left: calc(28px + var(--space-4));
}

.guide-step__marker {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  margin-top: 1px;
  border-radius: var(--radius-full);
  background: var(--tint-green-16);
  border: 1.5px solid var(--tint-green-28);
  color: var(--color-primary-dark);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.guide-step__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
  flex: 1 1 auto;
}

.guide-step__title {
  margin: 0;
  color: var(--color-text);
  font-size: var(--font-size-large);
  font-weight: 600;
  line-height: 1.4;
}

/* The prose. Larger and looser than a table, because it is read rather than
   scanned. */
.guide-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.guide-text__paragraph {
  margin: 0;
  color: var(--color-text);
  font-size: var(--font-size-medium);
  line-height: 1.7;
}

/* A label as it appears on screen — a button, a tab, a heading — set apart
   from the sentence around it so the reader knows what to look for. */
.guide-ui {
  display: inline;
  padding: 1px 6px;
  border-radius: var(--radius-sm);
  background: var(--tint-navy-06);
  border: 1px solid var(--tint-navy-10);
  color: var(--color-primary-dark);
  font-family: var(--font-family-bold);
  font-weight: 600;
  font-size: 0.95em;
  white-space: nowrap;
}

.guide-step__where {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-2);
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.guide-step__where-icon {
  flex-shrink: 0;
  color: var(--color-primary-green);
}

.guide-step__where-label {
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.guide-step__where-crumb {
  padding: 1px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  color: var(--color-text);
}

.guide-step__where-separator {
  color: var(--color-text-faint);
}

/* --- Callouts -------------------------------------------------------------- */
.guide-callout {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  border-left-width: 4px;
  background: var(--color-surface-sunken);
}

.guide-callout__icon {
  display: inline-flex;
  flex-shrink: 0;
  margin-top: 3px;
  color: var(--color-text-muted);
}

.guide-callout__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.guide-callout__label {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  font-family: var(--font-family-bold);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: uppercase;
}

.guide-callout .guide-text__paragraph {
  font-size: var(--font-size-medium);
  line-height: 1.6;
}

.guide-callout--tip {
  border-left-color: var(--color-primary-green);
  background: var(--tint-green-10);
}

.guide-callout--tip .guide-callout__icon,
.guide-callout--tip .guide-callout__label {
  color: #1e8e63;
}

.guide-callout--note {
  border-left-color: #2980b9;
  background: rgba(52, 152, 219, 0.08);
}

.guide-callout--note .guide-callout__icon,
.guide-callout--note .guide-callout__label {
  color: #2980b9;
}

.guide-callout--warning {
  border-left-color: var(--color-warning);
  background: rgba(245, 158, 11, 0.09);
}

.guide-callout--warning .guide-callout__icon,
.guide-callout--warning .guide-callout__label {
  color: #b45309;
}

.guide-callout--role {
  border-left-color: var(--color-primary-dark);
  background: var(--tint-navy-04);
}

.guide-callout--role .guide-callout__icon,
.guide-callout--role .guide-callout__label {
  color: var(--color-primary-dark);
}

/* --- The sign-off quiz ----------------------------------------------------- */
.guide-quiz-frame {
  display: block;
}

.guide-quiz {
  padding: var(--space-6);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  scroll-margin-top: var(--space-4);
}

.guide-quiz__header {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.guide-quiz__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-full);
  background: var(--color-primary-green);
  color: var(--color-white);
}

.guide-quiz__heading {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.guide-quiz__title {
  margin: 0;
  color: var(--color-primary-dark);
  font-size: var(--font-size-xlarge);
  font-weight: 600;
}

.guide-quiz__blurb {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-medium);
  line-height: 1.6;
}

/* What came of the last attempt, or the standing sign-off. */
.guide-quiz__outcome {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  border: 1px solid transparent;
}

.guide-quiz__outcome-icon {
  flex-shrink: 0;
  margin-top: 1px;
}

.guide-quiz__outcome-title {
  margin: 0 0 2px;
  font-size: var(--font-size-large);
  font-family: var(--font-family-bold);
  font-weight: 600;
}

.guide-quiz__outcome-text {
  margin: 0;
  font-size: var(--font-size-medium);
  line-height: 1.6;
}

.guide-quiz__outcome--pass {
  background: var(--tint-green-16);
  border-color: var(--tint-green-28);
  color: var(--color-success-dark);
}

.guide-quiz__outcome--pass .guide-quiz__outcome-text {
  color: var(--color-text);
}

.guide-quiz__outcome--fail {
  background: rgba(245, 158, 11, 0.1);
  border-color: rgba(245, 158, 11, 0.3);
  color: #b45309;
}

.guide-quiz__outcome--fail .guide-quiz__outcome-text {
  color: var(--color-text);
}

.guide-quiz__questions {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.guide-question {
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunken);
  transition: border-color var(--transition-base), background var(--transition-base);
}

.guide-question--wrong {
  border-color: rgba(245, 158, 11, 0.5);
  background: rgba(245, 158, 11, 0.06);
}

.guide-question--right {
  border-color: var(--tint-green-28);
  background: var(--tint-green-10);
}

.guide-question__fieldset {
  border: 0;
  margin: 0;
  padding: 0;
  min-width: 0;
}

.guide-question__prompt {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  width: 100%;
  margin-bottom: var(--space-3);
  padding: 0;
  color: var(--color-text);
  font-size: var(--font-size-medium);
  font-family: var(--font-family-bold);
  font-weight: 600;
  line-height: 1.5;
}

.guide-question__number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-full);
  background: var(--color-primary-dark);
  color: var(--color-white);
  font-size: var(--font-size-small);
}

.guide-question__prompt-text {
  flex: 1 1 auto;
  min-width: 0;
}

.guide-question__verdict {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  font-size: var(--font-size-small);
  white-space: nowrap;
}

.guide-question__verdict--wrong {
  background: rgba(245, 158, 11, 0.16);
  color: #b45309;
}

.guide-question__verdict--right {
  background: var(--tint-green-28);
  color: var(--color-success-dark);
}

.guide-question__options {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-left: calc(24px + var(--space-3));
}

/* An option is one big target: the radio is hidden and drawn again as a ring,
   so the whole row answers the click and the chosen one is plain to see. */
.guide-option {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--font-size-medium);
  line-height: 1.5;
  cursor: pointer;
  transition: border-color var(--transition-fast), background var(--transition-fast);
}

.guide-option:hover {
  border-color: var(--color-border-strong);
  background: var(--tint-navy-04);
}

.guide-option__input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.guide-option__control {
  display: inline-block;
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 2px;
  border-radius: var(--radius-full);
  border: 2px solid var(--color-border-strong);
  background: var(--color-surface);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.guide-option__input:checked + .guide-option__control {
  border-color: var(--color-primary-green);
  box-shadow: inset 0 0 0 4px var(--color-surface), inset 0 0 0 10px var(--color-primary-green);
}

.guide-option:has(.guide-option__input:checked) {
  border-color: var(--color-primary-green);
  background: var(--tint-green-10);
}

.guide-option__input:focus-visible + .guide-option__control {
  box-shadow: var(--focus-ring);
}

.guide-option__text {
  min-width: 0;
}

.guide-question__explanation {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin: var(--space-3) 0 0;
  padding: var(--space-2) var(--space-3);
  padding-left: calc(24px + var(--space-3));
  color: var(--color-text);
  font-size: var(--font-size-medium);
  line-height: 1.6;
}

.guide-question__explanation-icon {
  flex-shrink: 0;
  margin-top: 4px;
  color: #b45309;
}

.guide-quiz__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

.guide-quiz__hint {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

/* --- Narrow screens -------------------------------------------------------- */
@media (max-width: 900px) {
  .guides-header {
    flex-direction: column;
    align-items: stretch;
  }

  .guides-progress {
    align-items: flex-start;
    min-width: 0;
  }

  .guide-show {
    grid-template-columns: 1fr;
    gap: var(--space-5);
  }

  .guide-show__nav {
    position: static;
  }

  .guide-subnav__list {
    max-height: none;
  }

  .guide__intro {
    flex-direction: column;
  }

  .guide-steps__aside {
    padding-left: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .guide-card,
  .guides-progress__fill {
    transition: none;
  }

  .guide-card:hover {
    transform: none;
  }
}
