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

/* ── Theme tokens ────────────────────────────────────────────────────────────
   Colors are CSS custom properties so a single `data-theme` swap on <html>
   re-themes the whole UI. :root holds the light palette (default); the dark
   overrides apply for an explicit data-theme="dark" and for data-theme="system"
   when the OS prefers dark. FullCalendar 6 reads its own --fc-* props, so we set
   those here too instead of fighting its bundled CSS. Per-calendar event colors
   come from the DB inline and are intentionally left untouched. */
:root {
  color-scheme: light;

  --bg-page: #f5f5f5;
  --bg-surface: #fff;
  --bg-control: #fafafa;
  --bg-control-hover: #e6e6e6;
  --bg-disabled: #f0f0f0;
  --bg-subtle: #f5f5f5;
  --bg-stepper: #f3f3f3;
  --bg-row-hover: #f7f9fc;
  --bg-menu-hover: #f0f0f0;

  --text: #111;
  --text-strong: #222;
  --text-body: #333;
  --text-muted: #555;
  --text-muted-2: #666;
  --text-faint: #888;
  --text-disabled: #999;
  --text-dim: #bbb;
  --text-account: #444;

  --border: #ddd;
  --border-panel: #e0e0e0;
  --border-control: #ccc;
  --border-input: #d0d0d0;
  --border-light: #eee;
  --border-lighter: #f0f0f0;
  --border-faint: #f3f3f3;
  --border-faintest: #f5f5f5;

  --accent: #3788d8;
  --accent-hover: #2670bc;
  --primary: #2563eb;
  --primary-hover: #1d4ed8;
  --today: #1a73e8;
  --fab: #1a73e8;
  --fab-hover: #1666cf;
  --today-outline: #93c5fd;
  --warn: #c0392b;

  --error-bg: #fee2e2;
  --error-border: #fca5a5;
  --error-text: #b91c1c;
  --info-bg: #eff6ff;
  --info-border: #bfdbfe;
  --info-text: #1d4ed8;
  --danger-border: #dc2626;

  --scrim: rgba(0,0,0,.3);
  --shadow: rgba(0,0,0,.18);
  --shadow-fab: rgba(0,0,0,.25);

  --fc-page-bg-color: #fff;
  --fc-border-color: #ddd;
  --fc-neutral-bg-color: #f5f5f5;
  --fc-neutral-text-color: #808080;
  --fc-today-bg-color: rgba(26,115,232,.10);
  --fc-highlight-color: rgba(26,115,232,.12);
  --fc-list-event-hover-bg-color: #f7f9fc;
  --fc-non-business-color: rgba(0,0,0,.04);
  --nonworking-fg: #c0392b;
  --nonworking-bg: rgba(192,57,43,.08);
}

/* Dark palette, shared by explicit dark and system-prefers-dark. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg-page: #121212;
  --bg-surface: #1e1e1e;
  --bg-control: #2a2a2a;
  --bg-control-hover: #3a3a3a;
  --bg-disabled: #262626;
  --bg-subtle: #262626;
  --bg-stepper: #2a2a2a;
  --bg-row-hover: #2a2f3a;
  --bg-menu-hover: #2f2f2f;

  --text: #e8e8e8;
  --text-strong: #e8e8e8;
  --text-body: #dcdcdc;
  --text-muted: #b0b0b0;
  --text-muted-2: #a0a0a0;
  --text-faint: #8a8a8a;
  --text-disabled: #777;
  --text-dim: #666;
  --text-account: #c0c0c0;

  --border: #3a3a3a;
  --border-panel: #333;
  --border-control: #444;
  --border-input: #444;
  --border-light: #2c2c2c;
  --border-lighter: #2c2c2c;
  --border-faint: #262626;
  --border-faintest: #262626;

  --accent: #5b9bd5;
  --accent-hover: #74ade0;
  --primary: #3b82f6;
  --primary-hover: #60a5fa;
  --today: #8ab4f8;
  --fab: #3b82f6;
  --fab-hover: #60a5fa;
  --today-outline: #3b82f6;
  --warn: #ff6b5e;

  --error-bg: #3a1d1d;
  --error-border: #7f3a3a;
  --error-text: #f5a3a3;
  --info-bg: #16263b;
  --info-border: #2f4d73;
  --info-text: #9bc4f5;
  --danger-border: #e06666;

  --scrim: rgba(0,0,0,.6);
  --shadow: rgba(0,0,0,.5);
  --shadow-fab: rgba(0,0,0,.6);

  --fc-page-bg-color: #1e1e1e;
  --fc-border-color: #3a3a3a;
  --fc-neutral-bg-color: #262626;
  --fc-neutral-text-color: #aaa;
  --fc-today-bg-color: rgba(138,180,248,.10);
  --fc-highlight-color: rgba(138,180,248,.14);
  --fc-list-event-hover-bg-color: #2a2f3a;
  --fc-non-business-color: rgba(0,0,0,.25);
  --nonworking-fg: #ef6b5e;
  --nonworking-bg: rgba(239,107,94,.12);
}

@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] {
    color-scheme: dark;

    --bg-page: #121212;
    --bg-surface: #1e1e1e;
    --bg-control: #2a2a2a;
    --bg-control-hover: #3a3a3a;
    --bg-disabled: #262626;
    --bg-subtle: #262626;
    --bg-stepper: #2a2a2a;
    --bg-row-hover: #2a2f3a;
    --bg-menu-hover: #2f2f2f;

    --text: #e8e8e8;
    --text-strong: #e8e8e8;
    --text-body: #dcdcdc;
    --text-muted: #b0b0b0;
    --text-muted-2: #a0a0a0;
    --text-faint: #8a8a8a;
    --text-disabled: #777;
    --text-dim: #666;
    --text-account: #c0c0c0;

    --border: #3a3a3a;
    --border-panel: #333;
    --border-control: #444;
    --border-input: #444;
    --border-light: #2c2c2c;
    --border-lighter: #2c2c2c;
    --border-faint: #262626;
    --border-faintest: #262626;

    --accent: #5b9bd5;
    --accent-hover: #74ade0;
    --primary: #3b82f6;
    --primary-hover: #60a5fa;
    --today: #8ab4f8;
    --fab: #3b82f6;
    --fab-hover: #60a5fa;
    --today-outline: #3b82f6;
    --warn: #ff6b5e;

    --error-bg: #3a1d1d;
    --error-border: #7f3a3a;
    --error-text: #f5a3a3;
    --info-bg: #16263b;
    --info-border: #2f4d73;
    --info-text: #9bc4f5;
    --danger-border: #e06666;

    --scrim: rgba(0,0,0,.6);
    --shadow: rgba(0,0,0,.5);
    --shadow-fab: rgba(0,0,0,.6);

    --fc-page-bg-color: #1e1e1e;
    --fc-border-color: #3a3a3a;
    --fc-neutral-bg-color: #262626;
    --fc-neutral-text-color: #aaa;
    --fc-today-bg-color: rgba(138,180,248,.10);
    --fc-highlight-color: rgba(138,180,248,.14);
    --fc-list-event-hover-bg-color: #2a2f3a;
    --fc-non-business-color: rgba(0,0,0,.25);
    --nonworking-fg: #ef6b5e;
    --nonworking-bg: rgba(239,107,94,.12);
  }
}

body {
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 14px;
  background: var(--bg-page);
  color: var(--text);
  height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* ── Auth pages ── */
.auth-page {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.auth-card {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 2.5rem 2rem;
  width: 100%;
  max-width: 380px;
}

.auth-logo {
  height: 64px;
  width: 64px;
  object-fit: contain;
  display: block;
  margin: 0 auto 0.75rem;
}

.auth-card h1 {
  font-size: 1.5rem;
  font-weight: 700;
  margin-bottom: 1.5rem;
  text-align: center;
  letter-spacing: -0.5px;
}

.auth-card label {
  display: block;
  font-weight: 500;
  margin-top: 1rem;
  margin-bottom: 0.3rem;
}

.auth-card input {
  display: block;
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border-control);
  border-radius: 4px;
  font-size: 14px;
}

.auth-card input:focus {
  outline: 2px solid var(--accent);
  border-color: transparent;
}

.auth-card button[type="submit"] {
  margin-top: 1.5rem;
  width: 100%;
  padding: 0.6rem;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 4px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.auth-card button[type="submit"]:hover { background: var(--accent-hover); }
.auth-card button[type="submit"]:disabled { opacity: 0.6; cursor: not-allowed; }

.error-msg {
  background: var(--error-bg);
  border: 1px solid var(--error-border);
  border-radius: 4px;
  color: var(--error-text);
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.75rem;
  font-size: 13px;
}

.info-msg {
  background: var(--info-bg);
  border: 1px solid var(--info-border);
  border-radius: 4px;
  color: var(--info-text);
  padding: 0.5rem 0.75rem;
  margin-bottom: 1rem;
  font-size: 13px;
}

/* Transient toast (saved / copied feedback). Above all modals. */
.app-toast {
  position: fixed;
  left: 50%;
  bottom: 2rem;
  transform: translate(-50%, 1rem);
  background: var(--text-strong);
  color: var(--bg-surface);
  padding: 0.6rem 1rem;
  border-radius: 6px;
  font-size: 14px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
  z-index: 1000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.app-toast.show {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* ── Calendar page ── */
#page-calendar {
  flex: 1;
  display: flex;
  flex-direction: column;
  height: 100dvh;
}

.top-bar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.5rem 1rem;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border-panel);
  height: 44px;
}

.app-logo {
  height: 24px;
  width: 24px;
  object-fit: contain;
  margin-right: -0.5rem; /* tighten gap to .app-name (top-bar gap is 1rem) */
}

.app-name {
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: -0.3px;
}

.user-email {
  color: var(--text-muted-2);
  font-size: 13px;
  flex: 1;
}

.logout-countdown {
  color: var(--text-faint);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.logout-countdown--warn {
  color: var(--warn);
  font-weight: 600;
}

.btn-outline {
  padding: 0.3rem 0.8rem;
  border: 1px solid var(--border-control);
  border-radius: 4px;
  background: var(--bg-surface);
  font-size: 13px;
  cursor: pointer;
}

.btn-outline:hover { background: var(--bg-subtle); }

.calendar-body {
  flex: 1;
  display: flex;
  overflow: hidden;
  position: relative; /* anchor for the absolute "+" FAB */
}

#calendar {
  flex: 1;
  padding: 1rem;
  overflow: auto;
  background: var(--bg-surface);
}

/* ── Agenda view ── */
/* Agenda mode keeps #calendar mounted for its header toolbar (view buttons)
   but collapses the FC view area; the agenda list fills the rest below. */
.calendar-body.agenda-mode {
  flex-direction: column;
}

.calendar-body.agenda-mode #calendar {
  flex: 0 0 auto;
  /* FC's height:'100%' option puts an inline height on #calendar; without this
     override it keeps the full body height and squeezes the agenda to 0px. */
  height: auto !important;
  overflow: visible;
  padding-bottom: 0;
}

.calendar-body.agenda-mode #calendar .fc-view-harness {
  display: none;
}

/* Agenda title overlay: shown in place of FC's own toolbar title while in
   agenda mode. We never write FC's .fc-toolbar-title (it corrupts FC's preact
   title reconciliation); instead hide it and reveal this sibling. */
.agenda-toolbar-title {
  display: none;
  margin: 0;
  font-size: 1.75em;
  font-weight: inherit;
  /* Pass clicks through so it never triggers the title's jump-to-date picker. */
  pointer-events: none;
}

.calendar-body.agenda-mode .fc-toolbar-title {
  display: none;
}

.calendar-body.agenda-mode .agenda-toolbar-title {
  display: block;
}

.agenda {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bg-surface);
}

.agenda-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 1rem 1.25rem 4rem;
}

/* Date-range pickers shown only while searching the agenda. */
.agenda-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  align-items: center;
  padding: 0.75rem 1.25rem;
  border-bottom: 1px solid var(--border-panel);
  background: var(--bg-control);
}

.agenda-range {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

/* Toolbar search box (injected after the "today" button). Input, clear button
   and spinner sit in a flex row so the "×" and spinner never overlap. */
.cal-search {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-left: 0.5rem;
}

.cal-search-input {
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  background: var(--bg-control);
  color: var(--text);
  font: inherit;
}

.cal-search-clear {
  border: none;
  background: transparent;
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  color: var(--text);
  padding: 0 0.2rem;
}

/* "Search in progress" spinner — same look as the agenda loading spinner,
   shown next to the search box while a search-driven load runs. A fixed-size
   slot so toggling it doesn't shift the "×" button. */
.cal-search-spinner {
  flex: none;
  width: 1rem;
  height: 1rem;
  border: 2px solid var(--border-control);
  border-top-color: var(--today);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

/* Compact agenda from/to date boxes: just wide enough for their digits
   (2 for month/day, 4 for year), like the token-expiry fields. */
#ev-agenda-from-date-fields .ev-dnum,
#ev-agenda-to-date-fields .ev-dnum {
  width: 2.6em;
  text-align: center;
  padding: 0.4rem 0.25rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  font: inherit;
  font-size: 13px;
  background: var(--bg-control);
  color: var(--text-strong);
}
#ev-agenda-from-date-fields .ev-year,
#ev-agenda-to-date-fields .ev-year { width: 3.6em; }

.agenda-day {
  margin-top: 1.25rem;
}

.agenda-day-header {
  position: sticky;
  top: -1px;
  background: var(--bg-surface);
  z-index: 1;
  font-weight: 600;
  padding: 0.35rem 0;
  border-bottom: 1px solid var(--border-light);
}

.agenda-day-header.is-today {
  color: var(--today);
}

.agenda-row {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.5rem 0.25rem;
  border-bottom: 1px solid var(--border-faint);
  cursor: pointer;
}

.agenda-row:hover {
  background: var(--bg-row-hover);
}

.agenda-time {
  flex: 0 0 7rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.agenda-dot {
  flex: 0 0 0.6rem;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  align-self: center;
}

.agenda-main {
  flex: 1;
  min-width: 0;
}

.agenda-title {
  font-weight: 500;
}

.agenda-loc {
  color: var(--text-faint);
  font-size: 0.85em;
}

.agenda-status {
  text-align: center;
  color: var(--text-faint);
  padding: 1rem;
}

.agenda-spinner {
  display: inline-block;
  width: 1.1rem;
  height: 1.1rem;
  border: 2px solid var(--border-control);
  border-top-color: var(--today);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  vertical-align: middle;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.agenda-sentinel {
  height: 1px;
}

/* ── Floating "new event" button (all views) ── */
.fab {
  position: absolute;
  right: 1.5rem;
  bottom: 1.5rem;
  z-index: 50;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 50%;
  border: none;
  background: var(--fab);
  color: #fff;
  font-size: 1.9rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 2px 8px var(--shadow-fab);
}

.fab:hover {
  background: var(--fab-hover);
}

/* ── Settings panel ── */
.settings-overlay {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  z-index: 100;
}

.settings-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 360px;
  max-width: 100vw;
  background: var(--bg-surface);
  border-left: 1px solid var(--border-panel);
  z-index: 101;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* The sections scroll between the fixed header and the pinned Save footer. */
.settings-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
}

.settings-footer {
  flex: 0 0 auto;
  padding: 0.75rem 1rem;
  border-top: 1px solid var(--border-panel);
  background: var(--bg-surface);
}

.settings-footer button {
  width: 100%;
}

.settings-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border-panel);
  font-weight: 600;
  font-size: 15px;
  flex: 0 0 auto;
  background: var(--bg-surface);
}

.btn-icon {
  border: none;
  background: none;
  cursor: pointer;
  font-size: 16px;
  color: var(--text-muted-2);
  padding: 0.25rem;
  line-height: 1;
}
.btn-icon:hover { color: var(--text); }

.settings-section {
  padding: 1rem;
  border-bottom: 1px solid var(--border-lighter);
}

.settings-section h2 {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-faint);
  margin-bottom: 0.75rem;
}

.account-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--border-faintest);
}
.account-row:last-child { border-bottom: none; }

.account-url {
  flex: 1;
  font-size: 12px;
  color: var(--text-account);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.btn-danger-sm {
  padding: 0.2rem 0.5rem;
  border: 1px solid var(--error-border);
  border-radius: 3px;
  background: var(--bg-surface);
  color: var(--error-text);
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
}
.btn-danger-sm:hover { background: var(--error-bg); }

.token-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--border-faintest);
}
.token-row:last-child { border-bottom: none; }
.token-meta { flex: 1; display: flex; flex-direction: column; gap: 0.1rem; overflow: hidden; }
.token-name { font-size: 12px; font-weight: 600; }
.token-sub { font-size: 11px; color: var(--text-faint); }
.token-badge {
  display: inline-block;
  align-self: flex-start;
  padding: 0 0.35rem;
  border-radius: 3px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  background: var(--bg-subtle);
  color: var(--text-faint);
}
.token-rw { background: var(--accent, #3788d8); color: #fff; }

#token-modal { min-width: min(92vw, 440px); }
.token-modal-title { margin: 0 0 0.4rem; font-weight: 600; }
.token-secret-row { display: flex; gap: 0.4rem; margin: 0.6rem 0; }
.token-secret-row input {
  flex: 1;
  font-family: monospace;
  font-size: 11px;
}

.calendar-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0;
}

.cal-color {
  width: 28px;
  height: 28px;
  border: 1px solid var(--border-control);
  border-radius: 4px;
  padding: 2px;
  cursor: pointer;
}

.cal-label {
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
}

.cal-default-label {
  margin-left: auto;
  font-size: 12px;
  color: var(--text-muted-2);
  display: flex;
  align-items: center;
  gap: 0.3rem;
  cursor: pointer;
  white-space: nowrap;
}

details#add-account-details {
  margin-top: 0.75rem;
}
details#add-account-details summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--accent);
  user-select: none;
  padding: 0.2rem 0;
}

.inner-form {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding-top: 0.75rem;
}
.inner-form label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
}
.inner-form input,
.inner-form select {
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--border-control);
  border-radius: 4px;
  font-size: 13px;
}
.inner-form input:focus,
.inner-form select:focus {
  outline: 2px solid var(--accent);
  border-color: transparent;
}
.inner-form button[type="submit"] {
  margin-top: 0.5rem;
  padding: 0.45rem 0.8rem;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 4px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  align-self: flex-start;
}
.inner-form button[type="submit"]:hover { background: var(--accent-hover); }
.inner-form button[type="submit"]:disabled { opacity: .6; cursor: not-allowed; }

.pref-note { margin: 0; font-size: 11px; color: var(--text-faint); line-height: 1.4; }

.loading, .empty-note { font-size: 12px; color: var(--text-faint); }
.error-note { font-size: 12px; color: var(--error-text); }

/* ── Event detail modal ── */
.fc-event, .fc-event-main { cursor: pointer; }

.event-overlay {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  z-index: 200;
}

.event-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 500px;
  height: auto;
  min-width: 340px;
  min-height: fit-content;
  max-width: min(90vw, 760px);
  max-height: calc(100vh - 2rem);
  background: var(--bg-surface);
  border: 1px solid var(--border-panel);
  border-radius: 6px;
  box-shadow: 0 8px 32px var(--shadow);
  z-index: 201;
  display: flex;
  flex-direction: column;
  overflow: auto;
  resize: both;
}

.event-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border-panel);
  font-weight: 600;
  font-size: 15px;
}

.event-modal-body {
  padding: 1rem;
  overflow-y: auto;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.event-modal-header { flex: none; }

.ev-field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.ev-label {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-faint);
}

.event-modal-body input[type="text"],
.event-modal-body .ev-dnum,
.event-modal-body textarea {
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  font: inherit;
  font-size: 13px;
  background: var(--bg-control);
  color: var(--text-strong);
}

.event-modal-body textarea { resize: vertical; }

/* Custom date fields: year/month/day numeric inputs + 📅 picker button. The
   hidden native date input only hosts the browser's calendar popup. */
.ev-date-fields {
  display: inline-flex;
  align-items: stretch;
  gap: 0.15rem;
}

.event-modal-body .ev-dnum {
  width: 3.4em;
  text-align: center;
  padding-left: 0.25rem;
  padding-right: 0.25rem;
}

.event-modal-body .ev-year { width: 4.6em; }

/* Token expiry reuses the custom date fields inside the settings .inner-form,
   whose inputs are otherwise full-width. Keep each box just wide enough for its
   digits (2 for month/day, 4 for year) and match the modal's compact styling. */
#ev-token-expires-date-fields .ev-dnum {
  width: 2.6em;
  text-align: center;
  padding-left: 0.25rem;
  padding-right: 0.25rem;
  background: var(--bg-control);
  color: var(--text-strong);
}
#ev-token-expires-date-fields .ev-year { width: 3.6em; }

.ev-dsep {
  display: flex;
  align-items: center;
  color: var(--text-faint);
  font-weight: 600;
}

.ev-cal-btn {
  margin-left: 0.25rem;
  padding: 0 0.4rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  background: var(--bg-control);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}

.ev-cal-btn:hover { background: var(--bg-control-hover); }
.ev-cal-btn:disabled { cursor: default; opacity: 0.5; }

/* Custom mini date picker popup (replaces the native one so it can honour the
   user's first-day-of-week setting). Appended to <body>, positioned in JS. */
.ev-cal-pop {
  position: fixed;
  z-index: 210;
  background: var(--bg-surface);
  border: 1px solid var(--border-input);
  border-radius: 6px;
  box-shadow: 0 6px 24px var(--shadow);
  padding: 0.5rem;
  width: 15rem;
  font-size: 13px;
}

.ev-cal-pop[hidden] { display: none; }

.ev-cal-pop-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.4rem;
}

.ev-cal-title { font-weight: 600; border: 0; background: none; cursor: pointer; font-size: inherit; color: inherit; }
.ev-cal-title:hover { text-decoration: underline; }

.ev-cal-nav {
  border: 1px solid var(--border-input);
  border-radius: 4px;
  background: var(--bg-control);
  width: 1.8em;
  line-height: 1.4;
  cursor: pointer;
}

.ev-cal-nav:hover { background: var(--bg-control-hover); }

.ev-cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
}

.ev-cal-dow {
  text-align: center;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-faint);
  padding: 0.2rem 0;
}

.ev-cal-day {
  border: 0;
  background: none;
  padding: 0.3rem 0;
  border-radius: 4px;
  cursor: pointer;
  color: var(--text-strong);
}

.ev-cal-day:hover { background: var(--bg-control-hover); }
.ev-cal-day.other-month { color: var(--text-dim); }
.ev-cal-day.today { outline: 1px solid var(--today-outline); }
.ev-cal-day.selected { background: var(--primary); color: #fff; }
.ev-cal-day.disabled {
  color: var(--text-disabled);
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

.ev-cal-grid.months { grid-template-columns: repeat(3, 1fr); }

.ev-cal-month {
  border: 0;
  background: none;
  padding: 0.5rem 0;
  border-radius: 4px;
  cursor: pointer;
  color: var(--text-strong);
}

.ev-cal-month:hover { background: var(--bg-control-hover); }
.ev-cal-month.today { outline: 1px solid var(--today-outline); }
.ev-cal-month.selected { background: var(--primary); color: #fff; }

/* Header title is a jump-to-date trigger (opens the mini picker). */
.fc-toolbar-title { cursor: pointer; }
.fc-toolbar-title:hover { text-decoration: underline; }

/* HH:MM spinner pair (+ AM/PM toggle in 12h mode). Rebuilt per modal-open to
   match the time_format setting. */
.ev-time-fields {
  display: inline-flex;
  align-items: stretch;
  gap: 0.15rem;
}

.ev-ampm {
  margin-left: 0.25rem;
  padding: 0 0.5rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  background: var(--bg-control);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.ev-ampm:hover { background: var(--bg-control-hover); }
.ev-ampm:disabled { cursor: default; opacity: 0.6; }

.event-modal-body .ev-hh,
.event-modal-body .ev-mm {
  width: 3.4em;
  text-align: center;
  padding-left: 0.25rem;
  padding-right: 0.25rem;
}

/* Custom ▲▼ stepper buttons (cross-browser, always visible). The column
   stretches to the input height and the two buttons split it 50/50, so each
   arrow gets a full-size, non-overlapping hit target. */
.ev-spin {
  display: inline-flex;
  flex-direction: column;
  margin-left: 0.1rem;
}

.ev-spin button {
  flex: 1 1 0;
  box-sizing: border-box;
  width: 1.6em;
  min-height: 0;
  padding: 0;
  border: 1px solid var(--border-input);
  background: var(--bg-stepper);
  color: var(--text-muted);
  font-size: 9px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ev-spin button:hover { background: var(--bg-control-hover); }
.ev-spin-up { border-radius: 4px 4px 0 0; }
.ev-spin-down { border-radius: 0 0 4px 4px; border-top: none; }

.ev-colon { display: flex; align-items: center; color: var(--text-faint); font-weight: 600; }

.event-modal-body input[readonly],
.event-modal-body textarea[readonly],
.event-modal-body input[disabled],
.ev-check input[disabled] { cursor: default; }

.event-modal-body input[disabled],
.event-modal-body textarea[disabled] {
  background: var(--bg-disabled);
  color: var(--text-faint);
}

.event-modal-footer {
  flex: none;
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.75rem 1rem;
  border-top: 1px solid var(--border-panel);
}

.btn-primary {
  padding: 0.3rem 0.9rem;
  border: 1px solid var(--primary);
  border-radius: 4px;
  background: var(--primary);
  color: #fff;
  font-size: 13px;
  cursor: pointer;
}

.btn-primary:hover { background: var(--primary-hover); }
.btn-primary:disabled { opacity: .6; cursor: default; }

.ev-group {
  border: 1px solid var(--border-light);
  border-radius: 4px;
  padding: 0.6rem 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.ev-group legend {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-faint);
  padding: 0 0.25rem;
}

.ev-check {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 13px;
}

.ev-dt-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.ev-dt-row .ev-label {
  width: auto;
  min-width: 3rem;
  white-space: nowrap;
  flex: none;
}

.ev-recur-editor {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.5rem;
}
.ev-recur-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.ev-recur-interval, .ev-recur-count { width: 4rem; }
.ev-recur-row select { flex: none; }
.ev-recur-row .ev-radio {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 13px;
}
.ev-recur-unit { font-size: 13px; color: var(--text-muted); }
.ev-recur-summary {
  font-size: 13px;
  color: var(--text-muted);
  font-style: italic;
  margin-bottom: 0.25rem;
}
.ev-recur-preview {
  font-size: 13px;
  color: var(--primary);
  min-height: 1.2em;
}

.ev-reminders-box {
  display: flex;
  flex-direction: column;
}

.ev-reminders {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.ev-reminder {
  font-size: 13px;
  color: var(--text-body);
  padding: 0.3rem 0.5rem;
  background: var(--bg-subtle);
  border-radius: 4px;
}
.ev-reminder.empty-note { background: none; padding: 0; }
.ev-reminder-locked { color: var(--text-disabled); }

.ev-reminder-row {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.ev-reminder-row .ev-reminder { flex: 1; }
.ev-reminder-row .ev-reminder-word {
  font-size: 13px;
  color: var(--text-body);
}
.ev-reminder-value {
  width: 4.5rem;
  padding: 0.3rem 0.4rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  font: inherit;
  font-size: 13px;
}
.ev-reminder-unit {
  padding: 0.3rem 0.4rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  font: inherit;
  font-size: 13px;
}
.ev-reminder-row .ev-hh,
.ev-reminder-row .ev-mm {
  width: 2.6em;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  font: inherit;
  font-size: 13px;
  padding-top: 0.3rem;
  padding-bottom: 0.3rem;
}
.ev-reminder-del { font-size: 14px; }
.ev-reminder-add {
  align-self: flex-start;
  margin-top: 0.25rem;
  font-size: 18px;
}

.event-modal-body select {
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  font: inherit;
  font-size: 13px;
  background: var(--bg-control);
  color: var(--text-strong);
}

/* Footer Delete sits on the left; Cancel/Save stay right. */
#btn-event-delete { margin-right: auto; }

.btn-danger {
  padding: 0.3rem 0.9rem;
  border: 1px solid var(--danger-border);
  border-radius: 4px;
  background: var(--bg-surface);
  color: var(--error-text);
  font-size: 13px;
  cursor: pointer;
}
.btn-danger:hover { background: var(--error-bg); }
.btn-danger:disabled { opacity: .6; cursor: default; }

/* Right-click context menu on events. */
.ev-context-menu {
  position: fixed;
  z-index: 250;
  min-width: 120px;
  background: var(--bg-surface);
  border: 1px solid var(--border-input);
  border-radius: 4px;
  box-shadow: 0 4px 16px var(--shadow);
  padding: 0.25rem;
  display: flex;
  flex-direction: column;
}
.ev-context-menu button {
  text-align: left;
  padding: 0.4rem 0.6rem;
  border: none;
  background: none;
  font: inherit;
  font-size: 13px;
  color: var(--text-strong);
  border-radius: 3px;
  cursor: pointer;
}
.ev-context-menu button:hover { background: var(--bg-menu-hover); }
.ev-context-menu #ctx-delete { color: var(--error-text); }
.ev-context-menu #ctx-delete:hover { background: var(--error-bg); }

/* Confirm (yes/no) dialog — above the event modal. */
#confirm-overlay { z-index: 300; }
.confirm-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 320px;
  max-width: 90vw;
  background: var(--bg-surface);
  border: 1px solid var(--border-panel);
  border-radius: 6px;
  box-shadow: 0 8px 32px var(--shadow);
  z-index: 301;
  padding: 1.25rem;
}
.confirm-modal p {
  margin: 0 0 1rem;
  font-size: 14px;
  color: var(--text-strong);
}
.confirm-footer {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
}
.scope-options {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1rem;
}
.scope-options button {
  text-align: left;
  width: 100%;
}

/* ── Tasks (VTODO) ─────────────────────────────────────────────────────────── */

/* A task's checkbox square replaces FullCalendar's round event dot. It takes
   the event (per-calendar) colour as its border; a completed task fills the box
   and shows a tick. */
.fc-task-box {
  box-sizing: border-box;
  display: inline-block;
  flex: 0 0 auto;
  width: 0.8em;
  height: 0.8em;
  margin: 0 0.35em 0 0.1em;
  border: 1.5px solid currentColor;
  border-radius: 2px;
  vertical-align: -0.05em;
  cursor: pointer;
  position: relative;
}
.fc-task-box.done::after {
  content: "✓";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -55%);
  font-size: 0.7em;
  line-height: 1;
}
/* In dayGrid the event text colour is the calendar colour, so currentColor on
   the box already matches. In timeGrid/list the box sits on a coloured chip;
   keep it readable with the chip's own contrast. */
.fc-event .fc-task-box { color: inherit; }

/* Grayed-out completed tasks (the alternative to hiding them). */
.fc-task-grayed { opacity: 0.55; }
.fc-task-grayed .fc-event-title,
.fc-task-grayed .fc-list-event-title { text-decoration: line-through; }

/* Non-working day coloring (public holidays + country-correct weekend).
   The whole day cell/column is tinted and the day number turns red; hovering
   the number shows the holiday/weekend name via a `title` attribute set in JS. */
.fc-day-nonworking { background: var(--nonworking-bg); }
.fc-day-nonworking .fc-daygrid-day-number,
.fc-day-nonworking .fc-col-header-cell-cushion,
.fc-day-nonworking.fc-col-header-cell .fc-col-header-cell-cushion {
  color: var(--nonworking-fg);
}
/* Today keeps its own bg tint; just the number goes red when it's also non-working. */
.fc-daygrid-day.fc-day-today.fc-day-nonworking { background: var(--fc-today-bg-color); }
.fc-daygrid-day.fc-day-today.fc-day-nonworking .fc-daygrid-day-number { color: var(--nonworking-fg); }
/* Agenda day header that is a non-working day. */
.agenda-day-header.agenda-day-nonworking { color: var(--nonworking-fg); }

/* Agenda square mirrors the grid one, coloured per calendar inline. */
.agenda-box {
  box-sizing: border-box;
  flex: 0 0 0.7rem;
  width: 0.7rem;
  height: 0.7rem;
  border: 1.5px solid currentColor;
  border-radius: 2px;
  align-self: center;
  cursor: pointer;
  position: relative;
}
.agenda-box.done::after {
  content: "✓";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -55%);
  font-size: 0.6rem;
  line-height: 1;
}
.agenda-row.is-task-done { opacity: 0.55; }
.agenda-row.is-task-done .agenda-title { text-decoration: line-through; }

/* Journal marker: a downward-pointing triangle (pencil tip), filled with the
   per-calendar colour. Mirrors the event dot / task box markers. */
.fc-journal-tri {
  box-sizing: border-box;
  display: inline-block;
  flex: 0 0 auto;
  width: 0.7em;
  height: 0.7em;
  margin: 0 0.4em 0 0.1em;
  background: currentColor;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  vertical-align: 0;
}
.fc-event .fc-journal-tri { color: inherit; }
.agenda-tri {
  box-sizing: border-box;
  flex: 0 0 0.7rem;
  width: 0.7rem;
  height: 0.7rem;
  background: currentColor;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  align-self: center;
}

/* Journal body: a two-tab editor (raw-Markdown "Edit" textarea + rendered,
   read-only "Display" pane). */
.ev-journal-tabs {
  display: flex;
  gap: 0.25rem;
  margin-bottom: 0.4rem;
}
.ev-journal-tab {
  padding: 0.25rem 0.7rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  background: var(--bg-control);
  color: var(--text-body);
  cursor: pointer;
  font: inherit;
  font-size: 13px;
}
.ev-journal-tab.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.event-modal-body textarea.ev-journal-edit {
  width: 100%;
  box-sizing: border-box;
  min-height: 14rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.ev-journal-display {
  width: 100%;
  box-sizing: border-box;
  min-height: 14rem;
  max-height: 28rem;
  overflow-y: auto;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--border-input);
  border-radius: 4px;
  background: var(--bg-control);
  color: var(--text-strong);
  font-size: 13px;
}
/* Tame the rendered Markdown's vertical rhythm inside the modal. */
.ev-journal-display > :first-child { margin-top: 0; }
.ev-journal-display > :last-child { margin-bottom: 0; }
.ev-journal-display pre {
  overflow-x: auto;
  padding: 0.5rem;
  border-radius: 4px;
  background: var(--bg-subtle);
}
.ev-journal-display code {
  background: var(--bg-subtle);
  padding: 0.1em 0.3em;
  border-radius: 3px;
}
.ev-journal-display pre code { background: none; padding: 0; }

/* The global `* { margin:0; padding:0 }` reset strips list indents/markers and
   table borders; restore them inside the rendered Markdown only. */
.ev-journal-display ul,
.ev-journal-display ol { padding-left: 1.6em; margin: 0.4em 0; }
.ev-journal-display ul { list-style: disc; }
.ev-journal-display ol { list-style: decimal; }
.ev-journal-display ul ul { list-style: circle; }
.ev-journal-display ul ul ul { list-style: square; }
.ev-journal-display li { margin: 0.15em 0; }
.ev-journal-display li > ul,
.ev-journal-display li > ol { margin: 0.15em 0; }
.ev-journal-display p { margin: 0.5em 0; }
.ev-journal-display h1,
.ev-journal-display h2,
.ev-journal-display h3,
.ev-journal-display h4 { margin: 0.7em 0 0.3em; line-height: 1.25; }
.ev-journal-display blockquote {
  margin: 0.6em 0;
  padding: 0.1em 0.9em;
  border-left: 3px solid var(--border-input);
  color: var(--text-dim);
}
.ev-journal-display a { color: var(--accent); }
.ev-journal-display hr { border: none; border-top: 1px solid var(--border-faint); margin: 0.8em 0; }
.ev-journal-display img { max-width: 100%; }

/* Tables: the reset removes borders, leaving text-only; restore them. */
.ev-journal-display table { border-collapse: collapse; margin: 0.6em 0; }
.ev-journal-display th,
.ev-journal-display td { border: 1px solid var(--border-input); padding: 0.3em 0.6em; }
.ev-journal-display th { background: var(--bg-subtle); text-align: left; }

/* Task-list checkboxes (markdown-it-task-lists): no bullet, aligned box. */
.ev-journal-display ul.contains-task-list { list-style: none; padding-left: 0.6em; }
.ev-journal-display .task-list-item { list-style: none; }
.ev-journal-display .task-list-item-checkbox { margin-right: 0.45em; }

/* Custom containers (`::: name`). A neutral default plus a few named accents. */
.ev-journal-display .md-container {
  margin: 0.7em 0;
  padding: 0.5em 0.9em;
  border-left: 4px solid var(--accent);
  border-radius: 4px;
  background: var(--bg-subtle);
}
.ev-journal-display .md-container > :first-child { margin-top: 0; }
.ev-journal-display .md-container > :last-child { margin-bottom: 0; }
.ev-journal-display .md-warning { border-left-color: var(--warn); }
.ev-journal-display .md-danger { border-left-color: var(--danger-border); }
.ev-journal-display .md-tip,
.ev-journal-display .md-success { border-left-color: var(--today); }

/* Footnotes (markdown-it-footnote). */
.ev-journal-display .footnotes {
  font-size: 0.9em;
  border-top: 1px solid var(--border-faint);
  margin-top: 1em;
  padding-top: 0.4em;
  color: var(--text-dim);
}
.ev-journal-display mark { background: #fde68a; color: #000; padding: 0 0.15em; }

/* highlight.js tokens, themed (GitHub-ish), light by default. */
.ev-journal-display .hljs { display: block; }
.ev-journal-display .hljs-comment,
.ev-journal-display .hljs-quote { color: #6a737d; font-style: italic; }
.ev-journal-display .hljs-keyword,
.ev-journal-display .hljs-selector-tag,
.ev-journal-display .hljs-literal,
.ev-journal-display .hljs-type,
.ev-journal-display .hljs-built_in { color: #d73a49; }
.ev-journal-display .hljs-string,
.ev-journal-display .hljs-regexp,
.ev-journal-display .hljs-meta-string { color: #032f62; }
.ev-journal-display .hljs-number,
.ev-journal-display .hljs-symbol,
.ev-journal-display .hljs-bullet,
.ev-journal-display .hljs-link { color: #005cc5; }
.ev-journal-display .hljs-title,
.ev-journal-display .hljs-section,
.ev-journal-display .hljs-name { color: #6f42c1; }
.ev-journal-display .hljs-attr,
.ev-journal-display .hljs-attribute,
.ev-journal-display .hljs-variable,
.ev-journal-display .hljs-tag { color: #22863a; }
.ev-journal-display .hljs-meta { color: #6a737d; }
.ev-journal-display .hljs-emphasis { font-style: italic; }
.ev-journal-display .hljs-strong { font-weight: 600; }

/* highlight.js dark tokens — explicit dark theme and system-prefers-dark. */
:root[data-theme="dark"] .ev-journal-display .hljs-comment,
:root[data-theme="dark"] .ev-journal-display .hljs-quote { color: #8b949e; }
:root[data-theme="dark"] .ev-journal-display .hljs-keyword,
:root[data-theme="dark"] .ev-journal-display .hljs-selector-tag,
:root[data-theme="dark"] .ev-journal-display .hljs-literal,
:root[data-theme="dark"] .ev-journal-display .hljs-type,
:root[data-theme="dark"] .ev-journal-display .hljs-built_in { color: #ff7b72; }
:root[data-theme="dark"] .ev-journal-display .hljs-string,
:root[data-theme="dark"] .ev-journal-display .hljs-regexp { color: #a5d6ff; }
:root[data-theme="dark"] .ev-journal-display .hljs-number,
:root[data-theme="dark"] .ev-journal-display .hljs-symbol,
:root[data-theme="dark"] .ev-journal-display .hljs-bullet,
:root[data-theme="dark"] .ev-journal-display .hljs-link { color: #79c0ff; }
:root[data-theme="dark"] .ev-journal-display .hljs-title,
:root[data-theme="dark"] .ev-journal-display .hljs-section,
:root[data-theme="dark"] .ev-journal-display .hljs-name { color: #d2a8ff; }
:root[data-theme="dark"] .ev-journal-display .hljs-attr,
:root[data-theme="dark"] .ev-journal-display .hljs-attribute,
:root[data-theme="dark"] .ev-journal-display .hljs-variable,
:root[data-theme="dark"] .ev-journal-display .hljs-tag { color: #7ee787; }
:root[data-theme="dark"] .ev-journal-display .hljs-meta { color: #8b949e; }

@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] .ev-journal-display .hljs-comment,
  :root[data-theme="system"] .ev-journal-display .hljs-quote { color: #8b949e; }
  :root[data-theme="system"] .ev-journal-display .hljs-keyword,
  :root[data-theme="system"] .ev-journal-display .hljs-selector-tag,
  :root[data-theme="system"] .ev-journal-display .hljs-literal,
  :root[data-theme="system"] .ev-journal-display .hljs-type,
  :root[data-theme="system"] .ev-journal-display .hljs-built_in { color: #ff7b72; }
  :root[data-theme="system"] .ev-journal-display .hljs-string,
  :root[data-theme="system"] .ev-journal-display .hljs-regexp { color: #a5d6ff; }
  :root[data-theme="system"] .ev-journal-display .hljs-number,
  :root[data-theme="system"] .ev-journal-display .hljs-symbol,
  :root[data-theme="system"] .ev-journal-display .hljs-bullet,
  :root[data-theme="system"] .ev-journal-display .hljs-link { color: #79c0ff; }
  :root[data-theme="system"] .ev-journal-display .hljs-title,
  :root[data-theme="system"] .ev-journal-display .hljs-section,
  :root[data-theme="system"] .ev-journal-display .hljs-name { color: #d2a8ff; }
  :root[data-theme="system"] .ev-journal-display .hljs-attr,
  :root[data-theme="system"] .ev-journal-display .hljs-attribute,
  :root[data-theme="system"] .ev-journal-display .hljs-variable,
  :root[data-theme="system"] .ev-journal-display .hljs-tag { color: #7ee787; }
  :root[data-theme="system"] .ev-journal-display .hljs-meta { color: #8b949e; }
}

.ev-task-hint {
  margin: 0.4rem 0 0;
  font-size: 12px;
  color: var(--text-faint);
}

/* ── Sharing ──────────────────────────────────────────────────────────────── */
.share-cal-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.2rem 0;
}
.share-cal-row .ev-check { margin: 0; }
/* Read-only share: the per-calendar writable/default controls are irrelevant. */
#share-cal-picker.share-ro .share-cal-w,
#share-cal-picker.share-ro .share-cal-d { display: none; }

#shareres-download { text-decoration: none; }

/* Share-view page (share.html) */
.page-share { display: flex; flex-direction: column; height: 100vh; }
.share-view-title { font-weight: 600; margin-left: 0.5rem; }
.share-spacer { flex: 1 1 auto; }
.share-item { padding: 1.5rem; overflow: auto; }
.share-item-card {
  max-width: 640px;
  margin: 0 auto;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #ddd);
  border-radius: 8px;
  padding: 1.25rem 1.5rem;
}
.share-item-card h2 { margin-top: 0; }
.share-item-when { color: var(--text-faint); }
.share-item-notes {
  white-space: pre-wrap;
  font-family: inherit;
  background: var(--surface-2, #f6f6f6);
  padding: 0.75rem;
  border-radius: 6px;
}

/* Item-share landing (single item opens in the normal modal). */
.share-item-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

/* ── Mobile / touch layer ──────────────────────────────────────────────────
   Everything below only applies on narrow viewports; desktop (>768px) is left
   exactly as designed above. The settings panel and every modal become bottom
   sheets (docked to the bottom edge, full width, rounded top, grab handle);
   tap targets grow to the 44px guideline; form inputs use 16px to stop iOS
   from auto-zooming on focus. JS (app.js) adds long-press → context menu and
   swipe-down → dismiss, both keyed to the same breakpoint. */
@media (max-width: 768px) {
  /* Bottom-sheet pattern shared by the settings panel and all modals. The
     desktop centered transform is dropped; JS drives a translateY for the
     swipe-to-dismiss drag, and the transition eases it back on release. */
  .settings-panel,
  .event-modal,
  .confirm-modal {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    max-width: 100vw;
    min-width: 0;
    transform: none;
    border: none;
    border-top: 1px solid var(--border-panel);
    border-radius: 16px 16px 0 0;
    max-height: 90dvh;
    resize: none;
    transition: transform 0.18s ease-out;
  }
  /* Dragging adds .sheet-dragging inline transform; suppress the easing so the
     sheet tracks the finger 1:1, then re-enable it for the spring-back. */
  .settings-panel.sheet-dragging,
  .event-modal.sheet-dragging,
  .confirm-modal.sheet-dragging {
    transition: none;
  }

  /* Grab-handle affordance pinned to the top of each sheet. */
  .settings-header::before,
  .event-modal-header::before,
  .confirm-modal::before {
    content: "";
    position: absolute;
    top: 0.45rem;
    left: 50%;
    transform: translateX(-50%);
    width: 2.25rem;
    height: 0.25rem;
    border-radius: 999px;
    background: var(--border-control);
  }
  .settings-header,
  .event-modal-header { position: relative; padding-top: 1.1rem; }
  .confirm-modal { position: fixed; padding-top: 1.6rem; }

  /* Touch targets: 44px minimum, larger glyphs. */
  .btn-outline,
  .btn-primary,
  .btn-danger {
    min-height: 44px;
    font-size: 15px;
  }
  .btn-icon { min-width: 44px; min-height: 44px; font-size: 20px; }
  .ev-context-menu button { min-height: 44px; font-size: 15px; }
  .ev-journal-tab { min-height: 40px; padding: 0.45rem 1rem; font-size: 15px; }
  .cal-color { width: 36px; height: 36px; }
  .ev-spin button { width: 2.2em; }
  .ev-cal-nav { width: 2.4em; }
  .ev-cal-day { padding: 0.55rem 0; }
  .fab:active { background: var(--fab-hover); transform: scale(0.94); }

  /* 16px inputs prevent the iOS focus-zoom; widen the cramped date spinners. */
  .event-modal-body input[type="text"],
  .event-modal-body .ev-dnum,
  .event-modal-body textarea,
  .event-modal-body select,
  .settings-scroll input,
  .settings-scroll select,
  .cal-search-input {
    font-size: 16px;
  }
  .event-modal-body .ev-dnum { width: 3em; }
  .event-modal-body .ev-year { width: 4em; }

  /* Mini date-picker popup must never overflow the viewport. */
  .ev-cal-pop { width: min(15rem, 92vw); }

  /* Journal editor: smaller minimums so Edit + Display fit a portrait phone. */
  .event-modal-body textarea.ev-journal-edit,
  .ev-journal-display { min-height: 10rem; }
  .ev-journal-display { max-height: 50dvh; }

  /* Stop the page from ever growing wider than the screen: the top bar's
     intrinsic width (logo + name + buttons) used to force a horizontal scroll,
     leaving a grey gutter and pushing the action buttons off-screen. */
  html, body { overflow-x: hidden; }
  #page-calendar { width: 100vw; max-width: 100vw; overflow: hidden; }

  /* Top bar: drop the email + the long auto-logout text, and let the row wrap
     instead of overflowing so the action buttons stay reachable. */
  .user-email,
  .logout-countdown { display: none; }
  .top-bar {
    flex-wrap: wrap;
    height: auto;
    min-width: 0;
    gap: 0.6rem;
    padding: 0.5rem 0.75rem;
  }
  .top-bar .btn-outline { padding: 0.3rem 0.6rem; }

  /* FullCalendar header: let the toolbar wrap instead of overflowing, and put
     the title on its own line above the button groups. */
  .fc .fc-toolbar.fc-header-toolbar { flex-wrap: wrap; gap: 0.4rem; }
  .fc .fc-toolbar-title { font-size: 1.3rem; }

  /* Touch feedback where hover never fires. */
  .agenda-row:active { background: var(--bg-row-hover); }
  .ev-context-menu button:active,
  .btn-outline:active { background: var(--bg-subtle); }
  .ev-cal-day:active { background: var(--bg-control-hover); }
}

/* Narrow-phone tier: agenda time column shrinks so titles keep room. */
@media (max-width: 480px) {
  .agenda-time { flex-basis: 5rem; }
  .fab { right: 1rem; bottom: 1rem; }
}

/* Short-viewport tier (landscape phones): height — not width — is the scarce
   axis, so the chrome must stop eating it. Keyed on height so portrait phones
   (tall) never match and vertical mode is untouched. Declared after the
   max-width block so its compact min-heights win where both apply. */
@media (max-height: 500px) {
  /* Reclaim the 44px touch targets — in landscape there's width to spare, and
     the user can rotate back for big targets. */
  .btn-outline,
  .btn-primary,
  .btn-danger,
  .fc .fc-button {
    min-height: 0;
    padding: 0.25rem 0.6rem;
    font-size: 14px;
  }
  .btn-icon { min-height: 0; min-width: 0; }

  /* Slim the two header rows so the grid keeps the remaining height. */
  .top-bar { height: auto; padding: 0.2rem 0.75rem; gap: 0.5rem; }
  .fc .fc-toolbar.fc-header-toolbar { margin-bottom: 0.4em; gap: 0.3rem; }
  .fc .fc-toolbar-title { font-size: 1.15rem; }

  /* Bottom-sheet modals can use nearly the whole short viewport. */
  .settings-panel,
  .event-modal,
  .confirm-modal { max-height: 96dvh; }
  .event-modal-body textarea.ev-journal-edit,
  .ev-journal-display { min-height: 6rem; }
}

/* ── Accessibility ──────────────────────────────────────────────────────────
   Keyboard operability: a single visible focus ring for every interactive
   control. Uses :focus-visible so a mouse click never shows the ring, only
   keyboard navigation does. The auth/settings input rules above already set
   their own :focus outline; this covers buttons, links, and the custom
   widgets (agenda rows, date-picker grid, AM/PM, tabs, context menu) that had
   no focus feedback at all. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* Some controls (agenda rows, calendar days) clip or have no padding, so an
   offset ring would be cut off — pull it inside for those. */
.agenda-row:focus-visible,
.ev-cal-day:focus-visible,
.fc .fc-daygrid-event:focus-visible,
.fc .fc-timegrid-event:focus-visible,
.fc .fc-daygrid-day:focus-visible,
.fc .fc-timegrid-col:focus-visible {
  outline-offset: -2px;
}
/* The day cell's outline would be hidden behind sibling cells without this. */
.fc .fc-daygrid-day:focus-visible {
  position: relative;
  z-index: 1;
}
/* Skip link: visually hidden until focused, then pinned to the top-left. */
.skip-link {
  position: absolute;
  left: 0;
  top: 0;
  transform: translateY(-120%);
  z-index: 1100;
  margin: 0.25rem;
  padding: 0.5rem 0.9rem;
  background: var(--accent);
  color: #fff;
  border-radius: 4px;
  font-size: 14px;
  text-decoration: none;
}
.skip-link:focus {
  transform: translateY(0);
}

/* Honour a user's reduced-motion preference: drop the modal/sheet slide and
   spinner animation, keeping the UI fully usable without movement. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
