/* ==========================================================================
   NoriClinic design system
   Near-monochrome by default. Colour carries meaning, never decoration —
   a screen with nothing wrong on it shows almost no colour at all.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans+Arabic:wght@400;500;600;700&display=swap');

:root {
  /* Neutrals — the entire structure of the app is built from these */
  --n-0:   #ffffff;
  --n-25:  #fcfcfd;
  --n-50:  #f8f9fb;
  --n-100: #f1f3f7;
  --n-150: #e8ebf1;
  --n-200: #dfe3ea;
  --n-300: #c6ccd8;
  --n-400: #9aa3b2;
  --n-500: #6b7482;
  --n-600: #4d5560;
  --n-700: #363c46;
  --n-800: #23272e;
  --n-900: #14171c;

  /* One accent. Primary action only. */
  --accent:       #4b5bd6;
  --accent-hover: #3f4dc0;
  --accent-soft:  #eef0fc;
  --accent-ring:  rgba(75, 91, 214, .18);

  /* Status — reserved for confirmation state and attention */
  --ok:      #17795e;
  --ok-soft: #e6f4ef;
  --warn:      #9a6206;
  --warn-soft: #fdf3e2;
  --danger:      #b3261e;
  --danger-soft: #fdeceb;

  /* Space — 4px base */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 24px; --s-6: 32px; --s-7: 48px; --s-8: 64px;

  --r-sm: 6px; --r-md: 10px; --r-lg: 14px;

  /* Two shadows. That is the whole elevation system. */
  --shadow-card:    0 1px 2px rgba(20, 23, 28, .04), 0 1px 3px rgba(20, 23, 28, .06);
  --shadow-overlay: 0 12px 32px rgba(20, 23, 28, .16), 0 2px 8px rgba(20, 23, 28, .08);

  /* Surfaces that sit over content and must follow the theme. Named by role
     rather than by colour so the dark palette can redefine them honestly. */
  --surface-blur: rgba(255, 255, 255, .85);
  --backdrop:     rgba(20, 23, 28, .4);
  --warn-line:    #f0dcb8;
  --warn-tint:    #fffcf6;

  --sidebar-w: 248px;
  --font: 'IBM Plex Sans Arabic', system-ui, -apple-system, 'Segoe UI', sans-serif;
}

/* ==========================================================================
   Themes
   --------------------------------------------------------------------------
   Two independent axes:

     data-theme="light|dark"   the neutral ramp and the surfaces
     data-accent="blue|…"      the single action colour

   They are independent because they answer different questions — someone can
   want the dark palette in green — and keeping them apart means adding an
   accent never touches the dark palette and vice versa.

   The dark ramp is NOT the light one inverted. Inverting produces pure black
   under white text, which vibrates; and it makes every border disappear. The
   dark surfaces are lifted off black and the borders are lightened until they
   read at the same strength as the light theme's do.
   ========================================================================== */

[data-theme="dark"] {
  --n-0:   #15181e;   /* card / raised surface — not black */
  --n-25:  #12151a;
  --n-50:  #0e1116;   /* page ground, the darkest thing on screen */
  --n-100: #1b1f27;
  --n-150: #252a34;   /* borders: the light theme's job, lightened to match */
  --n-200: #2f3540;
  --n-300: #414957;
  --n-400: #6b7484;
  --n-500: #929bab;
  --n-600: #b3bac6;
  --n-700: #ced4dd;
  --n-800: #e6eaf0;   /* body text */
  --n-900: #f5f7fa;

  /* Status colours are re-picked, not reused: the light theme's ink-dark
     green and red are unreadable on a dark ground. */
  --ok:        #4ade9a;
  --ok-soft:   #10291f;
  --warn:      #f0b429;
  --warn-soft: #2b2110;
  --danger:      #ff8a80;
  --danger-soft: #2e1614;

  --surface-blur: rgba(21, 24, 30, .85);
  --backdrop:     rgba(0, 0, 0, .6);
  --warn-line:    #3a2f18;
  --warn-tint:    #1d1810;

  /* Shadows do almost nothing on a dark ground; the borders carry elevation
     instead, so these are reduced rather than kept for their own sake. */
  --shadow-card:    0 1px 2px rgba(0, 0, 0, .3);
  --shadow-overlay: 0 12px 32px rgba(0, 0, 0, .5), 0 2px 8px rgba(0, 0, 0, .3);

  color-scheme: dark;   /* native scrollbars, form controls and caret follow */
}

/* --- accents -------------------------------------------------------------
   One hue each. The soft tint is the accent at low opacity over the page
   ground, so it works in both themes without a second definition. */

[data-accent="green"] {
  --accent:       #0f8a5f;
  --accent-hover: #0c7350;
  --accent-soft:  color-mix(in srgb, #0f8a5f 10%, var(--n-0));
  --accent-ring:  rgba(15, 138, 95, .2);
}
[data-accent="purple"] {
  --accent:       #7a5af8;
  --accent-hover: #684ae0;
  --accent-soft:  color-mix(in srgb, #7a5af8 10%, var(--n-0));
  --accent-ring:  rgba(122, 90, 248, .2);
}
[data-accent="teal"] {
  --accent:       #0d7d8c;
  --accent-hover: #0a6773;
  --accent-soft:  color-mix(in srgb, #0d7d8c 10%, var(--n-0));
  --accent-ring:  rgba(13, 125, 140, .2);
}
[data-accent="rose"] {
  --accent:       #c2405f;
  --accent-hover: #a83450;
  --accent-soft:  color-mix(in srgb, #c2405f 10%, var(--n-0));
  --accent-ring:  rgba(194, 64, 95, .2);
}

/* The default blue needs the same treatment in dark, where a flat tint of the
   light theme's soft blue would glow. */
[data-theme="dark"] {
  --accent-soft: color-mix(in srgb, var(--accent) 16%, var(--n-0));
}

/* --- reset --------------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.6;
  color: var(--n-800);
  background: var(--n-50);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.3; letter-spacing: -.01em; }
h1 { font-size: 24px; }
h2 { font-size: 18px; }
h3 { font-size: 15px; }
p  { margin: 0; }

a { color: inherit; text-decoration: none; }
a:hover { color: var(--accent); }

/* Keyboard focus must be visible everywhere, not only on buttons and inputs.
   :focus-visible rather than :focus so a mouse click never leaves a ring. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}

button, input, select, textarea { font: inherit; color: inherit; }

table { border-collapse: collapse; width: 100%; }

/* --- utilities ----------------------------------------------------------- */

.muted      { color: var(--n-500); }
.small      { font-size: 13px; }
.tiny       { font-size: 12px; }
.strong     { font-weight: 600; }
.tabular    { font-variant-numeric: tabular-nums; }
.stack      { display: flex; flex-direction: column; gap: var(--s-4); }
.row        { display: flex; align-items: center; gap: var(--s-3); }
.row-between{ display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.wrap       { flex-wrap: wrap; }
.grow       { flex: 1; }
.center     { text-align: center; }
.hidden     { display: none !important; }
.mt-4 { margin-top: var(--s-4); }
.mt-5 { margin-top: var(--s-5); }
.mt-6 { margin-top: var(--s-6); }

/* --- app shell ----------------------------------------------------------- */

.app { display: flex; min-height: 100vh; }

.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: var(--n-0);
  border-inline-start: 1px solid var(--n-150);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}

.brand {
  padding: var(--s-5) var(--s-5) var(--s-4);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -.02em;
}
.brand span { color: var(--accent); }
.brand small {
  display: block;
  font-size: 11px;
  font-weight: 500;
  color: var(--n-400);
  letter-spacing: .04em;
  margin-top: 2px;
}

.nav { padding: var(--s-2) var(--s-3); display: flex; flex-direction: column; gap: 2px; flex: 1; }

.nav a {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: 9px var(--s-3);
  border-radius: var(--r-sm);
  color: var(--n-600);
  font-size: 14px;
  font-weight: 500;
  transition: background .12s ease, color .12s ease;
}
.nav a:hover { background: var(--n-100); color: var(--n-900); }
.nav a.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.nav a .ico { width: 18px; text-align: center; opacity: .85; font-size: 15px; }
.nav a .count {
  margin-inline-start: auto;
  font-size: 11px;
  font-weight: 600;
  background: var(--n-150);
  color: var(--n-600);
  padding: 1px 7px;
  border-radius: 20px;
}
.nav a.active .count { background: var(--accent); color: #fff; }

.sidebar-foot {
  padding: var(--s-4) var(--s-5);
  border-top: 1px solid var(--n-150);
  font-size: 13px;
}
.sidebar-foot .who { font-weight: 600; }
.sidebar-foot .role { color: var(--n-400); font-size: 12px; }

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

.topbar {
  height: 60px;
  padding: 0 var(--s-6);
  background: var(--surface-blur);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--n-150);
  display: flex;
  align-items: center;
  gap: var(--s-4);
  position: sticky;
  top: 0;
  z-index: 20;
}

.search { position: relative; flex: 1; max-width: 460px; }
.search input {
  width: 100%;
  height: 36px;
  padding: 0 36px 0 var(--s-3);
  border: 1px solid var(--n-200);
  border-radius: var(--r-sm);
  background: var(--n-50);
  font-size: 14px;
  outline: none;
  transition: border-color .12s, box-shadow .12s, background .12s;
}
.search input:focus {
  background: var(--n-0);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring);
}
.search .ico {
  position: absolute;
  inset-inline-start: var(--s-3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--n-400);
  pointer-events: none;
  font-size: 14px;
}
.search kbd {
  position: absolute;
  inset-inline-end: var(--s-2);
  top: 50%;
  transform: translateY(-50%);
  font-size: 11px;
  color: var(--n-400);
  background: var(--n-0);
  border: 1px solid var(--n-200);
  border-radius: 4px;
  padding: 1px 5px;
  font-family: var(--font);
}
.search input:focus ~ kbd { display: none; }

.content { padding: var(--s-6); max-width: 1240px; width: 100%; }

.page-head { margin-bottom: var(--s-5); }
.page-head .sub { color: var(--n-500); font-size: 14px; margin-top: 2px; }

/* --- cards --------------------------------------------------------------- */

.card {
  background: var(--n-0);
  border: 1px solid var(--n-150);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}
.card-head {
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--n-150);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
}
.card-head h2 { font-size: 15px; }
.card-body { padding: var(--s-5); }
.card-body.flush { padding: 0; }

/* --- stats --------------------------------------------------------------- */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: var(--s-3);
}
.stat {
  background: var(--n-0);
  border: 1px solid var(--n-150);
  border-radius: var(--r-md);
  padding: var(--s-4);
}
.stat b {
  display: block;
  font-size: 26px;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.stat span { font-size: 12.5px; color: var(--n-500); }
.stat.ok b     { color: var(--ok); }
.stat.warn b   { color: var(--warn); }
.stat.danger b { color: var(--danger); }

/* --- tables -------------------------------------------------------------- */

.table-wrap { overflow-x: auto; }

table thead th {
  text-align: start;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--n-500);
  padding: var(--s-3) var(--s-5);
  border-bottom: 1px solid var(--n-150);
  background: var(--n-25);
  white-space: nowrap;
}
table tbody td {
  padding: var(--s-3) var(--s-5);
  border-bottom: 1px solid var(--n-100);
  font-size: 14px;
  vertical-align: middle;
}
table tbody tr:last-child td { border-bottom: 0; }
table tbody tr { transition: background .1s ease; }
table tbody tr:hover { background: var(--n-25); }
table tbody tr.is-cancelled td { opacity: .5; }
table tbody tr.is-now { background: var(--accent-soft); }
table tbody tr.is-now:hover { background: var(--accent-soft); }

.cell-time { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.cell-name { font-weight: 500; }
.cell-actions { text-align: end; white-space: nowrap; }

/* --- badges -------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 500;
  padding: 3px 9px;
  border-radius: 20px;
  background: var(--n-100);
  color: var(--n-600);
  white-space: nowrap;
}
.badge.ok     { background: var(--ok-soft);     color: var(--ok); }
.badge.warn   { background: var(--warn-soft);   color: var(--warn); }
.badge.danger { background: var(--danger-soft); color: var(--danger); }
.badge.accent { background: var(--accent-soft); color: var(--accent); }
.badge .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* --- buttons ------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 36px;
  padding: 0 var(--s-4);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: var(--accent);
  color: #fff;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background .12s ease, border-color .12s ease, box-shadow .12s ease;
}
.btn:hover  { background: var(--accent-hover); color: #fff; }
.btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.btn.secondary {
  background: var(--n-0);
  color: var(--n-700);
  border-color: var(--n-200);
}
.btn.secondary:hover { background: var(--n-50); border-color: var(--n-300); color: var(--n-900); }

.btn.ghost { background: transparent; color: var(--n-600); }
.btn.ghost:hover { background: var(--n-100); color: var(--n-900); }

.btn.danger { background: var(--n-0); color: var(--danger); border-color: var(--n-200); }
.btn.danger:hover { background: var(--danger-soft); border-color: var(--danger); }

.btn.sm { height: 30px; padding: 0 10px; font-size: 13px; }
.btn.block { width: 100%; }

/* --- forms --------------------------------------------------------------- */

.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-size: 13px; font-weight: 500; color: var(--n-700); }
.field .hint { font-size: 12px; color: var(--n-500); }

.input, input[type=text], input[type=email], input[type=password],
input[type=tel], input[type=date], input[type=time], input[type=number],
select, textarea {
  width: 100%;
  height: 38px;
  padding: 0 var(--s-3);
  border: 1px solid var(--n-200);
  border-radius: var(--r-sm);
  background: var(--n-0);
  font-size: 14px;
  outline: none;
  transition: border-color .12s, box-shadow .12s;
}
textarea { height: auto; min-height: 90px; padding: var(--s-3); line-height: 1.6; resize: vertical; }
select { appearance: none; background-image: none; cursor: pointer; }

.input:focus, input:focus, select:focus, textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring);
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--s-4);
}

fieldset { border: 0; padding: 0; margin: 0; }

/* --- typeahead ----------------------------------------------------------- */

.combo { position: relative; }

.combo-list {
  position: absolute;
  z-index: 40;
  top: calc(100% + 4px);
  inset-inline: 0;
  margin: 0;
  padding: var(--s-1);
  list-style: none;
  background: var(--n-0);
  border: 1px solid var(--n-200);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-overlay);
  max-height: 300px;
  overflow-y: auto;
}

.combo-list li {
  padding: 8px var(--s-3);
  border-radius: var(--r-sm);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.combo-list li:hover,
.combo-list li.active { background: var(--accent-soft); }

/* Field-level audit detail: old → new, in a grid so the values line up down
   the column and a changed number is findable at a glance. */
.audit-changes { margin-top: var(--s-1); }
.audit-changes summary {
  cursor: pointer;
  font-size: 12px;
  color: var(--accent);
}
.audit-change {
  display: grid;
  grid-template-columns: minmax(80px, 1fr) minmax(0, 1fr) 14px minmax(0, 1fr);
  gap: var(--s-2);
  align-items: baseline;
  padding: 2px 0;
  font-size: 12px;
}
.audit-field { color: var(--n-600); }
.audit-old   { color: var(--n-500); text-decoration: line-through; }
.audit-arrow { color: var(--n-400); text-align: center; }
.audit-new   { color: var(--n-800); font-weight: 500; }

.history-entry {
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--n-150);
}
.history-entry:last-child { border-bottom: 0; }

/* The research question box. Sized like the primary action on the screen,
   because it is — the filter builder underneath is for correcting it. */
.ask-label {
  display: block;
  font-size: 13px;
  color: var(--n-600);
  margin-bottom: var(--s-2);
}
.ask-row {
  display: flex;
  gap: var(--s-2);
  align-items: stretch;
}
/* Type selector to outrank the shared `input[type=text]` sizing rule. */
input[type=text].ask-input {
  flex: 1;
  min-width: 0;
  height: 48px;
  font-size: 16px;         /* 16px keeps iOS from zooming the page on focus */
}
.ask-row .btn { height: 48px; padding-inline: var(--s-5); }

@media (max-width: 560px) {
  .ask-row { flex-direction: column; }
}

/* Intake rows: one clinical record per line, so a second lab is another line
   rather than another trip through a dialog. */
.intake-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)) auto;
  gap: var(--s-3);
  align-items: end;
  padding: var(--s-3) 0;
  border-bottom: 1px dashed var(--n-150);
}
.intake-row:last-child { border-bottom: 0; }
.intake-row .field { margin: 0; min-width: 0; }
.intake-row .combo { position: relative; }
.intake-remove {
  align-self: end;
  margin-bottom: 2px;
  color: var(--n-500);
}
.intake-remove:hover { color: var(--danger); }

@media (max-width: 700px) {
  .intake-row {
    grid-template-columns: 1fr;
    padding: var(--s-4) 0;
  }
  .intake-remove { justify-self: start; }
}

/* Care suggestions: visible but subordinate to the record itself. They are
   prompts about documentation, so they must never look like an alert. */
.suggest-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}
.suggest-chip {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: var(--s-2) var(--s-3);
  background: var(--n-0);
  border: 1px solid var(--n-200);
  border-radius: var(--r-sm);
  cursor: pointer;
  text-align: start;
  font: inherit;
  color: inherit;
}
.suggest-chip:hover  { border-color: var(--accent); background: var(--accent-soft); }
.suggest-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.suggest-name { font-size: 14px; font-weight: 500; }
.suggest-why  { font-size: 12px; color: var(--n-500); }

/* Confirmation that the typed term was linked to a standard concept. Quiet on
   purpose — it reports what happened, it is not something to read every time. */
.combo-linked {
  margin-top: var(--s-1);
  font-size: 12px;
  color: var(--ok);
  font-variant-numeric: tabular-nums;
}
.combo-linked[hidden] { display: none; }

.combo-name { font-size: 14px; font-weight: 500; }
.combo-meta { font-size: 12px; color: var(--n-500); font-variant-numeric: tabular-nums; }

.combo-empty {
  padding: var(--s-3);
  font-size: 13px;
  color: var(--n-500);
  cursor: default;
}
.combo-empty:hover { background: transparent; }

/* --- slot grid ----------------------------------------------------------- */

.slots { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.slot {
  min-width: 76px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--n-200);
  border-radius: var(--r-sm);
  background: var(--n-0);
  font-size: 13px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: all .12s ease;
}
.slot:hover { border-color: var(--accent); color: var(--accent); }
.slot.taken {
  background: var(--n-100);
  color: var(--n-400);
  border-color: var(--n-150);
  cursor: not-allowed;
  text-decoration: line-through;
}
.slot.past { opacity: .4; cursor: not-allowed; }
.slot.selected { background: var(--accent); border-color: var(--accent); color: #fff; }

/* --- day picker ---------------------------------------------------------- */

/* Scrolls sideways rather than wrapping: a fortnight stays one readable band,
   and the logical properties keep the scroll direction correct in both
   writing directions. */
.day-strip {
  display: flex;
  gap: var(--s-2);
  overflow-x: auto;
  padding-block-end: var(--s-2);
  scroll-snap-type: x proximity;
}
.day-chip {
  flex: 0 0 auto;
  min-width: 78px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--n-200);
  border-radius: var(--r-sm);
  background: var(--n-0);
  color: inherit;
  cursor: pointer;
  scroll-snap-align: start;
  font: inherit;
  line-height: 1.3;
}
.day-chip:hover:not(:disabled) { border-color: var(--accent); }
.day-chip .dow  { font-size: 13px; font-weight: 600; }
.day-chip .dom  { font-size: 12px; color: var(--n-500); }
.day-chip .free { font-size: 11px; color: var(--ok); }
.day-chip.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.day-chip.active .dom,
.day-chip.active .free { color: #fff; }
.day-chip.closed,
.day-chip:disabled { opacity: .45; cursor: not-allowed; }
.day-chip.closed .free { color: var(--n-500); }

/* --- timeline ------------------------------------------------------------ */

.timeline { position: relative; padding-inline-start: var(--s-5); }
.timeline::before {
  content: '';
  position: absolute;
  inset-inline-start: 5px;
  top: 6px;
  bottom: 6px;
  width: 1px;
  background: var(--n-200);
}
.tl-item { position: relative; padding-bottom: var(--s-5); }
.tl-item:last-child { padding-bottom: 0; }
.tl-item::before {
  content: '';
  position: absolute;
  inset-inline-start: calc(-1 * var(--s-5) + 1px);
  top: 7px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--n-0);
  border: 2px solid var(--n-300);
}
.tl-item.accent::before { border-color: var(--accent); }
.tl-item.warn::before   { border-color: var(--warn); }
.tl-date { font-size: 12px; color: var(--n-500); font-variant-numeric: tabular-nums; }
.tl-title { font-weight: 500; margin-top: 1px; }
.tl-detail { font-size: 13px; color: var(--n-600); margin-top: 2px; white-space: pre-wrap; }


/* --- empty / error states ------------------------------------------------ */

.empty {
  padding: var(--s-7) var(--s-5);
  text-align: center;
  color: var(--n-500);
}
.empty .ico { font-size: 30px; opacity: .35; }
.empty h3 { color: var(--n-700); margin: var(--s-3) 0 var(--s-1); }
.empty p { font-size: 14px; max-width: 380px; margin: 0 auto; }
.empty .btn { margin-top: var(--s-4); }

/* --- flash --------------------------------------------------------------- */

.flash-wrap {
  position: fixed;
  top: var(--s-4);
  inset-inline-end: var(--s-4);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  max-width: 380px;
}
.flash {
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-overlay);
  background: var(--n-0);
  border: 1px solid var(--n-200);
  font-size: 14px;
  display: flex;
  gap: var(--s-2);
  animation: slide-in .22s cubic-bezier(.2,.8,.3,1);
}
.flash.success { border-inline-start: 3px solid var(--ok); }
.flash.error   { border-inline-start: 3px solid var(--danger); }
.flash.info    { border-inline-start: 3px solid var(--accent); }

@keyframes slide-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* --- modal --------------------------------------------------------------- */

dialog.modal {
  border: 0;
  padding: 0;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-overlay);
  max-width: 560px;
  width: calc(100vw - var(--s-6));
  background: var(--n-0);
  color: inherit;
}
dialog.modal::backdrop { background: var(--backdrop); backdrop-filter: blur(2px); }
dialog.modal .card-head { border-bottom: 1px solid var(--n-150); }
dialog.modal .modal-body { padding: var(--s-5); }
dialog.modal .modal-foot {
  padding: var(--s-4) var(--s-5);
  border-top: 1px solid var(--n-150);
  display: flex;
  justify-content: flex-end;
  gap: var(--s-2);
  background: var(--n-25);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}

/* --- patient record ------------------------------------------------------ */

.patient-header {
  position: sticky;
  top: 60px;                      /* clears the topbar */
  z-index: 15;
  background: var(--surface-blur);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--n-150);
  padding: var(--s-4) 0;
  margin-bottom: var(--s-4);
}
.patient-header h1 { font-size: 21px; }

.patient-alerts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-3);
}

/* Section jump-list. Horizontal so it never competes with the record itself. */
.record-nav {
  display: flex;
  gap: var(--s-1);
  overflow-x: auto;
  padding-bottom: var(--s-2);
  margin-bottom: var(--s-4);
  border-bottom: 1px solid var(--n-150);
}
.record-nav a {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 6px var(--s-3);
  border-radius: var(--r-sm);
  font-size: 13px;
  font-weight: 500;
  color: var(--n-500);
  white-space: nowrap;
}
.record-nav a:hover { background: var(--n-100); color: var(--n-900); }
.record-nav .nav-count {
  font-size: 11px;
  background: var(--n-150);
  color: var(--n-600);
  padding: 0 6px;
  border-radius: 20px;
}

/* Anchored jumps must not land under the sticky header. */
.record-section, #overview, #consultations, #timeline, #appointments,
#communications, #lab-trends { scroll-margin-top: 150px; }

.section-empty {
  padding: var(--s-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  flex-wrap: wrap;
}

.record-list { list-style: none; margin: 0; padding: 0; }

.record {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--n-100);
}
.record:last-child { border-bottom: 0; }
.record:hover { background: var(--n-25); }

.record-main { min-width: 0; }
.record-title { font-weight: 500; }
.record-detail {
  font-size: 13px;
  color: var(--n-600);
  margin-top: 3px;
  font-variant-numeric: tabular-nums;
}
.record-note {
  font-size: 13px;
  color: var(--n-500);
  margin-top: 4px;
  white-space: pre-wrap;
}
.record-actions {
  display: flex;
  gap: var(--s-1);
  flex-shrink: 0;
  opacity: 0;
  transition: opacity .12s ease;
}
.record:hover .record-actions,
.record:focus-within .record-actions { opacity: 1; }
/* Touch has no hover — actions must always be reachable there. */
@media (pointer: coarse) { .record-actions { opacity: 1; } }

/* --- lab trend ----------------------------------------------------------- */

/* The chart is three fixed bands: value label, plot, date label. Fixing the
   label rows is what lets the reference band line up with the bars — both are
   measured against the same plot box. */
.trend {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: var(--s-2);
  height: 130px;
  overflow-x: auto;
}
.trend-col {
  flex: 1;
  min-width: 44px;
  height: 100%;
  display: grid;
  grid-template-rows: 16px 1fr 16px;
  justify-items: center;
  align-items: end;
}
.trend-bar {
  width: 100%;
  align-self: end;
  background: var(--accent);
  border-radius: 4px 4px 0 0;
  min-height: 4px;
}
.trend-bar.warn { background: var(--warn); }

/* The plot box the band is measured in — same top and bottom insets as the
   label rows above, so 40% here is 40% of the bars' own scale. */
.trend-plotarea {
  position: absolute;
  inset-inline: 0;
  top: 16px;
  bottom: 16px;
  pointer-events: none;
}
.trend-band {
  position: absolute;
  inset-inline: 0;
  background: var(--ok-soft);
  border-top: 1px dashed var(--ok);
  border-bottom: 1px dashed var(--ok);
  opacity: .7;
}

/* --- drawer -------------------------------------------------------------- */

dialog.drawer {
  border: 0;
  padding: 0;
  margin: 0 0 0 auto;             /* RTL: slides in from the left edge */
  height: 100vh;
  max-height: 100vh;
  width: 460px;
  max-width: 100vw;
  background: var(--n-0);
  color: inherit;
  box-shadow: var(--shadow-overlay);
}
dialog.drawer::backdrop { background: var(--backdrop); backdrop-filter: blur(2px); }
dialog.drawer[open] { animation: drawer-in .18s cubic-bezier(.2,.8,.3,1); }

@keyframes drawer-in {
  from { transform: translateX(-24px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

dialog.drawer form {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
.drawer-head {
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--n-150);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
}
.drawer-head h2 { font-size: 16px; }
.drawer-body {
  padding: var(--s-5);
  overflow-y: auto;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}
.drawer-foot {
  padding: var(--s-4) var(--s-5);
  border-top: 1px solid var(--n-150);
  background: var(--n-25);
  display: flex;
  justify-content: flex-end;
  gap: var(--s-2);
  flex-wrap: wrap;
}

@media (max-width: 560px) {
  dialog.drawer { width: 100vw; }
  .patient-header { top: 0; }
}

/* --- tabs ---------------------------------------------------------------- */

.tabs { display: flex; gap: var(--s-1); border-bottom: 1px solid var(--n-150); }
.tabs a {
  padding: var(--s-3) var(--s-4);
  font-size: 14px;
  font-weight: 500;
  color: var(--n-500);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color .12s, border-color .12s;
}
.tabs a:hover { color: var(--n-800); }
.tabs a.active { color: var(--accent); border-bottom-color: var(--accent); }

/* --- auth / onboarding --------------------------------------------------- */

.auth-page {
  min-height: 100vh;
  display: grid;
  place-items: center;
  background: var(--n-100);
  padding: var(--s-5);
}
.auth {
  width: 100%;
  max-width: 400px;
  background: var(--n-0);
  border: 1px solid var(--n-150);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  padding: var(--s-6);
}
.auth .brand { padding: 0 0 var(--s-2); text-align: center; }
.auth .lead { text-align: center; color: var(--n-500); font-size: 14px; margin-bottom: var(--s-5); }


/* --- responsive ---------------------------------------------------------- */

@media (max-width: 900px) {
  .nav a { white-space: nowrap; }
  .brand { padding: var(--s-4) var(--s-4); }
  .content { padding: var(--s-4); }
  .topbar { padding: 0 var(--s-4); }
  .search kbd { display: none; }
}

/* Touch sizing. Desktop density is deliberate at a desk with a mouse; on a
   phone those same controls are 30px targets, and reception taps them
   one-handed while holding a receiver. */
@media (max-width: 900px) and (pointer: coarse) {
  .btn    { height: 44px; padding: 0 var(--s-5); }
  .btn.sm { height: 38px; padding: 0 var(--s-3); }
  .nav a  { padding: 12px var(--s-3); }

  .input, input[type=text], input[type=email], input[type=password],
  input[type=tel], input[type=date], input[type=time], input[type=number],
  select { height: 44px; }

  /* 16px is the threshold below which iOS Safari zooms the page on focus. */
  input, select, textarea { font-size: 16px; }

  .table-cards td a { padding: 4px 0; }
}

/* Tables that matter on a phone opt into a card layout via .table-cards.
   Every element in the chain must become a block — setting only `tr` to block
   leaves the cells in an anonymous table row and changes nothing.
   Column headers are gone at this width, so each cell carries its own label. */
@media (max-width: 620px) {
  .table-cards,
  .table-cards tbody,
  .table-cards tr,
  .table-cards td { display: block; width: 100%; }

  .table-cards thead { display: none; }

  .table-cards tr {
    border: 1px solid var(--n-150);
    border-radius: var(--r-md);
    padding: var(--s-3) var(--s-4);
    margin-bottom: var(--s-2);
    background: var(--n-0);
  }
  .table-cards tr:hover { background: var(--n-0); }
  .table-cards tr.is-now { background: var(--accent-soft); }

  .table-cards td {
    border: 0;
    padding: 3px 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-3);
    text-align: start;
  }
  .table-cards td::before {
    content: attr(data-label);
    flex-shrink: 0;
    font-size: 12px;
    color: var(--n-500);
  }
  /* An empty cell would otherwise render as a stray floating label. */
  .table-cards td:empty { display: none; }

  .table-cards .cell-actions { justify-content: flex-end; padding-top: var(--s-2); }
  .table-cards .cell-actions::before { content: none; }
}

@media print {
  .sidebar, .topbar, .btn, .cell-actions { display: none !important; }
  body { background: #fff; }
  .card { box-shadow: none; border-color: #ddd; }
}

/* ==========================================================================
   Dashboard
   --------------------------------------------------------------------------
   The day, laid out by priority: what needs a decision sits beside what is
   happening now, and the numbers that explain both sit above. Density is the
   point — a clinic screen is read at a glance between patients — so the
   restraint is in the colour and the borders, never in the whitespace.
   ========================================================================== */

.metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--s-3);
}
.metric {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--s-4);
  background: var(--n-0);
  border: 1px solid var(--n-150);
  border-radius: var(--r-md);
}
.metric-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  font-size: 13px;
  color: var(--n-600);
}
/* The icon is a quiet landmark for scanning, not decoration competing with
   the number it sits beside. */
.metric-ico {
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border-radius: 8px;
  background: var(--n-50);
  font-size: 13px;
  color: var(--n-500);
}
.metric b { font-size: 28px; line-height: 1.25; font-weight: 650; }
.metric-sub { font-size: 12px; color: var(--n-500); }

/* Only the cards that can demand action carry a tone. */
.metric.ok     .metric-ico { background: var(--ok-soft);     color: var(--ok); }
.metric.warn   .metric-ico { background: var(--warn-soft);   color: var(--warn); }
.metric.danger .metric-ico { background: var(--danger-soft); color: var(--danger); }
.metric.warn   b { color: var(--warn); }
.metric.danger b { color: var(--danger); }

.dash-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.9fr) minmax(300px, 1fr);
  gap: var(--s-4);
  align-items: start;
}
.dash-pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--s-4);
}

/* --- timeline ------------------------------------------------------------ */

.timeline { list-style: none; margin: 0; padding: 0; position: relative; }
/* One continuous rule behind the dots: the day reads as a single thread
   rather than a stack of unrelated rows. */
.timeline::before {
  content: "";
  position: absolute;
  inset-inline-start: 78px;
  top: 18px; bottom: 18px;
  width: 2px;
  background: var(--n-150);
}

.tl-row {
  display: grid;
  grid-template-columns: 62px 18px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-2);
  border-radius: var(--r-md);
  position: relative;
}
.tl-row + .tl-row { margin-top: 2px; }
.tl-row:hover { background: var(--n-25); }

.tl-time { font-size: 13px; color: var(--n-500); text-align: end; }
.tl-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--n-0);
  border: 2px solid var(--n-300);
  justify-self: center;
  position: relative;
  z-index: 1;
}

.tl-body {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-width: 0;
  text-decoration: none;
  color: inherit;
}
.tl-who { display: flex; flex-direction: column; min-width: 0; }
.tl-name {
  font-weight: 550;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tl-type { font-size: 12px; color: var(--n-500); }
.tl-now {
  margin-inline-start: var(--s-2);
  color: var(--accent);
  font-weight: 600;
}

.tl-tags { display: flex; align-items: center; gap: var(--s-2); }
.tl-go {
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border-radius: 8px;
  color: var(--n-400);
  text-decoration: none;
  font-size: 18px;
}
.tl-row:hover .tl-go { background: var(--n-100); color: var(--n-700); }

/* The appointment in the room right now. A left rule and a tinted ground —
   enough to find instantly, not enough to shout. */
.tl-row.is-current {
  background: var(--accent-soft);
  box-shadow: inset 3px 0 0 var(--accent);
}
.tl-row.is-current .tl-dot { border-color: var(--accent); background: var(--accent); }
.tl-row.is-current .tl-time { color: var(--accent); font-weight: 600; }
.tl-row.is-next .tl-dot { border-color: var(--accent); }
.tl-row.is-done { opacity: .55; }
.tl-row.is-slot .tl-dot { border-style: dashed; }

.risk-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--n-300);
  display: inline-block;
  flex: none;
}
.risk-dot.ok     { background: var(--ok); }
.risk-dot.warn   { background: var(--warn); }
.risk-dot.danger { background: var(--danger); }

/* --- avatars ------------------------------------------------------------- */

.avatar {
  width: 34px; height: 34px;
  flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .3px;
}
.avatar.sm { width: 26px; height: 26px; font-size: 10px; }
.avatar.warn  { background: var(--warn-soft);  color: var(--warn); }
.avatar.ghost { background: var(--n-100); color: var(--n-500); font-size: 16px; }

.stack-avatars { display: flex; }
.stack-avatars .avatar { border: 2px solid var(--n-0); }
.stack-avatars .avatar + .avatar { margin-inline-start: -10px; }

/* --- side panels --------------------------------------------------------- */

.attn-list { list-style: none; margin: 0; padding: 0; }
.attn { display: flex; gap: var(--s-3); padding: var(--s-3) 0; }
.attn + .attn { border-top: 1px solid var(--n-100); }
.attn-body { min-width: 0; flex: 1; }
.attn-body a { text-decoration: none; color: inherit; }
.attn-body a:hover { color: var(--accent); }

.msg-grid, .sum-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
  gap: var(--s-3);
}
.msg-grid > div, .sum-grid > div { display: flex; flex-direction: column; }
.msg-grid b { font-size: 20px; }
.msg-grid span { font-size: 12px; color: var(--n-500); }
.sum-grid b { font-size: 22px; }
.msg-grid .is-bad b { color: var(--danger); }
.is-bad  { color: var(--danger); }
.is-good { color: var(--ok); }

/* --- charts -------------------------------------------------------------- */

.spark {
  display: flex;
  align-items: flex-end;
  gap: var(--s-2);
  height: 132px;
}
.spark-col {
  flex: 1;
  height: 100%;
  display: grid;
  grid-template-rows: 14px 1fr 16px;
  justify-items: center;
  align-items: end;
  gap: 4px;
}
.spark-bar {
  width: 100%;
  max-width: 34px;
  align-self: end;
  background: var(--accent-soft);
  border-radius: 6px 6px 0 0;
  min-height: 4px;
}
.spark-bar.today { background: var(--accent); }
.spark-val { color: var(--n-500); }

/* A conic gradient rather than SVG: three shares, no library, and the shape
   stays correct at any size. */
.ring {
  --low: 0; --med: 0;
  width: 116px; height: 116px;
  flex: none;
  border-radius: 50%;
  background: conic-gradient(
    var(--ok)     0 calc(var(--low) * 1%),
    var(--n-300)  0 calc((var(--low) + var(--med)) * 1%),
    var(--danger) 0 100%
  );
  display: grid;
  place-items: center;
}
.ring-hole {
  width: 78px; height: 78px;
  border-radius: 50%;
  background: var(--n-0);
  display: grid;
  place-items: center;
  text-align: center;
  line-height: 1.2;
}
.ring-hole b { font-size: 20px; }

.legend { list-style: none; margin: 0; padding: 0; font-size: 13px; }
.legend li {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: 3px 0;
}
.legend b { margin-inline-start: auto; }

/* --- narrower screens ---------------------------------------------------- */

@media (max-width: 1100px) {
  /* What needs a decision comes first when the columns collapse: on a phone
     between patients, the exceptions are the reason the screen was opened. */
  .dash-grid { grid-template-columns: 1fr; }
  .dash-aside { order: -1; }
  .dash-pair  { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
  .metric b { font-size: 24px; }
  .timeline::before { inset-inline-start: 62px; }
  .tl-row {
    grid-template-columns: 48px 14px minmax(0, 1fr);
    row-gap: var(--s-2);
  }
  .tl-tags { grid-column: 3; justify-content: flex-start; }
  .tl-go { display: none; }
  .risk-label { display: none; }
  .ring { width: 96px; height: 96px; }
  .ring-hole { width: 64px; height: 64px; }
}

/* --- theme toggle -------------------------------------------------------- */

/* A segmented control rather than a switch: there are three states, and
   "follow the system" is not the off position of anything. */
.theme-toggle {
  display: flex;
  gap: 2px;
  padding: 2px;
  background: var(--n-100);
  border-radius: var(--r-sm);
}
.theme-toggle button {
  width: 28px; height: 26px;
  display: grid; place-items: center;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--n-500);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  transition: background .12s ease, color .12s ease;
}
.theme-toggle button:hover { color: var(--n-800); }
.theme-toggle button.active {
  background: var(--n-0);
  color: var(--accent);
  box-shadow: var(--shadow-card);
}

@media (max-width: 640px) {
  /* The label is in the title attribute; on a phone the icons carry it. */
  .theme-toggle button { width: 26px; }
}

/* ==========================================================================
   Sidebar: collapsed and mobile states
   --------------------------------------------------------------------------
   Three layouts from one markup:

     wide            248px, icons + labels
     collapsed       68px, icons only, label on hover
     narrow (phone)  off-canvas, opened by the hamburger

   Everything is expressed with logical properties, so the drawer slides in
   from the right in Arabic and from the left in English without a second rule.
   ========================================================================== */

.brand-mark { display: block; }
.brand-mark:hover { color: inherit; }

/* --- collapsed (desktop) -------------------------------------------------- */

.app.is-collapsed { --sidebar-w: 68px; }

.app.is-collapsed .brand small,
.app.is-collapsed .nav a > span:not(.ico):not(.count),
.app.is-collapsed .sidebar-foot,
.app.is-collapsed .sidebar-collapse .lbl { display: none; }

.app.is-collapsed .brand {
  padding: var(--s-5) 0 var(--s-4);
  text-align: center;
  font-size: 0;                    /* hides "NoriClinic", keeps the mark */
}
.app.is-collapsed .brand-mark span { font-size: 20px; }
.app.is-collapsed .brand-mark      { font-size: 0; }

.app.is-collapsed .nav { padding: var(--s-2); }
.app.is-collapsed .nav a {
  justify-content: center;
  padding: 10px 0;
  position: relative;
}
.app.is-collapsed .nav a .ico { width: auto; font-size: 17px; }

/* The count still has to be visible when there is no room for it inline. */
.app.is-collapsed .nav a .count {
  position: absolute;
  top: 3px;
  inset-inline-end: 8px;
  margin: 0;
  padding: 0 4px;
  font-size: 10px;
  min-width: 15px;
  text-align: center;
}

/* The label becomes a tooltip. Without it a collapsed sidebar is a column of
   symbols nobody can learn. */
.app.is-collapsed .nav a::after {
  content: attr(data-label);
  position: absolute;
  inset-inline-start: calc(100% + 8px);
  top: 50%;
  transform: translateY(-50%);
  padding: 5px 10px;
  background: var(--n-900);
  color: var(--n-0);
  font-size: 12px;
  white-space: nowrap;
  border-radius: var(--r-sm);
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease;
  z-index: 40;
}
.app.is-collapsed .nav a:hover::after,
.app.is-collapsed .nav a:focus-visible::after { opacity: 1; }

.app.is-collapsed .sidebar-collapse { justify-content: center; }
.app.is-collapsed .sidebar-collapse .chev { transform: scaleX(-1); }

/* --- the collapse control ------------------------------------------------- */

.sidebar-collapse {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  padding: var(--s-3) var(--s-5);
  border: 0;
  border-top: 1px solid var(--n-150);
  background: transparent;
  color: var(--n-500);
  font-size: 13px;
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.sidebar-collapse:hover { background: var(--n-100); color: var(--n-800); }
.sidebar-collapse .chev {
  font-size: 16px;
  line-height: 1;
  display: inline-block;
  transition: transform .16s ease;
}

/* --- hamburger and scrim -------------------------------------------------- */

.hamburger {
  display: none;                   /* desktop has a permanent sidebar */
  width: 36px; height: 36px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--n-200);
  border-radius: var(--r-sm);
  background: var(--n-0);
  color: var(--n-700);
  font-size: 16px;
  cursor: pointer;
  flex: none;
}
.hamburger:hover { background: var(--n-100); }

.sidebar-scrim {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 45;
  border: 0;
  padding: 0;
  background: var(--backdrop);
  cursor: pointer;
}

/* --- narrow --------------------------------------------------------------- */

@media (max-width: 900px) {
  .hamburger { display: flex; }

  /* Off-canvas rather than the old horizontal strip: a scrolling row of seven
     items hides most of them, and hidden navigation is navigation nobody uses. */
  .sidebar {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    z-index: 50;
    width: min(82vw, 300px);
    height: 100dvh;
    transform: translateX(0);        /* open is the resting position */
    transition: transform .2s ease;
    box-shadow: var(--shadow-overlay);
    border-bottom: 0;
  }

  /* Hiding is stated per direction rather than through a custom property.
     The property version broke when the language switch changed dir on a live
     document: the variable kept its old value and the closed panel sat on top
     of the page in English. Two plain rules cannot go stale that way. */
  [dir="rtl"] .app:not(.is-open) .sidebar { transform: translateX(100%); }
  [dir="ltr"] .app:not(.is-open) .sidebar { transform: translateX(-100%); }
  .app.is-open .sidebar-scrim { display: block; }

  /* The collapsed desktop state has no meaning here. */
  .app.is-collapsed { --sidebar-w: 248px; }
  .app.is-collapsed .brand small,
  .app.is-collapsed .nav a > span:not(.ico):not(.count),
  .app.is-collapsed .sidebar-foot { display: revert; }
  .app.is-collapsed .brand,
  .app.is-collapsed .brand-mark { font-size: revert; text-align: start; }
  .app.is-collapsed .nav a { justify-content: flex-start; padding: 9px var(--s-3); }
  .app.is-collapsed .nav a::after { content: none; }
  .app.is-collapsed .nav a .count { position: static; }

  .sidebar-collapse { display: none; }
  .nav { flex-direction: column; overflow: visible; padding: var(--s-2) var(--s-3); }
  .sidebar-foot { display: block; }
  .brand small { display: block; }
}

/* Someone who has asked for less motion gets the panel without the slide. */
@media (prefers-reduced-motion: reduce) {
  .sidebar { transition: none; }
  .sidebar-collapse .chev { transition: none; }
}

/* --- appearance picker ---------------------------------------------------- */

.choice-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--s-3);
}
.choice {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--n-200);
  border-radius: var(--r-md);
  background: var(--n-0);
  color: inherit;
  text-align: start;
  cursor: pointer;
  font: inherit;
  transition: border-color .12s ease, background .12s ease;
}
.choice:hover { border-color: var(--n-300); }
.choice.active {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: 0 0 0 1px var(--accent);
}
.choice-ico   { font-size: 16px; line-height: 1.4; }
.choice-label { font-weight: 600; font-size: 14px; }
.choice-hint  { font-size: 12px; color: var(--n-500); }
.choice.active .choice-hint { color: var(--n-600); }

.swatches { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.swatch {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: var(--s-3);
  width: 84px;
  border: 1px solid var(--n-200);
  border-radius: var(--r-md);
  background: var(--n-0);
  color: var(--n-600);
  cursor: pointer;
  font: inherit;
  transition: border-color .12s ease;
}
.swatch:hover { border-color: var(--n-300); }
.swatch.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }

/* The dot paints itself with the accent the button represents, because each
   button carries its own data-accent — the swatch previews the colour rather
   than describing it. */
.swatch-dot {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .06);
}

/* --- language switch ------------------------------------------------------ */

.lang-toggle button {
  height: 30px;
  min-width: 34px;
  padding: 0 var(--s-2);
  border: 1px solid var(--n-200);
  border-radius: var(--r-sm);
  background: var(--n-0);
  color: var(--n-600);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.lang-toggle button:hover { background: var(--n-100); color: var(--n-900); }

/* --- message template editor --------------------------------------------- */

.tpl {
  border: 1px solid var(--n-150);
  border-radius: var(--r-md);
  background: var(--n-0);
}
.tpl summary {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  cursor: pointer;
  list-style: none;
}
.tpl summary::-webkit-details-marker { display: none; }
.tpl summary::before {
  content: "A";
  color: var(--n-400);
  transition: transform .12s ease;
}
.tpl[open] summary::before { transform: rotate(90deg); }
.tpl[open] summary { border-bottom: 1px solid var(--n-150); }
.tpl-body { padding: var(--s-4); }

/* The preview is shaped like the thing it previews: a chat bubble, so the
   doctor is judging a message rather than a form field. */
.tpl-preview { margin-bottom: var(--s-4); }
.bubble {
  margin-top: var(--s-2);
  padding: var(--s-3) var(--s-4);
  background: var(--ok-soft);
  border-radius: 14px 14px 14px 4px;
  max-width: 460px;
  font-size: 14px;
  line-height: 1.7;
}
.bubble-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin: var(--s-2) 0;
  max-width: 460px;
}
.bubble-buttons span {
  flex: 1;
  min-width: 90px;
  text-align: center;
  padding: 6px var(--s-3);
  border: 1px solid var(--n-200);
  border-radius: 8px;
  font-size: 13px;
  color: var(--accent);
  background: var(--n-0);
}

.tpl-vars { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: var(--s-2); }
.chip {
  padding: 2px 8px;
  border: 1px solid var(--n-200);
  border-radius: 20px;
  background: var(--n-50);
  color: var(--n-600);
  font-size: 12px;
  font-family: ui-monospace, monospace;
  cursor: pointer;
}
.chip:hover { border-color: var(--accent); color: var(--accent); }
