/* The signed-in shell: the sidebar, the sign-in screen, and the components
   the account and admin pages need. Layered on top of app.css rather than
   folded into it — app.css is the tool's own stylesheet and every screen in
   the product loads it, so keeping the chrome separate means a change to the
   shell cannot reflow a protocol page by accident.

   Tokens come from app.css (:root), including its dark scheme, so nothing
   here defines a colour twice. */

:root {
  --rail: 248px;
  --rail-collapsed: 64px;
}

/* --- Layout -------------------------------------------------------------- */

body.app.has-sidebar {
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr);
  min-height: 100vh;
  transition: grid-template-columns 180ms var(--ease);
}

body.app.has-sidebar.nav-collapsed { grid-template-columns: var(--rail-collapsed) minmax(0, 1fr); }

.app-main { min-width: 0; display: flex; flex-direction: column; }

/* app.css centres `main` in an 880px column, which is right for a page with
   the whole window to itself and too narrow once a rail takes 248px of it.
   The tables on the People page and the OPD list both want the room. */
body.app.has-sidebar main {
  max-width: 1200px;
  width: 100%;
  padding: 1.75rem 2rem 4rem;
}

/* The bar is a strip only while something is in it — on most screens the
   sidebar took the brand and the account, so it should not reserve a stripe
   of height for itself. */
body.app.has-sidebar .topbar:not(:has(nav > *)) {
  min-height: 0;
  padding: 0;
  border-bottom: none;
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* --- The rail ------------------------------------------------------------ */

.sidebar {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--rail-bg);
  border-right: 1px solid var(--border);
  overflow: hidden;
}

.sidebar-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.9rem 0.6rem 0.75rem 0.9rem;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-width: 0;
  color: var(--text);
  text-decoration: none;
}

.sidebar-brand:hover { text-decoration: none; }

.brand-mark {
  flex: none;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: linear-gradient(145deg, color-mix(in srgb, var(--accent) 85%, white), var(--accent-hover));
  color: #fff;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  box-shadow: var(--shadow-xs), inset 0 1px 0 rgb(255 255 255 / 0.2);
}

.brand-text { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.brand-text strong { font-size: 0.95rem; font-weight: 650; letter-spacing: -0.01em; }

/* The product's line under its name, then the hospital's under that. */
.brand-tagline {
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--accent-text);
  letter-spacing: 0.01em;
}

/* The hospital's own name, on its own line under the brand. Wrapped to two
   lines rather than cut: "Government Medical College Hospital, Thrissur" is
   an ordinary answer here, and "Government Medical Colle…" is not a name. */
.sidebar-site {
  display: flex;
  align-items: flex-start;
  gap: 0.45rem;
  margin: -0.25rem 0.75rem 0.5rem 0.9rem;
  padding: 0.4rem 0.6rem;
  border-radius: 6px;
  background: color-mix(in srgb, var(--text) 4%, transparent);
  font-size: 0.74rem;
  font-weight: 500;
  line-height: 1.35;
  color: var(--text-2);
}

.sidebar-site .icon { flex: none; width: 1rem; height: 1rem; margin-top: 0.05rem; color: var(--muted); }

.sidebar-site span {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-width: 0;
}

.nav-toggle, .nav-open {
  flex: none;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  min-height: 0;
  margin-left: auto;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 7px;
  background: none;
  box-shadow: none;
  color: var(--muted);
  cursor: pointer;
}

.nav-toggle:hover, .nav-open:hover { background: var(--surface-3); color: var(--text); }

.nav-toggle svg, .nav-open svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.nav-open { display: none; }

.sidebar-nav {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0.25rem 0.6rem 1rem;
}

.nav-group + .nav-group { margin-top: 1.1rem; }

.nav-group-label {
  margin: 0 0 0.3rem 0.65rem;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--faint);
}

.nav-item {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  margin: 1px 0;
  padding: 0.45rem 0.65rem;
  border-radius: 8px;
  color: var(--text-2);
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 500;
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease);
}

.nav-item:hover {
  background: color-mix(in srgb, var(--text) 6%, transparent);
  color: var(--text);
  text-decoration: none;
}

/* The one that is on: lifted onto the surface, with the accent on the icon
   and the label. Reads as a selected sheet, not a highlighted word. */
.nav-item.is-active {
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-xs), 0 0 0 1px var(--border);
}

.nav-item.is-active .nav-icon { color: var(--accent); }
.nav-item.is-active .nav-label { font-weight: 600; }

.nav-icon {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 2px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--muted);
}

.nav-item:hover .nav-icon { color: var(--text-2); }

.nav-label { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }

/* The one-line hint is the difference between a nav and a list of nouns — a
   doctor who has never seen "Questions" should not have to press it to learn
   what it is. Two lines at most; gone when the rail is collapsed, where the
   icon and the title attribute carry it instead. */
.nav-label small {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: 1px;
  font-size: 0.72rem;
  font-weight: 400;
  line-height: 1.35;
  color: var(--muted);
}

.nav-item.is-active .nav-label small { color: var(--muted); }

/* --- The account block --------------------------------------------------- */

.sidebar-foot { padding: 0.6rem; border-top: 1px solid var(--border); }

/* The panel opens UPWARD: it is anchored to the bottom of the rail, so
   opening downward ran "Sign out" off the bottom of the window.
   `column-reverse` puts the panel above the summary visually while leaving
   the DOM in the order <details> requires. */
.account-menu { display: flex; flex-direction: column-reverse; }

.account-menu summary {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0.5rem;
  border-radius: 8px;
  cursor: pointer;
  list-style: none;
  transition: background-color var(--fast) var(--ease);
}

.account-menu summary::-webkit-details-marker { display: none; }
.account-menu summary:hover,
.account-menu[open] summary { background: color-mix(in srgb, var(--text) 6%, transparent); }

.avatar {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: linear-gradient(145deg, var(--accent-soft-2), var(--accent-soft));
  color: var(--accent-text);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 25%, transparent);
}

.account-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.account-text strong {
  font-size: 0.86rem;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.account-text small { font-size: 0.72rem; color: var(--muted); }

.account-menu .chev {
  width: 14px;
  height: 14px;
  margin-left: auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--faint);
  transform: rotate(180deg);
  transition: transform 0.15s var(--ease);
}

.account-menu[open] .chev { transform: none; }

.account-panel {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.15rem;
  margin: 0 0 0.35rem;
  padding: 0.5rem;
  font-size: 0.86rem;
  background: var(--raised);
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  box-shadow: var(--shadow-md);
}

.account-username {
  margin: 0 0 0.25rem;
  padding: 0.25rem 0.5rem 0;
  color: var(--muted);
  font-size: 0.75rem;
  font-family: var(--mono);
}

/* Appearance. A segmented control rather than a switch, because there are
   three answers and "Auto" is the one most people should be on. The pressed
   state comes off `data-theme-choice`, which the inline head script has
   already stamped — so it is correct on the first paint. */
.theme-choice {
  display: flex;
  width: 100%;
  margin: 0.25rem 0 0.35rem;
  padding: 3px;
  border-radius: 8px;
  background-color: var(--surface-2);
}

.theme-choice button {
  flex: 1;
  min-height: 0;
  padding: 0.3rem 0;
  border: none;
  border-radius: 6px;
  background: none;
  box-shadow: none;
  color: var(--muted);
  font: inherit;
  font-size: 0.76rem;
  font-weight: 600;
  cursor: pointer;
}

.theme-choice button:hover { color: var(--text); background: none; }

:root[data-theme-choice="system"] .theme-choice [data-theme-set="system"],
:root[data-theme-choice="light"] .theme-choice [data-theme-set="light"],
:root[data-theme-choice="dark"] .theme-choice [data-theme-set="dark"] {
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-xs), 0 0 0 1px var(--border);
}

.account-panel a,
.account-panel button.link {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  min-height: 0;
  padding: 0.4rem 0.5rem;
  border-radius: 6px;
  color: var(--text-2);
  font-weight: 500;
  text-align: left;
  text-decoration: none;
}

.account-panel a:hover,
.account-panel button.link:hover {
  background: var(--surface-2);
  text-decoration: none;
  color: var(--text);
}

.account-panel form { margin: 0; }
.account-panel .icon { width: 1rem; height: 1rem; color: var(--muted); }
.account-panel button.link.danger .icon { color: inherit; }
.account-panel button.link.danger { color: var(--danger-text); }
.account-panel button.link.danger:hover { background: var(--danger-soft); }

/* --- Collapsed --------------------------------------------------------- */

/* Confined to the width where a collapsed rail is a thing that exists. Below
   it the sidebar is a drawer with the whole screen to play with. */
@media (min-width: 821px) {
  body.nav-collapsed .brand-text,
  body.nav-collapsed .brand-tagline,
  body.nav-collapsed .sidebar-site,
  body.nav-collapsed .nav-group-label,
  body.nav-collapsed .nav-label,
  body.nav-collapsed .account-text,
  body.nav-collapsed .account-menu .chev,
  body.nav-collapsed .account-panel { display: none; }

  /* Stacked, not side by side: at 64px the mark and the button do not fit on
     one row, and the one that overflowed was the button. */
  body.nav-collapsed .sidebar-head {
    flex-direction: column;
    gap: 0.4rem;
    padding: 0.75rem 0.5rem 0.5rem;
    justify-content: center;
  }

  body.nav-collapsed .nav-toggle { margin: 0; }
  body.nav-collapsed .nav-toggle svg { transform: rotate(180deg); }
  body.nav-collapsed .sidebar-nav { padding: 0.25rem 0.5rem 1rem; }
  body.nav-collapsed .nav-item { justify-content: center; padding: 0.6rem 0; }
  body.nav-collapsed .nav-icon { margin-top: 0; width: 20px; height: 20px; }
  body.nav-collapsed .account-menu summary { justify-content: center; padding: 0.4rem 0; }

  /* A collapsed group still needs to be separable from the next one, and the
     label that did that is gone. */
  body.nav-collapsed .nav-group + .nav-group {
    margin-top: 0.6rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--border);
  }
}

/* --- Narrow screens ------------------------------------------------------ */

/* The rail becomes a drawer rather than shrinking: a clinic's list on a
   tablet needs its whole width. */
@media (max-width: 820px) {
  body.app.has-sidebar,
  body.app.has-sidebar.nav-collapsed { grid-template-columns: minmax(0, 1fr); }

  .sidebar {
    position: fixed;
    z-index: 40;
    inset: 0 auto 0 0;
    width: var(--rail);
    transform: translateX(-100%);
    transition: transform 0.2s var(--ease);
    box-shadow: var(--shadow-lg);
  }

  body.nav-open .sidebar { transform: none; }

  .nav-open { display: grid; margin-left: 0; margin-right: auto; }
  body.app.has-sidebar .topbar,
  body.app.has-sidebar .topbar:not(:has(nav > *)) {
    min-height: 3.25rem;
    padding: 0.5rem 1rem;
    border-bottom: 1px solid var(--border);
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
  }
  body.app.has-sidebar main { padding: 1.25rem 1rem 4rem; }

  body.nav-open::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 39;
    background: rgb(8 10 14 / 0.4);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
  }
}

/* --- Sign in ------------------------------------------------------------- */

body.signin {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: 1.5rem;
  background:
    radial-gradient(60rem 40rem at 15% -10%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 70%),
    radial-gradient(40rem 30rem at 110% 110%, color-mix(in srgb, var(--accent) 8%, transparent), transparent 70%),
    var(--bg);
}

.signin-panel {
  width: min(400px, 100%);
  max-width: none;
  padding: 0;
  margin: 0;
}

.signin-brand { display: flex; align-items: center; gap: 0.85rem; margin-bottom: 0.7rem; }
.signin-brand h1 { margin: 0; font-size: 1.4rem; line-height: 1.15; }
.signin-brand .brand-mark { width: 44px; height: 44px; font-size: 1.05rem; border-radius: 13px; }

/* The tagline is the sidebar's, at this screen's scale — it sits under a
   1.4rem heading here and under a 0.95rem one there. */
.signin-brand .brand-tagline { margin: 0.1rem 0 0; font-size: 0.82rem; }

/* The hospital on its own line under the brand, as in the rail
   (`.sidebar-site`): a real name is three lines beside the mark and one under
   it. Aligned with the panel below rather than indented to the text, so the
   card, this line and the note under it share one left edge. */
.signin-site {
  display: flex;
  align-items: flex-start;
  gap: 0.45rem;
  margin: 0 0 1.1rem;
  padding: 0.45rem 0.65rem;
  border-radius: 7px;
  background: color-mix(in srgb, var(--text) 4%, transparent);
  font-size: 0.8rem;
  font-weight: 500;
  line-height: 1.35;
  color: var(--muted);
}

.signin-site .icon { flex: none; width: 1rem; height: 1rem; margin-top: 0.1rem; color: var(--muted); }
.signin-site span { min-width: 0; }

.signin-form {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-md);
}

.signin-form h2 { margin: 0 0 0.1rem; font-size: 1.1rem; }
.signin-form label { margin: 0; }
.signin-form button.primary { --h: 42px; margin-top: 0.35rem; }
.signin-form .error {
  margin: 0;
  padding: 0.55rem 0.75rem;
  border-radius: var(--radius-sm);
  background: var(--danger-soft);
}

/* Who this link is for, so the recipient can tell it is theirs before they
   type anything into it. */
.invite-who {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  margin: 0 0 0.3rem;
  padding: 0.75rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  font-size: 0.88rem;
}

.invite-who .muted { font-size: 0.8rem; }

.signin-note {
  margin: 1.1rem 0.25rem 0;
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--muted);
}

/* --- Page furniture ----------------------------------------------------- */

.page { width: 100%; }
.page.narrow { max-width: 46rem; }

label > small { display: block; margin-top: 0.3rem; font-weight: 400; font-size: 0.8rem; line-height: 1.45; }

.form-stack { display: flex; flex-direction: column; gap: 1rem; align-items: stretch; }
.form-stack label { margin: 0; }
.form-stack button { align-self: flex-start; }

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem 1.1rem;
  align-items: start;
  margin-top: 1rem;
}

.form-grid label { margin: 0; }
.form-grid button { grid-column: 1 / -1; justify-self: start; }

fieldset.departments {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
  gap: 0.55rem 1rem;
  margin: 0;
  padding: 1rem 1.1rem 1.1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}

/* The title is a heading inside the box, not a <legend> cut into its border:
   the legend is kept for assistive technology and hidden, and an ordinary
   paragraph carries the words, so no browser's legend rendering is involved. */
.check-title {
  grid-column: 1 / -1;
  margin: 0;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
}

.req {
  margin-left: 0.4rem;
  padding: 0.05rem 0.5rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  vertical-align: middle;
  color: var(--warn-text);
  background: var(--warn-soft);
}

fieldset.departments .muted { grid-column: 1 / -1; margin: -0.25rem 0 0.15rem; }

label.check {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-weight: 400;
  color: var(--text);
  white-space: nowrap;
}

label.check > input { width: auto; margin: 0; flex: none; }

/* The escape hatch, set apart from the departments themselves: it is not a
   twentieth department, it is the answer that means none of them apply. */
label.check.every {
  grid-column: 1 / -1;
  display: flex;
  margin: 0.35rem 0 0;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border);
}

/* --- Table --------------------------------------------------------------- */

.table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  overflow: hidden;
  font-size: 0.9rem;
}

.table th, .table td {
  padding: 0.75rem 0.9rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

.table th:first-child, .table td:first-child { padding-left: 1.1rem; }
.table th:last-child, .table td:last-child { padding-right: 1.1rem; }

.table th {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--surface-2);
  white-space: nowrap;
}

/* No hover on a row: nothing happens when you press one, and a surface that
   answers the pointer is promising that something will. */
.table tbody tr:last-child td { border-bottom: none; }
.table tr.is-disabled td { opacity: 0.55; }
.table td code { font-size: 0.82em; }

.table .btn-small { vertical-align: middle; }

/* A row's own buttons, kept on one right-hand edge. `text-align: right` alone
   left the gap between them to the whitespace in the markup, and a wrap would
   make the one row that has two of them twice the height of its neighbours. */
.table .cell-actions { display: flex; flex-wrap: nowrap; justify-content: flex-end; gap: 0.4rem; }
.table .cell-actions form { margin: 0; }

/* `width: 1%` with `nowrap` is the shrink-to-content column: the table gives
   this one exactly its buttons' width and spends the rest on the names, which
   are what anyone is reading this table for. */
.accounts th:last-child, .accounts td:last-child { width: 1%; white-space: nowrap; }
.table-note { margin-top: 0.9rem; }

/* "Add someone" and "Change" open over the table, the way "New patient" does
   on the OPD list: the same `.btn.primary` in the page head, the same `.modal`
   (app.css, `_ui.html`). */
.add-account, .edit-account { width: min(92vw, 34rem); }
.edit-account .departments { background: var(--surface-2); }

.copy-row { display: flex; gap: 0.5rem; margin: 0.75rem 0; }

.copy-row input {
  flex: 1;
  min-width: 0;
  margin: 0;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background-color: var(--surface-2);
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.82rem;
}

.copy-row button { flex: none; }

.issued { border-color: color-mix(in srgb, var(--accent) 40%, var(--border)); box-shadow: var(--shadow-sm); }
.issued h2 { margin: 0 0 0.4rem; font-size: 1rem; }
.issued-value { margin: 0 0 0.5rem; }
.issued-value code {
  display: inline-block;
  padding: 0.35rem 0.7rem;
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  color: var(--accent-text);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.facts { margin: 0; }
.facts dt {
  margin-top: 1rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.facts dt:first-child { margin-top: 0; }
.facts dd { display: flex; flex-direction: column; gap: 0.25rem; margin: 0.3rem 0 0; }
.facts dd code { align-self: flex-start; font-size: 0.85rem; }
.facts dd .muted { font-size: 0.85rem; line-height: 1.5; }

.empty-state { padding: 3rem 0; }
.empty-state h1 { margin: 0 0 0.75rem; font-size: 1.4rem; }
.empty-state code { word-break: break-all; }
