/* CBF Schedule. One rule per thing: base styles first, by part of the screen, then the changes for
   each screen size (medium, phones, touch) and for printing at the end. */

/* ============================================================ Tokens */
/* The Steadfast look shared with Focus and FollowThrough: a warm off-white ground, white cards with a
   1px warm edge and almost no shadow, one blue accent kept for selection and the main action, and
   Manrope. Colour is for exceptions, so a schedule where everything is fine is nearly monochrome. */
@font-face {
  font-family: "Manrope";
  src: url("fonts/Manrope.ttf") format("truetype");
  font-weight: 200 800;
  font-display: swap;
}
:root {
  --bg: #f6f4f1;          /* the page ground */
  --surface: #fffefc;     /* cards, panels, the grid */
  --surface-raised: #ffffff;
  --surface-2: #f2eee7;   /* row and button hover */
  --surface-3: #e9e4db;
  --border: #e9e4db;      /* dividers between rows */
  --border-strong: #d8d1c5; /* field, button and card edges */
  --border-hover: #bbb2a4;
  --border-month: #bbb2a4;
  --text: #1f1d1a;
  --muted: #6b655c;
  --faint: var(--muted);  /* resting labels and hints: in light the one grey that's AA at 12px; dark keeps a softer one */
  --accent: #3457dc;
  --accent-solid: #3457dc; /* the fill of a primary button */
  --accent-hover: #2a47b8;
  --on-accent: #ffffff;
  --accent-soft: #eef1fd;
  --accent-tint: #f6f7fe;
  --hl-bg: #3457dc;
  --on-hl: #ffffff;
  --sel: #3457dc;
  --focus-ring: rgba(52, 87, 220, .32);

  /* Planning Center status colors: teal and red-orange, so confirmed and declined differ in hue and
     lightness (each also has its own glyph shape). */
  --st-c: #1f8a70;   /* confirmed  ✓ */
  --st-c-soft: #9fcabd; /* the quiet ✓ on names: nothing to do */
  --st-u: #cf8f3e;   /* unconfirmed ● */
  --st-o: #b8621b;   /* overdue ◉: unconfirmed and running late */
  --st-n: #8c8374;   /* not sent yet ○ (3:1 on the grid, as a graphic needs) */
  --st-d: #cf4827;   /* declined ✕ */
  --st-b: #9f3a2b;   /* blocked out ⊘ */
  --warn-text: #8a5d1f;
  --bad-text: #b63c1e;
  --danger-solid: #b63c1e; /* the fill of a danger button, under white text (≥4.5:1) */

  --open-bg: #faf1e3;
  --open-text: #8a5d1f;
  --open-border: #e3bd85;

  --pending: #7048c8;
  --pending-soft: #f2edfb;

  /* The strip across the top of a test copy (Beta / Local test): dark, with a yellow tag. */
  --beta-bg: #2b2721;
  --beta-text: #f4f0e7;
  --beta-tag: #f2c14e;
  --tip-bg: #2b2721;     /* tooltips: dark on the light theme, the usual way */
  --tip-text: #f8f5ef;
  --tip-sub: #cfc7b8;
  --tip-border: #2b2721;

  --scrim: rgba(24, 21, 16, .38);
  --shadow: 0 8px 28px rgba(20, 24, 22, .14);
  --shadow-modal: 0 24px 70px rgba(20, 24, 22, .28);
  --shadow-sm: 0 1px 2px rgba(31, 37, 34, .04);
  --radius-sm: 4px;
  --radius-md: 6px;   /* buttons, fields, menu rows */
  --radius-lg: 8px;   /* cards, panels, menus */
  --radius-xl: 12px;  /* dialogs */
  --radius-sheet: 16px; /* the top corners of a sheet from the bottom (phones) */
  /* Type: one scale, smallest to largest (phones use the upper steps). */
  --fs-1: 10.5px;
  --fs-2: 11px;
  --fs-3: 11.5px;
  --fs-4: 12px;
  --fs-5: 12.5px;
  --fs-6: 13px;
  --fs-7: 13.5px;
  --fs-8: 14px;
  --fs-9: 15px;
  --fs-10: 16px;
  --fs-11: 17px;
  --fs-12: 20px;
  --fs-13: 22px;
  --font-sans: "Manrope", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --col: 92px;
  --poscol: 136px;
  --rail-w: 64px;
  color-scheme: light;
}

/* Dark: when the device is dark and nobody picked Light, or when Dark was picked. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #15120d;
    --surface: #1e1a13;
    --surface-raised: #252017;
    --surface-2: #2c2719;
    --surface-3: #363024;
    --border: #322d23;
    --border-strong: #423c2f;
    --border-hover: #564f3f;
    --border-month: #564f3f;
    --text: #f4f0e7;
    --muted: #b3ab9b;
    --faint: #a09788;
    --accent: #93a6f0;
    --accent-solid: #4a6aee;
    --accent-hover: #6580f3;
    --on-accent: #ffffff;
    --accent-soft: #1d2746;
    --accent-tint: #1b1c22;
    --hl-bg: #4a6aee;
    --sel: #93a6f0;
    --focus-ring: rgba(99, 129, 244, .42);
    --st-c: #2aa385;
    --st-c-soft: #3f7a69;
    --st-u: #d99a4e;
    --st-o: #e8763a;
    --st-n: #8a8172;
    --st-d: #e0553a;
    --st-b: #d0605a;
    --warn-text: #e5b678;
    --bad-text: #f0906f;
    --danger-solid: #c2402a;
    --open-bg: #33270f;
    --open-text: #e5b678;
    --open-border: #6e5326;
    --pending: #a78bfa;
    --pending-soft: #261d3d;
    --beta-bg: #4a4130;
    --beta-text: #f4f0e7;
    --beta-tag: #f2c14e;
    --tip-bg: #3d3629;     /* raised, with an edge: a light box would glare on the dark theme */
    --tip-text: #f4f0e7;
    --tip-sub: #c2baa9;
    --tip-border: #5a5242;
    --scrim: rgba(0, 0, 0, .55);
    --shadow: 0 8px 28px rgba(0, 0, 0, .4);
    --shadow-modal: 0 24px 70px rgba(0, 0, 0, .55);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #15120d;
  --surface: #1e1a13;
  --surface-raised: #252017;
  --surface-2: #2c2719;
  --surface-3: #363024;
  --border: #322d23;
  --border-strong: #423c2f;
  --border-hover: #564f3f;
  --border-month: #564f3f;
  --text: #f4f0e7;
  --muted: #b3ab9b;
  --faint: #a09788;
  --accent: #93a6f0;
  --accent-solid: #4a6aee;
  --accent-hover: #6580f3;
  --on-accent: #ffffff;
  --accent-soft: #1d2746;
  --accent-tint: #1b1c22;
  --hl-bg: #4a6aee;
  --sel: #93a6f0;
  --focus-ring: rgba(99, 129, 244, .42);
  --st-c: #2aa385;
  --st-c-soft: #3f7a69;
  --st-u: #d99a4e;
  --st-o: #e8763a;
  --st-n: #8a8172;
  --st-d: #e0553a;
  --st-b: #d0605a;
  --warn-text: #e5b678;
  --bad-text: #f0906f;
  --danger-solid: #c2402a;
  --open-bg: #33270f;
  --open-text: #e5b678;
  --open-border: #6e5326;
  --pending: #a78bfa;
  --pending-soft: #261d3d;
  --beta-bg: #4a4130;
  --beta-text: #f4f0e7;
  --beta-tag: #f2c14e;
  --tip-bg: #3d3629;     /* raised, with an edge: a light box would glare on the dark theme */
  --tip-text: #f4f0e7;
  --tip-sub: #c2baa9;
  --tip-border: #5a5242;
  --scrim: rgba(0, 0, 0, .55);
  --shadow: 0 8px 28px rgba(0, 0, 0, .4);
  --shadow-modal: 0 24px 70px rgba(0, 0, 0, .55);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);
  color-scheme: dark;
}

/* ============================================================ Base */
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; }
/* An app, not a page: no selecting text, except in the boxes you type in. */
body {
  display: flex;
  flex-direction: column;
  height: 100dvh;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  font: var(--fs-8)/1.45 var(--font-sans);
  -webkit-font-smoothing: antialiased;
  -webkit-user-select: none;
  user-select: none;
}
input, textarea, [contenteditable="true"] { -webkit-user-select: text; user-select: text; }
button, input, select { font: inherit; color: inherit; }
button { cursor: pointer; }
/* One focus ring everywhere: a soft 3px band in the accent. Windows High Contrast gets a solid line. */
:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 1px; }
@media (forced-colors: active) { :focus-visible { outline: 2px solid CanvasText; } }
code { padding: 0 4px; border-radius: var(--radius-sm); background: var(--surface-2); font-size: var(--fs-4); }
.i { width: 17px; height: 17px; flex: none; display: block; }
.muted { color: var(--muted); }
.small { font-size: var(--fs-5); }
.warn-text { color: var(--warn-text); }
.bad { color: var(--bad-text); }
/* Read by screen readers only. */
.sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Scrollbars: always shown when there's more to scroll, taking their own room instead of floating
   over the content (Mac, phones and newer Windows hide them until you scroll). Styling them in
   Chrome, Edge and Safari is what turns the floating kind off. Firefox gets the same colors. */
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { border: 3px solid transparent; border-radius: 999px; background: var(--border-strong) padding-box; }
::-webkit-scrollbar-thumb:hover { background-color: var(--border-hover); }
::-webkit-scrollbar-corner { background: transparent; }
@supports not selector(::-webkit-scrollbar) {
  * { scrollbar-color: var(--border-strong) transparent; }
}

/* ============================================================ Buttons and small controls */
/* Small controls (icon buttons, week arrows, the × on a token) get a bigger invisible hit area
   from a ::after, so they stay compact but are easy to tap. */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 34px;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  font-size: var(--fs-7);
  font-weight: 600;
  white-space: nowrap;
  transition: background .12s, border-color .12s, color .12s;
}
.btn:hover:not(:disabled) { background: var(--surface-2); border-color: var(--border-hover); }
.btn:disabled { opacity: .55; cursor: default; }
.btn.primary { background: var(--accent-solid); border-color: var(--accent-solid); color: var(--on-accent); }
.btn.primary:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn.danger { background: var(--danger-solid); border-color: var(--danger-solid); color: var(--on-accent); }
.btn.danger:hover:not(:disabled) { background: color-mix(in srgb, var(--danger-solid), #000 12%); border-color: transparent; }
.btn.ghost { border-color: transparent; background: none; color: var(--muted); }
.btn.ghost:hover:not(:disabled) { border-color: transparent; color: var(--text); }
.btn.sm { height: 28px; padding: 0 9px; font-size: var(--fs-5); }
.btn.sm .i { width: 14px; height: 14px; }

.icon-btn {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: none;
  border: 0;
  border-radius: var(--radius-md);
  background: none;
  color: var(--muted);
}
.icon-btn::after { content: ""; position: absolute; inset: -6px; }
.icon-btn:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }
.icon-btn:disabled { opacity: .35; cursor: default; }
.icon-btn .i { width: 16px; height: 16px; }

.link { padding: 4px; border: 0; background: none; color: var(--accent); font-size: var(--fs-6); }

/* The header's buttons (drafts, ⋯) and the rail's account and Sign in buttons. */
.tool {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 11px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  font-size: var(--fs-7);
  font-weight: 600;
  transition: background .12s, border-color .12s;
}
.tool:hover { background: var(--surface-2); border-color: var(--border-hover); }
.tool.icon { width: 36px; padding: 0; justify-content: center; }
.tool[aria-expanded="true"] { background: var(--surface-2); }
.tool.busy .i { animation: spin 1s linear infinite; } /* working on it (a disabled button alone doesn't spin) */

.count-badge { min-width: 18px; padding: 0 5px; border-radius: 999px; background: var(--accent-solid); color: var(--on-accent); font-size: var(--fs-2); line-height: 18px; text-align: center; }
.count-badge.quiet { background: var(--surface-3); color: var(--text); }

/* A sunken track with the chosen answer raised on it, as in Focus. */
.seg { display: inline-flex; padding: 2px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg); }
.seg button { display: grid; place-items: center; width: 32px; height: 30px; border: 1px solid transparent; border-radius: var(--radius-sm); background: none; color: var(--muted); }
.seg button:hover:not([aria-pressed="true"]) { color: var(--text); }
.seg button[aria-pressed="true"] { border-color: var(--border); background: var(--surface-raised); box-shadow: var(--shadow-sm); color: var(--text); }
.theme-seg button { width: 28px; height: 26px; }
.theme-seg .i { width: 14px; height: 14px; }

.switch { position: relative; display: flex; align-items: center; gap: 10px; padding: 7px 16px; font-size: var(--fs-7); cursor: pointer; user-select: none; }
.switch input { position: absolute; opacity: 0; pointer-events: none; }
.switch .track { position: relative; width: 32px; height: 18px; flex: none; border-radius: 999px; background: var(--surface-3); transition: background .15s; }
.switch .track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--on-accent); box-shadow: 0 1px 2px rgba(0, 0, 0, .25); transition: transform .15s; }
.switch input:checked + .track { background: var(--accent-solid); }
.switch input:checked + .track::after { transform: translateX(14px); }
.switch input:focus-visible + .track { outline: 3px solid var(--focus-ring); outline-offset: 1px; }
.switch.disabled { opacity: .45; cursor: default; }

/* ‹ › week arrows. */
.shift {
  position: relative;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: none;
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text);
}
.shift::after { content: ""; position: absolute; inset: -8px; }
.shift .i { width: 16px; height: 16px; }
.shift:hover { background: var(--surface-2); border-color: var(--border-hover); }
.today-link { font-size: var(--fs-4); font-weight: 600; padding: 2px 4px; }

/* ============================================================ Shell and the rail */
/* The app's areas sit in a narrow rail on the left: Schedule, Requests, Rules and Report (Help
   opens from ⋯ or F1), with the account at its foot. Everything about the schedule itself is in the main column. */
/* A test copy says so across the top (Beta, or Local test on this computer), with its branch. Red
   stripes when it shows Planning Center's real schedule, because changes made there are real. */
body:has(> .env-bar:not([hidden])) { --env-bar-h: 26px; }
.env-bar { flex: none; display: flex; align-items: center; justify-content: center; gap: 8px; height: var(--env-bar-h); padding: 0 12px; background: var(--beta-bg); color: var(--beta-text); font-size: var(--fs-5); line-height: 1; white-space: nowrap; overflow: hidden; }
.env-bar > * { overflow: hidden; text-overflow: ellipsis; }
.env-tag { flex: none; padding: 3px 7px; border-radius: 4px; background: var(--beta-tag); color: #2b2721; font-size: var(--fs-2); font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.env-branch { flex: 0 1 auto; min-width: 0; /* on a phone the branch gives way, never the warning */ font-family: ui-monospace, Consolas, monospace; font-weight: 600; }
.env-data { flex: none; opacity: .85; }
.env-bar.live { background: repeating-linear-gradient(135deg, var(--danger-solid) 0 16px, color-mix(in srgb, var(--danger-solid), #000 22%) 16px 32px); color: #fff; }
.env-bar.live .env-tag { background: #fff; color: var(--danger-solid); }
.env-bar.live .env-data { opacity: 1; font-weight: 700; }

.shell { flex: 1; min-height: 0; display: flex; }
.main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.rail {
  position: relative;
  z-index: 20;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: var(--rail-w);
  flex: none;
  padding: 12px 6px 10px;
  background: var(--bg);
  border-right: 1px solid var(--border);
}
.brand { display: flex; flex-direction: column; align-items: center; gap: 4px; margin: 0 0 8px; }
.brand .title { display: none; } /* the mark names the church; phones show the title instead */
.logo-mark { display: block; width: 32px; height: 32px; border-radius: var(--radius-lg); }
.badge { padding: 1px 7px; border-radius: 999px; background: var(--open-bg); color: var(--open-text); font-size: var(--fs-1); font-weight: 600; }

.nav { display: flex; flex-direction: column; gap: 2px; width: 100%; }
.nav-item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  width: 100%;
  padding: 8px 2px 6px;
  border: 0;
  border-radius: var(--radius-lg);
  background: none;
  color: var(--muted);
  font-size: var(--fs-1);
  font-weight: 500;
  line-height: 1.1;
}
.nav-item .i { width: 21px; height: 21px; stroke-width: 1.8; }
.nav-item:hover { background: var(--surface-2); color: var(--text); }
/* Selected: the wash and the accent carry it, not bold, so the label never reflows. */
.nav-item[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); }
.nav-item .count-badge { position: absolute; top: 3px; right: 8px; }
.count-badge.warn { background: var(--warn-text); color: var(--surface); } /* dark text on the light amber of the dark theme */

.selects { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* The title and the tools share the room either side equally, so the search sits in the middle. */
.topbar > .selects, .topbar > .tools { flex: 1 1 0; min-width: max-content; }
.select {
  height: 36px;
  padding: 0 30px 0 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  /* The chevron is a data URL, so it can't use a variable: its stroke is a fixed warm grey that reads on both themes. */
  background: var(--surface-raised) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23988f80' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 9px center / 14px;
  font-size: var(--fs-7);
  font-weight: 600;
  appearance: none;
  cursor: pointer;
}
.select:hover { background-color: var(--surface-2); }
/* The service is the schedule's title. */
#serviceType.select, .st-title { max-width: 260px; height: 36px; padding-left: 2px; border-color: transparent; background-color: transparent; font-size: var(--fs-11); font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#serviceType.select { padding-right: 24px; background-position: right 4px center; background-size: 15px; }
#serviceType.select:hover { background-color: var(--surface-2); }
.st-title { display: inline-flex; align-items: center; }

.tool .chev { display: inline-grid; place-items: center; width: 14px; height: 14px; color: var(--muted); }
.tool .chev .i { width: 14px; height: 14px; }

/* The account (or Sign in) at the foot of the rail. */
.rail-foot { display: flex; align-items: center; justify-content: center; width: 100%; margin-top: auto; padding-top: 10px; border-top: 1px solid var(--border); }
.account { position: relative; min-width: 0; }
.account-top { display: none; }
.tool.account-btn, .tool.signin-btn { width: 100%; justify-content: center; padding: 0; border-color: transparent; background: none; }
.tool.account-btn:hover, .tool.signin-btn:hover { background: var(--surface-2); }
.rail .tool .label { display: none; }
/* Sign in says so, like the areas above it: a lone person icon doesn't read as "sign in". */
.rail .account:has(.signin-btn) { width: 100%; }
.rail .tool.signin-btn { flex-direction: column; gap: 3px; height: auto; padding: 8px 2px 6px; color: var(--accent); font-size: var(--fs-1); font-weight: 600; line-height: 1.1; }
.rail .tool.signin-btn .i { width: 21px; height: 21px; }
.rail .tool.signin-btn .label { display: inline; }
.avatar {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: var(--fs-2);
  font-weight: 700;
  object-fit: cover;
}

/* ============================================================ Top bar: the schedule's toolbar */
/* The service as the title, then the search in the middle (views and filters are in its list), and
   the drafts (once there's one) and ... at the right. Nothing here is a tool: those are areas in the rail. */
.topbar {
  position: relative;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 56px;
  padding: 8px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.topbar-break { display: none; }

.searchbox {
  position: relative;
  flex: 0 1 640px;
  min-width: 240px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
  min-height: 36px;
  padding: 3px 4px 3px 32px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  cursor: text;
  transition: border-color .12s, box-shadow .12s;
}
.searchbox:hover:not(:focus-within) { border-color: var(--border-hover); }
.searchbox:focus-within { border-color: var(--accent-solid); box-shadow: 0 0 0 3px var(--focus-ring); }
.search-ic { position: absolute; left: 10px; top: 9px; color: var(--faint); }
.search-ic .i { width: 16px; height: 16px; }
.tokens { display: contents; }
.searchbox input { flex: 1; min-width: 110px; height: 28px; padding: 0 4px; border: 0; outline: 0; background: none; font-size: var(--fs-8); }
.token {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 100%;
  height: 26px;
  padding: 0 2px 0 7px;
  border-radius: var(--radius-md);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: var(--fs-6);
  font-weight: 600;
  white-space: nowrap;
}
.token .i { width: 13px; height: 13px; }
.token-label { overflow: hidden; text-overflow: ellipsis; }
.token-count { padding: 0 6px; border-radius: 999px; background: var(--accent-solid); color: var(--on-accent); font-size: var(--fs-2); line-height: 16px; }
.token button { position: relative; display: grid; place-items: center; width: 20px; height: 20px; padding: 0; border: 0; border-radius: var(--radius-sm); background: none; color: inherit; opacity: .75; }
.token button::after { content: ""; position: absolute; inset: -6px; }
.token button:hover { opacity: 1; background: color-mix(in srgb, var(--accent) 16%, transparent); }
.token button .i { width: 12px; height: 12px; }
.token-clear { height: 26px; padding: 0 8px; border: 0; border-radius: var(--radius-md); background: none; color: var(--muted); font-size: var(--fs-5); font-weight: 600; }
.token-clear:hover { background: var(--surface-2); color: var(--text); }
.status-token .g { width: 14px; height: 14px; }
.need-token { background: var(--open-bg); color: var(--open-text); }

.suggest {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 30;
  max-height: min(60vh, 440px);
  overflow: auto;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}
.sugg-h { padding: 6px 8px 3px; font-size: var(--fs-2); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.sugg { display: flex; align-items: center; gap: 9px; width: 100%; padding: 7px 8px; border: 0; border-radius: var(--radius-md); background: none; text-align: left; }
.sugg .i { width: 15px; height: 15px; color: var(--faint); }
.sugg.active, .sugg:hover { background: var(--surface-2); }
.sugg mark { background: none; color: inherit; font-weight: 700; }
.sugg .meta { margin-left: auto; padding-left: 12px; font-size: var(--fs-4); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sugg-empty { padding: 10px 8px; color: var(--muted); }
/* The list under the empty search box: views, Show only and Teams, each item ticked while it's on. */
.sugg-row { display: flex; align-items: center; gap: 2px; }
.sugg-row .sugg { flex: 1; min-width: 0; }
.sugg-row .sugg > span:not(.meta):not(.sugg-check) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sugg-row .icon-btn { opacity: .55; }
.sugg-row:hover .icon-btn { opacity: 1; }
.sugg-check { display: grid; place-items: center; width: 15px; flex: none; }
.sugg-check .i { color: var(--accent); }
.sugg.on { color: var(--accent); font-weight: 600; }
.sugg .g { width: 15px; height: 15px; }
.sugg .need-n { color: var(--open-text); font-weight: 600; font-variant-numeric: tabular-nums; }
.sugg-sub { padding: 6px 8px 2px 32px; font-size: var(--fs-3); font-weight: 600; color: var(--faint); }
.sugg-sep { margin: 4px 0; border-top: 1px solid var(--border); }

.tools { display: flex; align-items: center; justify-content: flex-end; gap: 6px; }

/* Drafts: the Published / draft switcher, and the strip under the header while in a draft. */
.drafts { position: relative; }
#draftBtn .chev { width: 14px; height: 14px; color: var(--muted); }
#draftBtn .label { max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#draftBtn.in-draft { border-color: var(--pending); background: var(--pending-soft); color: var(--pending); font-weight: 600; }
#draftBtn.in-draft .chev { color: inherit; }

/* ============================================================ Menus that drop down */
.pop {
  position: absolute;
  top: calc(100% - 4px);
  right: 16px;
  z-index: 30;
  width: 300px;
  padding: 6px 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}
.pop h4 { margin: 8px 16px 2px; font-size: var(--fs-2); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.pop .hint { margin: 0 16px 6px; font-size: var(--fs-4); color: var(--faint); }
.pop-sec + .pop-sec { border-top: 1px solid var(--border); margin-top: 6px; padding-top: 4px; }
.pop-foot { display: flex; justify-content: flex-start; align-items: center; flex-wrap: wrap; gap: 0 2px; padding: 6px 12px 2px; border-top: 1px solid var(--border); margin-top: 6px; }
.menu-item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 16px; border: 0; background: none; color: inherit; font-size: var(--fs-7); text-align: left; text-decoration: none; }
.menu-item:hover { background: var(--surface-2); }
.menu-item .i { width: 16px; height: 16px; color: var(--muted); }
.menu-item .count-badge { margin-left: auto; }
.menu-item:disabled { opacity: .55; }
.menu-item.busy .i { animation: spin 1s linear infinite; }
.menu-item.danger, .menu-item.danger .i { color: var(--bad-text); }

/* The ⋯ menu: view options, tools, and the theme and version at its foot. */
.menu-pop { right: 12px; }
.phone-only { display: none !important; } /* Report and Help live in the rail on a computer */
.menu-pop .legend { padding: 4px 16px 8px; }
.menu-pop .updated { flex: 1 1 100%; margin: 0 4px 4px; font-size: var(--fs-4); color: var(--faint); }
.menu-tools { padding: 2px 0; }
.foot-end { display: inline-flex; align-items: center; gap: 6px; margin-left: auto; }
.version { padding: 4px; font-size: var(--fs-4); color: var(--faint); }

/* Saved views */
.view-row { display: flex; align-items: center; padding-right: 8px; }
.view-row .icon-btn { opacity: .55; }
.view-row:hover .icon-btn, .view-row .icon-btn:focus-visible { opacity: 1; }
.view-item { flex: 1; min-width: 0; display: flex; align-items: center; gap: 9px; padding: 7px 16px; border: 0; background: none; color: inherit; font-size: var(--fs-7); text-align: left; }
.view-item:hover { background: var(--surface-2); }
.view-item > .i { width: 15px; height: 15px; flex: none; color: var(--accent); visibility: hidden; }
.view-item[aria-pressed="true"] { font-weight: 600; }
.view-item[aria-pressed="true"] > .i { visibility: visible; }
.view-item > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.view-item.two-line > span { display: flex; flex-direction: column; }
.view-item.two-line b { font-weight: inherit; overflow: hidden; text-overflow: ellipsis; }
.view-item.two-line small { font-size: var(--fs-4); font-weight: 400; color: var(--muted); }

.draft-pop { right: 0; top: calc(100% + 6px); width: 310px; }

/* The account menu opens upwards from the foot of the rail. */
.account-pop { left: 0; right: auto; top: auto; bottom: calc(100% + 8px); width: 280px; }
.account-pop .hint { margin: 2px 16px 8px; }
.account-pop .avatar .i { width: 15px; height: 15px; }
.account-head { display: flex; align-items: center; gap: 10px; padding: 10px 16px 6px; }
.account-head .avatar { width: 36px; height: 36px; font-size: var(--fs-6); }
.account-head div { display: flex; flex-direction: column; min-width: 0; }
.account-head span { font-size: var(--fs-5); color: var(--muted); }
.account-actions { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 16px 8px; }
.account-theme { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 2px 16px 8px; font-size: var(--fs-6); color: var(--muted); }

/* ============================================================ Strips under the header, status, key */
/* First-visit key, what changed since you last looked, and "you're in a draft". */
.key-strip { display: flex; align-items: center; gap: 14px; padding: 6px 16px; background: var(--accent-tint); }
.key-strip .legend { flex: 1; }
.key-strip .link { white-space: nowrap; }
.fresh-strip { background: var(--accent-soft); font-size: var(--fs-6); gap: 10px; }
.fresh-strip > span { flex: 1; min-width: 0; }
.draft-strip { gap: 10px; background: var(--pending-soft); font-size: var(--fs-6); }
.draft-strip > .i { width: 16px; height: 16px; flex: none; color: var(--pending); }
.draft-strip > span { flex: 1; min-width: 0; }
.draft-name { color: var(--pending); }

.legend { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: var(--fs-4); color: var(--muted); }
.legend span { display: inline-flex; align-items: center; gap: 5px; }
.legend.inline { display: inline-flex; vertical-align: middle; gap: 4px 10px; }
/* The key one to a line: the mark, its name, and what it means (Help and the tour). */
.legend-list { display: grid; grid-template-columns: 18px auto 1fr; gap: 5px 8px; align-items: start; margin: 6px 0 2px; padding: 0; list-style: none; line-height: 1.35; }
.legend-list li { display: contents; }
.legend-mark { display: flex; justify-content: center; align-items: center; height: 1.35em; }
.legend-list b { font-weight: 600; color: var(--text); white-space: nowrap; }
.legend-note { color: var(--muted); }
.swatch-pending { display: inline-block; width: 16px; height: 11px; border-radius: 3px; border: 1px dashed var(--pending); background: var(--pending-soft); }
.updated { color: var(--faint); }

/* ============================================================ The board */
.app { position: relative; flex: 1; min-height: 0; display: flex; }
/* Sideways, the grid shows the dates that fit and moves a whole date at a time (‹ ›, swipes,
   Shift+wheel), so it has no sideways scrollbar. Its up-and-down one keeps its lane, so the
   dates' widths don't change as it comes and goes. */
.board { flex: 1; min-width: 0; overflow: hidden auto; scrollbar-gutter: stable; touch-action: pan-y pinch-zoom; background: var(--surface); outline: none; }
.board.panning { cursor: grabbing; user-select: none; }
.board.is-loading .grid { opacity: .55; transition: opacity .15s; }
/* ‹ › waiting on more dates: the dates on screen fade and can't be clicked, and a note says to wait.
   Only after a moment, so a quick load doesn't flash. */
.board.is-stepping { cursor: progress; }
.board.is-stepping .grid :is(tbody, th.date, th.series) { opacity: .4; pointer-events: none; transition: opacity .2s .15s; }
.step-wait { position: absolute; top: 72px; left: 50%; z-index: 6; display: flex; align-items: center; gap: 8px; padding: 8px 14px; border: 1px solid var(--border-strong); border-radius: 999px; background: var(--surface); box-shadow: var(--shadow); color: var(--text); font-size: var(--fs-6); font-weight: 600; white-space: nowrap; transform: translateX(-50%); animation: fade-in .2s .15s both; }
.spinner { width: 14px; height: 14px; flex: none; border: 2px solid var(--accent); border-right-color: transparent; border-radius: 50%; animation: spin .8s linear infinite; }
@keyframes fade-in { from { opacity: 0; } }
body.drafting .board { box-shadow: inset 0 3px 0 var(--pending); }
/* Room to scroll the last row up off the very bottom of the window (and out from under Copy / Paste). */
.board { padding-bottom: 96px; }

.status { padding: 56px 16px; text-align: center; color: var(--muted); }
.status.error { color: var(--bad-text); }
.status.error p { margin: 0 0 14px; }
.range-nav { display: flex; align-items: center; justify-content: center; gap: 8px; font-weight: 600; font-size: var(--fs-7); }
.status .range-nav { max-width: 320px; margin: 0 auto 12px; }

/* Loading stand-in */
.skeleton { padding: 24px 16px; }
.sk-row { display: flex; gap: 10px; margin-bottom: 12px; }
.sk { flex: 1; height: 18px; border-radius: var(--radius-md); background: var(--surface-2); animation: pulse 1.2s ease-in-out infinite; }
.sk-head .sk { height: 26px; }
.sk-row .sk:first-child { flex: 0 0 140px; }
.skeleton p { text-align: center; }
@keyframes pulse { 50% { opacity: .45; } }

/* Signing in */
.signin-screen { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.signin-screen img { height: 44px; width: auto; }
.signin-screen p { margin: 0; max-width: 340px; }
/* The logo's navy lettering needs a light backdrop on the dark theme. */
:root[data-theme="dark"] .signin-screen img, :root[data-theme="dark"] .help-logo { box-sizing: content-box; padding: 6px 10px; border-radius: var(--radius-lg); background: #fff; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .signin-screen img, :root:not([data-theme="light"]) .help-logo { box-sizing: content-box; padding: 6px 10px; border-radius: var(--radius-lg); background: #fff; }
}
.guest-box { width: min(360px, 100%); }
.or { display: flex; align-items: center; gap: 10px; margin: 6px 0 12px; color: var(--faint); font-size: var(--fs-4); }
.or::before, .or::after { content: ""; flex: 1; border-top: 1px solid var(--border); }
.guest-form { display: flex; flex-direction: column; gap: 8px; text-align: left; }
.guest-form label { font-size: var(--fs-6); color: var(--text); }
.guest-form .hint { margin: 0; font-size: var(--fs-4); color: var(--faint); }
.guest-row { display: flex; gap: 8px; }
.guest-row input { flex: 1; min-width: 0; height: 34px; padding: 0 10px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface-raised); }
.guest-row input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus-ring); }
.guest-err { margin: 0; color: var(--bad-text); font-size: var(--fs-6); }

/* ============================================================ Grid */
/* Dates across the top, positions down the side. Space does the work of lines: a hairline
   between teams, and a heavier rule where a month starts. */
/* The dates are sized to fill the screen (see measureCols in app.js); with fewer dates than fit
   (past the last plan, or only some dates shown), they keep that width and leave room on the right. */
table.grid { border-collapse: separate; border-spacing: 0; width: max-content; }
.grid thead th { position: sticky; top: 0; z-index: 3; background: var(--surface); }
.grid .month-start { border-left: 2px solid var(--border-month) !important; }

.grid th.corner {
  left: 0;
  z-index: 5;
  min-width: var(--poscol);
  max-width: var(--poscol);
  padding: 5px 6px 7px 8px;
  text-align: left;
  vertical-align: top;
  font-size: var(--fs-4);
  font-weight: 600;
  color: var(--muted);
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border-strong);
}

/* In the corner, right against the first date and level with it (however tall the date's header
   gets): This week (once you've moved away), then ‹ ›, which move one date at a time. */
/* This week goes above ‹ › when the corner is too narrow for all three (a phone): the corner must
   never grow, or every date would shift off its place. While you're on this week it's only
   invisible, keeping its room, so ‹ › stay put as it comes and goes. */
.corner-nav { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 4px 2px; }
.corner-nav .shift-pair { display: flex; gap: 2px; }
.corner-nav .shift { display: grid; place-items: center; width: 26px; height: 26px; border: 1px solid var(--border-strong); border-radius: 50%; background: var(--surface); color: var(--muted); }
.corner-nav .shift:hover { background: var(--surface-2); color: var(--text); }
/* At the first or last date there is. */
.corner-nav .shift:disabled { opacity: .35; pointer-events: none; }
/* The arrow that was pressed, while its dates load: a spinner in its place. */
.corner-nav .shift.waiting:disabled { opacity: 1; border-color: var(--accent); color: var(--accent); }
.shift.waiting .i { visibility: hidden; }
.shift.waiting::before { content: ""; position: absolute; inset: 0; width: 12px; height: 12px; margin: auto; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin .8s linear infinite; }
.corner-nav .today-link:disabled { opacity: .35; pointer-events: none; }
.today-link.off { visibility: hidden; }
.corner-nav .shift .i { width: 15px; height: 15px; }
.today-s { display: none; } /* phones only, where the corner is too narrow for This week beside ‹ › */
.corner-nav .today-link { margin-right: 2px; padding: 2px 4px; font-size: var(--fs-4); font-weight: 600; white-space: nowrap; }

/* A date: its button opens the date's menu; "3 needed" shows only the rows still needed. */
.grid th.date {
  min-width: var(--col);
  max-width: var(--col);
  padding: 5px 6px 4px;
  text-align: left;
  vertical-align: top;
  font-weight: normal;
  border-bottom: 1px solid var(--border-strong);
}
.date-btn { display: block; max-width: 100%; margin: -2px -4px; padding: 2px 4px; border: 0; border-radius: var(--radius-md); background: none; text-align: left; }
.date-btn:hover { background: var(--surface-3); }
.date-btn[aria-expanded="true"] { background: var(--accent-soft); }
.date-line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 5px; white-space: nowrap; }
.dow { font-size: var(--fs-1); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.day { font-size: var(--fs-8); font-weight: 600; }
/* This week's service: a tint and a "This week" tag beside the date. */
.next-tag { align-self: center; padding: 0 5px; border-radius: 999px; background: var(--accent-soft); color: var(--accent); font-size: var(--fs-1); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; line-height: 15px; }
.open-count { display: inline-block; margin-top: 2px; padding: 0; border: 0; border-radius: var(--radius-sm); background: none; color: var(--open-text); font-family: inherit; font-size: var(--fs-3); font-weight: 600; cursor: pointer; }
.open-count:hover { text-decoration: underline; }
.open-count[aria-pressed="true"] { padding: 0 6px; background: var(--open-text); color: var(--surface); text-decoration: none; }
.grid th.date.hl-on { box-shadow: inset 0 3px 0 var(--hl-bg); }
.grid th.date.col-sel { background: var(--accent-soft); }
.grid th.date.col-sel .day { color: var(--accent); }
.grid th.date.next { background: var(--accent-tint); box-shadow: none; }
.grid th.date.past { background: var(--surface); }
.grid th.date.past .day { color: var(--faint); font-weight: 600; }
/* A date jumped to (?date=…) is pointed out for a moment. */
@keyframes flash { 0%, 60% { background: color-mix(in srgb, var(--accent) 22%, var(--surface)); } }
.grid th.date.flash, .grid td.cell.flash { animation: flash 2.4s ease-out; }

/* Series or sermon titles (with "Sermon titles & readings" on): once over each run of dates that
   share one, on a row above the dates. Both rows stay at the top while the grid scrolls down; the
   dates sit under the titles (--series-h, the titles row's height, is set when the grid is drawn).
   The text never widens its columns. */
.grid thead tr.series-row th { padding: 10px 8px 0 0; text-align: left; vertical-align: bottom; font-weight: 600; }
.grid thead tr.series-row th.corner-s { left: 0; z-index: 5; border-right: 1px solid var(--border); }
.grid thead tr.days th { top: var(--series-h, 0px); }
th.series span {
  display: block;
  width: 0;
  min-width: 100%;
  padding: 5px 0 0 8px;
  border-top: 2px solid var(--border-strong);
  color: var(--faint);
  font-size: var(--fs-2);
  letter-spacing: .07em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* A date with no title: "+ Title" for those who can add one, like the plan notes' "+ Theme". */
th.series-add .note-add { display: block; width: 100%; padding: 5px 0 0 8px; border: 0; border-top: 2px solid transparent; background: none; text-align: left; font-weight: 500; white-space: nowrap; }
th.series-add .note-add:hover { color: var(--accent); }
/* For those who can change it, a title is a button that opens it for editing. */
th.series .series-edit { display: block; width: 100%; padding: 0; border: 0; background: none; text-align: left; cursor: pointer; }
th.series .series-edit:hover span, th.series .series-edit:focus-visible span { border-top-color: var(--accent); color: var(--accent); }
th.series.dirty span, th.series-add.dirty .note-add { border-top-color: var(--pending); }

/* Groups: a heading on a lightly tinted band as tall as a one-person row; click to fold. The chevron
   has the same space to its left as above and below it, and the row names line up with the heading. */
.grid tr.team-row th {
  --team-bg: var(--bg);
  height: auto;
  padding: 0;
  text-align: left;
  background: var(--team-bg);
}
/* Positions in Planning Center that the layout doesn't place yet. */
.grid tr.team-row.uncategorized th { --team-bg: color-mix(in srgb, var(--warn-text) 9%, var(--surface)); }
.grid tr.team-row.uncategorized .team-toggle { color: var(--warn-text); }
.team-head { position: sticky; left: 0; display: inline-flex; align-items: center; vertical-align: top; }
.team-head .info { margin-left: 2px; }
.team-toggle {
  position: relative;
  left: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 26px; /* = a row: 20px pill + 3px cell padding above and below */
  padding: 0 10px;
  border: 0;
  background: none;
  color: var(--text);
  font-size: var(--fs-7);
  font-weight: 700;
}
.team-toggle:hover { color: var(--accent); }
.team-toggle .i { width: 14px; height: 14px; color: var(--muted); transition: transform .15s; }
.team-toggle[aria-expanded="false"] .i { transform: rotate(-90deg); }

/* Several service types: a heading per service, and no cells on the other service's dates. */
.grid tr.st-row th { height: 30px; padding: 0 12px; text-align: left; background: var(--surface); color: var(--accent); font-size: var(--fs-4); font-weight: 700; letter-spacing: .05em; text-transform: uppercase; border-bottom: 1px solid var(--border-strong); }
.grid td.na { min-width: var(--col); max-width: var(--col); background: repeating-linear-gradient(135deg, transparent 0 6px, var(--surface-2) 6px 7px), var(--bg); }

/* Row names, with the Planning Center team on a second, lighter line. */
.grid th.pos {
  position: sticky;
  left: 0;
  z-index: 2;
  min-width: var(--poscol);
  max-width: var(--poscol);
  padding: 3px 10px 3px 30px; /* the first line centres on the 20px pills; the left edge lines up with the group heading */
  text-align: left;
  vertical-align: top;
  font-weight: 500;
  font-size: var(--fs-6); /* Manrope runs wider than the system face; this keeps "Acoustic Guitar" on one line */
  line-height: 20px;
  color: var(--muted);
  background: var(--surface);
  border-right: 1px solid var(--border);
}
.grid th.pos.row-sel { background: var(--accent-soft); color: var(--accent); box-shadow: inset 3px 0 0 var(--sel); }
.pos-sub { display: block; font-size: var(--fs-3); font-weight: 400; line-height: 15px; color: var(--muted); }

.grid td.cell {
  position: relative;
  min-width: var(--col);
  max-width: var(--col);
  padding: 3px;
  vertical-align: top;
  background: var(--surface);
  cursor: cell;
  user-select: none;
  scroll-margin: calc(var(--head-h, 44px) + 4px) 8px 8px calc(var(--poscol) + 8px);
}
.grid td.cell.hl-col { background: var(--accent-tint); }
.grid td.cell:hover { background: var(--surface-2); }
.grid td.cell:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; z-index: 1; }
.grid td.cell.dirty::after, .grid td.note.dirty::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  border: 5px solid transparent;
  border-top-color: var(--pending);
  border-right-color: var(--pending);
}
/* A status filter fades the cells that don't match. */
.grid td.cell.dim .cell-inner { opacity: .28; }
.cell-inner { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-height: 20px; }

/* Lines from the plan's notes in Planning Center (theme, readings); schedulers can edit them. The
   text starts where the names in the pills above it do (the pill's 1px border + 7px padding). */
.plan-note { display: block; max-width: 100%; padding: 0 0 0 8px; font-size: var(--fs-1); line-height: 1.25; color: var(--muted); white-space: pre-line; overflow-wrap: anywhere; }
.grid td.note { position: relative; min-width: var(--col); max-width: var(--col); padding: 4px 3px; vertical-align: top; background: var(--surface); }
.grid td.note .plan-note { font-size: var(--fs-2); font-weight: 600; color: var(--text); }
.grid td.note.note-edit { cursor: pointer; }
.grid td.note.note-edit:hover { background: var(--surface-2); }
.note-add { font-size: var(--fs-4); color: var(--faint); }
/* A reading in its Reader cell, for those who can change it: click to edit, "+ Reading #1" when empty. */
.grid td.cell .note-btn, .grid td.cell .cell-note-add { display: table; max-width: calc(100% - 4px); margin: 1px 0 0 4px; padding: 1px 4px; border: 0; border-radius: var(--radius-sm); background: none; font-family: inherit; text-align: left; cursor: pointer; }
.grid td.cell .cell-note-add { font-size: var(--fs-1); }
.grid td.cell .note-btn:hover, .grid td.cell .cell-note-add:hover { background: var(--surface-2); color: var(--accent); text-decoration: underline; }
.grid td.cell .note-btn.dirty, .grid td.cell .cell-note-add.dirty { color: var(--pending); }
.grid td.note .note-add { padding-left: 8px; }

/* The Unavailable row at the bottom. */
.grid tbody.unavail th.pos { color: var(--muted); font-weight: 500; }
.grid tbody.unavail td.cell { background: var(--bg); }
.grid tbody.unavail td.cell[data-plan]:hover { background: var(--surface-2); }
.grid tbody.unavail td.cell.sel { background: var(--accent-tint); }
.grid tbody.unavail .pill .nm { color: var(--muted); }
.grid tbody.unavail .pill.hl .nm { color: var(--on-hl); }
.grid td.loading { padding: 10px 12px; color: var(--muted); background: var(--bg); }

/* ---- Names ---- */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  max-width: 100%;
  height: 22px;
  padding: 0 7px 0 3px;
  border: 1px solid transparent;
  border-radius: 11px;
  font-size: var(--fs-5);
  line-height: 20px;
  white-space: nowrap;
}
.pill .nm { overflow: hidden; text-overflow: ellipsis; }
.pill.k-C { padding-left: 7px; } /* confirmed: no glyph */
.pill.k-D .nm { text-decoration: line-through; color: var(--muted); }
.pill.blocked .nm, .pill.k-B .nm { color: var(--muted); }
.pill.conflict:not(.hl) { border-color: color-mix(in srgb, var(--warn-text) 45%, transparent); }
.pill.hl { background: var(--hl-bg); border-color: var(--hl-bg); color: var(--on-hl); font-weight: 600; }
.pill.hl.k-D .nm, .pill.hl.blocked .nm, .pill.hl.k-B .nm { color: var(--on-hl); }
.pill.added { border: 1px dashed var(--pending); background: var(--pending-soft); }
.pill.edited { border-color: var(--pending); }
/* Blocked out: muted, with the slashed-ring glyph; no strike-through (that means declined). */
.pill.blocked:not(.hl) { border-color: transparent; background: none; }
.pill.removed { opacity: .5; }
.pill.removed .nm { text-decoration: line-through; }
/* "+": a spot nobody fills yet, and a button for those who can fill it. */
.pill.open { justify-content: center; gap: 1px; min-width: 22px; height: 22px; padding: 0 5px; border: 1px dashed var(--border-strong); background: transparent; color: var(--faint); font-size: var(--fs-3); font-weight: 600; cursor: default; }
/* In the grid, a little smaller, so rows are 26px and more of the schedule fits. */
.grid .pill { height: 20px; font-size: var(--fs-4); line-height: 18px; }
.grid .pill.open { min-width: 20px; height: 20px; }
.pill.open .i { width: 12px; height: 12px; }
/* Amber and clickable only where you can fill the spot (a team leader: their own teams); grey elsewhere. */
.pill.open.add-needed { border-color: var(--open-border); color: var(--open-text); cursor: pointer; }
.pill.open.add-needed:hover { border-style: solid; background: color-mix(in srgb, var(--open-border) 18%, transparent); }
/* Also in another group that day (!), and changed since you last looked (blue dot). */
.clash-mark { display: inline-grid; place-items: center; width: 13px; height: 13px; flex: none; border-radius: 50%; background: var(--warn-text); color: var(--surface); font: 700 9.5px/1 var(--font-sans); font-style: normal; }
.fresh-dot { display: inline-block; width: 7px; height: 7px; flex: none; border-radius: 50%; background: var(--accent-solid); box-shadow: 0 0 0 2px var(--surface); }
/* Scheduling rules: a broken rule is a red square (unlike the round amber ! for another group that
   day), a softer one an amber square, and an override a small note. */
.rule-mark { display: inline-grid; place-items: center; width: 13px; height: 13px; flex: none; border-radius: 3px; background: var(--bad-text); color: var(--surface); font: 700 9.5px/1 var(--font-sans); font-style: normal; }
.rule-mark.soft { background: var(--warn-text); }
.override-mark { display: inline-grid; place-items: center; width: 13px; height: 13px; flex: none; color: var(--muted); font-style: normal; }
.override-mark .i { width: 12px; height: 12px; }
.pill.hl .override-mark { color: var(--on-hl); }
.pill.rule-break:not(.hl) { border-color: color-mix(in srgb, var(--bad-text) 55%, transparent); }
.pill.hl .fresh-dot { box-shadow: 0 0 0 2px var(--hl-bg); }

/* ---- Status glyphs: each a different shape in the status colour, so colour is never the only signal ---- */
.g { display: block; width: 14px; height: 14px; flex: none; }
.g circle { fill: none; stroke: var(--gc); stroke-width: 1.5; }
.g circle.dot { fill: var(--gc); stroke: none; }
.g path { fill: none; stroke: var(--gc); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.g.mini { width: 12px; height: 12px; }
.g-C { --gc: var(--st-c-soft); }
.g-C path, .g-X path { stroke-width: 2.1; }
.g-U { --gc: var(--st-u); }
.g-O { --gc: var(--st-o); }
.g-N { --gc: var(--st-n); }
.g-D { --gc: var(--st-d); }
.g-B { --gc: var(--st-b); }
.g-X { --gc: var(--open-text); }
.pill.hl .g { --gc: var(--on-hl); }
.pill.hl .g circle { stroke: var(--on-hl); stroke-width: 1.5; }
.pill.hl .g circle.dot { fill: var(--on-hl); stroke: none; }
.pill.hl .g-C path { stroke: var(--on-hl); }

/* ---- Selecting, copying and pasting cells, like a spreadsheet ---- */
/* One border around a whole block of cells: the selected range (solid), a paste preview (solid,
   green, names shown in place), and the copied block (dashed). Classes say which sides of a cell
   are on the outline: bt/bb/bl/br (solid) and ct/cb/cl/cr (dashed). */
.grid td.cell.rg, .grid td.cell.pv {
  --bt: 0; --bb: 0; --bl: 0; --br: 0;
  box-shadow: inset 0 calc(var(--bt) * 2px) 0 var(--edge), inset 0 calc(var(--bb) * -2px) 0 var(--edge),
    inset calc(var(--bl) * 2px) 0 0 var(--edge), inset calc(var(--br) * -2px) 0 0 var(--edge);
}
.grid td.cell.rg, .grid td.cell.rg:hover { --edge: var(--sel); background: color-mix(in srgb, var(--accent) 11%, var(--surface)); }
.grid td.cell.pv, .grid td.cell.pv:hover { --edge: var(--st-c); background: color-mix(in srgb, var(--st-c) 12%, var(--surface)); }
.grid td.cell.bt { --bt: 1; }
.grid td.cell.bb { --bb: 1; }
.grid td.cell.bl { --bl: 1; }
.grid td.cell.br { --br: 1; }
/* No grid lines inside a paste preview: it reads as one block. */
.grid td.cell.pv:not(.br) { border-right-color: transparent; }
.grid td.cell.pv:not(.bb) { border-bottom-color: transparent; }
.grid td.cell.pv .pill.open { display: none; }
.grid td.cell.cp::before { content: ""; position: absolute; inset: 0; z-index: 1; border: 0 dashed var(--accent); pointer-events: none; }
.grid td.cell.ct::before { border-top-width: 2px; }
.grid td.cell.cb::before { border-bottom-width: 2px; }
.grid td.cell.cl::before { border-left-width: 2px; }
.grid td.cell.cr::before { border-right-width: 2px; }
/* The current cell has its own border; inside a range, like a spreadsheet, it's just left unshaded
   (only the range's outer border shows). */
.grid td.cell.sel, .grid td.cell.sel:hover { background: var(--accent-tint); outline: 2px solid var(--sel); outline-offset: -2px; z-index: 1; }
.grid td.cell.sel:not(.rg):not(.pv) { box-shadow: none; }
.grid td.cell.sel.rg, .grid td.cell.sel.rg:hover { background: var(--surface); outline: none; }
.ghosts { display: contents; }
.pill.ghost { border: 1px dashed var(--st-c); background: transparent; color: var(--st-c); }
/* ▾ and ⇄ on a cell, top right: on hover, and always on the current cell. */
/* Centred on the first name: 6px cell padding + (22px pill - 22px button) / 2. */
.cell-tools { position: absolute; right: 3px; top: 2px; z-index: 2; display: none; gap: 3px; }
.grid td.cell:hover .cell-tools, .grid td.cell.sel .cell-tools { display: flex; }
.cell-btn { display: grid; place-items: center; width: 22px; height: 22px; padding: 0; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface-raised); color: var(--muted); box-shadow: var(--shadow-sm); cursor: pointer; }
.cell-btn:hover, .cell-btn:focus-visible { border-color: var(--accent); color: var(--accent); }
.cell-btn .i { width: 13px; height: 13px; }

/* ============================================================ The cell dropdown */
/* One plain menu on the cell: the list (the cell itself becomes the search box), the status menu,
   or a step that asks first. It hangs under the cell, or over it when there's more room above; on
   narrow screens it's a sheet from the bottom. */
.quick { position: fixed; z-index: 46; display: flex; flex-direction: column; align-items: flex-start; }
.quick.up:not(.as-sheet) { flex-direction: column-reverse; }
.quick.end:not(.as-sheet) { align-items: flex-end; }
.quick.as-sheet { left: 0; right: 0; bottom: 0; top: auto !important; z-index: 50; align-items: stretch; max-height: 50dvh; background: var(--surface); border-radius: var(--radius-sheet) var(--radius-sheet) 0 0; box-shadow: var(--shadow); overflow: hidden; }
.sheet-backdrop { position: fixed; inset: 0; z-index: 49; background: var(--scrim); }
body:has(.quick.as-sheet:not([hidden])) .board { padding-bottom: 50dvh; }

/* The sheet's head: which cell, and a grab handle (the dimmed backdrop closes it too). */
.quick-head { position: relative; display: flex; align-items: center; gap: 2px; padding: 14px 4px 6px 12px; border-bottom: 1px solid var(--border); }
.quick-head::before { content: ""; position: absolute; top: 5px; left: 50%; width: 36px; height: 4px; border-radius: 2px; background: var(--border-strong); transform: translateX(-50%); }
.quick-head .icon-btn { width: 28px; height: 28px; }
.quick-title { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 6px; white-space: nowrap; }
.quick-title strong { overflow: hidden; text-overflow: ellipsis; font-size: var(--fs-8); }
.quick-title span { font-size: var(--fs-4); color: var(--muted); }

/* The search box, exactly on the cell, with ▴ to close. */
.q-field { position: relative; display: flex; flex: none; }
/* On the cell, but never narrower than a name and its × need: in a narrow column (the last one
   included, where it grows to the left) the box spills over its neighbour, as a spreadsheet's does. */
.quick:not(.as-sheet) .q-field { width: max(var(--cell-w), 200px); height: var(--cell-h); }
.q-field input { flex: 1; min-width: 0; height: 100%; padding: 0 28px 0 8px; border: 0; border-radius: 2px; outline: none; background: var(--surface); box-shadow: inset 0 0 0 2px var(--sel); color: var(--text); font: inherit; font-size: var(--fs-6); }
.q-field input::placeholder { color: var(--faint); }
.q-caret { position: absolute; right: 3px; top: 50%; display: grid; place-items: center; width: 22px; height: 22px; padding: 0; border: 0; border-radius: var(--radius-md); background: none; color: var(--muted); transform: translateY(-50%); cursor: pointer; }
.q-caret:hover { background: var(--surface-2); color: var(--accent); }
.q-caret .i { width: 13px; height: 13px; transform: rotate(180deg); }
/* Who's on the date, in the box as on the cell (each with × to take them off), then a line to add
   another. The cell's outline moves from the line to the whole box. */
.q-field.has-chips { flex-direction: column; align-items: stretch; gap: 3px; padding: 6px 4px 3px; border-radius: 2px; background: var(--surface); box-shadow: inset 0 0 0 2px var(--sel); cursor: text; }
.quick:not(.as-sheet) .q-field.has-chips { height: auto; min-height: var(--cell-h); }
.q-field.has-chips input { flex: none; height: 24px; padding: 0 24px 0 4px; box-shadow: none; background: none; }
.q-field.has-chips .q-caret { top: auto; bottom: 4px; transform: none; }
.q-chip { display: flex; align-items: center; gap: 2px; min-width: 0; }
.q-chip .pill { min-width: 0; cursor: default; }
.q-chip-x { display: grid; flex: none; place-items: center; width: 18px; height: 18px; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--faint); cursor: pointer; }
.q-chip-x .i { width: 11px; height: 11px; }
.q-chip-x:hover, .q-chip-x.active { background: var(--surface-2); color: var(--bad-text); }
.quick.as-sheet .q-field.has-chips { height: auto; padding: 8px 10px 4px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); box-shadow: none; }
.quick.as-sheet .q-field.has-chips:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus-ring); }
.quick.as-sheet .q-field.has-chips input, .quick.as-sheet .q-field.has-chips input:focus { height: 32px; padding: 0 4px; border: 0; box-shadow: none; }
.quick.as-sheet .q-chip-x { width: 28px; height: 28px; }

/* The menu: one line per choice, a ✓ column, the name, one fact in grey brackets. */
.q-list { display: flex; flex-direction: column; min-width: max(var(--cell-w, 0px), 260px); max-width: 380px; max-height: var(--list-max, 320px); overflow: auto; margin: 2px 0; padding: 4px 0; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow); }
.q-opt { display: flex; flex: none; align-items: center; gap: 6px; width: 100%; min-height: 30px; padding: 0 12px 0 8px; border: 0; background: none; color: var(--text); font: inherit; font-size: var(--fs-7); text-align: left; white-space: nowrap; cursor: pointer; }
.q-opt:hover, .quick .q-opt.active { background: var(--surface-2); }
.quick .q-opt.active { box-shadow: inset 2px 0 0 var(--accent); }
.q-opt .nm { flex: none; max-width: 70%; overflow: hidden; text-overflow: ellipsis; }
.q-info { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--faint); font-size: var(--fs-5); font-weight: 400; }
.q-ck { display: grid; flex: none; place-items: center; width: 16px; color: var(--accent); }
.q-ck .i { width: 14px; height: 14px; }
/* Blocked out, or kept off by a rule: listed so it's clear why, but can't be picked here. */
.q-opt.off { color: var(--faint); cursor: default; }
.q-opt.off:hover, .q-opt.static:hover { background: none; }
.q-opt.static { cursor: default; }
.q-sep { flex: none; height: 1px; margin: 4px 0; background: var(--border); }
/* The foot of the list: the rest of the right-click menu, always in reach (touch has no right-click). */
.q-opt.q-more { position: sticky; bottom: -4px; margin-top: 4px; border-top: 1px solid var(--border); background: var(--surface); color: var(--muted); }
.q-opt.q-more .q-ck { color: var(--muted); }
.q-opt.q-more:hover, .quick .q-opt.q-more.active { background: var(--surface-2); color: var(--text); }
/* The status menu: a heading per person. */
.q-label { flex: none; padding: 6px 12px 2px; font-size: var(--fs-5); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.quick-msg { margin: 6px 12px; font-size: var(--fs-5); color: var(--muted); white-space: normal; }
.quick-msg.bad { color: var(--bad-text); }

/* A step that asks first: a question, a line of why, the rule, a note for an override, buttons. */
.q-step { display: flex; flex-direction: column; gap: 6px; width: 300px; max-width: 100%; padding: 8px 12px 10px; white-space: normal; }
.q-step-title { margin: 0; font-size: var(--fs-7); font-weight: 600; }
.q-step-text { margin: 0; font-size: var(--fs-5); color: var(--muted); }
.q-step-rules { margin: 0; padding-left: 18px; font-size: var(--fs-5); color: var(--muted); }
.q-step-note { width: 100%; padding: 6px 8px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface); color: var(--text); font: inherit; font-size: var(--fs-6); resize: vertical; }
.q-step-note:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus-ring); }
.q-step-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }

/* Block out with a reason: the reason, above the list. */
.q-opts { display: flex; flex: none; gap: 6px; align-items: flex-end; padding: 4px 8px 6px; }
.q-opts label { display: flex; flex-direction: column; gap: 2px; font-size: var(--fs-2); color: var(--muted); }
.q-opts label:last-child { flex: 1; min-width: 0; }
.q-opts input { width: 100%; min-width: 0; height: 30px; padding: 0 8px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface); color: var(--text); font: inherit; font-size: var(--fs-6); }
.q-opts input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus-ring); }

/* Narrow screens: the same menu fills the sheet, with the search box on top. */
.quick.as-sheet .q-field { margin: 8px 10px 4px; height: 38px; }
.quick.as-sheet .q-field input { padding: 0 10px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); box-shadow: none; font-size: var(--fs-10); }
.quick.as-sheet .q-field input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus-ring); }
.quick.as-sheet .q-list { flex: 1; min-height: 0; min-width: 0; max-width: none; max-height: none; margin: 0; border: 0; border-radius: 0; box-shadow: none; }
.quick.as-sheet .q-opt { min-height: 40px; padding: 0 16px 0 12px; font-size: var(--fs-9); }
.quick.as-sheet .q-step { width: auto; }

.info { position: relative; display: inline-flex; padding: 0; border: 0; background: none; vertical-align: middle; color: var(--faint); cursor: help; }
.info .i { width: 14px; height: 14px; }
.info::after { content: ""; position: absolute; inset: -8px; }
.info:hover { color: var(--accent); }
.alert { margin: 10px 0; padding: 8px 10px; border-radius: var(--radius-lg); background: color-mix(in srgb, var(--st-d) 12%, var(--surface)); color: var(--bad-text); font-size: var(--fs-6); }
.quick-confirm-actions { display: flex; flex-wrap: wrap; gap: 6px; }

/* A plan note's editor. */
.note-text { width: 100%; padding: 8px 10px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface-raised); font: inherit; resize: vertical; }
.note-text:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus-ring); }
/* Text to copy by hand when the clipboard isn't available. */
.copy-box { width: 100%; height: 34px; padding: 0 10px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface-raised); color: var(--text); font: inherit; }
.copy-box:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus-ring); }

/* ============================================================ Bars at the bottom */
/* Unsaved changes: review, undo, discard, save as a draft, publish. It sits under the grid, not over
   it: the grid gets shorter while it's there, so nothing on it is hidden. Its contents keep to the
   middle, as wide as they need. */
.savebar {
  flex: none;
  position: relative;
  z-index: 45;
  padding-inline: max(0px, calc((100% - 720px) / 2));
  background: var(--surface);
  border-top: 1px solid var(--border-strong);
  box-shadow: 0 -4px 12px rgba(0, 0, 0, .05);
}
.savebar.in-draft { border-top: 2px solid var(--pending); }
.savebar-main { display: flex; align-items: center; gap: 6px; padding: 8px 8px 8px 14px; }
.savebar-main .btn.primary .i { width: 15px; height: 15px; }
.savebar-text { flex: 1; min-width: 0; font-size: var(--fs-7); }
.savebar-alert { margin: 0 12px 10px; }
.savebar-text .bad { color: var(--bad-text); }
.pending-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--pending); flex: none; margin-right: 4px; }
.hist-btns { display: inline-flex; gap: 2px; margin-right: 2px; }
.review { list-style: none; margin: 0; padding: 6px; max-height: 38vh; overflow: auto; border-bottom: 1px solid var(--border); }
.review li { display: flex; align-items: center; gap: 4px; }
.review-item { flex: 1; min-width: 0; display: flex; flex-direction: column; padding: 6px 8px; border: 0; border-radius: var(--radius-md); background: none; text-align: left; font-size: var(--fs-6); }
.review-item:hover { background: var(--surface-2); }
.review-item .where { font-size: var(--fs-4); color: var(--muted); }
.review-item .bad { font-size: var(--fs-4); color: var(--bad-text); }
/* Undo this change (one change in the list): says what it does, so it isn't mistaken for closing the list. */
.review .undo-one { flex: none; gap: 5px; color: var(--muted); }
.review .undo-one:hover { color: var(--text); }
.review .undo-one .i { width: 14px; height: 14px; }
.pin-form { display: flex; align-items: center; gap: 8px; padding: 8px 8px 8px 14px; }
.pin-form label { font-size: var(--fs-7); font-weight: 600; white-space: nowrap; }
.pin-form input { flex: 1; min-width: 0; height: 34px; padding: 0 10px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface-raised); }
/* After publishing: Planning Center's Send button. */
.send-prompt { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px 10px 14px; }
.send-prompt .savebar-text .info { margin-left: 2px; }
.send-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.send-actions a.btn { text-decoration: none; }
.send-actions a.btn.opened { color: var(--muted); }

/* Copy / Paste, bottom left (above the save bar when that's showing). */
.selbar { position: fixed; left: 16px; bottom: 16px; z-index: 44; display: flex; align-items: center; gap: 8px; padding: 6px 6px 6px 12px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow); font-size: var(--fs-6); animation: rise-left .15s ease-out; }
@keyframes rise-left { from { transform: translateY(8px); opacity: 0; } }
body:has(#savebar:not([hidden])) .selbar { bottom: calc(var(--savebar-h, 64px) + 8px); }
.selbar .btn .i { width: 14px; height: 14px; }

.toast {
  position: fixed;
  left: 50%;
  bottom: 110px;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 12px;
  transform: translateX(-50%);
  padding: 8px 10px 8px 14px;
  border-radius: var(--radius-lg);
  background: var(--text);
  color: var(--bg);
  font-size: var(--fs-7);
  box-shadow: var(--shadow);
}
.toast button { padding: 3px 8px; border: 0; border-radius: var(--radius-sm); background: none; color: inherit; font-weight: 700; text-decoration: underline; }
.toast:not(:has(button)) { padding-right: 14px; }
/* An earlier Undo kept under a newer note (see toast in app.js). */
.toast:has(.toast-prev) { flex-wrap: wrap; row-gap: 2px; }
.toast-prev { display: flex; flex-basis: 100%; align-items: center; gap: 12px; opacity: .8; font-size: .92em; }
.toast.error { background: var(--bad-text); color: var(--surface); }

/* Tooltips (tooltip.js): over the element (under it when there's no room), with an arrow at it.
   "Name · fact · fact" shows as the name over the facts; a shortcut shows as a key. */
.tip {
  position: fixed;
  z-index: 1100;
  max-width: min(300px, calc(100vw - 16px));
  padding: 6px 10px 7px;
  border: 1px solid var(--tip-border);
  border-radius: var(--radius-md);
  background: var(--tip-bg);
  color: var(--tip-text);
  box-shadow: var(--shadow);
  font-size: var(--fs-5);
  font-weight: 500;
  line-height: 1.4;
  overflow-wrap: anywhere;
  pointer-events: none;
  animation: tip-in .12s ease-out;
}
.tip[hidden] { display: none; }
@keyframes tip-in { from { opacity: 0; transform: translateY(2px); } }
.tip.below { animation-name: tip-in-below; }
.tip.now { animation: none; }
@keyframes tip-in-below { from { opacity: 0; transform: translateY(-2px); } }
.tip::after { content: ""; position: absolute; left: var(--arrow-x, 50%); top: 100%; width: 8px; height: 8px; margin: -4px 0 0 -4px; transform: rotate(45deg); background: inherit; border: solid var(--tip-border); border-width: 0 1px 1px 0; }
.tip.below::after { top: 0; border-width: 1px 0 0 1px; }
.tip b { font-weight: 700; }
.tip-head, .tip-line, .tip-sub { display: block; }
.tip-sub { color: var(--tip-sub); }
.tip-line + .tip-line { margin-top: 2px; }
/* A key: a light chip with the tooltip's own text colour, never the page's (light) key style. */
.tip kbd { display: inline-block; margin-top: 4px; padding: 0 6px; border: 1px solid color-mix(in srgb, var(--tip-text) 35%, transparent); border-radius: var(--radius-sm); background: color-mix(in srgb, var(--tip-text) 14%, transparent); color: var(--tip-text); font-family: inherit; font-size: var(--fs-3); font-weight: 600; line-height: 1.6; }
.tip-line:has(+ kbd), .tip-sub:has(+ kbd) { display: inline; margin-right: 8px; }

/* Install the app: a card bottom right (above the bottom bar on a phone), offered once. */
.install-card { position: fixed; right: 16px; bottom: 16px; z-index: 58; display: flex; align-items: center; gap: 12px; width: 380px; max-width: calc(100vw - 32px); padding: 12px 12px 12px 14px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-xl); box-shadow: var(--shadow); font-size: var(--fs-7); animation: rise-left .2s ease-out; }
.install-card img { flex: none; border-radius: 9px; }
.install-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.install-text span { color: var(--muted); font-size: var(--fs-5); line-height: 1.35; }
.install-actions { flex: none; display: flex; flex-direction: column-reverse; gap: 4px; }
body:has(#savebar:not([hidden])) .install-card, body:has(#selbar:not([hidden])) .install-card { display: none; }

/* ============================================================ Dialogs */
.modal { position: fixed; inset: 0; z-index: 70; display: grid; place-items: center; }
.modal-backdrop { position: absolute; inset: 0; background: var(--scrim); }
.modal-box { position: relative; width: min(420px, calc(100vw - 32px)); padding: 18px 20px 14px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-xl); box-shadow: var(--shadow-modal); animation: rise-in .15s ease-out; }
@keyframes rise-in { from { transform: translateY(8px); opacity: 0; } }
.modal-box h3 { margin: 0 0 8px; font-size: var(--fs-10); font-weight: 700; line-height: 1.25; }
.modal-box p { margin: 0 0 6px; color: var(--muted); }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.modal-box:not(.wide) { max-height: calc(100dvh - 32px); overflow: auto; } /* a phone held sideways */
/* A cell tapped on a touch screen: each name with what its tooltip would say. */
.cell-details { margin: 0; padding: 0; list-style: none; }
.cell-details li { display: flex; flex-direction: column; gap: 2px; padding: 8px 0; border-top: 1px solid var(--border); }
.cell-details li:first-child { border-top: 0; }
.cell-details .muted { font-size: var(--fs-7); }
/* The first-run tour (tour.js): a card beside the thing it's about, everything else dimmed. */
.tour { position: fixed; inset: 0; z-index: 75; }
.tour-scrim { position: absolute; inset: 0; display: none; background: var(--scrim); }
.tour.centered .tour-scrim { display: block; }
.tour-spot { position: fixed; border-radius: var(--radius-lg); box-shadow: 0 0 0 2px var(--accent), 0 0 0 200vmax var(--scrim); pointer-events: none; transition: left .25s ease, top .25s ease, width .25s ease, height .25s ease; }
.tour.centered .tour-spot { display: none; }
.tour-card { position: fixed; width: min(340px, calc(100vw - 32px)); max-height: calc(100dvh - 32px); overflow-y: auto; padding: 16px 18px 12px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-xl); box-shadow: var(--shadow-modal); animation: rise-in .15s ease-out; }
.tour.centered .tour-card { width: min(400px, calc(100vw - 32px)); }
.tour-count { margin: 0 0 4px; color: var(--muted); font-size: var(--fs-4); font-weight: 600; }
.tour-count:empty { display: none; }
.tour-card h3 { margin: 0 32px 6px 0; font-size: var(--fs-10); font-weight: 700; line-height: 1.25; }
.tour-body { color: var(--muted); font-size: var(--fs-7); line-height: 1.5; }
.tour-body p { margin: 0 0 6px; }
.tour-body b { color: var(--text); font-weight: 600; }
.tour-body .legend { margin: 10px 0 4px; color: var(--text); font-size: var(--fs-5); }
.tour-foot { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.tour-dots { flex: 1; display: flex; gap: 5px; }
.tour-dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--border-strong); }
.tour-dots i.on { background: var(--accent); }
/* Something to try: the app shows through (lighter) and can be used; a ring pulses round what to click. */
.tour.trying { pointer-events: none; }
.tour.trying .tour-card { pointer-events: auto; }
.tour.trying .tour-spot { box-shadow: 0 0 0 2px var(--accent), 0 0 0 200vmax color-mix(in srgb, var(--scrim) 45%, transparent); }
.tour-point { position: fixed; border: 2px solid var(--accent); border-radius: var(--radius-md); pointer-events: none; animation: tour-pulse 1.4s ease-out infinite; }
@keyframes tour-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent); } 100% { box-shadow: 0 0 0 12px transparent; } }
@media (prefers-reduced-motion: reduce) { .tour-point { animation: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); } }
.tour-tasks { margin: 10px 0 2px; padding: 10px 12px; list-style: none; border-radius: var(--radius-md); background: var(--surface-2); font-size: var(--fs-7); line-height: 1.4; }
.tour-tasks li { display: flex; gap: 8px; align-items: flex-start; color: var(--muted); }
.tour-tasks li + li { margin-top: 6px; }
.tour-tasks li.now { color: var(--text); font-weight: 600; }
.tour-tasks li.now b { font-weight: 700; }
.tour-tasks li.done { color: var(--muted); }
.tour-check { display: grid; place-items: center; flex: none; width: 18px; height: 18px; margin-top: 1px; border: 1.5px solid var(--border-strong); border-radius: 50%; }
.tour-tasks li.now .tour-check { border-color: var(--accent); }
.tour-check svg { width: 12px; height: 12px; fill: none; stroke: transparent; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.tour-tasks li.done .tour-check { border-color: var(--st-c); background: var(--st-c); }
.tour-tasks li.done .tour-check svg { stroke: var(--surface); }
.tour-install { display: flex; align-items: center; gap: 12px; margin: 10px 0 4px; }
.tour-install img { flex: none; border-radius: 9px; }
.tour-x { position: absolute; top: 10px; right: 10px; display: grid; place-items: center; width: 28px; height: 28px; padding: 0; border: 0; border-radius: var(--radius-md); background: none; color: var(--muted); cursor: pointer; }
.tour-x:hover { background: var(--surface-2); color: var(--text); }
.tour-x svg { width: 16px; height: 16px; }
.modal-box.wide { width: min(560px, calc(100vw - 32px)); max-height: calc(100vh - 48px); display: flex; flex-direction: column; }
.modal-box.wide .help-body { flex: 1; min-height: 0; overflow: auto; margin: 0 -8px; padding: 0 8px; }
:is(.modal-box, .page) .field { display: flex; flex-direction: column; gap: 4px; margin: 10px 0; font-size: var(--fs-5); color: var(--muted); }
.field select, .field input { height: 32px; padding: 0 8px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface); font-size: var(--fs-6); color: var(--text); }
:is(.modal-box, .page) .field textarea, .chg-msg { width: 100%; padding: 8px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface); font: inherit; font-size: var(--fs-6); color: var(--text); resize: vertical; }
:is(.modal-box, .page) .check { display: flex; align-items: flex-start; gap: 8px; margin: 10px 0; font-size: var(--fs-7); color: var(--text); }
:is(.modal-box, .page) .check input { margin-top: 3px; }
:is(.modal-box, .page) .quick-confirm-actions a.btn { text-decoration: none; }
.choice-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.publish-list { margin: 8px 0 0; padding-left: 18px; font-size: var(--fs-6); }
.publish-list li { margin: 3px 0; }

/* Scheduling rules and Check rules. */
.rules-body { flex: 1; min-height: 0; overflow: auto; margin: 0 -8px; padding: 0 8px; }
.rules-top { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 2px 0 8px; }
.rules-top [data-rb-new] { margin-left: auto; }
.rules-top .select { width: auto; }
.rule-filter { height: 28px; }
.rule-sec h4 { margin: 14px 0 4px; font-size: var(--fs-4); font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--muted); }
.rule-ul, .rule-items { margin: 0; padding: 0; list-style: none; }
.rule-item { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-top: 1px solid var(--border); }
.rule-body { flex: 1; min-width: 0; }
:is(.modal-box, .page) .rule-text { margin: 0; color: var(--text); font-size: var(--fs-7); }
:is(.modal-box, .page) .rule-note { margin: 2px 0 0; font-size: var(--fs-5); font-style: italic; }
:is(.modal-box, .page) .rule-meta { margin: 2px 0 0; font-size: var(--fs-3); color: var(--faint); }
.rule-actions { display: flex; flex: none; gap: 2px; }
.rule-badge { flex: none; min-width: 84px; padding: 1px 6px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); color: var(--muted); font-size: var(--fs-3); font-weight: 600; line-height: 18px; text-align: center; white-space: nowrap; }
.rule-badge.enforced { border-color: color-mix(in srgb, var(--bad-text) 50%, transparent); background: color-mix(in srgb, var(--bad-text) 8%, var(--surface)); color: var(--bad-text); }
.rule-items > li { padding: 7px 0; border-top: 1px solid var(--border); font-size: var(--fs-6); color: var(--text); }
.rule-where { margin-right: 4px; font-weight: 600; }
.rule-sentence { display: block; font-size: var(--fs-4); color: var(--muted); }
.rule-override { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 3px; font-size: var(--fs-5); color: var(--muted); }
.rule-override .i { width: 13px; height: 13px; }
:is(.modal-box, .page) .rules-empty { margin: 16px 0; }
.rule-warn-head { display: flex; align-items: center; gap: 6px; margin-top: 12px !important; color: var(--warn-text) !important; font-weight: 600; }
.rule-warn-head .i { width: 16px; height: 16px; }
.rule-builder h4 { margin: 4px 0 0; font-size: var(--fs-8); }
.rb-seg { display: flex; flex-wrap: wrap; width: fit-content; max-width: 100%; }
.rb-seg button { width: auto; padding: 0 10px; font-size: var(--fs-6); font-weight: 600; }
.rb-seg button[aria-checked="true"] { background: var(--accent-soft); color: var(--accent); }
.field .hint { font-size: var(--fs-4); color: var(--faint); }
.rb-results { display: flex; flex-direction: column; max-height: 230px; overflow: auto; }
.rb-pick { display: flex; align-items: baseline; gap: 8px; min-height: 32px; padding: 0 8px; border: 0; border-radius: var(--radius-md); background: none; color: var(--text); font-size: var(--fs-6); text-align: left; }
.rb-pick:hover, .rb-pick:focus-visible { background: var(--surface-2); }
.rb-pick .nm { font-weight: 500; }
.rb-picked { display: flex; align-items: center; gap: 10px; }
/* Where: a group (bold) or a position under it (indented); either can be picked. */
.spot-btn { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; height: 32px; padding: 0 8px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface); color: var(--text); font-size: var(--fs-6); text-align: left; }
.spot-btn.empty { color: var(--faint); }
.spot-btn > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spot-btn .i { width: 14px; height: 14px; flex: none; color: var(--muted); }
.spot-btn[aria-expanded="true"] .i { transform: rotate(180deg); }
/* "or another spot": each extra spot with a button to take it away. */
:is(.modal-box, .page) .field.rb-or { margin-top: -4px; }
.rb-or-row { display: flex; align-items: center; gap: 6px; }
.rb-or-row .spot-btn { flex: 1; min-width: 0; }
:is(.modal-box, .page) .rb-or-add { margin: -4px 0 0; }
.rb-or-add .link { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-5); }
.rb-or-add .i { width: 13px; height: 13px; }
.spot-list { display: flex; flex-direction: column; max-height: 280px; overflow: auto; padding: 4px; border: 1px solid var(--border-strong); border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--shadow-sm); }
.spot-opt { display: flex; align-items: center; gap: 8px; flex: none; width: 100%; min-height: 30px; padding: 0 10px; border: 0; border-radius: var(--radius-md); background: none; color: var(--text); font-size: var(--fs-6); text-align: left; }
.spot-opt.spot-group { margin-top: 4px; font-weight: 700; }
.spot-opt.spot-group:first-child, .spot-opt.spot-any + .spot-group { margin-top: 0; }
div.spot-opt.spot-group { color: var(--muted); }
.spot-opt.spot-row { padding-left: 26px; }
button.spot-opt:hover, button.spot-opt:focus-visible { background: var(--surface-2); outline: none; }
.spot-opt[aria-selected="true"] { background: var(--accent-soft); color: var(--accent); }
.spot-opt .i { width: 14px; height: 14px; margin-left: auto; }
.rb-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--text); font-size: var(--fs-6); }
.rb-row input { width: 72px; }
:is(.modal-box, .page) .rule-preview { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; margin: 12px 0 10px; padding: 8px 10px; border-radius: var(--radius-lg); background: var(--surface-2); color: var(--text); font-size: var(--fs-7); }
.rb-actions { display: flex; gap: 8px; }
.report-target > span { display: block; white-space: nowrap; }

/* Help, and the keyboard shortcuts. */
.help-sec + .help-sec { margin-top: 12px; }
.help-sec h4 { margin: 0 0 4px; font-size: var(--fs-2); font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.help-sec ul { margin: 0; padding-left: 18px; font-size: var(--fs-7); line-height: 1.45; }
.help-sec li + li { margin-top: 4px; }
.help-sec b { font-weight: 650; }
/* The church logo sits quietly at the foot of Help, above the name and version. */
.help-logo { display: block; height: 32px; width: auto; margin: 24px 0 0; }
.help-logo + .help-foot { margin-top: 8px; }
.help-foot { margin: 12px 0 0; font-size: var(--fs-4); color: var(--faint); }
.keys { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; margin: 10px 0 0; align-items: center; }
.keys dt { margin: 0; }
.keys dd { margin: 0; font-size: var(--fs-7); }
kbd { display: inline-block; padding: 1px 6px; border: 1px solid var(--border-strong); border-bottom-width: 2px; border-radius: var(--radius-sm); background: var(--surface-2); font: var(--fs-4)/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; white-space: nowrap; }

/* A date's menu: sermon and notes, then More… */
.date-notes { display: grid; grid-template-columns: auto 1fr; gap: 6px 12px; margin: 10px 0; font-size: var(--fs-7); }
.date-notes dt { display: flex; gap: 6px; align-items: baseline; font-weight: 600; color: var(--muted); }
.date-notes dt .link { padding: 0; font-size: var(--fs-4); }
.date-notes dd { margin: 0; white-space: pre-line; }
.date-more { margin: 10px -20px 0; border-top: 1px solid var(--border); }
.date-more summary { display: flex; align-items: center; gap: 6px; padding: 9px 20px 6px; list-style: none; color: var(--muted); font-size: var(--fs-7); cursor: pointer; }
.date-more summary::-webkit-details-marker { display: none; }
.date-more summary:hover { color: var(--text); }
.date-more summary .i { width: 15px; height: 15px; transition: transform .15s; }
.date-more[open] summary .i { transform: rotate(180deg); }
.date-actions { display: flex; flex-direction: column; }
.date-actions .menu-item { padding: 9px 20px; }
.copy-list { max-height: 38vh; margin: 6px 0; padding-left: 18px; overflow: auto; font-size: var(--fs-6); }
.copy-list li + li { margin-top: 2px; }

/* Serving report */
.report-wrap { max-height: 55vh; margin: 0 -8px; padding: 0 8px; overflow: auto; }
table.report { width: 100%; border-collapse: collapse; font-size: var(--fs-6); }
.report th, .report td { padding: 6px 14px 6px 8px; border-bottom: 1px solid var(--border); text-align: left; vertical-align: top; white-space: nowrap; }
.report thead th { position: sticky; top: 0; background: var(--surface); }
.report thead button { padding: 0; border: 0; background: none; font-weight: 600; color: var(--muted); }
.report thead button[aria-pressed="true"] { color: var(--accent); }
.report tbody th { font-weight: 500; }
.report tbody th .link { padding: 0; font-size: var(--fs-6); font-weight: 600; color: var(--text); }

/* A person's calendar link */
.cal-group { border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 12px 14px; margin: 0 0 12px; }
.cal-group h4 { margin: 0 0 4px; font-size: var(--fs-8); }
.cal-group p { margin: 0; }
.cal-group .field { margin: 0; }
.cal-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
.cal-actions a.btn { text-decoration: none; }
.copy-row { display: flex; gap: 6px; }
.copy-row input { flex: 1; min-width: 0; font-size: var(--fs-5); }

/* Change requests */
#reqBody { max-height: 62vh; overflow: hidden auto; }
.req-h { margin: 14px 0 2px; font-size: var(--fs-4); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.req-h:first-child { margin-top: 4px; }
.req-list { margin: 0; padding: 0; list-style: none; }
.req-list > li { padding: 10px 0; border-bottom: 1px solid var(--border); font-size: var(--fs-7); }
.req-list > li p { margin: 4px 0 0; }
.req-list > li .quick-confirm-actions { margin-top: 8px; flex-wrap: wrap; }
.req-list > li:not(.open) { opacity: .7; }
.req-list > li.focus { padding: 10px 8px; border-radius: var(--radius-lg); background: var(--accent-tint); }
.req-status { float: right; margin-left: 8px; font-size: var(--fs-4); color: var(--muted); }
.req-list > li.open .req-status { color: var(--warn-text); font-weight: 600; }
.req-events { margin-top: 6px; font-size: var(--fs-5); color: var(--muted); }
.req-events summary { cursor: pointer; width: max-content; }
.req-events ol { margin: 4px 0 0; padding-left: 18px; }
.req-events li { margin: 3px 0; }
.req-events time { font-variant-numeric: tabular-nums; color: var(--text); }
.req-decline { margin-top: 8px; }
.req-decline input { height: 30px; padding: 0 8px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface); color: var(--text); }
/* Request a change */
.chg-what { color: var(--text) !important; }
.chg-types { display: flex; flex-wrap: wrap; margin: 8px 0 4px; }
.chg-types button { width: auto; flex: 1 1 auto; padding: 0 10px; font-size: var(--fs-6); font-weight: 600; white-space: nowrap; }
.chg-types button[aria-checked="true"] { background: var(--accent-soft); color: var(--accent); }
.chg-types button:disabled { opacity: .45; cursor: not-allowed; }
.chg-msg { margin: 8px 0; background: var(--surface-2); }

/* Demo: sign in as someone else */
.demo-find { width: 100%; height: 32px; margin: 6px 0; padding: 0 8px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface); color: var(--text); }
.demo-people { max-height: 50vh; margin: 0; padding: 0; overflow: auto; list-style: none; }
.demo-people a { display: block; padding: 7px 4px; border-bottom: 1px solid var(--border); color: var(--text); text-decoration: none; }
.demo-people a:hover { background: var(--accent-tint); }

/* ============================================================ Areas (pages) */
/* Requests, Rules, Report and Help take the schedule's place: a title (with tabs or a control
   beside it), then the same content the dialogs held. */
body.on-page .topbar, body.on-page .key-strip, body.on-page .app, body.on-page .savebar, body.on-page .selbar, body.on-page .print-head { display: none !important; }
.page { flex: 1; min-height: 0; overflow: auto; padding: 18px 28px 32px; background: var(--surface); }
.page-box { max-width: 880px; }
/* The serving report is as wide as its table, so no column wraps (a narrow screen scrolls sideways).
   Its heading and intro stay within the screen, and in place while it scrolls. */
.page:has(.report-page) { container-type: inline-size; }
.page-box.report-page { width: max-content; min-width: min(880px, 100%); max-width: none; }
.report-page :is(.page-head, .page-body > p) { position: sticky; left: 0; contain: inline-size; max-width: min(880px, 100cqw); }
.page-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin-bottom: 14px; }
.page-head h2 { margin: 0; font-size: var(--fs-12); font-weight: 700; }
.page-head-end { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.help-page .page-head-end { margin-left: 0; } /* Take the tour sits beside the tabs */
.page-tabs { display: inline-flex; }
.page-tabs button { display: inline-flex; align-items: center; gap: 6px; width: auto; padding: 0 12px; font-size: var(--fs-6); font-weight: 600; }
.page-tabs button[aria-selected="true"] { background: var(--accent-soft); color: var(--accent); }
.page-tabs .count-badge { font-size: var(--fs-1); line-height: 16px; min-width: 16px; }
.page .rules-body { margin: 0; padding: 0; overflow: visible; }
.page .report-wrap { max-height: none; margin: 0; padding: 0; overflow: visible; }
.page .inline-field { display: inline-flex; flex-direction: row; align-items: center; gap: 8px; margin: 0; }
.page .inline-field .select { width: auto; height: 32px; }
.page .help-body { max-width: 72ch; }
.page .help-sec h4 { margin-top: 10px; font-size: var(--fs-4); }
.page .help-sec ul { font-size: var(--fs-8); }
.page .req-list > li.focus { padding: 10px 12px; }
.page p.muted { color: var(--muted); font-size: var(--fs-7); }

/* ============================================================ Right-click menu */
.ctx-menu {
  position: fixed;
  z-index: 1000;
  min-width: 200px;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow);
}
.ctx-item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 6px 10px; border: 0; border-radius: var(--radius-md); background: none; color: var(--text); font-size: var(--fs-6); text-align: left; white-space: nowrap; cursor: default; }
.ctx-item .i { width: 15px; height: 15px; flex: none; color: var(--muted); }
.ctx-item span { flex: 1; }
.ctx-item kbd { margin-left: 16px; padding: 0; border: 0; background: none; color: var(--faint); font-size: var(--fs-3); line-height: 1; }
.ctx-item:hover:not([disabled]), .ctx-item:focus-visible { outline: none; background: var(--accent-soft); color: var(--accent); }
.ctx-item:hover:not([disabled]) .i, .ctx-item:focus-visible .i { color: var(--accent); }
.ctx-item.danger, .ctx-item.danger .i { color: var(--bad-text); }
.ctx-item.danger:hover, .ctx-item.danger:focus-visible { background: color-mix(in srgb, var(--bad-text) 10%, var(--surface)); color: var(--bad-text); }
.ctx-item[disabled] { opacity: .45; }
.ctx-sep { height: 1px; margin: 4px 6px; background: var(--border); }

/* The bottom bar is for phones (below). */
.tabbar { display: none; }
.print-head { display: none; padding: 0 0 8px; }
.print-title { display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px; font-size: var(--fs-9); }
.print-when { margin-left: auto; font-size: var(--fs-4); color: var(--muted); }

/* ============================================================ Medium screens (up to 1280px) */
/* A little less room: the header's count badges sit on their buttons' corners. */
@media (max-width: 1280px) {
  .tool .count-badge { position: absolute; top: -5px; right: -5px; }
  #draftBtn .count-badge { position: static; }
  .searchbox { min-width: 200px; }
}

/* ============================================================ Narrow screens (up to 900px) */
/* Also phones turned sideways: a touch screen under 500px tall (keep in step with sheetMq in app.js). */
@media (max-width: 900px), (max-height: 500px) and (pointer: coarse) {
  /* The dropdown is a bottom sheet here; leave room to scroll the selected cell above it. */
  .grid td.cell { scroll-margin-bottom: calc(50dvh + 12px); }
  /* With the sheet up, the save bar floats at the top instead, where it can still be reached. */
  body:has(.quick.as-sheet:not([hidden])) .savebar { position: fixed; top: calc(10px + env(safe-area-inset-top)); left: 12px; right: 12px; z-index: 55; padding-inline: 0; border: 1px solid var(--border); border-radius: var(--radius-xl); box-shadow: var(--shadow); overflow: hidden; }
}

/* ============================================================ Compact view off (⋯ menu) */
/* The grid is compact unless Compact view is turned off: then rows are 34px (a 22px pill with 6px
   above and below) and dates wider. :where() keeps these from outranking the phone layout below. */
:root:where(.roomy) { --col: 112px; --poscol: 156px; }
:where(.roomy) .grid td.cell { padding: 6px 4px; }
:where(.roomy) .cell-inner { gap: 3px; min-height: 22px; }
:where(.roomy) .grid .pill { height: 22px; font-size: var(--fs-5); line-height: 20px; }
:where(.roomy) .grid .pill.open { min-width: 22px; height: 22px; }
:where(.roomy) .cell-tools { top: 6px; }
:where(.roomy) .grid th.pos { padding-top: 7px; padding-bottom: 7px; }
:where(.roomy) .team-toggle { height: 34px; padding: 0 12px 0 10px; }
:where(.roomy) .grid th.date { padding: 8px 8px 7px; }
:where(.roomy) .grid td.note { padding: 7px 4px; } /* the same sides as a cell, so the notes line up with the names */

/* ============================================================ Phones (up to 760px, or sideways) */
/* An app bar (service and account), the search, the schedule, and the everyday actions in a bar at
   the bottom, where menus open as sheets. Sized like a phone's own apps rather than a web page:
   16px text, nothing smaller than 12px, and everything you tap at least 40px (most 44-48px).
   A phone turned sideways (a touch screen under 500px tall) keeps it; keep in step with phoneMq. */
@media (max-width: 760px), (max-height: 500px) and (pointer: coarse) {
  .env-long { display: none; } /* the test-copy strip: "Real data", not "Real Planning Center data" */
  :root { --col: 128px; --poscol: 132px; --tabbar-h: 56px; }
  html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; } /* no bigger text turning sideways */
  body { padding: env(safe-area-inset-top) env(safe-area-inset-right) 0 env(safe-area-inset-left); font-size: var(--fs-10); background: var(--surface); }
  button, a, input, select, label, td.cell { touch-action: manipulation; } /* a tap acts at once, never zooms */
  .small { font-size: var(--fs-8); }
  .link { font-size: var(--fs-9); }
  .count-badge { min-width: 20px; font-size: var(--fs-4); line-height: 20px; }
  .icon-btn { width: 40px; height: 40px; border-radius: 10px; }
  .icon-btn .i { width: 20px; height: 20px; }
  .shell { flex-direction: column; }

  /* The areas are in the bar at the bottom, so the rail goes. */
  .rail { display: none; }

  /* App bar: the service is the title (or the service's name), with the account at the right;
     under it the search (views and filters in its list) and the draft switcher once there's a draft. */
  .topbar { flex-wrap: wrap; min-height: 0; padding: 4px 12px 10px; gap: 8px; }
  .topbar-break { display: block; order: 2; flex-basis: 100%; height: 0; }
  .topbar > .selects { order: 0; flex: 1 1 auto; min-width: 0; }
  #serviceType.select, .st-title { field-sizing: content; width: auto; max-width: 100%; height: 44px; padding: 0 26px 0 0; font-size: var(--fs-12); }
  #serviceType.select { background-position: right 2px center; background-size: 17px; }
  #serviceType.select:hover { background-color: transparent; }
  .st-title { padding-right: 0; }
  .account { display: none; }
  .account-top { display: block; order: 1; flex: none; margin-left: auto; }
  .tool.account-btn, .tool.signin-btn { width: auto; height: 44px; padding: 0 4px; border-radius: var(--radius-xl); }
  .account-btn .avatar { width: 32px; height: 32px; font-size: var(--fs-5); }
  .account-top .account-btn .label { display: none; }
  .account-top .signin-btn .label { display: inline; }
  .account-pop { position: fixed; top: calc(56px + var(--env-bar-h, 0px) + env(safe-area-inset-top)); bottom: auto; left: 12px; right: 12px; width: auto; }
  .account-pop .menu-item { padding: 10px 16px; }
  .searchbox { order: 3; flex: 1 1 0; min-width: 0; max-width: none; margin-left: 0; min-height: 44px; padding-left: 38px; border-color: transparent; border-radius: var(--radius-xl); background: var(--surface-2); }
  .searchbox input { min-width: 50px; height: 40px; }
  .searchbox:focus-within { background: var(--surface); }
  .search-ic { left: 13px; top: 13px; }
  .search-ic .i { width: 18px; height: 18px; }
  .sugg { min-height: 48px; font-size: var(--fs-10); }
  .token { height: 32px; font-size: var(--fs-9); }
  .topbar > .tools { order: 5; flex: none; min-width: 0; margin: 0; }
  .topbar .tool { width: 44px; height: 44px; padding: 0; justify-content: center; border-color: transparent; border-radius: var(--radius-xl); background: var(--surface-2); }
  .topbar .tool .label, .topbar .tool .chev, #draftBtn .count-badge { display: none; }
  #draftBtn { width: 44px; padding: 0; }
  #draftBtn.in-draft { width: auto; padding: 0 8px; }
  #menuBtn { display: none !important; }
  .phone-only { display: flex !important; }
  .not-phone { display: none !important; } /* e.g. Compact view: phones have their own sizes */
  /* Text boxes at 16px, or iPhones zoom in when one is tapped. */
  .searchbox input, .q-opts input, .q-step-note, .field select, .field input,
  .modal-box .field textarea, .chg-msg, .note-text { font-size: var(--fs-10); }
  .key-strip { padding: 6px 12px; gap: 10px; font-size: var(--fs-8); }

  /* The schedule: names you can read at arm's length, rows a finger tall. */
  .pill, .grid .pill { height: 30px; padding: 0 9px 0 5px; border-radius: 15px; font-size: var(--fs-9); line-height: 28px; }
  .pill.k-C { padding-left: 9px; }
  .plan-note, .grid td.note .note-add { padding-left: 10px; } /* in line with the names: 1px border + 9px padding */
  .grid td.note { padding: 4px 6px; } /* the same sides as a cell */
  .pill.open, .grid .pill.open { min-width: 30px; height: 30px; font-size: var(--fs-7); }
  .pill.open .i { width: 14px; height: 14px; }
  .g { width: 17px; height: 17px; }
  .rule-mark { width: 16px; height: 16px; font-size: var(--fs-3); }
  .cell-inner { gap: 4px; min-height: 30px; }
  .grid td.cell { padding: 6px; }
  .cell-tools { top: 10px; } /* 6px cell padding + (30px pill - 22px button) / 2 */
  .grid th.pos { padding: 11px 6px 9px 34px; font-size: var(--fs-9); } /* the first line centres on the 30px pills */
  .team-toggle { gap: 6px; height: 42px; padding-left: 14px; font-size: var(--fs-8); } /* 30px pill + 6px each side; chevron (42 - 14) / 2 in */
  .team-toggle .i { width: 14px; height: 14px; }
  .grid tr.st-row th { height: 36px; font-size: var(--fs-6); }
  .grid th.date { padding: 10px 10px 9px; }
  .dow { font-size: var(--fs-4); }
  .day { font-size: var(--fs-11); }
  .date-btn { margin: -6px -6px; padding: 6px 6px; } /* a taller target, drawn in the same place */
  .next-tag { padding: 0 7px; font-size: var(--fs-4); line-height: 19px; }
  /* One date at a time, so "N needed" goes beside the date rather than under it: a shorter header. */
  .grid th.date .date-btn { display: inline-block; vertical-align: middle; }
  .open-count { margin: 0 0 0 10px; padding: 10px 0; vertical-align: middle; font-size: var(--fs-7); }
  .open-count[aria-pressed="true"] { padding: 4px 8px; }
  th.series span { padding-top: 7px; font-size: var(--fs-5); }
  th.series .series-edit { padding-bottom: 6px; }
  .corner-nav { gap: 6px; }
  .corner-nav .shift { width: 38px; height: 38px; }
  .corner-nav .shift .i { width: 19px; height: 19px; }
  .corner-nav .today-link { padding: 8px 4px; font-size: var(--fs-8); }

  /* The bottom bar. */
  .tabbar { position: relative; z-index: 40; display: flex; flex: none; padding: 0 4px env(safe-area-inset-bottom); background: var(--surface); border-top: 1px solid var(--border); }
  body:has(.signin-screen) .tabbar { display: none; } /* nothing to move around before signing in */
  .tabbar button { position: relative; flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; height: calc(var(--tabbar-h) - 1px); padding: 0; border: 0; background: none; color: var(--muted); font-size: var(--fs-4); font-weight: 600; -webkit-tap-highlight-color: transparent; }
  .tabbar .i { width: 23px; height: 23px; stroke-width: 1.8; }
  .tabbar button:active { color: var(--text); }
  .tabbar button[aria-expanded="true"], .tabbar button[aria-pressed="true"], .tabbar button.current { color: var(--accent); }
  .tabbar .count-badge { position: absolute; top: 3px; left: calc(50% + 4px); }
  .page { padding: 14px 16px 28px; }
  .page-head h2 { font-size: var(--fs-13); }
  .page-tabs button { height: 40px; font-size: var(--fs-9); }
  .page-tabs .count-badge { min-width: 20px; font-size: var(--fs-4); line-height: 20px; }
  .page p.muted { font-size: var(--fs-9); }
  .page .help-sec h4, .help-sec h4 { font-size: var(--fs-6); }
  .page .help-sec ul, .help-sec ul { font-size: var(--fs-10); line-height: 1.5; }
  .help-foot { font-size: var(--fs-7); }
  .page .inline-field .select { height: 40px; }
  body.on-page .topbar { display: flex !important; } /* the app bar stays; the search row goes */
  body.on-page .topbar > :not(.selects):not(.account-top):not(#filtersPop) { display: none !important; } /* More still opens */

  /* Menus open as sheets from the bottom, like a phone's own. */
  #filtersPop, #viewsPop, #draftPop { position: fixed; top: auto; left: 0; right: 0; bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom)); width: auto; max-height: calc(100dvh - 140px); overflow: auto; padding: 8px 0 10px; border-width: 1px 0 0; border-radius: var(--radius-sheet) var(--radius-sheet) 0 0; box-shadow: var(--shadow); }
  #filtersPop::before, #viewsPop::before, #draftPop::before { content: ""; display: block; width: 36px; height: 4px; margin: 0 auto 6px; border-radius: 2px; background: var(--border-strong); }
  .menu-item[data-print] { display: none; } /* printing is for the computer */
  .menu-item, .view-item { min-height: 50px; padding: 10px 20px; font-size: var(--fs-10); }
  .menu-item .i, .view-item > .i { width: 20px; height: 20px; }
  .switch { min-height: 50px; padding: 10px 20px; font-size: var(--fs-10); }
  .pop h4 { margin: 14px 20px 4px; font-size: var(--fs-6); }
  .pop-foot { padding: 10px 16px 2px; font-size: var(--fs-7); }
  .date-notes { font-size: var(--fs-9); }
  .date-notes dt .link { font-size: var(--fs-8); }
  .date-more summary { min-height: 44px; font-size: var(--fs-9); }
  .ctx-item { min-height: 44px; font-size: var(--fs-9); }

  /* Everything you tap at least 40px (the mark stays small), and no text under 12px. */
  .token button { width: 32px; height: 32px; }
  .token button::after { inset: -4px; }
  .token-clear { height: 40px; padding: 0 12px; font-size: var(--fs-9); }
  .theme-seg button { width: 44px; height: 40px; }
  .theme-seg .i { width: 18px; height: 18px; }
  .quick.as-sheet .q-chip-x { width: 40px; height: 40px; margin: -6px -8px -6px -4px; }
  .date-notes dt .link { margin: -10px -8px; padding: 10px 8px; }
  .plan-note { font-size: var(--fs-5); }
  .grid td.note .plan-note { font-size: var(--fs-6); }
  .sugg-h { font-size: var(--fs-4); }
  .pos-sub { font-size: var(--fs-5); line-height: 16px; }
  .grid thead tr.series-row th.corner-s { padding-right: 6px; vertical-align: bottom; }
  th.corner-s .today-s { display: block; margin: -4px -4px 0 auto; padding: 8px 4px; font-size: var(--fs-8); }
  .grid:has(.today-s) .corner-nav .today-link { display: none; }

  /* Compact view, a phone's own (⋯ / More; off by default): 24px pills and shorter rows, so more
     of the schedule fits on screen, still with no text under 12px. */
  .phone-compact .grid .pill { height: 24px; padding: 0 8px 0 4px; border-radius: 12px; font-size: var(--fs-7); line-height: 22px; }
  .phone-compact .grid .pill.k-C { padding-left: 8px; }
  .phone-compact .grid .pill.open { min-width: 24px; height: 24px; font-size: var(--fs-6); }
  .phone-compact .grid .pill.open .i { width: 12px; height: 12px; }
  .phone-compact .grid .g { width: 15px; height: 15px; }
  .phone-compact .grid .cell-inner { gap: 3px; min-height: 24px; }
  .phone-compact .grid td.cell { padding: 4px 6px; }
  .phone-compact .grid .cell-tools { top: 5px; } /* 4px cell padding + (24px pill - 22px button) / 2 */
  .phone-compact .grid th.pos { padding: 7px 6px 5px 34px; font-size: var(--fs-8); } /* the first line centres on the 24px pills */
  .phone-compact .grid .team-toggle { height: 34px; font-size: var(--fs-7); }
  .phone-compact .grid tr.st-row th { height: 30px; }
  .phone-compact .grid td.note { padding: 3px 6px; }
  .phone-compact .grid .plan-note, .phone-compact .grid td.note .note-add { padding-left: 9px; } /* in line with the names: 1px border + 8px padding */
  .phone-compact .grid th.date { padding: 7px 10px 6px; }

  /* The cell dropdown (a bottom sheet here): rows a finger tall, like a phone's own lists. */
  .quick.as-sheet { max-height: 75dvh; padding-bottom: env(safe-area-inset-bottom); font-size: var(--fs-10); }
  .quick-head { padding: 16px 6px 8px 16px; }
  .quick-head .icon-btn { width: 40px; height: 40px; }
  .quick-title strong { font-size: var(--fs-11); }
  .quick-title span { font-size: var(--fs-8); }
  .quick.as-sheet .q-field { margin: 10px 10px 6px; height: 44px; }
  .quick.as-sheet .q-field input { border-radius: 10px; }
  .quick.as-sheet .q-opt { min-height: 48px; gap: 10px; padding: 0 16px 0 12px; font-size: var(--fs-10); }
  .quick.as-sheet .q-ck .i { width: 17px; height: 17px; }
  .quick.as-sheet .q-info { font-size: var(--fs-8); }
  .quick.as-sheet .q-label { padding: 10px 16px 4px; font-size: var(--fs-8); }
  .quick-msg { margin: 8px 12px; font-size: var(--fs-8); }
  .q-step-title { font-size: var(--fs-10); }
  .q-step-text, .q-step-rules { font-size: var(--fs-8); }
  .q-opts label { font-size: var(--fs-7); }
  .q-opts input { height: 44px; }
  .btn { height: 44px; font-size: var(--fs-10); }
  .btn.sm { height: 40px; font-size: var(--fs-9); }
  .btn .i, .btn.sm .i { width: 18px; height: 18px; }

  /* Dialogs, a size up. */
  .modal-box { padding: 20px 20px 16px; border-radius: 16px; }
  .modal-box h3 { font-size: var(--fs-12); }
  .modal-box p { font-size: var(--fs-9); }
  :is(.modal-box, .page) .field { font-size: var(--fs-8); }
  .field select, .field input { height: 44px; border-radius: 10px; }
  :is(.modal-box, .page) .check { font-size: var(--fs-9); }
  :is(.modal-box, .page) .check input { width: 20px; height: 20px; margin-top: 1px; }
  .field .hint { font-size: var(--fs-7); }
  .publish-list { font-size: var(--fs-9); }
  .copy-list { font-size: var(--fs-9); }
  table.report, .report tbody th .link { font-size: var(--fs-9); }
  .cal-group h4 { font-size: var(--fs-10); }
  .chg-types button { height: 40px; font-size: var(--fs-9); }
  .demo-find { height: 44px; font-size: var(--fs-10); }

  /* Change requests. */
  .req-h { font-size: var(--fs-6); }
  .req-list > li { padding: 14px 0; font-size: var(--fs-10); }
  .req-status { font-size: var(--fs-8); }
  .req-events { font-size: var(--fs-8); }
  .req-decline input { height: 44px; font-size: var(--fs-10); }

  /* The save bar sits just above the bottom bar (it's in the page, see above); toasts go to the top. */
  /* Two lines: what's changed with ↶ ↷ and Review, then Discard, Save as draft and Publish. */
  .savebar-main { flex-wrap: wrap; row-gap: 6px; padding: 8px 8px 10px 14px; }
  .savebar-main::after { content: ""; order: 1; flex-basis: 100%; }
  .savebar-main > .btn:not([data-review]) { order: 2; }
  .savebar-main > .btn.primary { margin-left: auto; }
  .savebar-main .btn.ghost { padding: 0 10px; }
  .savebar-text { flex: 1 1 0; font-size: var(--fs-9); }
  .review-item { font-size: var(--fs-9); }
  .review-item .where, .review-item .bad { font-size: var(--fs-7); }
  .pin-form label { font-size: var(--fs-9); }
  .pin-form input { height: 44px; font-size: var(--fs-10); }
  .selbar { left: 12px; bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 10px); max-width: calc(100vw - 24px); font-size: var(--fs-9); }
  .selbar .selbar-text { min-width: 0; white-space: normal; }
  /* Above the save bar (two rows here), not on top of it. */
  body:has(#savebar:not([hidden])) .selbar { bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 10px + var(--savebar-h, 108px)); }
  .toast { top: calc(12px + env(safe-area-inset-top)); bottom: auto; max-width: calc(100vw - 24px); font-size: var(--fs-9); }
  .install-card { left: 12px; right: 12px; width: auto; max-width: none; bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 10px); font-size: var(--fs-9); }
  .install-text span { font-size: var(--fs-8); }

  /* Scheduling rules, a size up. */
  .rule-sec h4 { margin-top: 18px; font-size: var(--fs-6); }
  /* The badge and ✎ 🗑 on a line of their own, so the rule gets the whole width under them. */
  .rule-item { flex-wrap: wrap; align-items: center; gap: 4px 12px; padding: 10px 0 12px; }
  .rule-body { order: 1; flex-basis: 100%; }
  .rule-actions { gap: 4px; margin-left: auto; margin-right: -8px; }
  .rule-badge { min-width: 72px; padding: 2px 8px; font-size: var(--fs-6); line-height: 20px; }
  :is(.modal-box, .page) .rule-text { font-size: var(--fs-10); }
  :is(.modal-box, .page) .rule-note { margin-top: 4px; font-size: var(--fs-8); }
  :is(.modal-box, .page) .rule-meta { margin-top: 4px; font-size: var(--fs-6); }
  .rule-items > li { padding: 12px 0; font-size: var(--fs-9); }
  .rule-sentence { font-size: var(--fs-8); }
  .rule-override { font-size: var(--fs-8); }
  .rule-filter { height: 40px; }
  .rule-builder h4 { font-size: var(--fs-10); }
  .rb-pick { min-height: 48px; font-size: var(--fs-10); }
  .spot-btn { height: 44px; font-size: var(--fs-10); }
  .spot-opt { min-height: 44px; font-size: var(--fs-10); }
  .rb-seg button { height: 40px; font-size: var(--fs-9); }
  .rb-row { font-size: var(--fs-9); }
  :is(.modal-box, .page) .rule-preview { font-size: var(--fs-9); }
}

/* ============================================================ Phones turned sideways */
/* Short and wide: the service, the search and the account on one row, and a lower bottom bar, so
   the schedule keeps most of the height. */
@media (max-height: 500px) and (pointer: coarse) {
  :root { --tabbar-h: 50px; }
  .topbar { flex-wrap: nowrap; align-items: center; padding: 4px 12px 6px; gap: 10px; }
  .topbar-break { display: none; }
  .topbar > .selects { flex: 0 1 auto; }
  .searchbox { order: 1; }
  .topbar > .tools { order: 2; }
  .account-top { order: 3; }
  .account-pop { top: calc(52px + var(--env-bar-h, 0px) + env(safe-area-inset-top)); left: auto; width: 340px; max-height: calc(100dvh - 64px - var(--env-bar-h, 0px)); overflow: auto; }
  .tabbar .i { width: 21px; height: 21px; }
  .tabbar button { gap: 2px; }
  #filtersPop, #viewsPop, #draftPop { max-height: calc(100dvh - var(--tabbar-h) - env(safe-area-inset-bottom) - 16px); }
  .quick.as-sheet { width: min(600px, 100%); margin: 0 auto; } /* centred, not stretched across */
}

/* Touch screens: a tap opens the cell, so its ▾ isn't needed. */
@media (hover: none) {
  .cell-tools { display: none !important; }
}

/* ============================================================ Print */
/* Just the grid, landscape, with a heading and the key; no selection or highlights, and every group
   heading (Welcome, Speaker, Unavailable…) gets the same light shading. */
@media print {
  @page { size: landscape; margin: 10mm; }
  body { display: block; height: auto; overflow: visible; background: #fff; }
  .env-bar, .rail, .tabbar, .topbar, .page, .quick, .savebar, .selbar, .toast, .install-card, .sheet-backdrop, .modal, .tour, .key-strip, .badge, .updated, .pop, .account,
  .ctx-menu, .cell-tools, .ghosts, .open-count, .clash-mark, .rule-mark, .override-mark, .fresh-dot { display: none !important; }
  .print-head { display: block !important; }
  .board { overflow: visible; padding: 0 !important; }
  /* Fit the weeks on the page and repeat the date row on every page. */
  table.grid { zoom: var(--print-zoom, .6); width: 100%; padding-right: 0 !important; }
  .grid thead { display: table-header-group; }
  .grid tr { break-inside: avoid; }
  .grid th, .grid td { position: static !important; }
  .date-btn { margin: 0; padding: 0; }
  .grid td.cell:focus-visible { outline: none; }
  .grid td.cell.sel, .grid td.cell.rg, .grid td.cell.pv, .grid td.cell.cp, .grid td.cell.sel.rg {
    outline: none !important;
    box-shadow: none !important;
    background: none !important;
  }
  .grid td.cell::before { display: none !important; }
  .grid td.cell:hover:not(.dirty):not(.hl-col) { background: none !important; }
  .grid th.pos.row-sel { background: none !important; color: inherit !important; box-shadow: none !important; }
  .grid th.date.col-sel { background: none !important; }
  .grid th.date.col-sel .day { color: inherit !important; }
  .grid tr.team-row th, .grid tr.team-row.uncategorized th, .grid tr.st-row th {
    background: #f2eee7 !important; /* --surface-2 in light: print is always light */
    border-top: 1px solid #d8d1c5 !important;
    border-bottom: 1px solid #d8d1c5 !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .grid tr.team-row .team-toggle, .grid tr.st-row .team-head { color: #1f1d1a !important; font-weight: 700; }
  .grid tr.team-row .team-toggle .i { display: none; }
}
