/* ==========================================================================
   Base layer — reset, typography, app shell, sidebar, topbar
   ========================================================================== */

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

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--text-md);
  line-height: var(--leading-normal);
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background var(--duration) var(--ease), color var(--duration) var(--ease);
}

h1, h2, h3, h4 { margin: 0; line-height: var(--leading-tight); font-weight: var(--weight-semibold); }
h1 { font-size: var(--text-xl); letter-spacing: -0.015em; }
h2 { font-size: var(--text-lg); letter-spacing: -0.01em; }
h3 { font-size: var(--text-base); }
p  { margin: 0; }

a { color: var(--text-brand); text-decoration: none; }
a:hover { text-decoration: underline; }

button { font: inherit; color: inherit; cursor: pointer; }

/* Visible, consistent focus for keyboard users only. */
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
:focus:not(:focus-visible) { outline: none; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Skip link for keyboard and screen-reader users. */
.skip-link {
  position: absolute; left: var(--space-4); top: -60px;
  z-index: 100; padding: var(--space-2) var(--space-4);
  background: var(--brand); color: #fff; border-radius: var(--radius);
  font-weight: var(--weight-semibold); transition: top var(--duration) var(--ease);
}
.skip-link:focus { top: var(--space-4); text-decoration: none; }

/* Scrollbars that match the theme. */
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: var(--radius-full); border: 3px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: var(--grey-400); background-clip: content-box; }

/* ==========================================================================
   App shell
   ========================================================================== */

.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  grid-template-rows: 100vh;
  transition: grid-template-columns var(--duration) var(--ease);
}
.app[data-collapsed="true"] { grid-template-columns: var(--sidebar-w-collapsed) 1fr; }

/* --- Sidebar --- */

.sidebar {
  grid-row: 1;
  display: flex; flex-direction: column;
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  overflow: hidden;
  z-index: var(--z-sidebar);
}

.sidebar__brand {
  display: flex; align-items: center; gap: var(--space-3);
  height: var(--topbar-h); padding: 0 var(--space-4);
  border-bottom: 1px solid var(--border); flex-shrink: 0;
}
.sidebar__logo { width: 32px; height: 32px; flex-shrink: 0; border-radius: var(--radius-sm); }
.sidebar__wordmark { display: flex; flex-direction: column; min-width: 0; }
.sidebar__name {
  font-size: var(--text-md); font-weight: var(--weight-bold);
  letter-spacing: -0.01em; white-space: nowrap;
}
.sidebar__tag {
  font-size: var(--text-2xs); color: var(--text-muted);
  text-transform: uppercase; letter-spacing: var(--tracking-caps); white-space: nowrap;
}

.sidebar__nav { flex: 1; overflow-y: auto; padding: var(--space-3) var(--space-2); }

.nav-group { margin-bottom: var(--space-5); }
.nav-group__label {
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
  text-transform: uppercase; letter-spacing: var(--tracking-caps);
  color: var(--text-muted); padding: 0 var(--space-3) var(--space-2);
  white-space: nowrap;
}

.nav-item {
  display: flex; align-items: center; gap: var(--space-3);
  width: 100%; padding: var(--space-2) var(--space-3);
  margin-bottom: 2px; border: 0; border-radius: var(--radius);
  background: transparent; color: var(--text-secondary);
  font-size: var(--text-md); font-weight: var(--weight-medium);
  text-align: left; white-space: nowrap;
  transition: background var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.nav-item:hover { background: var(--surface-hover); color: var(--text); }
.nav-item[aria-current="page"] {
  background: var(--brand-soft); color: var(--text-brand); font-weight: var(--weight-semibold);
}
.nav-item[aria-current="page"] .nav-item__icon { color: var(--brand); }

.nav-item__icon { width: 18px; height: 18px; flex-shrink: 0; color: var(--text-muted); }
.nav-item__label { flex: 1; overflow: hidden; text-overflow: ellipsis; }
.nav-item__badge {
  min-width: 20px; padding: 1px 6px; border-radius: var(--radius-full);
  background: var(--tone-danger-bg); color: var(--tone-danger-fg);
  font-size: var(--text-2xs); font-weight: var(--weight-bold); text-align: center;
}

.sidebar__footer { padding: var(--space-3) var(--space-2); border-top: 1px solid var(--border); flex-shrink: 0; }

/* Collapsed state: icons only, labels hidden but still in the a11y tree. */
.app[data-collapsed="true"] .sidebar__wordmark,
.app[data-collapsed="true"] .nav-group__label,
.app[data-collapsed="true"] .nav-item__label,
.app[data-collapsed="true"] .nav-item__badge,
.app[data-collapsed="true"] .profile__meta { display: none; }
.app[data-collapsed="true"] .nav-item { justify-content: center; padding: var(--space-3) 0; }
.app[data-collapsed="true"] .sidebar__brand { justify-content: center; padding: 0; }

/* --- Main column --- */

.main {
  grid-row: 1; display: flex; flex-direction: column;
  min-width: 0; overflow: hidden;
}

.topbar {
  display: flex; align-items: center; gap: var(--space-3);
  height: var(--topbar-h); padding: 0 var(--space-5);
  background: var(--bg-elevated); border-bottom: 1px solid var(--border);
  flex-shrink: 0; z-index: var(--z-topbar);
}

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex-shrink: 0;
  border: 1px solid transparent; border-radius: var(--radius);
  background: transparent; color: var(--text-secondary);
  transition: background var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.icon-btn:hover { background: var(--surface-hover); color: var(--text); }
.icon-btn svg { width: 18px; height: 18px; }
.icon-btn--badged { position: relative; }
.icon-btn--badged[data-count]:not([data-count="0"])::after {
  content: attr(data-count);
  position: absolute; top: 1px; right: 1px;
  min-width: 16px; padding: 0 4px; border-radius: var(--radius-full);
  background: var(--red-500); color: #fff;
  font-size: 10px; font-weight: var(--weight-bold); line-height: 16px; text-align: center;
}

/* --- Breadcrumbs --- */

.breadcrumbs { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.breadcrumbs__item { font-size: var(--text-md); color: var(--text-muted); white-space: nowrap; }
.breadcrumbs__item:last-child { color: var(--text); font-weight: var(--weight-semibold); }
.breadcrumbs__sep { color: var(--border-strong); }

/* --- Global search --- */

.search { position: relative; flex: 1; max-width: 460px; margin-left: auto; }
.search__input {
  width: 100%; height: 36px;
  padding: 0 var(--space-3) 0 36px;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface-2); color: var(--text);
  font-size: var(--text-md);
  transition: border-color var(--duration-fast) var(--ease), box-shadow var(--duration-fast) var(--ease);
}
.search__input::placeholder { color: var(--text-muted); }
.search__input:focus {
  outline: none; border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-soft); background: var(--surface);
}
.search__icon {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; color: var(--text-muted); pointer-events: none;
}
.search__results {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0;
  max-height: 420px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
  z-index: var(--z-dropdown); padding: var(--space-2);
}
.search__results[hidden] { display: none; }
/*
 * The same list, in flow rather than floating.
 *
 * .search__results above is absolutely positioned, which is right when it
 * hangs beneath a search box on a page — and wrong inside a dialog, where
 * there is no positioned wrapper to hang from. It then anchors to the modal
 * and draws itself below the whole thing, off the bottom of the panel: the
 * results arrive, and nobody can see them. That is what "filtering by typing
 * isn't working" was.
 *
 * catalog.js had already hit this and patched around it with an inline
 * position:static of its own, while billing, chronic and documents stayed
 * broken. One class, so the next dialog gets it right by default.
 */
.search__results--inline {
  position: static;
  max-height: 260px;
  box-shadow: none;
  margin-top: var(--space-2);
}
.search__results--inline .search__result { cursor: pointer; }
.search__result.is-selected {
  background: var(--brand-soft);
  box-shadow: inset 2px 0 0 var(--brand);
}
.search__result {
  display: flex; align-items: center; gap: var(--space-3);
  width: 100%; padding: var(--space-2) var(--space-3);
  border: 0; border-radius: var(--radius); background: transparent; text-align: left;
}
.search__result:hover, .search__result:focus-visible { background: var(--surface-hover); }
.search__result[disabled] { opacity: .75; cursor: default; }
.search__result[disabled]:hover { background: transparent; }
.search__result-name { font-size: var(--text-md); font-weight: var(--weight-medium); }
.search__result-meta {
  font-size: var(--text-xs); color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Search spans several tables, so results are banded by what they are —
   without the heading a price-list entry and a patient look identical. */
.search__group {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-3) var(--space-3) var(--space-1);
  font-size: var(--text-xs); font-weight: var(--weight-semibold);
  letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted);
}
.search__group:first-child { padding-top: var(--space-1); }
.search__result-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; flex: 0 0 32px; border-radius: var(--radius);
  background: var(--surface-hover); color: var(--text-muted);
}

/* --- Content area --- */

.content {
  flex: 1; overflow-y: auto;
  padding: var(--space-6);
  scroll-behavior: smooth;
}
.content__inner { max-width: var(--content-max); margin: 0 auto; }

.view-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-5);
}
.view-title { font-size: var(--text-2xl); font-weight: var(--weight-bold); letter-spacing: -0.02em; }
.view-subtitle { font-size: var(--text-md); color: var(--text-secondary); margin-top: var(--space-1); }
.view-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }

/* Views fade in so navigation feels intentional rather than abrupt. */
.view { animation: view-in var(--duration) var(--ease-out); }
@keyframes view-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* ==========================================================================
   Responsive — sidebar becomes an overlay drawer on narrow screens
   ========================================================================== */

@media (max-width: 1024px) {
  .content { padding: var(--space-4); }
  .search { max-width: 260px; }
}

@media (max-width: 860px) {
  .app, .app[data-collapsed="true"] { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed; inset: 0 auto 0 0;
    width: var(--sidebar-w); transform: translateX(-100%);
    transition: transform var(--duration) var(--ease); box-shadow: var(--shadow-lg);
  }
  .app[data-drawer="open"] .sidebar { transform: none; }
  .app[data-drawer="open"]::after {
    content: ''; position: fixed; inset: 0;
    background: var(--overlay); z-index: calc(var(--z-sidebar) - 1);
  }
  .app[data-collapsed="true"] .sidebar__wordmark,
  .app[data-collapsed="true"] .nav-item__label,
  .app[data-collapsed="true"] .nav-group__label { display: revert; }
  .app[data-collapsed="true"] .nav-item { justify-content: flex-start; padding: var(--space-2) var(--space-3); }
  .breadcrumbs { display: none; }
}

@media (max-width: 560px) {
  .topbar { padding: 0 var(--space-3); }
  .search { max-width: none; }
  .view-title { font-size: var(--text-xl); }
}

/* ============================================================
   PRINT
   ============================================================

   Only one page ever came out, and the rest of the table was simply gone.

   The cause was not the table. `.app` is laid out as a grid with
   `grid-template-rows: 100vh` — the application is exactly one viewport tall,
   which is right on screen and fatal on paper, because one viewport is one
   page. Everything below the fold fell outside the grid row and was discarded.
   The old print block overrode grid-template-COLUMNS and never touched the
   rows, so the fault survived every previous look at this file.

   Three things clip a printed page, and all three are undone here:
     1. a fixed height on an ancestor (100vh)
     2. overflow other than `visible` on an ancestor (.table-wrap scrolls)
     3. a grid or flex context that cannot flow past its declared track

   The layout is switched to plain block flow for print. Grid does not
   paginate; blocks do.
*/
@media print {
  @page { size: letter; margin: 12mm; }

  .sidebar, .topbar, .view-actions, .toast-stack,
  .pagination, .search, .segmented { display: none !important; }

  /* Block flow, no fixed height, nothing clipped. */
  .app {
    display: block !important;
    grid-template-columns: none !important;
    grid-template-rows: none !important;
    height: auto !important;
    overflow: visible !important;
  }
  .main, .content, .content__inner, .view, .card, .card__body {
    display: block !important;
    overflow: visible !important;
    height: auto !important;
    max-height: none !important;
    padding: 0;
  }
  .content__inner { max-width: none !important; }

  /* A table that scrolls on screen must not scroll on paper. */
  .table-wrap {
    overflow: visible !important;
    max-width: none !important;
    max-height: none !important;
  }

  /*
     Column headings repeat on every page. Without this, page two of a long
     financial table is a wall of unlabelled numbers — which is worse than a
     second page, because it looks like data rather than reading as one.
  */
  thead { display: table-header-group; }
  tfoot { display: table-footer-group; }

  /* Nothing is split down the middle. */
  tr, .kpi, .chair { break-inside: avoid; page-break-inside: avoid; }
  .card { break-inside: auto; }          /* a long card MAY span pages */
  h1, h2, h3, .card__title { break-after: avoid; }

  /*
     Denser, but still readable. 9pt with tight padding fits roughly twice the
     rows of the screen layout — fewer sheets of paper without reaching the size
     where a column of figures stops being checkable.
  */
  .table { font-size: 9pt; }
  .table th, .table td { padding: 3px 6px !important; }
  .view-title { font-size: 14pt; }

  /* Ink. A printed page is read on white. */
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .card { border: 1px solid #ccc !important; box-shadow: none !important; }

  /*
     Text fitting is a SCREEN behaviour: it shrinks text to fit a box that has
     a width on screen. On paper the box is a different size, and a figure
     already shrunk to 62% would print smaller again for no reason. Reset it.
  */
  [data-fit] { font-size: inherit !important; }
  .is-clipped {
    overflow: visible !important;
    text-overflow: clip !important;
    white-space: normal !important;
  }
}

/* The clock sits in the top bar: first thing on arriving, last on leaving. */
.clock-widget { display: inline-flex; align-items: center; }
.clock-widget__done {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-1) var(--space-3); border-radius: var(--radius);
  background: var(--tone-ok-bg); color: var(--tone-ok-fg);
  font-size: var(--text-xs); font-weight: var(--weight-medium);
}

/* ============================================================
   Focus, motion and density — 2.23
   ============================================================ */

/* One focus treatment everywhere. A visible ring on keyboard focus only, so
   the interface is fully navigable without a mouse and does not look
   permanently outlined when using one. */
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
:focus:not(:focus-visible) { outline: none; }

/* Anything that scrolls must be reachable by keyboard, which means it needs a
   tab stop and therefore a focus ring of its own. */
.table-wrap:focus-visible, .palette__list:focus-visible { outline-offset: -2px; }

/* Cards and rows settle rather than snap. */
.card {
  transition: box-shadow var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease);
}

/* Content arrives instead of appearing. Applied to the view root only, so a
   tab change reads as a change and an in-place update does not flicker. */
.view { animation: view-in var(--duration) var(--ease-out); }
@keyframes view-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}

/* Numbers in a column should line up. */
.kpi__value, .table__num, .money-cell__value { font-variant-numeric: tabular-nums; }

/* Respect the system setting. This is not decoration: motion sensitivity is an
   accessibility requirement, and a clinical tool is used by people who cannot
   simply close the tab. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Large monitors: stop lines of text growing past a readable measure while
   still using the width for tables and boards. */
@media (min-width: 1800px) {
  .content__inner { max-width: 1680px; margin-inline: auto; }
}

/* Tablets and the narrow extension window. */
@media (max-width: 640px) {
  .grid--kpi { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
  .quick { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .view-header { flex-direction: column; align-items: flex-start; gap: var(--space-3); }
  .timeline__item { grid-template-columns: 44px 12px 1fr; }
  .timeline__item::before { left: 52px; }
}

/* High-contrast users get real borders rather than subtle ones. */
@media (prefers-contrast: more) {
  :root { --border: var(--grey-400); --border-strong: var(--grey-600); }
  .card, .kpi, .quick__item { border-width: 1px; }
}
