/* ------------------------------------------------------------------ tokens

   One product, two moods. Light is a soft pastel morning - lavender, sky and
   peach washes behind white cards. Dark is the same room at night - the same
   washes glowing out of deep navy behind frosted glass. Both share one
   typeface, one set of shapes and one meaning per colour:

     violet  the brand, and "with the doctor"
     peach   sitting in the waiting room
     sky     booked, expected
     green   done
     rose    no-show
     coral   the time right now

   Everything visual comes from the variables below; the rules further down
   never name a colour of their own. */

:root {
  --grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 .05 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  --base: #f7f5fd;
  --glow-a: #ebe6ff;                    /* top left */
  --glow-b: #e2f1ff;                    /* top right */
  --glow-c: #ffe7dc;                    /* bottom right */

  --surface: #ffffff;
  --surface-line: rgba(108, 77, 246, 0.08);
  --surface-shadow: 0 1px 2px rgba(60, 40, 140, .05), 0 20px 44px -30px rgba(80, 60, 160, .32);
  --inset: #f5f3fc;                     /* wells inside a card */
  --control: #ffffff;
  --control-line: rgba(108, 77, 246, 0.10);
  --control-shadow: 0 1px 2px rgba(60, 40, 140, .06);

  --ink: #29263f;
  --ink-soft: #5f5a7e;
  --ink-faint: #8a85a6;
  --ink-ghost: #bab4d6;
  --time: #5b3fe0;
  --rule: #f1eefa;
  --rule-hour: #e4def8;

  --accent: #6547f0;
  --accent-ink: #ffffff;
  --accent-soft: #eeeaff;
  --accent-text: #5b3fe0;
  --accent-glow: 0 4px 12px -6px rgba(101, 71, 240, .55);
  --kind-alt: #6547f0;

  --door: linear-gradient(135deg, #6c4df6 0%, #8f7bff 55%, #7cc6fe 100%);
  --door-line: transparent;
  --door-ink: #ffffff;
  --door-shadow: 0 16px 32px -20px rgba(101, 71, 240, .55);
  --lamp: linear-gradient(135deg, #ff8a5c 0%, #ffae7a 60%, #ffd29a 100%);
  --lamp-line: transparent;
  --lamp-ink: #ffffff;
  --lamp-shadow: 0 16px 32px -20px rgba(255, 125, 85, .55);

  --now: #ff7d55;
  --now-ink: #ffffff;
  --fresh-bg: #efeaff;
  --current-bg: #f4f1ff;

  --s-booked-bg: #eaf5ff;    --s-booked-fg: #2a70ad;
  --s-waiting-bg: #ffe9dc;   --s-waiting-fg: #b04a1a;
  --s-inroom-bg: #6547f0;  --s-inroom-fg: #ffffff;
  --s-done-bg: #e6f8ef;      --s-done-fg: #23875a;
  --s-noshow-bg: #ffe4ea;    --s-noshow-fg: #c2355a;
  --s-cancelled-bg: #f2f1f7; --s-cancelled-fg: #8a85a6;
  --dot-glow: none;

  --warn-bg: #ffe9dc;
  --warn-fg: #a8461a;
  --warn-line: transparent;
  --danger: #d63a5e;
  --ok: #2fbf82;
  --ok-glow: none;

  /* Popups read as floating above the page, so they get their own surface. */
  --pop: #ffffff;
  --pop-hover: #f4f1ff;
  --pop-line: #ece6ff;
  --pop-shadow: 0 1px 2px rgba(60, 40, 140, .06), 0 18px 40px -16px rgba(60, 40, 140, .3);
  --scrim: rgba(45, 42, 74, 0.35);

  --blur: blur(18px);
  --r-card: 22px;
  --r-inner: 14px;
  --r-field: 12px;

  --font: "Nunito", "Segoe UI", system-ui, -apple-system, sans-serif;
}

/* Theme is driven by data-theme on <html>, set by the inline script in each
   page's <head> before first paint. Reception defaults to light, the board
   defaults to the device setting, and the toggle button overrides either. */
:root[data-theme="dark"] {
  --grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 .14 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  --base: #0a1022;
  --glow-a: rgba(64, 200, 190, 0.18);
  --glow-b: rgba(255, 160, 110, 0.07);
  --glow-c: rgba(122, 92, 255, 0.26);

  --surface: rgba(255, 255, 255, 0.05);
  --surface-line: rgba(255, 255, 255, 0.10);
  --surface-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 30px 60px -30px rgba(0, 0, 0, .6);
  --inset: rgba(0, 0, 0, 0.16);
  --control: rgba(255, 255, 255, 0.07);
  --control-line: rgba(255, 255, 255, 0.12);
  --control-shadow: none;

  --ink: #e9ecf8;
  --ink-soft: #aab4d4;
  --ink-faint: #8791b5;
  --ink-ghost: #5c678c;
  --time: #c4b8ff;
  --rule: rgba(255, 255, 255, 0.06);
  --rule-hour: rgba(255, 255, 255, 0.13);

  --accent: #9d88ff;
  --accent-ink: #140c38;
  --accent-soft: rgba(157, 136, 255, 0.16);
  --accent-text: #c4b8ff;
  --accent-glow: 0 0 16px rgba(157, 136, 255, .35);
  --kind-alt: #b9a8ff;

  --door: linear-gradient(135deg, rgba(157, 136, 255, 0.30), rgba(124, 198, 254, 0.08));
  --door-line: rgba(157, 136, 255, 0.45);
  --door-ink: #ffffff;
  --door-shadow: 0 0 36px -12px rgba(157, 136, 255, .5), inset 0 1px 0 rgba(255, 255, 255, .12);
  --lamp: linear-gradient(135deg, rgba(255, 170, 90, 0.30), rgba(255, 170, 90, 0.07));
  --lamp-line: rgba(255, 181, 71, 0.45);
  --lamp-ink: #ffffff;
  --lamp-shadow: 0 0 36px -12px rgba(255, 181, 71, .4), inset 0 1px 0 rgba(255, 255, 255, .1);

  --now: #ff8f6b;
  --now-ink: #2a0d02;
  --fresh-bg: rgba(157, 136, 255, 0.16);
  --current-bg: rgba(157, 136, 255, 0.08);

  --s-booked-bg: rgba(124, 198, 254, 0.12);  --s-booked-fg: #9fd4ff;
  --s-waiting-bg: rgba(255, 181, 71, 0.14);  --s-waiting-fg: #ffb547;
  --s-inroom-bg: rgba(157, 136, 255, 0.22);  --s-inroom-fg: #d8d0ff;
  --s-done-bg: rgba(94, 242, 194, 0.10);     --s-done-fg: #5ef2c2;
  --s-noshow-bg: rgba(255, 107, 122, 0.14);  --s-noshow-fg: #ff8593;
  --s-cancelled-bg: rgba(255, 255, 255, 0.05); --s-cancelled-fg: #7c88ad;
  --dot-glow: 0 0 6px currentColor;

  --warn-bg: rgba(255, 181, 71, 0.12);
  --warn-fg: #ffcf85;
  --warn-line: rgba(255, 181, 71, 0.3);
  --danger: #ff8593;
  --ok: #5ef2c2;
  --ok-glow: none;

  --pop: #1b2140;
  --pop-hover: #262d52;
  --pop-line: rgba(255, 255, 255, 0.14);
  --pop-shadow: 0 20px 44px -10px rgba(0, 0, 0, 0.7);
  --scrim: rgba(3, 6, 18, 0.6);
}

/* ------------------------------------------------------------------ base */

* { box-sizing: border-box; }

html { background: var(--base); }

body {
  margin: 0;
  min-height: 100vh;
  padding: 26px 20px 32px;
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.45;
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  background:
    var(--grain),
    radial-gradient(ellipse 55% 60% at 0% 0%, var(--glow-a), transparent 70%),
    radial-gradient(ellipse 45% 50% at 90% 5%, var(--glow-b), transparent 70%),
    radial-gradient(ellipse 55% 60% at 100% 100%, var(--glow-c), transparent 70%),
    var(--base);
  background-attachment: fixed;
}

.wrap { max-width: 1120px; margin: 0 auto; }

.subtle { color: var(--ink-soft); font-size: 14px; font-weight: 600; }

button {
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  background: var(--control);
  border: 1px solid var(--control-line);
  box-shadow: var(--control-shadow);
  border-radius: 999px;
  padding: 9px 18px;
  cursor: pointer;
  min-height: 42px;
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
}
button:hover { box-shadow: 0 0 0 2px var(--accent-soft), var(--control-shadow); }
button:active { transform: translateY(1px); }
button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  box-shadow: var(--accent-glow);
}
button.plain {
  border: none;
  background: none;
  box-shadow: none;
  padding: 4px;
  min-height: 0;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
/* Momentary confirmation on the button that was pressed. */
button.ok {
  background: var(--s-done-bg);
  border-color: transparent;
  color: var(--s-done-fg);
}
button.danger { color: var(--danger); }

input, select, textarea {
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  background: var(--control);
  border: 1px solid var(--control-line);
  border-radius: var(--r-field);
  padding: 9px 14px;
  min-height: 42px;
  max-width: 100%;
}
input::placeholder, textarea::placeholder { color: var(--ink-faint); }
input:focus, select:focus, textarea:focus, button:focus-visible, [role="button"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
select option { background: var(--pop); color: var(--ink); }

.themebtn { min-width: 80px; }

/* Drawn rather than typed. Arrow characters render at different weights and
   baselines depending on the font the browser falls back to. */
.arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  width: 40px;
}
.arrow svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

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

.card {
  position: relative;
  z-index: 1;
  background: var(--surface);
  border: 1px solid var(--surface-line);
  border-radius: var(--r-card);
  box-shadow: var(--surface-shadow);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
}

/* The board has no popup menus, so it can safely clip to its rounded corners.
   The reception page must not clip, or the row menus get cut off. */
.card.clip { overflow: hidden; }

/* ------------------------------------------------------------------ header */

/* The legal documents, in a quiet line above each signed-in screen's header. */
.applegal {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 4px 18px;
  margin: -10px 0 10px;
  font-size: 13px;
  font-weight: 600;
}
.applegal a { color: var(--ink-faint); text-decoration: none; }
.applegal a:hover { color: var(--accent-text); text-decoration: underline; }
.applegal a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

.topbar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.daytitle {
  font-size: 32px;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0 0 8px;
}
.daytag {
  display: inline-block;
  vertical-align: middle;
  margin-left: 12px;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: var(--accent-glow);
}

.daynav { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.daynav input[type="date"] { border-radius: 999px; box-shadow: var(--control-shadow); }
:root[data-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(0.8); }

/* ------------------------------------------------------------------ status */

.pill {
  position: relative;
  display: inline-block;
  font-size: 13px;
  font-weight: 800;
  padding: 5px 13px 5px 24px;
  border-radius: 999px;
  white-space: nowrap;
}
.pill::before {
  content: '';
  position: absolute;
  left: 11px;
  top: 50%;
  width: 7px;
  height: 7px;
  margin-top: -3.5px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: var(--dot-glow);
}
.pill.booked    { background: var(--s-booked-bg);    color: var(--s-booked-fg); }
.pill.waiting   { background: var(--s-waiting-bg);   color: var(--s-waiting-fg); }
.pill.inroom { background: var(--s-inroom-bg);    color: var(--s-inroom-fg); box-shadow: none; }
.pill.done      { background: var(--s-done-bg);      color: var(--s-done-fg); }
.pill.noshow    { background: var(--s-noshow-bg);    color: var(--s-noshow-fg); }
.pill.cancelled { background: var(--s-cancelled-bg); color: var(--s-cancelled-fg); }

/* Appointment type, shown on every appointment on both screens. In person is
   the ordinary case and stays quiet; anything else is worth noticing. */
.kind {
  flex: none;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-faint);
  white-space: nowrap;
}
.kind.alt { color: var(--kind-alt); font-weight: 800; }

.dot {
  display: inline-block;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--ink-faint);
  margin-right: 8px;
  vertical-align: 0;
}
.dot.on { background: var(--ok); box-shadow: var(--ok-glow); }
.dot.off { background: var(--danger); }

/* ------------------------------------------------------------------ banners */

.banner {
  padding: 12px 18px;
  font-size: 16px;
  font-weight: 800;
  background: var(--warn-bg);
  color: var(--warn-fg);
  border: 1px solid var(--warn-line);
  border-radius: var(--r-inner);
  margin: 0 14px 12px;
}
.banner.hidden { display: none; }

/* Only the note banner carries a button - the connection one is text alone. */
#note:not(.hidden) { display: flex; align-items: center; gap: 14px; }
#note-text { flex: 1; }

/* When it was sent. Quiet enough to read past, there when it is wanted. */
.notetime {
  flex: none;
  font-size: 14px;
  font-weight: 600;
  opacity: 0.8;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.bannerclear {
  flex: none;
  color: var(--warn-fg);
  background: transparent;
  border: 1.5px solid currentColor;
  box-shadow: none;
  min-height: 34px;
  padding: 4px 16px;
}
.bannerclear:hover { opacity: 0.75; box-shadow: none; }
.bannerclear:disabled { opacity: 0.5; cursor: default; }

.errorbar {
  background: var(--s-noshow-bg);
  color: var(--s-noshow-fg);
  padding: 12px 18px;
  border-radius: var(--r-inner);
  font-size: 15px;
  font-weight: 700;
  margin-bottom: 12px;
}
.errorbar.hidden { display: none; }

/* Somebody getting the doctor's screen passcode wrong. Louder than an error
   and it stays until dismissed, because it is meant to be noticed. */
.alertbar {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--s-noshow-bg);
  color: var(--s-noshow-fg);
  border: 1.5px solid currentColor;
  border-radius: var(--r-inner);
  padding: 12px 18px;
  font-size: 15px;
  font-weight: 700;
  margin-bottom: 12px;
}
.alertbar.hidden { display: none; }
.alerttext { flex: 1; }
.alertdismiss {
  flex: none;
  background: transparent;
  border: 1.5px solid currentColor;
  box-shadow: none;
  color: inherit;
  min-height: 34px;
  padding: 4px 14px;
  font-size: 14px;
}

/* ------------------------------------------------------------------ week strip */

.weekstrip {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  margin-bottom: 18px;
}
.weekday {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  column-gap: 8px;
  align-items: baseline;
  min-width: 0;
  border: 1px solid transparent;
  border-radius: var(--r-inner);
  padding: 9px 12px;
  cursor: pointer;
  text-align: left;
}
.weekday:hover { background: var(--surface); }
.weekday.active {
  background: var(--surface);
  border-color: var(--surface-line);
  box-shadow: 0 1px 2px rgba(60, 40, 140, .05), 0 8px 20px -12px rgba(108, 77, 246, .35);
}
.wd-num {
  grid-row: 1 / 3;
  font-size: 27px;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.wd-name { font-size: 14px; font-weight: 800; color: var(--ink-soft); line-height: 1.2; }
.wd-count { font-size: 12px; font-weight: 600; color: var(--ink-faint); line-height: 1.2; white-space: nowrap; }
.weekday.active .wd-num, .weekday.istoday .wd-num { color: var(--accent-text); }
.weekday.active .wd-num { text-shadow: none; }

/* ------------------------------------------------------------------ reception rows

   Ruled like a day book: each hour opens with a firmer line, and the quarter
   hours inside it sit on lighter dashed ones. */

.wrap > .card { padding: 6px 0 0; }

.row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 20px 10px 34px;
  border-top: 1px dashed var(--rule);
  min-height: 54px;
  padding-top: 9px;
  padding-bottom: 9px;
}
.row.hour { border-top: 1px solid var(--rule-hour); }
.row:first-child { border-top: none; }

.row .time {
  font-variant-numeric: tabular-nums;
  font-size: 16px;
  font-weight: 800;
  color: var(--time);
  width: 52px;
  flex: none;
}
.row .who { flex: 1; min-width: 0; }
.row .who .nm { font-size: 17px; font-weight: 700; }
.row .who .rs {
  display: flex;
  gap: 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-faint);
}
.row .who .rs .tel { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Dim the content, never the row. Opacity on .row would create a stacking
   context that traps the popup menu underneath the rows below it. The pill
   keeps its full colour - its colour already says the appointment is over. */
.row.spent .nm { text-decoration: line-through; text-decoration-thickness: 1.5px; }
.row.spent .time,
.row.spent .who,
.row.spent .kind { opacity: 0.45; }

/* Free slots. Only the time and "Add patient" show until the slot is pointed
   at or typed into, so a morning of empty slots reads as space rather than as
   a wall of boxes. */
.row.empty-slot { min-height: 44px; padding-top: 5px; padding-bottom: 5px; }
.row.empty-slot .time { color: var(--ink-ghost); }

/* The dot at the far left crosses a slot out. It sits in the row's left margin
   rather than in the flow, so free and booked times line up in one column. */
.row .dot {
  position: absolute;
  left: 12px;
  top: 50%;
  translate: 0 -50%;
  width: 12px;
  height: 12px;
  min-height: 0;
  padding: 0;
  margin: 0;
  border-radius: 50%;
  border: 1.5px solid var(--ink-ghost);
  background: transparent;
  box-shadow: none;
  cursor: pointer;
  opacity: 0;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.row:hover .dot, .row .dot:focus-visible { opacity: 1; }
.row .dot:hover { border-color: var(--danger); box-shadow: none; }
.row .dot.on {
  opacity: 1;
  background: var(--ink-faint);
  border-color: var(--ink-faint);
}

/* A crossed-out slot: hatched and stripped of its inputs. */
.row.blocked { background: repeating-linear-gradient(135deg, transparent 0 8px, var(--rule-hour) 8px 9px); }
.row.blocked .time { text-decoration: line-through; }
.blockedout {
  flex: 1;
  /* Lines up with the text inside the "Add patient" boxes above and below. */
  padding-left: 13px;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink-faint);
}

.row .newname, .row .newreason, .row .newphone, .row .newkind {
  font: inherit;
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  background: transparent;
  border: 1px solid transparent;
  box-shadow: none;
  border-radius: var(--r-field);
  padding: 6px 12px;
  min-height: 38px;
  min-width: 0;
}
.row .newname { flex: 1.1; }
.row .newreason { flex: 1.2; }
.row .newphone { flex: 0.9; font-variant-numeric: tabular-nums; }
.row .newkind { flex: none; width: 150px; font-size: 15px; color: var(--ink-soft); }
.row .newname::placeholder { color: var(--ink-ghost); }
.row .newreason::placeholder,
.row .newphone::placeholder { color: var(--ink-faint); }

/* The extra fields wait until the slot is in use. */
.row.empty-slot:not(:hover):not(:focus-within) .newreason::placeholder,
.row.empty-slot:not(:hover):not(:focus-within) .newphone::placeholder { color: transparent; }
.row.empty-slot:not(:hover):not(:focus-within) .newkind { opacity: 0; }

.row.empty-slot:hover .newname,
.row.empty-slot:hover .newreason,
.row.empty-slot:hover .newphone,
.row.empty-slot:hover .newkind,
.row.empty-slot:focus-within .newname,
.row.empty-slot:focus-within .newreason,
.row.empty-slot:focus-within .newphone,
.row.empty-slot:focus-within .newkind { background: var(--inset); }

.row .newname:focus, .row .newreason:focus, .row .newphone:focus, .row .newkind:focus {
  border-color: var(--accent);
  background: var(--control);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.row .newkind:focus { color: var(--ink); }

/* Appears at the end of the line as soon as a name is typed. */
.addbtn {
  flex: none;
  background: var(--accent);
  border: none;
  color: var(--accent-ink);
  box-shadow: var(--accent-glow);
  font-size: 15px;
  font-weight: 700;
  padding: 6px 20px;
  min-height: 38px;
  border-radius: 999px;
  cursor: pointer;
}
.addbtn.hidden { display: none; }

/* The row being edited. */
.row select, .row input[data-edit] { min-height: 38px; padding: 6px 12px; background: var(--inset); }

.menu { position: relative; flex: none; }
.menu > button.plain {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  color: var(--ink-faint);
  font-size: 18px;
  font-weight: 900;
  line-height: 1;
  padding-bottom: 8px;
}
.menu > button.plain:hover { background: var(--accent-soft); color: var(--accent-text); }
.menu-pop {
  position: absolute;
  right: 0;
  top: 42px;
  z-index: 50;
  background: var(--pop);
  border: 1px solid var(--pop-line);
  border-radius: var(--r-inner);
  box-shadow: var(--pop-shadow);
  min-width: 206px;
  padding: 6px;
}
.menu-pop.hidden { display: none; }
/* Rows near the bottom of the list open their menu upward instead. */
.menu-pop.up { top: auto; bottom: 44px; }
.menu-pop button {
  display: block;
  width: 100%;
  text-align: left;
  border: none;
  background: none;
  box-shadow: none;
  border-radius: 12px;
  padding: 7px 10px;
  min-height: 0;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.menu-pop button:hover { background: var(--pop-hover); box-shadow: none; }
.menu-pop .pill { pointer-events: none; }
.menu-pop hr { border: none; border-top: 1px solid var(--pop-line); margin: 6px 4px; }

/* ------------------------------------------------------------------ note to the doctor */

.noteform {
  display: flex;
  gap: 10px;
  padding: 12px 14px;
  margin: 8px 12px 12px;
  align-items: center;
  background: var(--inset);
  border-radius: 18px;
}
.noteform input { flex: 1; border-radius: 999px; background: var(--control); }
.noteform #note-save {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: var(--accent-glow);
}

/* Under both message boxes: what belongs in a message, and that it does not
   last. Soft ink rather than faint, so it stays readable at this size. */
.msghint {
  margin: -4px 26px 12px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--ink-soft);
}
.modalbox .msghint { margin: -4px 2px 8px; }

.notelive {
  padding: 0 26px 16px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-soft);
}
.notelive.hidden { display: none; }
.notelive .lbl { color: var(--ink-faint); }
.notelive .notetime { margin-left: 8px; }

.footrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 20px;
}
.footrow .subtle { max-width: 64ch; font-weight: 600; }

/* This one ends the working day for both screens, so it is red in both themes
   - outlined until pointed at, so it is findable without shouting all day. */
button.stop {
  background: transparent;
  border: 1.5px solid var(--danger);
  color: var(--danger);
  box-shadow: none;
}
button.stop:hover { background: var(--danger); color: var(--base); }

/* ------------------------------------------------------------------ popups */

/* Deliberately not dismissible by clicking the backdrop or pressing Escape -
   the other room needs to know the message was actually seen, so the only
   way out is a button. */
.modal {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 500;
}
.modal.hidden { display: none; }
.modalbox {
  background: var(--pop);
  border: 1px solid var(--pop-line);
  border-radius: 24px;
  box-shadow: var(--pop-shadow);
  padding: 28px 30px 26px;
  width: 100%;
  max-width: 560px;
}
.modalkicker {
  display: inline-block;
  font-size: 14px;
  font-weight: 800;
  color: var(--s-waiting-fg);
  background: var(--s-waiting-bg);
  padding: 5px 13px;
  border-radius: 999px;
  margin-bottom: 14px;
}
.kickertime {
  font-weight: 600;
  opacity: 0.8;
  font-variant-numeric: tabular-nums;
  margin-left: 8px;
}
.modaltext {
  font-size: 28px;
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin-bottom: 26px;
  overflow-wrap: break-word;
}
.modalbtns {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  flex-wrap: wrap;
}
.modalbox button { min-width: 130px; font-size: 16px; min-height: 48px; }
.modalbox textarea {
  width: 100%;
  line-height: 1.5;
  resize: vertical;
  margin-bottom: 10px;
  background: var(--inset);
}
.modalerr {
  color: var(--danger);
  font-size: 14px;
  font-weight: 700;
  min-height: 20px;
  margin-bottom: 8px;
}
#doc-reply-box.hidden, .modalbtns button.hidden { display: none; }

/* ------------------------------------------------------------------ passcode screens */

.gate, .stopped {
  position: fixed;
  inset: 0;
  background:
    var(--grain),
    radial-gradient(ellipse 55% 60% at 0% 0%, var(--glow-a), transparent 70%),
    radial-gradient(ellipse 45% 50% at 90% 5%, var(--glow-b), transparent 70%),
    radial-gradient(ellipse 55% 60% at 100% 100%, var(--glow-c), transparent 70%),
    var(--base);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 100;
}
.stopped { z-index: 200; }
.gate.hidden, .stopped.hidden { display: none; }
.gatebox {
  background: var(--surface);
  border: 1px solid var(--surface-line);
  box-shadow: var(--surface-shadow);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border-radius: 24px;
  padding: 32px 28px 26px;
  width: 100%;
  max-width: 370px;
}
.gatebox h1 { font-size: 26px; font-weight: 800; letter-spacing: -0.01em; margin: 0 0 6px; }
.gatebox p { font-size: 15px; font-weight: 600; color: var(--ink-soft); margin: 0 0 20px; }
.gatebox input {
  width: 100%;
  font-size: 24px;
  letter-spacing: 6px;
  margin-bottom: 12px;
  text-align: center;
  background: var(--inset);
  border-radius: 999px;
}
.gatebox button { width: 100%; min-height: 50px; font-size: 16px; }
.gate-err { color: var(--danger); font-size: 14px; font-weight: 700; min-height: 20px; margin-top: 8px; }
.stopped .gatebox { max-width: 440px; }
.stopped p { line-height: 1.6; margin-bottom: 10px; }

/* This stylesheet has no blanket .hidden rule - each one is scoped to the thing
   it hides - so these need their own, or they show up on every page. */
#back-to-board.hidden, #gate-back.hidden { display: none; }

/* Who is signed in, and the way out. */
.account { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.board-wrap .footrow { margin-top: 16px; padding: 0 4px; }

/* The way out of the passcode screen, for the doctor who tapped Edit schedule
   and does not have the code. Quiet, because it is not the main thing to do. */
.gatebox .gateback {
  margin-top: 12px;
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--ink-soft);
  font-size: 14px;
  min-height: 0;
  padding: 8px;
}
.gatebox .gateback:hover { color: var(--ink); }

/* ------------------------------------------------------------------ doctor's board */

body.board { padding: 0; }
.board-wrap { max-width: 1100px; margin: 0 auto; padding: 24px 20px 30px; }

.board-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding: 0 4px 18px;
}
.board-date { font-size: 32px; font-weight: 800; letter-spacing: -0.02em; }

.board-wrap > .card { border-radius: 26px; padding-top: 14px; }

/* The door sign. Whoever the doctor should be thinking about right now, big
   enough to read from across the room. Violet while they are in with the
   doctor, peach while they are sitting outside, plain otherwise. */
.nowcard {
  margin: 0 14px 12px;
  padding: 22px 26px 24px;
  border-radius: 20px;
  background: var(--inset);
  border: 1px solid transparent;
}
.nowlabel {
  font-size: 16px;
  font-weight: 800;
  color: var(--ink-soft);
  margin-bottom: 2px;
}
.nowname {
  font-size: 58px;
  font-weight: 900;
  line-height: 1.05;
  letter-spacing: -0.02em;
  overflow-wrap: break-word;
}
.nowmeta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  font-size: 19px;
  font-weight: 700;
  color: var(--ink-soft);
  margin-top: 10px;
  font-variant-numeric: tabular-nums;
}
.nowmeta:empty { display: none; }

.nowcard.is-inroom {
  background: var(--door);
  border-color: var(--door-line);
  box-shadow: var(--door-shadow);
}
.nowcard.is-waiting {
  background: var(--lamp);
  border-color: var(--lamp-line);
  box-shadow: var(--lamp-shadow);
}
.nowcard.is-inroom .nowname, .nowcard.is-inroom .nowlabel, .nowcard.is-inroom .nowmeta { color: var(--door-ink); }
.nowcard.is-waiting .nowname, .nowcard.is-waiting .nowlabel, .nowcard.is-waiting .nowmeta { color: var(--lamp-ink); }
.nowcard.is-inroom .nowlabel, .nowcard.is-inroom .nowmeta,
.nowcard.is-waiting .nowlabel, .nowcard.is-waiting .nowmeta { opacity: 0.88; }

.brow {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 13px 26px;
  border-top: 1px dashed var(--rule);
}
.brow.hour { border-top: 1px solid var(--rule-hour); }
.brow .time {
  font-variant-numeric: tabular-nums;
  font-size: 20px;
  font-weight: 800;
  color: var(--time);
  width: 64px;
  flex: none;
}
.brow .who { flex: 1; min-width: 0; }
.brow .nm { font-size: 22px; font-weight: 700; }
.brow .rs { font-size: 15px; font-weight: 600; color: var(--ink-soft); margin-top: 2px; }
.brow .kind { font-size: 15px; }
.brow .pill { font-size: 14px; }
.brow.spent .time, .brow.spent .who, .brow.spent .kind { opacity: 0.45; }
.brow.spent .nm { text-decoration: line-through; text-decoration-thickness: 1.5px; }

/* Free slots: present so the doctor can see the shape of the day, quiet
   enough that the booked patients still carry the eye. */
.brow.free { padding-top: 8px; padding-bottom: 8px; }
.brow.free .time { color: var(--ink-ghost); font-size: 17px; }
.brow.free .nm { font-size: 16px; font-weight: 700; color: var(--ink-ghost); }
.brow.blocked { background: repeating-linear-gradient(135deg, transparent 0 8px, var(--rule-hour) 8px 9px); }
.brow.blocked .time { text-decoration: line-through; }
.brow.blocked .blockedout { font-size: 16px; }

/* Whoever is in the door sign above, marked in the list too. */
.brow.current { background: var(--current-bg); }

/* The time right now, drawn across the day where it falls. */
.nowline {
  position: relative;
  height: 0;
  border-top: 2px dashed var(--now);
  margin: -1px 0;
  z-index: 1;
}
/* The clock sits at the right-hand end, where free rows are empty and booked
   rows only have padding at that height - on the left it covered the times. */
.nowline span {
  position: absolute;
  right: 26px;
  top: -12px;
  background: var(--now);
  color: var(--now-ink);
  font-size: 12px;
  font-weight: 900;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  padding: 5px 10px;
  border-radius: 999px;
  box-shadow: 0 0 12px -2px var(--now);
}

/* Just booked. Fades out by itself so the day settles back to normal, and is a
   tint rather than a flash - it has to survive being glanced at, not caught. */
.brow.fresh { animation: freshfade 8s ease-out forwards; }
@keyframes freshfade {
  0%   { background: var(--fresh-bg); }
  70%  { background: var(--fresh-bg); }
  100% { background: transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .brow.fresh { animation: none; background: var(--fresh-bg); }
  button:active { transform: none; }
}

.stale .board-date, .stale .nowname { opacity: 0.6; }
.stale .nowcard.is-inroom, .stale .nowcard.is-waiting { filter: saturate(0.25); }

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

@media (max-width: 760px) {
  body { padding: 18px 12px 26px; }
  .daytitle, .board-date { font-size: 26px; }
  .weekstrip { gap: 2px; }
  .weekday { display: block; text-align: center; padding: 7px 2px; }
  .wd-num { font-size: 21px; }
  .wd-name { font-size: 12px; }
  .wd-count { font-size: 11px; white-space: normal; }
  .row { flex-wrap: wrap; gap: 8px 12px; padding: 10px 14px 10px 30px; }
  .row .dot { left: 10px; top: 28px; }
  .row .newname { flex: 1 1 60%; }
  .row .newreason, .row .newphone { flex: 1 1 40%; }
  /* No hover on a touch screen, so a free slot is just its time and name box
     until that box is tapped; then the rest of the line opens beneath it. */
  .row.empty-slot:not(:focus-within) .newreason,
  .row.empty-slot:not(:focus-within) .newphone,
  .row.empty-slot:not(:focus-within) .newkind { display: none; }
  /* Booked rows: time and name on the first line, type, status and menu
     beneath them on the right, so a long name never runs into the type. */
  .row:not(.empty-slot) .who { flex: 1 1 calc(100% - 70px); }
  .row:not(.empty-slot) .kind { margin-left: auto; }
  .noteform { flex-wrap: wrap; }
}

@media (max-width: 640px) {
  .board-wrap { padding: 16px 10px 24px; }
  .nowname { font-size: 40px; }
  .nowmeta { font-size: 16px; }
  .nowcard { margin: 0 8px 10px; padding: 18px 18px 20px; }
  .brow { gap: 12px; padding: 12px 16px; }
  .brow .time { font-size: 17px; width: 52px; }
  .brow .nm { font-size: 18px; }
  .brow .kind { display: none; }
  .banner { margin: 0 8px 10px; }
}

/* ------------------------------------------------------------------ practice tools

   Reports and the online booking settings, reached from reception's footer. */

/* A link that sits in a row of buttons and looks like one of them. */
a.btnlink {
  display: inline-flex;
  align-items: center;
  min-height: 42px;
  padding: 9px 18px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 800;
  text-decoration: none;
  color: var(--ink);
  background: var(--control);
  border: 1px solid var(--control-line);
  box-shadow: var(--control-shadow);
}
a.btnlink:hover { box-shadow: 0 0 0 2px var(--accent-soft), var(--control-shadow); }
a.btnlink:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The way back to the choice of screens, above each screen's title. Kept out
   of the button row so it never pushes the day arrows onto a second line. */
a.backlink {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 32px;
  margin: -6px 0 2px -4px;
  padding: 4px 10px 4px 4px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 800;
  color: var(--ink-soft);
  text-decoration: none;
}
a.backlink svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
a.backlink:hover { color: var(--accent-text); background: var(--accent-soft); }
a.backlink:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The online booking dialog. Left-aligned and taller than the message popups:
   it is a form, read top to bottom. */
.settingsbox {
  max-width: 540px;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  padding: 24px 26px 22px;
  text-align: left;
}
.settings-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.settings-head h2 { margin: 0; font-size: 24px; font-weight: 900; letter-spacing: -0.01em; }
.settings-close { width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; color: var(--ink-soft); }
.settings-close:hover { background: var(--accent-soft); color: var(--accent-text); }
.settings-close svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }

/* The on/off switch, the one decision that matters most, as its own row. */
.switch-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 18px;
  border-radius: 20px;
  background: var(--inset);
  cursor: pointer;
}
.switch-text { flex: 1; display: grid; gap: 2px; }
.switch-text strong { font-size: 17px; font-weight: 900; }
.switch-text span { font-size: 14px; font-weight: 600; color: var(--ink-soft); }
input.switch {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  position: relative;
  width: 52px;
  height: 30px;
  min-height: 0;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: var(--rule-hour);
  cursor: pointer;
  transition: background 0.15s ease;
}
input.switch::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
  transition: transform 0.15s ease;
}
input.switch:checked { background: var(--accent); box-shadow: var(--accent-glow); }
input.switch:checked::after { transform: translateX(22px); }
input.switch:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.settings-block { margin: 18px 0 0; padding: 0; border: 0; min-width: 0; }
.settings-block h2, .settings-block h3, .settings-block legend {
  padding: 0;
  margin: 0 0 8px 2px;
  font-size: 15px;
  font-weight: 900;
}
.linkrow { display: flex; gap: 8px; }
.linkrow input {
  flex: 1;
  min-width: 0;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink-soft);
  background: var(--inset);
  border-radius: 999px;
}
.settings-help { margin: 8px 2px 0; font-size: 13.5px; font-weight: 600; color: var(--ink-soft); }
.settings-help a { color: var(--accent-text); font-weight: 800; text-decoration: none; }
.settings-help a:hover { text-decoration: underline; }

/* Weekday chips and the "how far ahead" choice: real inputs, drawn as pills. */
.daychips, .segmented { display: flex; flex-wrap: wrap; gap: 6px; }
.daychip, .seg { position: relative; cursor: pointer; }
.daychip input, .seg input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.daychip span, .seg span {
  display: inline-grid;
  place-items: center;
  min-width: 52px;
  min-height: 38px;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 800;
  color: var(--ink-soft);
  background: var(--inset);
  border: 1.5px solid transparent;
}
.daychip:hover span, .seg:hover span { border-color: var(--rule-hour); }
.daychip input:checked + span, .seg input:checked + span {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: var(--accent-glow);
}
.daychip input:focus-visible + span, .seg input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

.settings-summary {
  margin: 20px 0 4px;
  padding: 12px 16px;
  border-radius: 16px;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--ink-soft);
  background: var(--inset);
}
.settings-summary.is-on { color: var(--s-done-fg); background: var(--s-done-bg); }
.settingsbox .modalbtns { margin-top: 8px; }
/* The message popups' buttons are all wide; this round close button is not. */
.settingsbox .settings-close { min-width: 0; min-height: 0; width: 38px; height: 38px; padding: 0; }

/* The same settings as a page of their own, reached from the choice of
   screens after signing in. One narrow column, read top to bottom. */
.bookingpage { max-width: 640px; }
.card.settingspage { padding: 24px 26px 22px; }
.settingspage .modalbtns button { min-width: 130px; min-height: 48px; font-size: 16px; }
@media (max-width: 520px) {
  .card.settingspage { padding: 18px 16px 16px; }
  .settingspage .linkrow { flex-wrap: wrap; }
  .settingspage .linkrow input { flex-basis: 100%; }
}

:root[data-theme="dark"] .pill.inroom { box-shadow: var(--accent-glow); }
