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

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

:root {
  --color-bg: #f5f6fa;
  --color-surface: #ffffff;
  --color-border: #e5e7eb;
  --color-text: #111827;
  --color-muted: #4b5563;
  --color-text-muted: #4b5563;
  --color-accent: #4f46e5;
  --color-accent-light: #eef2ff;
  --color-accent-hover: #4338ca;
  --color-accent-deep: #3730a3;
  --color-success: #10b981;
  --color-warning: #f59e0b;
  --color-danger: #ef4444;
  /* Semantic tints — themable (see themes.css; the dark theme re-points all of these). */
  --tint-danger-bg: #fef2f2;
  --tint-danger-border: #fecaca;
  --tint-danger-text: #dc2626;
  --tint-success-bg: #f0fdf4;
  --tint-success-border: #bbf7d0;
  --tint-success-text: #15803d;
  --tint-warning-bg: #fffbeb;
  --tint-warning-bg-strong: #fef3c7;
  --tint-warning-border: #fde68a;
  --tint-warning-text: #b45309;
  --tint-note-bg: #fef9c3;
  --tint-note-text: #854d0e;
  --tint-invited-bg: #fffdf5;
  --tint-info-bg: #eff6ff;
  --tint-info-text: #2563eb;
  --tint-today-bg: #f3f1ff;
  --color-accent-border: #c7d2fe;
  --color-accent-soft: #6366f1;
  --color-bg-hover: #eef0f3;
  --color-bg-subtle: #f4f6f8;
  --color-surface-dim: #fafbfc;
  --color-border-strong: #d1d5db;
  --color-muted-soft: #6b7280;
  --color-muted-faint: #b6bcc6;
  --radius: 10px;
  --shadow-sm: 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04);
  --shadow: 0 4px 12px rgba(0,0,0,0.08);
}

body {
  font-family: 'Inter', sans-serif;
  background: var(--color-bg);
  color: var(--color-text);
  font-size: 16px;
  line-height: 1.55;
}

/* ── Nav ── */
.loft-nav {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  padding: 0 20px;
  min-height: 56px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;             /* narrow screens: links drop to a second row */
  position: sticky;
  top: 0;
  z-index: 100;
}
.loft-nav-left { display: flex; align-items: center; gap: 20px; min-width: 0; flex-wrap: wrap; }
.loft-nav-brand { font-weight: 700; font-size: 16px; color: var(--color-text); display: flex; align-items: center; gap: 8px; text-decoration: none; }
.loft-nav-brand-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-accent); }
.loft-nav-links { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; }
.loft-nav-link {
  position: relative; padding: 17px 12px; font-size: 14.5px; font-weight: 500;
  color: var(--color-muted); text-decoration: none; white-space: nowrap;
}
.loft-nav-link:hover { color: var(--color-text); }
.loft-nav-link.active { color: var(--color-text); font-weight: 600; }
.loft-nav-link.active::after {
  content: ''; position: absolute; left: 10px; right: 10px; bottom: 0;
  height: 2.5px; border-radius: 2px 2px 0 0; background: var(--color-accent);
}
.loft-nav-right { display: flex; align-items: center; gap: 12px; }
.inbox-bell.active { color: var(--color-accent); }

/* The account menu: the avatar is the handle for everything about *you* —
   identity, preferences, manager tools, sign out. */
.nav-menu { position: relative; }
.nav-menu-btn { border: 2px solid transparent; cursor: pointer; padding: 0; font-family: inherit; }
.nav-menu-btn:hover, .nav-menu-btn[aria-expanded="true"] { border-color: var(--color-accent-border); }
.nav-menu-panel {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 220px;
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: 10px; box-shadow: var(--shadow); padding: 6px; z-index: 200;
}
.nav-menu-id { padding: 8px 10px 10px; }
.nav-menu-name { font-size: 14px; font-weight: 600; }
.nav-menu-email { font-size: 12.5px; color: var(--color-muted); overflow: hidden; text-overflow: ellipsis; }
.nav-menu-sep { height: 1px; background: var(--color-border); margin: 5px 4px; }
.nav-menu-item {
  display: block; width: 100%; text-align: left; padding: 8px 10px; border: 0; border-radius: 6px;
  background: none; font-family: inherit; font-size: 14px; color: var(--color-text);
  text-decoration: none; cursor: pointer;
}
.nav-menu-item:hover { background: var(--color-bg); }

/* ── Layout ── */
.loft-main { max-width: 960px; margin: 0 auto; padding: 24px 16px; }

/* ── Page header ── */
.page-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 20px; }
.page-header-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.page-title { font-size: 20px; font-weight: 700; }
.page-subtitle { font-size: 14px; color: var(--color-muted); margin-top: 2px; }

/* ── Buttons ── */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: none; border-radius: 8px; font-family: inherit; font-size: 15px; font-weight: 500; cursor: pointer; padding: 9px 16px; min-height: 40px; transition: all 0.15s; text-decoration: none; }
.btn-primary { background: var(--color-accent); color: white; }
.btn-primary:hover { background: var(--color-accent-hover); color: white; }
.btn-ghost { background: transparent; color: var(--color-muted); border: 1px solid var(--color-border); }
.btn-ghost:hover { background: var(--color-bg); }
.btn-success { background: var(--color-success); color: white; }
.btn-success:hover { background: #059669; color: white; }
.btn-danger { background: transparent; color: var(--color-danger); border: 1px solid var(--tint-danger-border); }
.btn-danger:hover { background: var(--tint-danger-bg); }
.btn-sm { padding: 7px 12px; font-size: 14px; border-radius: 6px; min-height: 36px; }
.btn-round { width: 38px; height: 38px; min-height: 38px; padding: 0; border-radius: 50%; font-size: 20px; line-height: 1; flex-shrink: 0; }
.btn-link { background: none; border: none; padding: 0; color: var(--color-text-secondary); cursor: pointer; font-family: inherit; font-size: inherit; font-weight: inherit; text-decoration: none; }
.btn-link:hover { text-decoration: underline; color: var(--color-text); }

/* ── Search ── */
.search-wrap { position: relative; }
.search-icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--color-muted); pointer-events: none; }
.search-input { width: 100%; padding: 10px 12px 10px 38px; border: 1px solid var(--color-border); border-radius: 8px; font-family: inherit; font-size: 14px; background: var(--color-surface); color: var(--color-text); box-shadow: var(--shadow-sm); outline: none; }
.search-input:focus { border-color: var(--color-accent); box-shadow: 0 0 0 3px rgba(79,70,229,0.1); }

/* ── Card ── */
.card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); box-shadow: var(--shadow-sm); margin-bottom: 16px; overflow: hidden; }
.card-header { padding: 14px 16px; border-bottom: 1px solid var(--color-border); display: flex; align-items: center; justify-content: space-between; }
.card-title { font-size: 15px; font-weight: 700; color: var(--color-text); }
.card-body { padding: 16px; }
.card-footer { padding: 14px 16px; border-top: 1px solid var(--color-border); display: flex; justify-content: flex-end; gap: 8px; }

/* ── At-door card ── */
.atdoor-card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); box-shadow: var(--shadow); margin-bottom: 16px; overflow: hidden; border-top: 3px solid var(--color-accent); }
.atdoor-sections { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; padding: 16px; }
.atdoor-section { background: var(--color-bg); border-radius: 8px; padding: 14px; }
.atdoor-section-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--color-muted); margin-bottom: 10px; }

/* ── Pass pips ── */
.pass-pips { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 8px; }
.pip { width: 12px; height: 12px; border-radius: 3px; }
.pip-on { background: var(--color-accent); }
.pip-off { background: var(--color-border); }
.pass-count { font-size: 13px; font-weight: 600; color: var(--color-accent); }
.pass-meta { font-size: 12px; color: var(--color-muted); margin-top: 2px; }

/* ── Payment options ── */
.payment-option { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border: 1px solid var(--color-border); border-radius: 7px; margin-bottom: 7px; cursor: pointer; transition: all 0.12s; background: white; }
.payment-option:hover { border-color: var(--color-accent); background: var(--color-accent-light); }
.payment-option.selected { border-color: var(--color-accent); background: var(--color-accent-light); }
.payment-option-icon { width: 28px; height: 28px; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 14px; background: var(--color-border); }
.payment-option-label { font-size: 13px; font-weight: 500; }

/* ── Badges ── */
.badge { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 20px; font-size: 11px; font-weight: 600; letter-spacing: 0.3px; }
.badge-guest { background: var(--color-bg-hover); color: var(--color-muted-soft); }
.badge-member { background: var(--tint-info-bg); color: var(--tint-info-text); }
.badge-devotee { background: var(--tint-success-bg); color: var(--tint-success-text); }
.badge-birthday { background: var(--tint-warning-bg-strong); color: var(--tint-warning-text); }
.badge-dietary { background: var(--tint-note-bg); color: var(--tint-note-text); }
.badge-count { display: inline-flex; align-items: center; justify-content: center; background: var(--color-border); color: var(--color-muted); border-radius: 20px; font-size: 11px; font-weight: 600; padding: 1px 8px; margin-left: 8px; }

/* ── Avatar ── */
.avatar { width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; color: white; flex-shrink: 0; background: var(--color-accent); }
.avatar-lg { width: 40px; height: 40px; font-size: 15px; }

/* ── Table ── */
.loft-table { width: 100%; border-collapse: collapse; }
.loft-table th { padding: 10px 16px; text-align: left; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--color-muted); border-bottom: 1px solid var(--color-border); }
.loft-table td { padding: 12px 16px; border-bottom: 1px solid var(--color-border); vertical-align: middle; }
.loft-table tr:last-child td { border-bottom: none; }
.loft-table tbody tr:hover { background: var(--color-surface-dim); }
.loft-table tr.row-selected { background: var(--color-accent-light); }

/* ── Person ── */
.person-name { font-weight: 600; font-size: 14px; }
.person-sub { font-size: 12px; color: var(--color-muted); margin-top: 1px; }

/* ── Form ── */
.form-group { margin-bottom: 16px; }
.form-label { display: block; font-size: 13px; font-weight: 500; margin-bottom: 6px; }
.form-control { width: 100%; padding: 9px 12px; border: 1px solid var(--color-border); border-radius: 8px; font-family: inherit; font-size: 14px; background: var(--color-surface); color: var(--color-text); outline: none; }
.form-control:focus { border-color: var(--color-accent); box-shadow: 0 0 0 3px rgba(79,70,229,0.1); }
.form-hint { font-size: 12px; color: var(--color-muted); margin-top: 4px; }

/* ── Inbox bell ── */
.inbox-bell { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 50%; color: var(--color-muted); text-decoration: none; transition: background 0.12s, color 0.12s; }
.inbox-bell:hover { background: var(--color-bg); color: var(--color-text); }
.inbox-bell-badge { display: inline-flex; align-items: center; justify-content: center; position: absolute; top: 2px; right: 2px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--color-danger); color: white; font-size: 10px; font-weight: 700; line-height: 16px; text-align: center; border: 2px solid var(--color-surface); box-sizing: content-box; }
[hidden].inbox-bell-badge { display: none; }

/* ── Inbox list ── */
.inbox-empty { padding: 32px 16px; text-align: center; color: var(--color-muted); font-size: 13px; }
.inbox-item { display: flex; align-items: flex-start; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--color-border); }
.inbox-item:last-child { border-bottom: none; }
.inbox-item-unread { background: var(--color-accent-light); }
.inbox-item-main { flex: 1; min-width: 0; }
.inbox-item-title { font-size: 14px; font-weight: 600; }
.inbox-item-unread .inbox-item-title::before { content: ''; display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--color-accent); margin-right: 8px; vertical-align: middle; }
.inbox-item-body { font-size: 13px; color: var(--color-muted); margin-top: 3px; }
.inbox-item-meta { font-size: 11px; color: var(--color-muted); margin-top: 5px; }
.inbox-item-dismiss { flex-shrink: 0; background: transparent; border: none; color: var(--color-muted); font-size: 18px; line-height: 1; cursor: pointer; padding: 2px 6px; border-radius: 6px; }
.inbox-item-dismiss:hover { background: var(--color-border); color: var(--color-text); }

/* ── Notification preferences ── */
.pref-intro { margin: 0 0 8px; font-size: 13px; color: var(--color-muted); }
.pref-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 14px 0; border-top: 1px solid var(--color-border); }
.pref-row:first-of-type { border-top: none; padding-top: 8px; }
.pref-row-text { flex: 1; min-width: 0; }
.pref-row-label { font-size: 14px; font-weight: 600; color: var(--color-text); }
.pref-row-desc { font-size: 12px; color: var(--color-muted); margin-top: 2px; }
.pref-toggle { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; font-size: 12px; color: var(--color-muted); cursor: pointer; user-select: none; }
.pref-toggle input { width: 16px; height: 16px; cursor: pointer; accent-color: var(--color-accent); }

/* ── Alert ── */
.alert { padding: 12px 16px; border-radius: 8px; font-size: 13px; margin-bottom: 16px; }
.alert-success { background: var(--tint-success-bg); color: var(--tint-success-text); border: 1px solid var(--tint-success-border); }
.alert-danger { background: var(--tint-danger-bg); color: var(--tint-danger-text); border: 1px solid var(--tint-danger-border); }
.alert-info { background: var(--color-accent-light); color: var(--color-accent); border: 1px solid var(--color-accent-border); }

/* ── Roster ── */
.muted { color: var(--color-text-muted, var(--color-muted-soft)); }
.roster-form { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.roster-form label { display: flex; flex-direction: column; font-size: 12px; gap: 4px; color: var(--color-text-muted, var(--color-muted-soft)); }
.roster-form select, .roster-form input { padding: 6px 8px; border: 1px solid var(--color-border-strong); border-radius: 6px; font-size: 14px; background: var(--color-surface); color: var(--color-text); font-family: inherit; }
.roster-check { flex-direction: row !important; align-items: center; gap: 8px !important; font-size: 15px !important; cursor: pointer; }
/* Stacked variant for the add-a-programme modal — full-width fields, one per row. */
.roster-form-stack { flex-direction: column; align-items: stretch; }
.roster-form-stack label { width: 100%; }
.roster-form-stack select, .roster-form-stack input[type=date], .roster-form-stack input[type=text] { width: 100%; }
.roster-form-stack input:disabled, .roster-form-stack select:disabled { opacity: .5; }
.roster-check input { width: 18px; height: 18px; accent-color: var(--color-accent); }
.roster-prog { padding: 16px 0; border-bottom: 1px solid var(--color-border); }
.roster-prog:first-child { padding-top: 0; }
.roster-prog:last-child { border-bottom: 0; padding-bottom: 0; }
.roster-prog-head { font-size: 16px; margin-bottom: 10px; display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.roster-event { margin: 8px 0 8px 12px; padding: 10px 12px; background: var(--color-surface-dim); border: 1px solid var(--color-bg-hover); border-radius: 8px; }
.roster-event-head { font-size: 14px; margin-bottom: 6px; display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.roster-kebab { flex-shrink: 0; border: 1px solid var(--color-border); background: transparent; cursor: pointer; font-size: 14px; line-height: 1; padding: 6px 12px; min-height: 36px; border-radius: 6px; color: var(--color-text); }
.roster-kebab:hover { background: var(--color-bg-hover); }
.roster-edit { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 10px; padding: 10px; background: var(--color-bg-subtle); border: 1px solid var(--color-border); border-radius: 8px; }
.roster-edit[hidden] { display: none; }  /* a class display: wins over the UA [hidden] rule, so re-assert it */
.roster-edit select, .roster-edit input { padding: 6px 8px; border: 1px solid var(--color-border-strong); border-radius: 6px; font-size: 13px; background: var(--color-surface); color: var(--color-text); font-family: inherit; }
.roster-edit input[type=text] { flex: 1; min-width: 0; }
.roster-slot { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 7px 0; font-size: 14px; border-top: 1px solid var(--color-bg-hover); }
.roster-event-head + .roster-slot { border-top: 0; }
.roster-slot-actions { display: flex; gap: 6px; flex-shrink: 0; align-items: center; }
.roster-slot-x { border: 1px solid var(--tint-danger-border); background: transparent; cursor: pointer; font-size: 14px; line-height: 1; padding: 6px 12px; min-height: 36px; border-radius: 6px; color: var(--color-danger); }
.roster-slot-x:hover { background: var(--tint-danger-bg); }
.roster-tag { font-size: 12px; padding: 3px 8px; border-radius: 999px; background: var(--color-accent-light); color: var(--color-accent-hover); }
.roster-tag-mine { background: var(--tint-success-bg); color: var(--tint-success-text); border: 1px solid var(--tint-success-border); }
.roster-add { display: flex; flex-wrap: wrap; align-items: center; margin-top: 10px; gap: 8px; }
.roster-add select, .roster-add input { padding: 6px 8px; border: 1px solid var(--color-border-strong); border-radius: 6px; font-size: 13px; background: var(--color-surface); color: var(--color-text); font-family: inherit; }
.roster-add input[type=text] { flex: 1; min-width: 0; }

/* ── Invitations (ask specific people) ── */
.roster-slot-wrap { border-top: 1px solid var(--color-bg-hover); }
.roster-slot-wrap:first-child { border-top: 0; }
.roster-slot-wrap .roster-slot { border-top: 0; }
.roster-invited { font-size: 12px; padding: 0 0 7px; }
.roster-invited .roster-slot-x { font-size: 13px; padding: 4px 8px; min-height: 0; margin-left: 4px; vertical-align: middle; }
.roster-ask { padding: 8px 10px 10px; margin: 0 0 8px; background: var(--color-bg-subtle); border: 1px solid var(--color-border); border-radius: 8px; }
.roster-ask[hidden] { display: none; }
.roster-ask-hint { font-size: 12px; margin-bottom: 8px; }
.roster-ask-search { width: 100%; padding: 8px 10px; border: 1px solid var(--color-border); border-radius: 8px; font-family: inherit; font-size: 14px; margin-bottom: 8px; outline: none; }
.roster-ask-search:focus { border-color: var(--color-accent); box-shadow: 0 0 0 3px rgba(79,70,229,0.1); }
.roster-ask-foot { font-size: 12px; margin: 2px 0 8px; }
.roster-ask-list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; max-height: 240px; overflow-y: auto; }
.roster-ask-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.roster-ask-main { min-width: 0; }
.roster-ask-row .role-check { min-width: 0; flex-wrap: wrap; }
/* What they're already on this week — the always-visible safety net under the name (mobile has no hover). */
.roster-ask-week { font-size: 12px; margin: 2px 0 0 26px; line-height: 1.35; }
/* Over-stretch heat: green 1–3, amber 4–5, red 6+. Colour plus words, never colour alone. */
.heat { font-size: 12px; font-weight: 600; padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.heat-ok { background: var(--tint-success-bg); color: var(--tint-success-text); border: 1px solid var(--tint-success-border); }
.heat-warn { background: var(--tint-warning-bg); color: var(--tint-warning-text); border: 1px solid var(--tint-warning-border); }
.heat-high { background: var(--tint-danger-bg); color: var(--tint-danger-text); border: 1px solid var(--tint-danger-border); }
/* Hint that the pill carries a hover summary (desktop). */
.heat-more { text-decoration: underline dotted; text-underline-offset: 2px; }
/* Instant hover tooltip (rendered on <body>, positioned by roster.js so the scroll box can't clip it). */
.tip-pop { position: absolute; z-index: 1000; max-width: 280px; white-space: pre-line; text-align: left;
    background: var(--color-text); color: var(--color-surface); font-size: 12px; font-weight: 400; line-height: 1.45;
    padding: 8px 10px; border-radius: 8px; box-shadow: 0 6px 18px rgba(0,0,0,0.2);
    opacity: 0; transition: opacity 0.08s; pointer-events: none; }
.tip-pop.visible { opacity: 1; }
.svc-invited { background: var(--tint-invited-bg); }
.svc-inv-actions { display: flex; gap: 6px; flex-shrink: 0; }

/* ── Services (by-person roster) ── */
.svc-mine { padding: 8px 0; border-top: 1px solid var(--color-bg-hover); display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.svc-mine:first-child { border-top: 0; }
.svc-mine-main { min-width: 0; }
.svc-day { margin-bottom: 18px; }
.svc-day:last-child { margin-bottom: 0; }
.svc-day-head { font-size: 15px; font-weight: 600; margin-bottom: 6px; }
/* Roster Day-view navigation header (‹ Prev day · date · Next day › · Today). */
.roster-daynav { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--color-border); }
.roster-daynav-label { font-size: 16px; font-weight: 700; flex: 1; min-width: 0; text-align: center; }
.svc-daynav { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.svc-daynav-label { font-size: 15px; font-weight: 600; text-align: center; flex: 1; min-width: 0; }
.svc-daynav button[disabled] { opacity: 0.4; cursor: default; }
.svc-row { display: flex; align-items: center; gap: 12px; padding: 8px 0; font-size: 14px; border-top: 1px solid var(--color-bg-hover); }
.svc-who { flex: 0 0 130px; font-weight: 600; }
.svc-what { flex: 1; min-width: 0; }
.svc-action { flex-shrink: 0; margin-left: auto; }
.svc-cancelled { opacity: 0.5; text-decoration: line-through; }
@media (max-width: 560px) {
    .svc-row { flex-wrap: wrap; gap: 4px 12px; }
    .svc-who { flex-basis: 100%; }
}

/* ── Roster views toggle ── */
.roster-views { display: inline-flex; gap: 0; margin-bottom: 16px; border: 1px solid var(--color-border); border-radius: 8px; overflow: hidden; }
.roster-view-btn { padding: 9px 18px; border: 0; background: var(--color-surface); color: var(--color-text); font-family: inherit; font-size: 15px; min-height: 40px; cursor: pointer; }
.roster-view-btn.active { background: var(--color-accent); color: #fff; }

/* ── Calendar grid (rooms × days) ── */
.cal-nav { display: flex; align-items: center; gap: 6px; }
.cal { display: grid; gap: 1px; background: var(--color-border); border: 1px solid var(--color-border); border-radius: 8px; overflow: hidden; min-width: 640px; }
.cal > div { background: var(--color-surface); }
.cal-h { padding: 8px 6px; font-size: 12px; font-weight: 600; text-align: center; background: var(--color-surface-dim); }
.cal-corner { background: var(--color-surface-dim); }
.cal-room { padding: 10px 8px; font-size: 13px; font-weight: 600; display: flex; align-items: center; }
.cal-cell { padding: 4px; display: flex; flex-direction: column; gap: 3px; min-height: 44px; }
/* Chips are flex rows: the label span truncates, the "needs N" badge never does — otherwise
   a long name swallows the badge and only the red edge survives (the count is the signal). */
.cal-ev { display: flex; align-items: center; font-size: 11px; line-height: 1.3; padding: 3px 6px; border-radius: 5px; background: var(--color-accent-light); color: var(--color-accent-deep); white-space: nowrap; overflow: hidden; }
.cal-ev-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.cal-ev .cal-needs, .cal-mev .cal-needs { flex-shrink: 0; }
.cal-ev-private { background: var(--tint-warning-bg-strong); color: var(--tint-warning-text); }
#view-calendar .card-body { overflow-x: auto; }

/* ── Calendar month grid ── */
.cal-month { display: grid; grid-template-columns: repeat(7, minmax(90px, 1fr)); gap: 1px; background: var(--color-border); border: 1px solid var(--color-border); border-radius: 8px; overflow: hidden; min-width: 640px; }
.cal-month > div { background: var(--color-surface); }
.cal-day { padding: 4px; min-height: 84px; display: flex; flex-direction: column; gap: 2px; }
.cal-day-out { background: var(--color-surface-dim); }
.cal-day-out .cal-daynum { color: var(--color-muted-faint); }
.cal-daynum { font-size: 12px; font-weight: 600; color: var(--color-text-muted, var(--color-muted-soft)); }
.cal-mev { display: flex; align-items: center; font-size: 10.5px; line-height: 1.25; padding: 2px 5px; border-radius: 4px; background: var(--color-accent-light); color: var(--color-accent-deep); white-space: nowrap; overflow: hidden; }
.cal-more { font-size: 10.5px; color: var(--color-text-muted, var(--color-muted-soft)); padding: 0 5px; }
/* Phone month: dots replace chips (see the @media block) — hidden by default. */
.cal-dots { display: none; flex-wrap: wrap; gap: 3px; margin-top: 2px; }
.cal-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--color-accent-soft); }
.cal-dot-private { background: #f59e0b; }
.cal-dot-needs { background: var(--color-danger); }

/* "Needs someone" — a red left edge on the chip plus a small count pill, so an unfilled service
   stands out at a glance on both week and month. Survives the chip's text being truncated. */
.cal-ev-needs { border-left: 3px solid var(--color-danger); padding-left: 4px; }
.cal-needs { display: inline-block; background: var(--color-danger); color: #fff; border-radius: 999px; padding: 0 6px; margin-left: 2px; font-size: 10px; font-weight: 700; white-space: nowrap; vertical-align: middle; }
.calw-needs .calw-time { color: var(--color-danger); font-weight: 600; }

/* Calendar key — explains the colours so the markers aren't a guessing game. */
.cal-legend { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-bottom: 12px; font-size: 13px; color: var(--color-text); }
.cal-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.cal-key { width: 14px; height: 14px; border-radius: 4px; flex-shrink: 0; }
.cal-key-needs { background: var(--color-danger); }
.cal-key-filled { background: var(--color-accent-soft); }
.cal-key-private { background: #f59e0b; }

/* Phone week: vertical day list (built only below 640px). */
.calw-day { padding: 10px 0; border-top: 1px solid var(--color-bg-hover); }
.calw-day:first-child { border-top: 0; padding-top: 0; }
.calw-dayhead { font-size: 14px; font-weight: 600; margin-bottom: 4px; }
.calw-row { display: flex; gap: 10px; padding: 4px 0; font-size: 13px; }
.calw-time { flex: 0 0 96px; color: var(--color-text-muted, var(--color-muted-soft)); }
.calw-what { flex: 1; min-width: 0; }
.calw-private .calw-time { color: var(--tint-warning-text); font-weight: 600; }
.calw-empty { font-size: 13px; padding: 2px 0; }

/* ── Templates ── */
.roster-tpl { padding: 12px 0; border-bottom: 1px solid var(--color-bg-hover); }
.roster-tpl:first-child { padding-top: 0; }
.roster-tpl:last-child { border-bottom: 0; padding-bottom: 0; }
.roster-tpl-events { font-size: 13px; margin: 4px 0 8px; line-height: 1.5; }
.roster-recur { margin-top: 6px; }
.day-toggles { display: inline-flex; flex-wrap: nowrap; gap: 10px; }
.day-toggle { display: inline-flex; align-items: center; gap: 5px; font-size: 14px; padding: 4px 2px; cursor: pointer; }
.day-toggle input { margin: 0; width: 20px; height: 20px; accent-color: var(--color-accent); }
.roster-tpl-head { display: flex; align-items: center; gap: 8px; }
.roster-tpl-head strong { margin-right: auto; }
.roster-tpl-editor { margin-top: 10px; padding: 10px; background: var(--color-bg-subtle); border: 1px solid var(--color-border); border-radius: 8px; }
.roster-tpl-te { padding: 8px 0; border-top: 1px solid var(--color-border); }
.roster-tpl-newevent { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--color-border-strong); }
.tpl-recur { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 10px 0; }
.tpl-events { margin-top: 4px; }
.tpl-save { margin-top: 12px; }
.roster-roles { display: flex; flex-wrap: wrap; gap: 4px 12px; margin: 6px 0 0; }
.role-check { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; padding: 4px 0; cursor: pointer; }
.role-check input { margin: 0; width: 18px; height: 18px; accent-color: var(--color-accent); }
/* "How many" for AllowMultiple roles in a template (e.g. Assistant serve-out × 3). */
.role-qty { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; padding: 4px 0; margin-right: 14px; }
.role-qty input { width: 56px; padding: 5px 8px; border: 1px solid var(--color-border-strong); border-radius: 6px; font-size: 14px; min-height: 36px; }

/* ── Mobile (phones; managers edit on the go) ──
   Many devotees read the roster on a phone, and a manager may need to fix a slot or a time
   between conversations. So this isn't a read-only shrink — the edit/add rows stay usable.
   Breakpoint 640px matches the calendar's min-width, below which the grids must scroll. */
@media (max-width: 640px) {
    /* Nav: two intentional rows instead of free wrapping. Brand + bell + avatar share the
       top row; the section links become an edge-to-edge horizontally-scrollable strip
       underneath (same pattern as the Feel the Love tabs) — no hamburger, every section
       stays one tap away. display:contents lifts brand and links out of .loft-nav-left so
       the links strip can claim the full bar width and wrap onto its own row. */
    .loft-nav { padding: 0 12px; gap: 0 8px; min-height: 0; }
    .loft-nav-left { display: contents; }
    .loft-nav-brand { order: 1; min-height: 52px; }
    .loft-nav-right { order: 2; gap: 8px; min-height: 52px; }
    .loft-nav-links {
        order: 3; flex-basis: 100%; flex-wrap: nowrap; overflow-x: auto;
        -webkit-overflow-scrolling: touch; scrollbar-width: none;
        margin: 0 -12px; padding: 0 4px;
        border-top: 1px solid var(--color-bg-hover);
    }
    .loft-nav-links::-webkit-scrollbar { display: none; }
    .loft-nav-link { padding: 12px 10px; }
    /* Friendlier thumb target for the account menu. */
    .loft-nav .avatar { width: 36px; height: 36px; }

    .loft-main { padding: 16px 12px; }

    /* Add-a-programme form stacks: date + name full width, button full width. (Target the text/date
       inputs specifically so the whole-Loft checkbox keeps its natural size.) */
    .roster-form label { width: 100%; }
    .roster-form .roster-check { width: auto; }
    .roster-form input[type=date], .roster-form input[type=text] { width: 100%; }

    /* Inline edit + add rows: full-width selects/notes/dates; the two time inputs paired on one row;
       buttons sharing the last row. Direct-child selectors (>) so nested controls — the day toggles
       and role checkboxes — are left alone. */
    .roster-edit > select, .roster-add > select,
    .roster-edit > input[type=text], .roster-add > input[type=text],
    .roster-edit > input[type=date], .roster-add > input[type=date] { flex: 1 1 100%; width: 100%; min-width: 0; }
    .roster-edit > input[type=time], .roster-add > input[type=time] { flex: 1 1 0; width: auto; min-width: 0; }
    .roster-edit > .btn, .roster-add > .btn { flex: 1 1 auto; justify-content: center; }

    /* The left indents eat scarce width on a phone. */
    .roster-event { margin-left: 0; }

    /* Let a slot's actions wrap under the role name instead of crushing it. */
    .roster-slot { flex-wrap: wrap; }
    .roster-slot-actions { flex-shrink: 1; }

    /* Recurrence row: extra row-gap so the label / 7-day group / Save button breathe when they wrap. */
    .roster-recur { row-gap: 10px; }

    /* Comfortable tap targets — 44px minimum on touch. */
    .btn-sm { padding: 10px 14px; min-height: 44px; }
    .roster-kebab, .roster-slot-x { padding: 10px 14px; font-size: 14px; min-height: 44px; }

    /* Calendar header (title + prev/range/next/today) wraps rather than overflowing. */
    #view-calendar .card-header { flex-wrap: wrap; gap: 8px; }

    /* Month fits seven columns by swapping unreadable chips for dots. The week is rendered as a
       vertical day list at this width (see roster.js), so no grid scrolling at all. */
    .cal-month { min-width: 0; grid-template-columns: repeat(7, minmax(0, 1fr)); }
    .cal-day { min-height: 54px; padding: 3px; }
    .cal-mev, .cal-more { display: none; }
    .cal-dots { display: flex; }
}

/* ── Modal (in-app confirm / prompt) ── */
.modal-overlay { position: fixed; inset: 0; background: rgba(17,24,39,0.45); display: flex; align-items: center; justify-content: center; z-index: 2000; padding: 16px; }
.modal { background: var(--color-surface); border-radius: 12px; box-shadow: var(--shadow); width: 100%; max-width: 420px; padding: 20px; max-height: calc(100vh - 32px); overflow-y: auto; }
.modal-title { font-size: 16px; font-weight: 700; margin-bottom: 8px; }
.modal-body { font-size: 14px; color: var(--color-text); margin-bottom: 14px; line-height: 1.5; }
.modal-input { width: 100%; padding: 9px 12px; border: 1px solid var(--color-border); border-radius: 8px; font-family: inherit; font-size: 14px; margin-bottom: 14px; outline: none; background: var(--color-surface); color: var(--color-text); }
.modal-input:focus { border-color: var(--color-accent); box-shadow: 0 0 0 3px rgba(79,70,229,0.1); }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }
.modal-ok.danger { background: var(--color-danger); }

/* Multi-choice modal (Modal.choose) — stacked full-width buttons, each with an optional hint line. */
.modal-choices { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; }
.modal-choice { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; text-align: left; padding: 11px 14px; white-space: normal; }
.modal-choice-label { font-weight: 600; }
.modal-choice-hint { font-size: 12.5px; font-weight: 400; line-height: 1.4; opacity: 0.85; }
.modal-ok.danger:hover { background: var(--tint-danger-text); color: #fff; }
body.modal-open { overflow: hidden; }

/* Today, highlighted so the eye lands on it. Week: column header + cells tinted; month: ringed cell. */
.cal-h-today { background: var(--color-accent-light); color: var(--color-accent); font-weight: 700; }
.cal-cell-today { background: var(--tint-today-bg); }
.cal-day.cal-today { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.cal-day.cal-today .cal-daynum { color: var(--color-accent); font-weight: 700; }
.calw-day.calw-today .calw-dayhead { color: var(--color-accent); }
.cal-today-pill { display: inline-block; font-size: 11px; font-weight: 700; color: #fff; background: var(--color-accent); border-radius: 999px; padding: 1px 8px; vertical-align: middle; }

/* Special programmes — a Food Festival, a visiting Swami, a Nature Retreat: days that break from
   the ordinary rhythm. A festive fuchsia chosen to be unmistakably distinct from needs-red,
   private-amber and the indigo event chips. Translucent tints layer over any theme (incl. Evening);
   pills/banners are solid fuchsia + white so they read on light or dark cells. Rules sit after
   cal-h-today so a day that is BOTH special and today still shows the special header. */
:root { --color-special: #a21caf; }
.cal-key-special { background: var(--color-special); }
.roster-tag-special { background: var(--color-special); color: #fff; }
/* Month cell: a fuchsia left edge + faint wash, with the headline leading the cell. */
.cal-day-special { background: rgba(162,28,175,0.07); box-shadow: inset 3px 0 0 var(--color-special); }
.cal-special-label { font-size: 10.5px; font-weight: 700; line-height: 1.2; color: #fff; background: var(--color-special);
    border-radius: 4px; padding: 2px 5px; margin: 1px 0 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Week grid: the day is a column, so its header carries the whole-day signal. */
.cal-h-special { background: var(--color-special); color: #fff; }
.cal-h-special-label { font-size: 10px; font-weight: 700; margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Week list (phone): a fuchsia edge on the day block + a headline banner under the date. */
.calw-day-special { box-shadow: inset 3px 0 0 var(--color-special); }
.calw-special { font-size: 12px; font-weight: 700; color: #fff; background: var(--color-special);
    border-radius: 6px; padding: 4px 8px; margin: 2px 0 6px; display: inline-block; }

/* Calendar days/events are tappable to open that day's roster (see roster.js openDayPanel). */
.cal-day[data-cal-day], .calw-day[data-cal-day], .cal-ev[data-cal-day], .cal-mev[data-cal-day] { cursor: pointer; }
.cal-day[data-cal-day]:hover { background: var(--color-accent-light); }
.calw-day[data-cal-day]:hover { background: var(--color-accent-light); }
.cal-ev[data-cal-day]:hover, .cal-mev[data-cal-day]:hover { filter: brightness(0.96); }

/* ── Day-detail modal (read-only roster for one day) ── */
.modal-panel { max-width: 540px; }
.modal-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.modal-panel-head .modal-title { margin-bottom: 0; }
.modal-panel-body { max-height: 70vh; overflow-y: auto; margin-bottom: 0; }
.rd-prog { margin-bottom: 14px; }
.rd-prog:last-child { margin-bottom: 0; }
.rd-prog-head { font-size: 16px; margin-bottom: 8px; }
.rd-event { margin: 8px 0; padding: 10px 12px; background: var(--color-surface-dim); border: 1px solid var(--color-bg-hover); border-radius: 8px; }
.rd-event-head { font-size: 14px; margin-bottom: 6px; }
.rd-slot { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; flex-wrap: wrap; padding: 7px 0; font-size: 14px; border-top: 1px solid var(--color-bg-hover); }
.rd-event-head + .rd-slot { border-top: 0; }
.rd-role { flex-shrink: 0; }
.rd-who { display: flex; align-items: center; flex-wrap: wrap; justify-content: flex-end; gap: 6px; margin-left: auto; }
.rd-close { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--color-border); display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px; font-size: 13px; }

/* ── Settings: catalogue editor (services / roles / rooms) ── */
.cat-type { padding: 12px 0; border-bottom: 1px solid var(--color-bg-hover); }
.cat-type:first-child { padding-top: 0; }
.cat-type:last-child { border-bottom: 0; padding-bottom: 0; }
/* The "add new" row at the top of a card: input takes the space, a normal-size button parked at the
   right edge. A divider sets it apart from the list below so they don't read as one crowded block. */
:root { --cat-act: 96px; }
.cat-addrow { display: grid; grid-template-columns: 1fr calc(var(--cat-act) * 3 + 16px); gap: 8px; align-items: center; }
.cat-addrow > .btn { justify-self: end; }
.cat-addrow { margin-bottom: 14px; padding-bottom: 16px; border-bottom: 1px solid var(--color-border); }
/* Match the catalogue inputs to one size so each section lines up cleanly. */
#cat-rooms .roster-add input[type=text],
#add-service-name { padding: 7px 10px; font-size: 14px; }
@media (max-width: 640px) {
    /* Stack everything full-width on a phone. */
    .cat-addrow { grid-template-columns: 1fr; }
}
.cat-roles { margin: 10px 0 0 12px; padding: 10px 12px; background: var(--color-bg-subtle); border: 1px solid var(--color-border); border-radius: 8px; }
.cat-role { padding: 8px 0; border-top: 1px solid var(--color-border); }
.cat-role:first-child { border-top: 0; padding-top: 0; }
.cat-room { padding: 10px 0; border-bottom: 1px solid var(--color-bg-hover); }
.cat-room:first-child { padding-top: 0; }
.cat-room:last-child { border-bottom: 0; padding-bottom: 0; }
.cat-off { opacity: 0.55; }
.cat-warn { font-size: 12px; color: var(--color-danger); margin-top: 4px; }
/* Read-first catalogue rows: the name (and roles / room note) read as plain text; the editing
   controls stay hidden behind an Edit toggle so the list scans cleanly instead of looking like a
   wall of form fields. */
.cat-row { display: flex; align-items: center; gap: 8px; }
.cat-row-name { flex: 1; min-width: 0; font-size: 15px; font-weight: 600; }
.cat-row-name .muted { font-weight: 400; }
.cat-row > .btn { flex-shrink: 0; }
.cat-offtag { font-size: 11px; font-weight: 600; color: var(--color-muted); border: 1px solid var(--color-border); border-radius: 999px; padding: 1px 7px; }
.cat-svc-summary { font-size: 13px; margin-top: 2px; }

/* ── Toast ── */
.toast { display: inline-flex; align-items: center; position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%) translateY(8px); background: #1a1a1a; color: #fff; padding: 10px 16px; border-radius: 8px; font-size: 14px; opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s; z-index: 1000; max-width: calc(100vw - 32px); }
.toast.visible { opacity: 1; transform: translateX(-50%) translateY(0); pointer-events: auto; }
.toast-error { background: var(--color-danger); }
.toast-dismiss { margin-left: 12px; flex-shrink: 0; background: rgba(255,255,255,0.2); color: #fff; border: 0; border-radius: 6px; padding: 5px 12px; font-size: 13px; font-weight: 600; cursor: pointer; }
.toast-dismiss:hover { background: rgba(255,255,255,0.32); }

/* ── Feel the Love ─────────────────────────────────────────────────────────────── */
/* Tab bar: pill tabs that scroll sideways on a phone instead of wrapping or crushing. */
.care-tabs { display: flex; gap: 6px; margin-bottom: 16px; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.care-tabs::-webkit-scrollbar { display: none; }
.care-tab { flex-shrink: 0; border: 1px solid var(--color-border); background: var(--color-surface, #fff); cursor: pointer; padding: 8px 14px; min-height: 40px; border-radius: 999px; font-size: 14px; color: var(--color-text); }
.care-tab:hover { background: var(--color-bg-hover); }
.care-tab.active { background: var(--color-accent); border-color: var(--color-accent); color: #fff; }

/* Rows: the name block gets the room; the (now small) action pair sits right and wraps
   underneath on a phone rather than squeezing the name into a vertical sliver. */
.care-row { flex-wrap: wrap; }
.care-row-main { flex: 1 1 240px; min-width: 0; }
.care-row .roster-slot-actions { flex-shrink: 0; margin-left: auto; }

/* ── Messaging ─────────────────────────────────────────────────────────────────── */
#msg-list {
    max-height: calc(100vh - 340px); min-height: 160px; overflow-y: auto;
    margin-bottom: 12px; border: 1px solid var(--color-border-strong, #d1d5db);
    border-radius: 10px; background: var(--color-surface);
    box-shadow: inset 0 1px 3px rgba(0,0,0,0.06);
    padding: 6px 0;
}
.msg { padding: 6px 16px; transition: background 0.1s; position: relative; }
.msg:hover { background: var(--color-bg-hover); border-radius: 6px; }
/* Always-visible comment button */
.msg-reply-btn { font-size: 0.82em; font-weight: 500; color: #4a9eff; margin-top: 5px; display: inline-block; }
.msg-reply-btn:hover { color: #2979d8; text-decoration: underline; }
/* ⋮ per-message menu — absolute top-right of .msg */
.msg-menu-trigger { font-size: 1.1em; font-weight: 700; color: var(--color-muted-soft); padding: 2px 4px; line-height: 1; }
.msg-menu-trigger:hover { color: var(--color-text); text-decoration: none; }
.msg-menu-dropdown {
    position: absolute; right: 0; top: 100%; z-index: 50;
    background: var(--color-card); border: 1px solid var(--color-border);
    border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,0.12);
    min-width: 120px; padding: 4px 0;
}
.msg-menu-item { display: block; width: 100%; text-align: left; padding: 7px 14px; font-size: 0.85em; color: var(--color-text); white-space: nowrap; }
.msg-menu-item:hover { background: var(--color-bg-hover); text-decoration: none; }
.msg-menu-item--danger { color: var(--color-danger) !important; }
/* Thread area */
.msg-thread-area { margin-top: 2px; }
.msg-thread-toggle { font-size: 0.8em; color: #4a9eff; background: none; border: none; cursor: pointer; padding: 2px 0; font-family: inherit; display: block; }
.msg-thread-toggle:hover { color: #2979d8; text-decoration: underline; }
.msg-replies { margin-top: 6px; padding: 2px 8px; border-left: 3px solid var(--color-accent-border); border-radius: 0 4px 4px 0; background: var(--color-bg); }
/* Unread divider — "New messages" line inside message list */
.msg-unread-divider { display: flex; align-items: center; gap: 8px; margin: 10px 16px 6px; color: var(--color-danger); font-size: 0.72em; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
.msg-unread-divider::before, .msg-unread-divider::after { content: ''; flex: 1; height: 1px; background: var(--color-danger); opacity: 0.35; }
/* Card dropdown */
.msg-card-dropdown { border-radius: 10px !important; }
/* Mobile messaging */
@media (max-width: 640px) {
    #msg-list {
        max-height: calc(100dvh - 260px);
        min-height: 180px;
        border-radius: 8px;
    }
    .msg { padding: 6px 10px; }
    #msg-compose-area { position: sticky; bottom: 0; background: var(--color-bg); padding-top: 6px; padding-bottom: 4px; }
    #msg-compose-area textarea { font-size: 16px; min-height: 52px; max-height: 120px; } /* 16px prevents iOS auto-zoom on focus */
    #msg-view > div:first-child { flex-wrap: wrap; gap: 6px; }
    #msg-view-name { font-size: 0.95rem; min-width: 0; }
}
