/* ==========================================================================
   AIPhysio theme — calm, patient-centred healthcare aesthetic.
   Single source of truth for all styling. See STYLE_GUIDE.md.
   ========================================================================== */

:root {
  color-scheme: light;

  /* Surfaces */
  --bg: #f4f7f5;
  --surface: #ffffff;
  --surface-hover: #f8faf8;

  /* Text */
  --ink: #1f322c;
  --ink-soft: #3d5249;
  --muted: #66766e;

  /* Lines */
  --line: #e2e9e4;
  --line-strong: #cbd8d2;

  /* Brand */
  --brand: #2e7d6b;
  --brand-dark: #256657;
  --brand-tint: #e4f0eb;
  --brand-tint-strong: #cfe4dc;

  /* Semantic */
  --danger: #b9453c;
  --danger-tint: #f9e9e7;
  --success: #2f7d5c;
  --success-tint: #e3f2e9;
  --warning: #a9761f;
  --warning-tint: #f7efdc;

  /* Type */
  --font-body: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-display: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;

  /* Shape & depth */
  --radius: 14px;
  --radius-sm: 10px;
  --shadow-card-hover: 0 4px 14px rgba(31, 50, 44, 0.07);
  --shadow-modal: 0 20px 60px rgba(31, 50, 44, 0.22);

  --focus-ring: 0 0 0 3px var(--brand-tint-strong);
}

/* ---------- Dark theme ----------
   Set via data-theme="dark" on <html> (see header.php / My account page).
   Same calm teal palette, rebalanced for low-light use: darker surfaces,
   softer text, and slightly brighter brand tones for contrast on dark. */
:root[data-theme="dark"] {
  color-scheme: dark;

  /* Surfaces */
  --bg: #131b18;
  --surface: #1b2622;
  --surface-hover: #223029;

  /* Text */
  --ink: #e8f0ec;
  --ink-soft: #c2d2ca;
  --muted: #8fa39a;

  /* Lines */
  --line: #2b3a34;
  --line-strong: #3d5249;

  /* Brand (hover = brighter, not darker, on a dark background) */
  --brand: #38907d;
  --brand-dark: #4fae98;
  --brand-tint: #1f3a33;
  --brand-tint-strong: #2c4f45;

  /* Semantic */
  --danger: #d0685e;
  --danger-tint: #3a2320;
  --success: #4fae85;
  --success-tint: #1d362b;
  --warning: #cfa24a;
  --warning-tint: #383020;

  /* Shape & depth */
  --shadow-card-hover: 0 4px 14px rgba(0, 0, 0, 0.4);
  --shadow-modal: 0 20px 60px rgba(0, 0, 0, 0.65);

  --focus-ring: 0 0 0 3px var(--brand-tint-strong);
}

/* Hardcoded colours that don't flow through the variables above. */
[data-theme="dark"] .alert.error { color: #f0a8a0; border-color: #6b3a34; }
[data-theme="dark"] .alert.success { color: #93d6b4; border-color: #35604a; }
[data-theme="dark"] .alert.warning { color: #e6c07c; border-color: #6b5a33; }
[data-theme="dark"] dialog.modal::backdrop { background: rgba(0, 0, 0, 0.6); }
[data-theme="dark"] .scanner { background: rgba(0, 0, 0, 0.75); }
[data-theme="dark"] .bottom-tabs { box-shadow: 0 -4px 14px rgba(0, 0, 0, 0.5); }
/* plan_grid.php sets a fixed light-mint background on plan day items. */
[data-theme="dark"] .plan-day-item { background: var(--brand-tint-strong); }

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  background: var(--bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}

/* ---------- Typography ---------- */

h1, h2 {
  font-family: var(--font-display);
  color: var(--ink);
}

h1 {
  font-size: 1.75rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin: 0 0 1rem;
}

h2 {
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.005em;
  margin: 1.75rem 0 0.75rem;
}

h3 {
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.4;
  margin: 1rem 0 0.5rem;
}

p { margin: 0 0 1rem; }

a { color: var(--brand-dark); }

a:hover { color: var(--brand); }

.muted { color: var(--muted); font-size: 0.875rem; }

/* ---------- Header & nav ---------- */

header {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 10;
}

.nav {
  padding: 0.9rem 1rem;
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
}

.brand {
  font-weight: 700;
  font-size: 1.2rem;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
}

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

.nav a.link {
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 500;
  padding: 0.35rem 0.5rem;
  border-radius: var(--radius-sm);
  transition: background 150ms ease, color 150ms ease;
}

.nav a.link:hover {
  color: var(--brand-dark);
  background: var(--brand-tint);
}

/* Currently-selected page: faint ring + tint so it reads as "you are here" */
.nav a.link.active {
  color: var(--brand-dark);
  background: var(--brand-tint);
  box-shadow: inset 0 0 0 1px var(--brand-tint-strong);
}

.nav a.link:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.nav .who {
  margin-left: auto;
  font-size: 0.85rem;
  color: var(--muted);
}

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

main {
  max-width: 960px;
  margin: 1.75rem auto 0;
  padding: 0 1rem 3rem;
}

footer {
  border-top: 1px solid var(--line);
  padding: 1.25rem 1rem;
  text-align: center;
  color: var(--muted);
  font-size: 0.8rem;
}

.row { display: flex; gap: 0.5rem; align-items: center; }
.row.wrap { flex-wrap: wrap; }
.spacer { flex: 1; }
.flex1 { flex: 1; }

/* ---------- Cards ---------- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem;
  margin-bottom: 1rem;
}

.card:last-child { margin-bottom: 0; }

.card h2:first-child { margin-top: 0; }

/* Stat cards (dashboard) */
.stat { display: flex; flex-direction: column; gap: 0.25rem; }
.stat .muted { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; }
.stat .stat-value { font-size: 1.75rem; font-weight: 650; letter-spacing: -0.01em; color: var(--ink); line-height: 1.2; }

.stat-window { display: inline-flex; flex-wrap: wrap; gap: 0.25rem; padding: 0.25rem; background: var(--line); border-radius: 999px; margin-bottom: 1rem; }
.stat-window-btn { display: inline-block; padding: 0.3rem 0.75rem; border-radius: 999px; font-size: 0.85rem; font-weight: 600; color: var(--muted); text-decoration: none; transition: color 150ms ease, background 150ms ease; }
.stat-window-btn:hover { color: var(--ink); }
.stat-window-btn.active { background: var(--brand); color: #fff; }

/* Four dashboard stat boxes: fit the width, equal height. */
.stats-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.stats-grid > .stat { height: 100%; justify-content: center; }

/* To-do list (patient retention + needs help) on the dashboard. */
.todo-grid { display: grid; grid-template-columns: 1fr; gap: 1.5rem; }
@media (min-width: 700px) {
  .todo-grid { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 1100px) {
  .todo-grid { grid-template-columns: 1fr 1fr 1fr; }
}
.todo-title {
  margin: 0 0 0.6rem;
  font-size: 0.82rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.todo-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.55rem; }
.todo-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.2rem 0.5rem; font-size: 0.95rem; }
.todo-detail { width: 100%; font-size: 0.85rem; }
.todo-medal { font-size: 1.1rem; line-height: 1; }
.badge.warn { background: var(--warning-tint); color: var(--warning); }
.badge.danger { background: var(--danger-tint); color: var(--danger); }
.badge.success { background: var(--success-tint); color: var(--success); }

/* ---------- Grids ---------- */

.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

/* ---------- Dashboard (physio) ---------- */

/* Stacked on phones; two side-by-side columns on wider screens. */
.dash-cols {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 1.5rem;
  align-items: start;
}

@media (min-width: 900px) {
  .dash-cols { grid-template-columns: 1fr 1fr; }
  /* Wider content column so the two panels can breathe. */
  main.wide { max-width: 1200px; }
  /* Keep stat cards compact instead of stretching across the full width. */
  main.wide .grid,
  main.broad .grid { grid-template-columns: repeat(2, minmax(0, 320px)); }
}

/* Full-width list pages (programs, exercises, physios). */
@media (min-width: 900px) {
  main.broad { max-width: none; }
}

/* Full-width app-style pages (patients list + detail): the page itself never
   scrolls on desktop — each pane scrolls inside itself, so nothing can drift
   or wiggle relative to the sticky header. */
@media (min-width: 900px) {
  main.full {
    max-width: none;
    margin-top: 0;
    height: calc(100vh - var(--header-h, 61px));
    padding: 1.25rem 2rem;
    overflow: hidden;
  }
  main.full .patients-layout {
    height: 100%;
    grid-template-rows: minmax(0, 1fr);
    align-items: stretch;
  }
  /* Name, DOB and tab bar stay put; only the tab content scrolls. */
  main.full .patient-content {
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  main.full .patient-main {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding-right: 0.5rem; /* room for the scrollbar */
    padding-bottom: 1rem;
  }
}

/* Patients pages (list + detail): scrollable patient list on the left,
   main content on the right. Stacked on phones. */
.patients-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem 1.5rem;
  align-items: start;
}

.patient-nav { display: flex; flex-direction: column; gap: 0.5rem; }

.patient-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  flex: 1;
  overflow-y: auto;
  /* Phones: the sidebar stacks, so cap the list so the add button stays reachable. */
  max-height: 320px;
}

.patient-add { width: 100%; }

/* Tab panels: even gap between the tab bar and the first element. */
.tab-panel { padding-top: 1rem; }
.tab-panel > :first-child { margin-top: 0; }

/* Home card: label/value on the left, action button on the right */
.home-card-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin-bottom: 0.75rem; }
.home-card-head .btn { flex: none; white-space: nowrap; }

/* Tab bar (patient page) */
.tabs {
  display: flex;
  gap: 0.25rem;
  margin-top: 0.75rem;
  border-bottom: 1px solid var(--line);
  overflow-x: auto; /* five tabs can overflow on narrow screens */
}

/* Sticky bottom tab bar (client dashboard) */
main.has-bottom-tabs { padding-bottom: calc(4.5rem + env(safe-area-inset-bottom, 0px)); }

.bottom-tabs {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.4rem 0.75rem calc(0.4rem + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
  border-top: 1px solid var(--line);
  box-shadow: 0 -4px 14px rgba(31, 50, 44, 0.08);
}

.bottom-tabs .tab {
  flex: 1;
  max-width: 170px;
  text-align: center;
  border-bottom: none;
  border-radius: 999px;
  padding: 0.45rem 1rem;
  transition: background 150ms ease, color 150ms ease;
}
.bottom-tabs .tab.active { background: var(--brand-tint); border-bottom: none; }

.tab {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--muted);
  padding: 0.5rem 0.9rem 0.4rem;
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease;
}

.tab:hover { color: var(--brand-dark); }
.tab.active { color: var(--brand-dark); border-bottom-color: var(--brand); }
.tab:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.tabs a.tab { text-decoration: none; }

.patient-list a {
  display: block;
  padding: 0.45rem 0.75rem;
  border-radius: var(--radius-sm);
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 0.95rem;
  transition: background 150ms ease, color 150ms ease;
}

.patient-list a:hover { background: var(--brand-tint); color: var(--brand-dark); }
.patient-list a.active { background: var(--brand-tint); color: var(--brand-dark); font-weight: 600; }

/* Schedule widget: reusable day timeline (schedule_sidebar.php), embedded
   in the Schedule sidebar and the Dashboard left column. */
:root { --sched-hour-h: 48px; --sched-gutter: 3.25rem; } /* --sched-hour-h must match $hourH in schedule_sidebar.php */

.schedule-widget { display: flex; flex-direction: column; gap: 0.5rem; }
.patient-nav > .schedule-widget { flex: 1; min-height: 0; }
.sched-title { margin: 0; font-size: 1.05rem; }

.sched-timeline-wrap { display: flex; flex-direction: column; gap: 0.5rem; flex: 1; min-height: 0; }

/* Events without a time: small link list above the timeline. */
.sched-untimed { display: flex; flex-direction: column; gap: 0.1rem; }
.sched-untimed a {
  display: block;
  padding: 0.35rem 0.6rem;
  border-radius: var(--radius-sm);
  color: var(--ink-soft);
  font-size: 0.9rem;
  text-decoration: none;
  transition: background 150ms ease, color 150ms ease;
}
.sched-untimed a:hover { background: var(--brand-tint); color: var(--brand-dark); }
.sched-untimed a.active { background: var(--brand-tint); color: var(--brand-dark); font-weight: 600; }

/* Week view (schedule.php): no hour labels — collapse the gutter and keep
   the hour lines. */
.schedule-widget.no-hours { --sched-gutter: 0px; }
.schedule-widget.no-hours .sched-hour span { display: none; }
.schedule-widget.no-hours .sched-timeline::before { display: none; }

/* Scrollable 24 h timeline. */
.sched-scroll { flex: 1; min-height: 0; overflow-y: auto; max-height: 420px; }
.sched-timeline { position: relative; }

/* Left gutter holds only the time values; events + now-line sit to its right.
   Positioned so the hour lines paint over the working-hours bands below. */
.sched-hour { height: var(--sched-hour-h); border-top: 1px solid var(--line); position: relative; z-index: 1; }
.sched-hour span {
  display: block;
  width: var(--sched-gutter);
  font-size: 0.7rem;
  color: var(--muted);
  padding: 1px 0 0 2px;
}
.sched-timeline::before {
  content: '';
  position: absolute;
  left: var(--sched-gutter);
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--line);
  z-index: 0;
  pointer-events: none;
}

/* Event boxes, positioned by start time and sized by duration. The box is a
   div holding the link (whole body) + a hover edit button. */
.sched-event {
  position: absolute;
  left: calc(var(--sched-gutter) + 4px);
  right: 4px;
  z-index: 1;
  display: block;
  overflow: hidden;
  background: var(--brand-tint);
  border: 1px solid var(--brand-tint-strong);
  border-left: 3px solid var(--brand);
  border-radius: 6px;
  padding: 2px 6px;
  color: var(--brand-dark);
  font-size: 0.75rem;
  line-height: 1.25;
  transition: background 150ms ease;
}
.sched-event-link {
  display: block;
  height: 100%;
  color: inherit;
  text-decoration: none;
}
.sched-event:hover { background: var(--brand-tint-strong); }
.sched-event.active { background: var(--brand); border-color: var(--brand); color: #fff; }
.sched-event.no-show { opacity: 0.6; }
.sched-event.no-show .sched-event-title { text-decoration: line-through; }
.sched-event-time { display: block; font-weight: 600; }
.sched-event-title {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0.85;
  padding-right: 24px;
}

/* Edit button, revealed when hovering the event box. */
.sched-event-edit {
  position: absolute;
  top: 2px;
  right: 2px;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border: none;
  border-radius: 4px;
  background: var(--brand);
  color: #fff;
  font-size: 0.85rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 150ms ease, background 150ms ease;
}
.sched-event:hover .sched-event-edit,
.sched-event-edit:focus-visible { opacity: 1; }

/* Working-hours bands shaded behind the day's events (schedule week view,
   fed by $schedHours in schedule_sidebar.php). */
.sched-hours-band {
  position: absolute;
  left: var(--sched-gutter);
  right: 4px;
  z-index: 0;
  /* Hatched like the break band below (same 6px stripes), in the brand
   * colour instead of tan, kept translucent so the hour lines and events
   * read through it. */
  background: repeating-linear-gradient(45deg,
    color-mix(in srgb, var(--brand) 20%, transparent) 0 6px,
    color-mix(in srgb, var(--brand) 7%, transparent) 6px 12px);
  border-radius: 4px;
  pointer-events: none;
}
/* Breaks get the same hatched fill as the break blocks in the
   working-hours tab, just translucent. */
.sched-hours-band.break {
  background: repeating-linear-gradient(45deg, rgba(247, 239, 220, 0.6) 0 6px, rgba(235, 223, 192, 0.6) 6px 12px);
}

/* Current-time indicator (today only). */
.sched-now {
  position: absolute;
  left: var(--sched-gutter);
  right: 0;
  height: 2px;
  background: var(--danger);
  z-index: 2;
  pointer-events: none;
}
.sched-now::before {
  content: '';
  position: absolute;
  left: 0;
  top: -3px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--danger);
}

/* Hover guide: dashed line at the mouse position with the time under it. */
.sched-hover {
  position: absolute;
  left: var(--sched-gutter);
  right: 0;
  height: 0;
  border-top: 1px dashed var(--muted);
  z-index: 2;
  pointer-events: none;
}
.sched-hover span {
  position: absolute;
  right: 0;
  top: -17px;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 4px;
  white-space: nowrap;
}

/* Drag indicator shown while picking a time range on the timeline. */
.sched-drag-ghost {
  position: absolute;
  left: var(--sched-gutter);
  right: 0;
  min-height: 12px; /* 15 min at --sched-hour-h: 48px */
  background: var(--brand-tint);
  border: 1px dashed var(--brand);
  border-radius: 4px;
  z-index: 3;
  pointer-events: none;
}

/* Schedule page: day navigation row (prev / date picker / next). */
.sched-daynav { display: flex; align-items: center; gap: 0.5rem; }
.sched-daynav .btn { flex: none; }
.sched-daynav input[type="date"] { flex: 1; min-width: 0; }
.sched-today { width: 100%; }
.sched-count { margin: 0.25rem 0.25rem 0; }
.sched-empty { padding: 0.45rem 0.75rem; }

/* Schedule page: week view (schedule.php) — seven day columns side by side. */
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.page-head .btn { flex: none; }
.week-nav { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-top: 1rem; }
.week-nav .btn { flex: none; }
.week-nav input[type="date"] { width: 100%; max-width: 220px; }
.week-grid {
  display: grid;
  grid-template-columns: minmax(3.25rem, auto) minmax(0, 1fr);
  gap: 0;
  margin-top: 0.75rem;
  height: calc(100vh - 250px);
  min-height: 420px;
  padding-bottom: 0.25rem;
}
/* The seven day columns share one grid (and one horizontal scroller), so
   phones can scroll the days sideways while the hour ruler stays pinned on
   the left. On wide screens the days fill the row exactly, as before. */
.week-days {
  display: grid;
  grid-template-columns: repeat(7, minmax(150px, 1fr));
  min-width: 0;
  min-height: 0;
  overflow-x: auto;
}
/* Hour ruler: skinny first column with the hour labels, scrolling in step
   with the day columns (same .sched-hour rows keep them aligned). */
.week-day.week-hours { border: none; background: none; padding-left: 0; padding-right: 0; }
.week-hours .sched-timeline::before { display: none; }
.week-hours .sched-hour span { width: auto; }
/* The ruler is a passive indicator — no scrollbar of its own, so the labels
   aren't clipped (it still scrolls via the wheel and the scroll sync). */
.week-hours .sched-scroll { scrollbar-width: none; }
.week-hours .sched-scroll::-webkit-scrollbar { display: none; }

/* Each day column wraps one day-timeline widget (schedule_sidebar.php),
   so the column scrolls its 24 h timeline vertically, like the dashboard. */
.week-day {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border: 1px solid var(--line);
  background: var(--surface);
  padding: 0.4rem;
  overflow: hidden;
}
/* Columns sit flush: one shared border line between neighbours (kept on
   today so its highlight isn't clipped). */
.week-day + .week-day:not(.today) { border-left: none; }
/* Scrollbars hidden — the columns still scroll (wheel/touch) and stay
   synced; the hour ruler shows the current position. */
.week-grid .sched-scroll { scrollbar-width: none; }
.week-grid .sched-scroll::-webkit-scrollbar { display: none; }
.week-day .schedule-widget { flex: 1; min-height: 0; }
.week-day .sched-title {
  margin: 0 0 0.25rem;
  padding: 0.25rem 0.4rem;
  font-size: 0.85rem;
  border-radius: var(--radius-sm);
}
.week-day.today { border-color: var(--brand); }
.week-day.today .sched-title { background: var(--brand-tint); color: var(--brand-dark); }
.week-day .sched-timeline-wrap { flex: 1; min-height: 0; }
.week-day .sched-scroll { max-height: none; flex: 1; }

/* Working-hours tab (schedule.php?view=hours): the same week grid, but each
   day's timeline shows the recurring shift + breaks instead of the
   appointments. Shifts look like appointment events; breaks use the hatched
   band fill and sit on top of the shift. */
.sched-shift { cursor: pointer; }
.sched-break {
  z-index: 2;
  background: repeating-linear-gradient(45deg, #F7EFDC 0 6px, #EBDFC0 6px 12px);
  border-color: #D9C68F;
  border-left: 3px solid #C9A85C;
  color: #6B5310;
  cursor: pointer;
}
.sched-break:hover {
  background: repeating-linear-gradient(45deg, #EFE2C2 0 6px, #E3D2A6 6px 12px);
}
.schedule-widget.hours-readonly .sched-shift,
.schedule-widget.hours-readonly .sched-break { cursor: default; }
/* Shift/break picker in the add-hours dialog. */
.hours-kind { display: flex; align-items: center; gap: 1rem; font-size: 0.9rem; }
.hours-kind label { display: inline-flex; align-items: center; gap: 0.3rem; cursor: pointer; }

/* ---------- Phones: one day per screen ----------
   The week becomes a swipeable day view: each day column takes the full
   width next to the pinned hour ruler, and the physio list becomes a row
   of chips instead of a stacked sidebar. Desktop is untouched. */
@media (max-width: 899px) {
  .page-head { flex-wrap: wrap; }
  .week-grid { grid-template-columns: var(--sched-gutter) minmax(0, 1fr); }
  .week-days {
    grid-template-columns: repeat(7, minmax(0, 1fr));
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
  }
  .week-days .week-day {
    scroll-snap-align: start;
    scroll-snap-stop: always; /* one day per swipe */
  }
  .patient-nav.sched-nav { flex-direction: row; align-items: center; gap: 0.5rem 0.75rem; min-width: 0; }
  .patient-nav.sched-nav .sched-title { flex: none; }
  .patient-nav.sched-nav .patient-list {
    flex: 1 1 0; /* basis 0 + min-width 0: the row scrolls instead of widening the page */
    min-width: 0;
    flex-direction: row;
    gap: 0.35rem;
    max-height: none;
    overflow-x: auto;
    overflow-y: hidden;
    padding-bottom: 0.3rem; /* room for the scrollbar */
  }
  .patient-nav.sched-nav .patient-list li { flex: none; }
  .patient-nav.sched-nav .patient-list a {
    padding: 0.35rem 0.8rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    white-space: nowrap;
    font-size: 0.9rem;
  }
  .patient-nav.sched-nav .patient-list a .patient-count { float: none; margin-left: 0.35rem; }
}

/* Schedule page: view tabs + shared bits. */
.sched-tabs { margin-top: 0.5rem; }
.hours-label {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}

/* Sidebar physio list: appointment count badge for the current week. */
.patient-list a .patient-count {
  float: right;
  margin-left: 0.5rem;
  padding: 0 0.4rem;
  font-size: 0.75rem;
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 999px;
}

@media (min-width: 900px) {
  .patients-layout { grid-template-columns: 240px minmax(0, 1fr); }
  .patient-nav {
    padding-right: 0.75rem;
    border-right: 1px solid var(--line);
  }
  .patient-list { max-height: none; }
  main.full .sched-scroll { max-height: none; }
}

/* Dashboard: schedule widget in a sticky left column, content on the right.
   Stacked on phones. */
.dash-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
  align-items: start;
}
.dash-content { min-width: 0; }

.dash-side {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem;
}

@media (min-width: 900px) {
  .dash-layout { grid-template-columns: 280px minmax(0, 1fr); }
  .dash-content { grid-column: 2; }
  .dash-side {
    position: fixed;
    left: 1rem;
    top: calc(var(--header-h, 61px) + 1rem);
    width: 280px;
    height: calc(100vh - var(--header-h, 61px) - 2rem);
    display: flex;
    flex-direction: column;
  }
  .dash-side .schedule-widget { flex: 1; min-height: 0; }
  .dash-side .sched-timeline-wrap { flex: 1; min-height: 0; }
  .dash-side .sched-scroll { flex: 1; min-height: 0; max-height: none; }
}

/* Client page (physio): main workflow + sidebar. Stacked on phones. */
.client-cols {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 1.5rem;
  align-items: start;
}

@media (min-width: 900px) {
  .client-cols { grid-template-columns: minmax(0, 1fr) 380px; }
}

/* QR code frame (client page): the SVG has a fixed pixel size but a viewBox,
   so it scales down cleanly to fit whatever card it lives in. */
.qr-frame { max-width: 100%; }
.qr-frame svg { display: block; max-width: 100%; height: auto; }

/* ---------- Buttons ---------- */

.btn {
  display: inline-block;
  background: var(--brand);
  color: #fff;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 0.6rem 1.15rem;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.4;
  cursor: pointer;
  text-decoration: none;
  transition: background 150ms ease, border-color 150ms ease, color 150ms ease;
}

.btn:hover { background: var(--brand-dark); }

.btn:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  box-shadow: var(--focus-ring);
}

.btn:disabled { opacity: 0.6; cursor: not-allowed; }

.btn.secondary {
  background: var(--brand-tint);
  color: var(--brand-dark);
}
.btn.secondary:hover { background: var(--brand-tint-strong); }

.btn.danger { background: var(--danger); }
.btn.danger:hover { background: #a03a32; }
.btn.danger:focus-visible { outline-color: var(--danger); }

.btn.ghost {
  background: transparent;
  color: var(--brand-dark);
  border-color: var(--line-strong);
}
.btn.ghost:hover {
  background: var(--brand-tint);
  border-color: var(--brand-tint-strong);
}

.btn.small { padding: 0.4rem 0.8rem; font-size: 0.85rem; }

/* ---------- Forms ---------- */

label {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-soft);
  margin: 0.75rem 0 0.3rem;
}

input[type=text],
input[type=email],
input[type=password],
input[type=date],
input[type=time],
input[type=number],
input[type=tel],
input[type=search],
textarea,
select {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 0.95rem;
  background: var(--surface);
  color: var(--ink);
  transition: border-color 150ms ease, box-shadow 150ms ease;
}

input:focus,
textarea:focus,
select:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: var(--focus-ring);
}

input::placeholder,
textarea::placeholder { color: var(--muted); opacity: 0.7; }

input[type=file] {
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  background: var(--surface-hover);
  color: var(--ink-soft);
}

input[type=file]::file-selector-button {
  background: var(--brand-tint);
  color: var(--brand-dark);
  border: none;
  border-radius: 8px;
  padding: 0.45rem 0.9rem;
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  margin-right: 0.6rem;
  transition: background 150ms ease;
}

input[type=file]::file-selector-button:hover { background: var(--brand-tint-strong); }

textarea { min-height: 90px; resize: vertical; }

/* ---------- Toolbar (search + filters) ---------- */

.toolbar {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

.toolbar .ex-search { flex: 1 1 220px; }

.toolbar select {
  flex: 0 0 auto;
  width: auto;
  min-width: 180px;
  max-width: 260px;
}

@media (max-width: 640px) {
  .toolbar select { flex: 1 1 100%; max-width: none; }
}

/* ---------- Tables ---------- */

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

th, td {
  text-align: left;
  padding: 0.65rem 0.75rem;
  border-bottom: 1px solid var(--line);
  font-size: 0.93rem;
}

th {
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 2px solid var(--line);
}

tbody tr { transition: background 150ms ease; }
tbody tr:hover { background: var(--surface-hover); }
tbody tr:last-child td { border-bottom: none; }

/* ---------- Row actions (table buttons) ---------- */

.actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.5rem;
  white-space: nowrap;
}

.actions form { display: flex; }

/* ---------- Badges & alerts ---------- */

.badge {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: var(--brand-tint);
  color: var(--brand-dark);
}

.alert {
  padding: 0.75rem 1rem;
  border-radius: var(--radius-sm);
  margin-bottom: 1rem;
  font-size: 0.92rem;
  line-height: 1.5;
}

.alert.error {
  background: var(--danger-tint);
  color: #8c332c;
  border: 1px solid #eec5c0;
}

.alert.success {
  background: var(--success-tint);
  color: #22604a;
  border: 1px solid #c2e0cf;
}

.alert.warning {
  background: var(--warning-tint);
  color: #7d5717;
  border: 1px solid #e8d9b0;
}

/* ---------- Modals ---------- */

dialog.modal {
  border: none;
  border-radius: var(--radius);
  padding: 0;
  width: min(480px, calc(100vw - 2rem));
  box-shadow: var(--shadow-modal);
  color: var(--ink);
  font-family: var(--font-body);
}

dialog.modal::backdrop {
  background: rgba(31, 50, 44, 0.45);
}

/* Wider popup for the drag-to-add appointment form. */
dialog.modal.wide { width: min(760px, calc(100vw - 2rem)); }

/* Two-column grid used by the appointment forms (popups + schedule page). */
.appt-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}
.appt-form > * { min-width: 0; }
.appt-form .span-2 { grid-column: 1 / -1; }
.appt-form .form-actions { margin-top: 0.5rem; }
@media (max-width: 520px) {
  .appt-form { grid-template-columns: 1fr; }
}

/* Wider popup for playing exercise videos. */
dialog.modal.video-modal { width: min(680px, calc(100vw - 2rem)); }
dialog.modal.video-modal .video-embed,
dialog.modal.video-modal video { max-width: 100%; }

.modal-body { padding: 1.25rem; }

.modal-head {
  display: flex;
  align-items: center;
  margin-bottom: 0.5rem;
  padding: 1.25rem 1.25rem 0;
}

.modal-head h2 { margin: 0; font-size: 1.15rem; }

.modal-close {
  margin-left: auto;
  background: none;
  border: none;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  color: var(--muted);
  padding: 0.25rem 0.6rem;
  border-radius: 8px;
  transition: background 150ms ease, color 150ms ease;
}

.modal-close:hover { background: var(--brand-tint); color: var(--ink); }

/* ---------- Feedback (screenshot + note) ---------- */

/* Feedback trigger in the header — styled like the nav links. */
.nav button.link {
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 500;
  padding: 0.35rem 0.5rem;
  border-radius: var(--radius-sm);
  border: none;
  background: none;
  font-family: inherit;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease;
}
.nav button.link:hover { color: var(--brand-dark); background: var(--brand-tint); }
.nav button.link:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* Feedback trigger injected into every popup's head. */
.modal-head .fb-trigger {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: none;
  border: none;
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
  padding: 0.25rem 0.6rem;
  border-radius: 8px;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease;
}
.modal-head .fb-trigger:hover { color: var(--brand-dark); background: var(--brand-tint); }
.modal-head .fb-trigger:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* Feedback dialog: screenshot + markup canvas. */
.fb-dialog .fb-hint { margin-top: 0; }
.fb-stage {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: #fff;
}
.fb-stage .fb-shot { display: block; width: 100%; height: auto; }
.fb-stage .fb-mark {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  cursor: crosshair;
  touch-action: none;
}
.fb-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; margin: 0.75rem 0 0.25rem; }
.fb-toolbar .fb-label { font-size: 0.82rem; font-weight: 600; color: var(--ink-soft); }
.fb-swatches { display: inline-flex; gap: 0.4rem; }
.fb-swatch {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid transparent;
  padding: 0;
  cursor: pointer;
  transition: transform 150ms ease;
}
.fb-swatch:hover { transform: scale(1.1); }
.fb-swatch.active { border-color: var(--ink); }
.fb-swatch:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.fb-tools { margin-left: auto; display: inline-flex; gap: 0.5rem; }
.fb-actions { margin-top: 0.75rem; justify-content: flex-end; }
.fb-status { min-height: 1.2em; margin-top: 0.5rem; font-size: 0.85rem; }
.fb-status.ok { color: var(--success); }
.fb-status.err { color: var(--danger); }

/* Feedback review (admin). */
.fb-tabs { margin-bottom: 1rem; }
.fb-thumb { width: 72px; height: auto; border: 1px solid var(--line); border-radius: 8px; display: block; }
.fb-page { display: block; font-size: 0.75rem; color: var(--muted); word-break: break-all; }
.fb-note { max-width: 260px; }
.fb-date { white-space: nowrap; }
.fb-small { font-size: 0.75rem; }
.fb-actions-cell { white-space: nowrap; }
form.inline { display: inline-block; }
.badge.open { background: var(--warning-tint); color: var(--warning); }
.badge.resolved { background: var(--success-tint); color: var(--success); }
.btn.ghost.danger { color: var(--danger); border-color: var(--line-strong); }
.btn.ghost.danger:hover { background: var(--danger-tint); border-color: var(--danger); }

/* ---------- Exercise list (collapsible) ---------- */

.ex-card summary {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  padding: 0.9rem 0;
  cursor: pointer;
  list-style: none;
  -webkit-tap-highlight-color: transparent;
}

.ex-card summary::-webkit-details-marker { display: none; }
.ex-card summary::marker { content: none; }

.ex-card summary:hover .ex-name strong { color: var(--brand-dark); }

.ex-card .ex-num { min-width: 1.2rem; text-align: center; font-weight: 600; }
.ex-card .ex-caret { color: var(--muted); transition: transform 150ms ease; }
.ex-card details[open] > summary .ex-caret { transform: rotate(90deg); }
.ex-detail { padding: 0 0 0 1.8rem; max-width: 640px; }

.ex-rx-box {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1.25rem;
  width: fit-content;
  margin: 0.9rem auto 0.25rem;
  padding: 0.55rem 1.1rem;
  background: var(--brand-tint);
  border-radius: calc(var(--radius) - 4px);
  font-weight: 600;
}
.ex-rx-item { white-space: nowrap; }
.ex-rx-item strong { font-weight: 700; }

/* ---------- Workout plan (client dashboard) ---------- */

.plan-progress { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1.5rem; }
.plan-progress-track {
  flex: 0 1 320px;
  height: 8px;
  background: var(--brand-tint);
  border-radius: 999px;
  overflow: hidden;
}
.plan-progress-fill { height: 100%; background: var(--brand); border-radius: 999px; transition: width 300ms ease; }

.plan-nav { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 0.6rem; margin-bottom: 0.4rem; }
.plan-nav .plan-progress { margin: 0; }
.plan-nav .plan-progress-track { flex: 1; }

.day-head { display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; margin-top: 0.25rem; padding-top: 1.1rem; border-top: 1px solid var(--line); }
.day-count { margin-left: auto; font-size: 0.85rem; }

.day-badge {
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.1rem 0.55rem;
  border-radius: 999px;
  white-space: nowrap;
}
.day-badge.done { background: var(--success-tint); color: var(--success); }
.day-badge.today { background: var(--brand-tint); color: var(--brand-dark); }
.day-badge.upcoming { background: var(--bg); color: var(--muted); }

.day-note-form { max-width: 480px; }
.day-note-form label { margin-top: 0; }

.day-card-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--line);
}
.day-complete-form { margin: 0; }

.plan-finished { margin: 1rem 0 0; font-weight: 600; color: var(--success); }

/* ---------- Workout notes ---------- */

.note-form { margin-top: 1rem; max-width: 480px; }
.note-form label { margin-top: 0; }
.note-form .note-actions { margin-top: 0.5rem; }

.my-note {
  margin: 0.75rem 0 0;
  padding: 0.6rem 0.75rem;
  background: var(--brand-tint);
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  line-height: 1.5;
}

.feed { list-style: none; margin: 0; padding: 0; }
.feed li { padding: 0.75rem 0; border-bottom: 1px solid var(--line); }
.feed li:last-child { border-bottom: none; padding-bottom: 0; }
.feed-head { display: flex; gap: 0.5rem; align-items: baseline; flex-wrap: wrap; }
.feed-when { margin-left: auto; white-space: nowrap; }
.feed-note { margin: 0.35rem 0 0.25rem; font-size: 0.95rem; line-height: 1.55; white-space: pre-wrap; }
.feed a { font-size: 0.85rem; }

.reply {
  margin: 0.5rem 0 0;
  padding: 0.5rem 0.75rem;
  background: var(--bg);
  border-left: 3px solid var(--brand);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: 0.9rem;
  line-height: 1.5;
}
.reply-form {
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  margin-top: 0.5rem;
  max-width: 480px;
}
.reply-form textarea { flex: 1; min-height: 0; }
.reply-form .btn { white-space: nowrap; }

.reply-row td { background: var(--surface-hover); }
.reply-cell { padding-left: 1.5rem; }

@media (max-width: 640px) {
  .ex-detail { padding-left: 0; }
}

/* ---------- Media ---------- */

.video-embed {
  position: relative;
  width: 100%;
  max-width: 340px;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: #000;
}

.video-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; }

video {
  width: 100%;
  max-width: 340px;
  border-radius: var(--radius-sm);
  background: #000;
}

.exercise-image {
  width: 100%;
  max-width: 340px;
  border-radius: var(--radius-sm);
}

/* Exercise list: inline picture thumbnails + placeholder */
.ex-thumb-btn {
  display: inline-flex;
  padding: 0;
  border: none;
  background: none;
  cursor: zoom-in;
  border-radius: var(--radius-sm);
}

.ex-thumb {
  width: 64px;
  height: 48px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
}

.ex-thumb-btn:hover .ex-thumb {
  border-color: var(--brand);
}


/* ---------- Auth pages ---------- */

.auth-wrap { max-width: 400px; margin: 2.5rem auto; }

.auth-wrap h1 { text-align: center; font-size: 1.5rem; margin-bottom: 0.25rem; }
.auth-wrap .auth-sub { text-align: center; margin-top: 0; }
.auth-wrap .btn { width: 100%; margin-top: 1rem; }
.auth-wrap .auth-hint { text-align: center; margin: 0.75rem 0 0; }

/* "or" divider between the login form and the QR scan option */
.auth-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1.25rem;
  color: var(--muted);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.auth-divider::before,
.auth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

/* QR scanner overlay: full-screen camera feed */
.scanner {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(31, 50, 44, 0.6);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 1.5rem;
}
.scanner[hidden] { display: none; }

.scanner-top {
  width: 100%;
  max-width: 340px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.scanner-top h2 { margin: 0; font-size: 1.15rem; color: #fff; }

.scanner-status {
  width: 100%;
  max-width: 340px;
  margin: 0;
  min-height: 1.2em;
  text-align: center;
  color: #fff;
  font-size: 0.9rem;
  line-height: 1.5;
}

.scanner-video {
  display: block;
  width: 100%;
  max-width: 340px;
  max-height: 65vh;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--radius);
  background: #000;
}

/* App install prompt (login page, mobile) */
.install-prompt {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1.25rem;
  padding: 0.75rem 1rem;
  background: var(--brand-tint);
  border: 1px solid var(--brand-tint-strong);
  border-radius: var(--radius-sm);
}
.install-prompt[hidden] { display: none; }
.install-prompt .ip-text { flex: 1; }
.install-prompt strong { display: block; font-size: 0.9rem; color: var(--brand-dark); }
.install-prompt .muted { margin: 0; }
.install-prompt .ip-share { font-size: 0.8em; }

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition: none !important;
    animation: none !important;
  }
}

/* ---------- Small screens ---------- */

@media (max-width: 640px) {
  .nav { gap: 0.75rem; padding: 0.75rem 0.75rem; }
  .nav .brand { font-size: 1.05rem; }
  .nav a.link, .nav button.link { font-size: 0.85rem; padding: 0.3rem 0.4rem; }
  .nav .who { display: none; }
  main { margin-top: 0; } /* tab panels keep their own 1rem top padding, matching the 1rem side gutters */
  .card { padding: 1rem; }
  .btn { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
}
