/* ============================================================
   Liberty Lou — Markets Dashboard
   ============================================================ */
:root {
  --bg: #f1f5f9;
  --surface: #ffffff;
  --ink: #0f172a;
  --muted: #64748b;
  --line: #e2e8f0;
  --brand: #15803d;
  --brand-d: #166534;
  --shadow: 0 1px 3px rgba(15, 23, 42, .08), 0 1px 2px rgba(15, 23, 42, .06);
  --radius: 12px;
  /* Organiser accent — deliberately distinct from every county colour and from
     the purple already used by the Events detail panel, so an Organiser Card
     is never visually confusable with an Event Card. */
  --organiser-accent: #4f46e5;
  --organiser-accent-light: #eef2ff;
  --organiser-accent-line: #c7d2fe;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--ink);
  font-size: 15px;
  line-height: 1.45;
}
.hidden { display: none !important; }
.app-banner {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  background: #b91c1c; color: #fff; padding: .6rem 1rem; font-size: .9rem;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  box-shadow: 0 2px 8px rgba(0,0,0,.25);
}
.app-banner button { background: transparent; border: 0; color: #fff; font-size: 1.2rem; cursor: pointer; line-height: 1; }
/* ---- Info popup ---- */
#info-popup {
  position: fixed;
  z-index: 9999;
  background: #f0f0f0;
  border: 1.5px solid #000;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0,0,0,.13);
  padding: .65rem 2.2rem .65rem .75rem;
  max-width: 300px;
  font-size: .73rem;
  line-height: 1.55;
  color: var(--ink);
}
.info-popup-x {
  position: absolute;
  top: .3rem;
  right: .3rem;
  border: none;
  background: none;
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  color: var(--muted);
  padding: .15rem .35rem;
  border-radius: 4px;
}
.info-popup-x:hover { color: var(--ink); background: rgba(15,23,42,.06); }
.app-loading {
  position: fixed; top: 64px; left: 50%; transform: translateX(-50%); z-index: 90;
  background: #1e293b; color: #fff; padding: .55rem 1.1rem; border-radius: 999px;
  display: flex; align-items: center; gap: .6rem; font-size: .88rem;
  box-shadow: 0 8px 24px rgba(15, 23, 42, .3);
}
.spinner {
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .35); border-top-color: #fff;
  animation: spin .8s linear infinite; flex: 0 0 16px;
}
@keyframes spin { to { transform: rotate(360deg); } }
a { color: var(--brand-d); }
h2, h3 { margin: 0 0 .4rem; }
.muted { color: var(--muted); }

/* ---------- buttons ---------- */
.btn {
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  padding: .5rem .9rem;
  border-radius: 8px;
  font-size: .9rem;
  cursor: pointer;
  transition: background .15s, border-color .15s;
}
.btn:hover { background: #f8fafc; }
.btn.primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn.primary:hover { background: var(--brand-d); }
.btn.ghost { background: transparent; }
.btn.danger { color: #b91c1c; }
.btn.full { width: 100%; }
.btn:disabled { opacity: .6; cursor: default; }
.btn[data-tooltip] { position: relative; }
.btn[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 7px);
  left: 50%;
  transform: translateX(-50%);
  background: #fefce8;
  color: #713f12;
  border: 1px solid #fde68a;
  font-size: .72rem;
  font-weight: 300;
  white-space: nowrap;
  padding: .25rem .55rem;
  border-radius: 5px;
  pointer-events: none;
  z-index: 9999;
  box-shadow: 0 2px 6px rgba(0,0,0,.1);
  /* v0.78b: `display: none` when idle, NOT `opacity: 0`.
     An absolutely-positioned, white-space:nowrap box still contributes to its
     scroll container's scrollWidth at zero opacity — which is what was putting
     a permanent horizontal scrollbar on the card modal. The overflow was 98px
     of tooltip nobody could see: no element's bounding rect exceeded the body,
     because pseudo-elements do not have one.
     The fade is kept as an animation on the visible state, since there is no
     transition to run from a display change. */
  display: none;
}
.btn[data-tooltip].tooltip-active::after {
  display: block;
  animation: tooltip-in .15s ease-out;
}
@keyframes tooltip-in { from { opacity: 0 } to { opacity: 1 } }
/* Left-edge buttons: anchor tooltip to button's left so it doesn't overflow left */
#dg-update::after, #em-send::after, #b-save::after {
  left: 0; transform: none;
}
/* Right-edge buttons: anchor tooltip to button's right so it doesn't overflow right */
#dg-cancel::after, #ev-add-btn::after, #em-cancel::after,
.note-form .btn[data-tooltip]::after {
  right: 0; left: auto; transform: none;
}
.link-btn { background: none; border: 0; color: var(--muted); cursor: pointer; font-size: .8rem; text-decoration: underline; padding: 0; }

/* ---------- brand ---------- */
.brand { display: flex; align-items: center; gap: .55rem; font-weight: 700; font-size: 1.05rem; }
.brand-ver { font-size: .7rem; font-weight: 600; color: var(--muted); opacity: .85; }
.brand-mark {
  display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 8px;
  background: var(--brand); color: #fff; font-size: .85rem; font-weight: 800;
}

/* ============================================================
   LOGIN
   ============================================================ */
/* Flex + margin:auto centring with a scrollable backdrop (same rationale as
   .modal): when the card outgrows a small screen — error note, user list,
   takeover panel, or the Android keyboard shrinking the view — grid
   place-items:center clips both ends with no way to scroll to the buttons. */
#login-screen {
  position: fixed; inset: 0;
  display: flex;
  overflow-y: auto;
  background: linear-gradient(135deg, #14532d, #166534 55%, #1e293b);
  padding: 1rem;
}
.login-card {
  background: var(--surface);
  width: 100%; max-width: 380px;
  margin: auto;
  padding: 2rem 1.75rem;
  border-radius: 16px;
  box-shadow: 0 20px 40px rgba(0, 0, 0, .25);
  display: flex; flex-direction: column; gap: .85rem;
}
.login-card .brand { font-size: 1.25rem; }
/* Login version chip: nested inline in the title span so it sits on the
   title's text baseline; a touch smaller than the topbar's .brand-ver. */
.login-card .brand-ver { font-size: .6rem; margin-left: .1rem; }
.login-sub { margin: -.3rem 0 .5rem; color: var(--muted); }
.login-card label { display: flex; flex-direction: column; gap: .3rem; font-size: .85rem; color: var(--muted); }
.login-card input {
  padding: .6rem .7rem; border: 1px solid var(--line);
  border-radius: 8px; font-size: 1rem;
}
/* Password show/hide eye — sits inside the input's right edge. */
.pw-wrap { position: relative; display: block; }
.pw-wrap input { width: 100%; padding-right: 2.4rem; box-sizing: border-box; }
.pw-toggle {
  position: absolute; top: 50%; right: .45rem; transform: translateY(-50%);
  display: grid; place-items: center;
  width: 1.7rem; height: 1.7rem; padding: 0;
  background: none; border: none; cursor: pointer;
  color: var(--muted); border-radius: 6px;
}
.pw-toggle:hover { color: var(--text, #0f172a); }
.pw-toggle svg { width: 1.1rem; height: 1.1rem; }
.login-error { color: #dc2626; font-size: .85rem; min-height: 1rem; margin: 0; }
.login-demo { font-size: .78rem; color: var(--muted); text-align: center; margin: .2rem 0 0; }
.login-demo code { background: #f1f5f9; padding: .1rem .3rem; border-radius: 4px; }

/* ============================================================
   APP SHELL
   ============================================================ */
.topbar {
  display: flex; align-items: center; gap: 1rem;
  padding: .65rem 1.25rem;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 20;
  flex-wrap: wrap;
}
.tabs { display: flex; gap: .25rem; flex: 1; }
.tab-btn {
  border: 0; background: transparent; color: var(--muted);
  padding: .5rem .85rem; border-radius: 8px;
  font-size: .92rem; font-weight: 600; cursor: pointer;
}
.tab-btn:hover { background: #f1f5f9; color: var(--ink); }
.tab-btn.active { background: #dcfce7; color: var(--brand-d); }
.user-box { display: flex; align-items: center; gap: .6rem; }
.user-email { font-size: .82rem; color: var(--muted); }

/* Mobile header controls — hidden on desktop, revealed in the responsive block. */
.topbar-actions { display: none; align-items: center; gap: .3rem; margin-left: auto; }
.icon-btn {
  display: inline-grid; place-items: center; width: 40px; height: 40px; padding: 0;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); color: var(--ink); cursor: pointer;
}
.icon-btn:hover { background: #f1f5f9; }
.icon-btn[aria-expanded="true"] { background: #dcfce7; color: var(--brand-d); border-color: #bbf7d0; }
.icon-btn svg { display: block; }

.content { padding: 1.25rem; max-width: 1280px; margin: 0 auto; }
.hint { color: var(--muted); margin: 0 0 1rem; font-size: .9rem; }

/* ---------- filters ---------- */
.filters {
  display: flex; gap: .6rem; flex-wrap: wrap; align-items: center;
  padding: .75rem 1.25rem; background: var(--surface);
  border-bottom: 1px solid var(--line);
  /* --topbar-h / --filters-h are kept in sync with the real element heights by
     a ResizeObserver in app.js — the topbar height varies (mobile single row,
     wrapped rows, open drawer, iOS font scaling), so sticky offsets must not
     be hardcoded. Fallbacks match the classic desktop heights. */
  position: sticky; top: var(--topbar-h, 53px); z-index: 15;
}
.filters input, .filters select {
  padding: .5rem .65rem; border: 1px solid var(--line);
  border-radius: 8px; font-size: .9rem; background: #fff;
}
.filters #f-search { flex: 1; min-width: 200px; }
.dir-count { margin-left: auto; color: var(--muted); font-size: .85rem; }

/* Print button in filter bar */
#print-btn { color: var(--muted); }
#print-btn:hover { color: var(--ink); background: rgba(15,23,42,.07); }

/* Status pill: Show All / Normal two-state toggle */
.status-pill {
  display: inline-flex; border: 1px solid var(--line);
  border-radius: 999px; overflow: hidden; background: #f8fafc;
  font-size: .78rem; font-weight: 500;
}
.sp-opt {
  padding: .35rem .85rem; background: transparent; border: none;
  cursor: pointer; color: var(--muted); white-space: nowrap; transition: background .12s, color .12s;
}
.sp-opt:hover { background: #f1f5f9; color: var(--ink); }
.sp-opt.sp-active { background: var(--brand); color: #fff; }

/* ============================================================
   DIRECTORY
   ============================================================ */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1rem;
}
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  overflow: hidden;
}
.market-card { cursor: pointer; transition: transform .12s, box-shadow .12s; display: flex; }
.market-card:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(15,23,42,.12); }
.card-bar { width: 6px; flex: 0 0 6px; }
.card-body { padding: .9rem 1rem; flex: 1; min-width: 0; }
.card-top { display: flex; justify-content: space-between; align-items: flex-start; gap: .5rem; }
.card-top h3 { font-size: 1rem; line-height: 1.25; }
.market-card .muted { font-size: .85rem; margin: .15rem 0 .6rem; }
.meta { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }
.meta.sub { margin-top: .5rem; font-size: .82rem; color: var(--muted); gap: .75rem; }
.empty { color: var(--muted); padding: 2rem; text-align: center; grid-column: 1/-1; }

/* chips & tags */
.chip { font-size: .72rem; font-weight: 700; padding: .15rem .5rem; border-radius: 999px; white-space: nowrap; }
.chip.county { color: var(--c); background: color-mix(in srgb, var(--c) 12%, white); }
/* Group chips are coloured inline via groupChipStyle() in app.js — a stable
   hue hashed from the group name, so dynamic groups need no per-group CSS
   (the old .group-farmers/-town/-community rules are retired, v0.56). */
.tag { font-size: .72rem; padding: .15rem .5rem; border-radius: 6px; background: #f1f5f9; color: #475569; white-space: nowrap; }
.tag-town { background: #dcfce7; color: var(--brand-d); font-weight: 700; }

/* ---- Archive (v0.58) ---- */
/* Archived cards must be unmistakable next to active ones: fully desaturated,
   dashed slate border, washed-out surface, ARCHIVED badge. */
.card.is-archived {
  filter: grayscale(1);
  opacity: .78;
  border: 1.5px dashed #94a3b8;
  background: #f1f5f9;
  box-shadow: none;
}
.card.is-archived:hover { transform: none; box-shadow: none; }
.badge-archived {
  font-size: .62rem; font-weight: 800; letter-spacing: .08em;
  padding: .18rem .5rem; border-radius: 4px;
  background: #334155; color: #f8fafc; white-space: nowrap;
}
.badge-archived-lg { font-size: .7rem; margin-left: .6rem; vertical-align: middle; }
/* Detail-modal Archive/Unarchive control (v0.60): a tag-sized pill on the
   header's chip row, RIGHT-JUSTIFIED and clear of everything else — lower
   than the modal's close × (the old top-right button collided with it) and
   pushed away from the county/Note pills by the flex auto margin. The guard
   message sits just left of the pill. */
.detail-head > div:first-child { flex: 1 1 auto; min-width: 0; }
.pill-archive-wrap { margin-left: auto; display: inline-flex; align-items: center; gap: .5rem; }
.pill-archive {
  font-size: .72rem; font-weight: 700; padding: .15rem .6rem;
  border-radius: 6px; border: none; cursor: pointer;
  background: #334155; color: #f8fafc; white-space: nowrap;
}
.pill-archive:hover { background: #1e293b; }

/* Directory top row: sub-view toggle left, Select/Archive actions right. */
.dir-topbar { display: flex; justify-content: space-between; align-items: flex-start; flex-wrap: wrap; gap: .5rem; }
.dir-actions { display: flex; gap: .4rem; flex-wrap: wrap; }
.dv-opt-archived.dv-active { background: #334155; border-color: #334155; }
/* Export dialogue: the Archived dataset pill stands apart from Events /
   Organisers / Both so "Both" can't read as "both including archived". */
.impex-ds-archived { margin-left: 1.4rem; position: relative; }
.impex-ds-archived::before {
  content: ""; position: absolute; left: -0.85rem; top: 15%; height: 70%;
  border-left: 1px solid var(--line);
}

/* Select mode (v0.59) — a selected card greys out like an archived card and
   shows a large circular tick watermark centred on the panel (YouTube-logo
   placement). pointer-events: none — clicks pass through to the card. */
.card { position: relative; }
.card-select-mark {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  display: none; align-items: center; justify-content: center;
}
.card.is-selected .card-select-mark { display: flex; }
.csm-circle {
  width: 68px; height: 68px; border-radius: 50%;
  background: rgba(51, 65, 85, .7); color: #fff;
  font-size: 2.3rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 12px rgba(15, 23, 42, .3);
}
.card.is-selected {
  filter: grayscale(1);
  opacity: .78;
  background: #f1f5f9;
}

/* ---- Directory: Events / Organisers sub-view toggle ---- */
/* v0.78b: WRAPS. Six pills (All · Organisers · Venues · Events · Event Cards ·
   Archived) measure 534px, so on a 375px phone this single row was pushing the
   whole document sideways — the page scrolled horizontally on the Directory tab
   and nowhere else. Wrapping to a second line costs nothing; a nowrap row that
   overflows the viewport costs every other element its alignment. */
.dir-view-toggle { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .9rem; }
.dv-opt {
  padding: .4rem 1rem; border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); cursor: pointer; font-size: .85rem; font-weight: 700;
  color: var(--muted); transition: background .12s, color .12s, border-color .12s;
}
.dv-opt:hover:not(.dv-active) { background: #f1f5f9; color: var(--ink); }
.dv-opt.dv-active { background: var(--brand); border-color: var(--brand); color: #fff; }
.dv-opt[data-view="organisers"].dv-active { background: var(--organiser-accent); border-color: var(--organiser-accent); }

/* Add-a-Card modal's Event/Organiser mode toggle — same pill style */
.add-type-toggle { margin-bottom: .9rem; }
.dv-opt[data-type="organiser"].dv-active { background: var(--organiser-accent); border-color: var(--organiser-accent); }
.am-organiser-tag {
  font-size: .8rem; color: var(--organiser-accent); background: var(--organiser-accent-light);
  border: 1px solid var(--organiser-accent-line); border-radius: 8px; padding: .4rem .7rem; margin: 0 0 .9rem;
}

/* ---- Organiser Card ----
   Deliberately different from .market-card on every visual axis: a wider,
   striped left bar (vs. a solid 6px county-coloured bar), an indigo border
   tint (vs. neutral), and an explicit ORGANISER badge — so the two card
   types can never be mistaken for one another at a glance. */
.organiser-card {
  cursor: pointer; transition: transform .12s, box-shadow .12s;
  display: flex; border-color: var(--organiser-accent-line);
}
.organiser-card:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(79,70,229,.22); }
.card-bar-organiser {
  width: 10px; flex: 0 0 10px;
  background: repeating-linear-gradient(135deg,
    var(--organiser-accent) 0 5px,
    var(--organiser-accent-light) 5px 10px);
}
.badge-organiser {
  background: var(--organiser-accent); color: #fff; letter-spacing: .04em;
}
.badge-organiser-lg {
  display: inline-block; background: var(--organiser-accent); color: #fff;
  font-size: .68rem; font-weight: 800; letter-spacing: .05em;
  padding: .18rem .6rem; border-radius: 6px; margin-left: .6rem; vertical-align: middle;
}

/* ============================================================
   PIPELINE (kanban)
   ============================================================ */
.kanban {
  display: grid;
  grid-template-columns: repeat(6, minmax(180px, 1fr));
  gap: .85rem;
  align-items: start;
  overflow-x: auto;
}
.stage-hidden { background: #475569; }
.kcol-hidden { border-style: dashed; }
.kcol-empty { color: var(--muted); font-size: .8rem; padding: .6rem; text-align: center; }
.kcol-subhead { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 700; padding: .35rem .15rem .1rem; }
.kcol-subhead-toggle { display: flex; justify-content: space-between; align-items: center; cursor: pointer; user-select: none; border-radius: 4px; }
.kcol-subhead-toggle:hover { color: var(--fg); background: rgba(0,0,0,.04); }
.kcol-subhead-chev { transition: transform .18s; display: flex; }
.kcol-subhead-chev.collapsed { transform: rotate(-90deg); }
.kcol-subhead-count { font-weight: 400; opacity: .7; }
.kcol-group-body { display: flex; flex-direction: column; gap: .55rem; margin-bottom: .3rem; }
.kcard-top { display: flex; justify-content: space-between; align-items: flex-start; gap: .4rem; }

/* per-event list in the detail modal */
.ev-help { font-size: .8rem; margin: -.2rem 0 .6rem; }
.ev-add-row { display: flex; gap: .5rem; margin: 0 0 .6rem; }
.ev-add-input { flex: 1; min-width: 0; }
.ev-row-extra { background: #fdf4ff; border-color: #e9d5ff; }
.ev-extra-tag { font-size: .72rem; color: #7c3aed; font-weight: 600; background: #ede9fe; padding: .1rem .4rem; border-radius: 9999px; white-space: nowrap; flex-shrink: 0; }
.ev-bin-btn { background: transparent; border: 0; padding: .15rem; cursor: pointer; color: var(--muted); opacity: .55; border-radius: 6px; display: inline-grid; place-items: center; }
.ev-bin-btn:hover { color: #dc2626; opacity: 1; background: rgba(220,38,38,.08); }
.ev-list { display: flex; flex-direction: column; gap: .35rem; }
.ev-list-scroll { max-height: calc(12 * 2.4rem); overflow-y: auto; position: relative; scroll-behavior: smooth; overscroll-behavior: contain; }
/* 3-column grid: [bin/slot 20px] [date flex] [toggle/tag auto] — keeps dates left-aligned regardless of bin presence */
.ev-row { display: grid; grid-template-columns: 20px 1fr auto; align-items: center; column-gap: .4rem; padding: .35rem .55rem; border: 1px solid var(--line); border-radius: 8px; font-size: .88rem; background: #fff; }
.ev-row.is-hidden { opacity: .55; }
.ev-row.ev-past { opacity: .45; color: var(--muted); }
.ev-row.ev-past .eye-btn { opacity: .7; }
.ev-row .eye-btn { padding: .2rem .3rem; }

/* Organiser Card's Events panel reuses .ev-row (bin/date/toggle) but each row
   spans a different market, so the middle grid cell wraps a market-name +
   date pair instead of a bare date span. Rows are clickable (data-market on
   the row itself is unique to this panel) to jump to that market's own card. */
.ev-row[data-market] { cursor: pointer; }
.ev-row-mid { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.ev-market-name { font-weight: 600; font-size: .82rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ev-row-date { font-size: .8rem; color: var(--muted); }
.ev-row.ev-past .ev-row-date { color: inherit; opacity: .85; }

/* HIDE / UNHIDE text chips inside action buttons */
.ev-label {
  display: inline-block; font-size: .45rem; font-weight: 400;
  letter-spacing: .06em; padding: .1rem .35rem; border-radius: 4px;
  line-height: 1.4; white-space: nowrap; pointer-events: none;
}
.ev-label-hide   { background: #fee2e2; color: #b91c1c; }
.ev-label-unhide { background: #dcfce7; color: #166534; }

/* action button shell — transparent; the label chip inside carries the colour */
.eye-btn {
  background: transparent; border: 0; padding: 2px; cursor: pointer;
  color: var(--muted); display: inline-grid; place-items: center; border-radius: 6px; flex: 0 0 auto;
}
.eye-btn:hover { background: rgba(15, 23, 42, .06); }
.card-top-right { display: flex; align-items: center; gap: .35rem; }
.market-card.is-hidden { opacity: .6; }
.tag-hidden { background: #fee2e2; color: #b91c1c; }
.kcol { background: #f8fafc; border: 1px solid var(--line); border-radius: var(--radius); min-width: 180px; }
.kcol-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: .6rem .75rem; font-weight: 700; font-size: .85rem;
  border-top-left-radius: var(--radius); border-top-right-radius: var(--radius);
  color: #fff;
}
.kcount { background: rgba(255,255,255,.3); border-radius: 999px; padding: 0 .5rem; font-size: .78rem; }
.stage-interested { background: #64748b; }
.stage-enquiry    { background: #0ea5e9; }
.stage-applied    { background: #f59e0b; }
.stage-booked     { background: #16a34a; }
.stage-paid       { background: #7c3aed; }
.kcol-sum { font-size: .72rem; color: var(--muted); padding: .35rem .75rem; border-bottom: 1px solid var(--line); }
.kcol-body { padding: .6rem; display: flex; flex-direction: column; gap: .55rem; min-height: 60px; }
.kcol-body.over { background: #ecfdf5; outline: 2px dashed #16a34a; outline-offset: -4px; border-radius: 8px; }

.kcard {
  background: #fff; border: 1px solid var(--line); border-left: 4px solid var(--c);
  border-radius: 8px; padding: .55rem .65rem; cursor: grab;
  box-shadow: var(--shadow); display: flex; flex-direction: column; gap: .4rem;
}
.kcard:active { cursor: grabbing; }
.kcard.dragging { opacity: .4; }
.kcard strong { font-size: .85rem; line-height: 1.2; }
.kcard-meta { display: flex; gap: .3rem; flex-wrap: wrap; }
.kcard-foot { display: flex; justify-content: space-between; font-size: .72rem; color: var(--muted); }

/* ============================================================
   MAP
   ============================================================ */
#map { height: 70vh; min-height: 420px; border-radius: var(--radius); border: 1px solid var(--line); box-shadow: var(--shadow); }

/* ============================================================
   INSIGHTS
   ============================================================ */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 1rem; margin-bottom: 1.25rem; }
.kpi {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 1rem 1.1rem; display: flex; flex-direction: column; gap: .15rem;
}
.kpi-v { font-size: 1.8rem; font-weight: 800; color: var(--brand-d); }
.kpi-k { font-weight: 600; }
.kpi-sub { font-size: .78rem; color: var(--muted); }

.insight-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 1rem; }
/* Panels stacked below the insight grid (Manage filter lists, Add a field,
   Seed Search) share the grid's own 1rem gap for a consistent rhythm. */
#tab-dashboard > .panel { margin-top: 1rem; }
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: 1.1rem 1.25rem; }
.panel h3 { font-size: .95rem; margin-bottom: .8rem; }
.chart { display: flex; flex-direction: column; gap: .5rem; }

.bar-row, .prog-row { display: grid; grid-template-columns: 120px 1fr auto; gap: .6rem; align-items: center; font-size: .82rem; }
.bar-track, .prog-track { background: #f1f5f9; border-radius: 999px; height: 12px; overflow: hidden; }
.bar-fill, .prog-fill { height: 100%; border-radius: 999px; transition: width .4s; }
.bar-val, .prog-val { color: var(--muted); font-variant-numeric: tabular-nums; }
.prog-row { grid-template-columns: 120px 1fr 110px auto; }
/* Data completeness Auto-fill (v0.53) — machine-first bulk fill per row */
.btn-autofill { font-size: .7rem; padding: .18rem .5rem; background: var(--brand); color: #fff; border: none; border-radius: 4px; cursor: pointer; white-space: nowrap; justify-self: end; max-width: 8.5rem; overflow: hidden; text-overflow: ellipsis; }
.btn-autofill:hover:not(:disabled) { background: var(--brand-d, #15803d); }
.btn-autofill:disabled { opacity: .45; cursor: default; }
.btn-autofill.af-running { background: #b45309; }
.btn-autofill-spacer { min-width: 3.6rem; }
/* "Other field…" catcher row + pointer note at the foot of Data completeness */
.comp-other { display: flex; gap: .5rem; align-items: center; margin-top: .7rem; }
.comp-other .dl-input { flex: 1; min-width: 0; font-size: .82rem; }
.comp-note { font-size: .75rem; margin: .55rem 0 0; }
/* Edit icon before the field dropdown (v0.61) — only shown once a field is
   selected; opens that field in the spreadsheet editor. */
.comp-other-edit { flex: 0 0 auto; font-size: .85rem; padding: .18rem .45rem; }
/* "Markets by group" listing-order toggle in the panel heading (v0.61) */
.chart-sort-btn { float: right; font-size: .7rem; font-weight: 500; padding: .15rem .6rem; border: 1px solid var(--line); border-radius: 999px; background: #fff; cursor: pointer; color: #475569; }
.chart-sort-btn:hover { background: #f8fafc; }

/* ============================================================
   CALENDAR
   ============================================================ */
.cal-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  /* Sticks below topbar + filters bar; both heights are live CSS vars (see
     .filters note). On mobile the filters bar is static/collapsed, so the
     media query below pins this to the topbar alone. */
  position: sticky; top: calc(var(--topbar-h, 53px) + var(--filters-h, 59px)); z-index: 14;
  background: var(--bg); padding: .6rem 0 .5rem; margin-bottom: 0;
  border-bottom: 1px solid var(--line);
}
.cal-nav { display: flex; align-items: center; gap: .5rem; }
.cal-title { font-size: 1.15rem; min-width: 12rem; text-align: center; cursor: pointer; }
.cal-title:hover { color: var(--brand); }
.cal-nav .btn { padding: .35rem .7rem; font-size: 1rem; line-height: 1; }
.cal-status { margin: 0; }

.cal-weekdays {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px;
  margin-bottom: 6px;
}
.cal-weekdays span {
  font-size: .72rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--muted); text-align: center; padding: .2rem 0;
}
.calendar { display: flex; flex-direction: column; gap: 6px; }

/* One week = a header strip (7 day numbers) + stacked lanes. */
.cal-week { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.cal-lane {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px;
}
/* cal-week-head is now a column container for 3 sub-rows:
   DOW bar → count row → date bar */
.cal-week-head { display: block; padding: 0; }
.cal-daynum {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  font-size: .82rem; font-weight: 600; color: var(--ink); min-height: 1.5rem;
}
.cal-daynum.other { color: #cbd5e1; }
.cal-dow {
  font-size: .6rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--muted); line-height: 1;
}
.cal-daynum.other .cal-dow { color: #cbd5e1; }
/* Date + its show/hide icon on one centred line; icon sits just right of the date. */
.cal-day-line { display: inline-flex; align-items: center; gap: 3px; }
.cal-daynum .dn { display: inline-grid; place-items: center; width: 1.5rem; height: 1.5rem; border-radius: 999px; }
.cal-daynum.today .dn { background: #dc2626; color: #fff; }
/* "Show All" text button on the date line. */
.cal-day-eye {
  padding: 2px 4px; position: relative; top: 1px; color: #cbd5e1;
  font-size: .44rem; font-weight: 400; letter-spacing: .04em; white-space: nowrap;
  user-select: none; -webkit-user-select: none;
  touch-action: none; /* prevent scroll starting on the button during long-press */
}
.cal-day-eye:not([disabled]):hover { color: var(--muted); }
.cal-day-eye:disabled { cursor: default; }
/* A fully-hidden day (and not currently peeked): dim the date number. */
.cal-daynum.day-hidden .dn { opacity: .4; }
/* has-hidden: ≥1 event on this day is hidden — eye active, click to peek. */
.cal-day-eye.has-hidden { color: var(--brand); }
.cal-day-eye.has-hidden:hover { color: var(--brand-d); }
/* day-peeking: hidden events are temporarily revealed — highlight the eye. */
.cal-day-eye.day-peeking { color: var(--brand-d); background: #dcfce7; border-radius: 6px; }
.cal-day-eye.day-peeking:hover { background: #bbf7d0; }

.cal-lanes { padding: 6px; display: flex; flex-direction: column; gap: 6px; }
.cal-empty { padding: .4rem; color: #cbd5e1; font-size: .8rem; text-align: center; }

/* A market occurrence bar — spans its day columns within the week. */
.cal-ev {
  border: 1px solid var(--line); border-left: 4px solid var(--c);
  background: color-mix(in srgb, var(--c) 7%, white);
  border-radius: 8px; padding: .4rem .55rem; cursor: pointer;
  font-size: .78rem; line-height: 1.3; min-width: 0; overflow: hidden;
  box-shadow: var(--shadow); display: flex; flex-direction: column; gap: .15rem;
}
.cal-ev:hover { box-shadow: 0 4px 12px rgba(15,23,42,.14); }
.cal-ev.multi { background: linear-gradient(90deg, color-mix(in srgb, var(--c) 16%, white), color-mix(in srgb, var(--c) 6%, white)); }
/* Peeked bars are normally hidden but temporarily revealed — dashed border + reduced
   saturation signals the "peek" state without being too distracting. */
.cal-ev.peeked { opacity: .75; border-style: dashed; border-left-style: solid; filter: saturate(.65); }
/* Past event bars — muted so future events stand out, but still openable
   (v0.70): historical events must be reachable for revision, so they keep
   pointer events and lift toward full opacity on hover. */
.cal-ev.past { opacity: .38; filter: saturate(.25) brightness(.95); }
.cal-ev.past:hover { opacity: .85; filter: saturate(.6); }

/* Projected bars (v0.70) — a date a venue's pattern predicts that has no Event
   Card yet. Dashed all round on a hatched wash so a real, materialised card is
   unmistakable at a glance. Clicking one offers to create the card. */
.cal-ev.projected {
  border-style: dashed; border-left-style: dashed;
  background:
    repeating-linear-gradient(135deg,
      color-mix(in srgb, var(--c) 9%, white) 0 6px,
      color-mix(in srgb, var(--c) 3%, white) 6px 12px);
  box-shadow: none;
}
.cal-ev.projected:hover {
  border-style: solid; border-left-style: solid;
  box-shadow: 0 4px 12px rgba(15,23,42,.14);
}
.cal-ev.projected .dot { border-style: dashed; }

/* Past day column header — grey date number and label. */
.cal-daynum.past .dn { color: #94a3b8; }
.cal-daynum.past .cal-dow { color: #cbd5e1; }
.cal-daynum.past .cal-day-eye { opacity: .45; }
/* Focused day column header — subtle green underline ring on the date circle. */
.cal-daynum.focused:not(.today) .dn { box-shadow: 0 0 0 2px var(--brand); border-radius: 999px; }
.cal-ev-head { display: flex; align-items: center; gap: .35rem; }
.cal-ev-name { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; }
.cal-ev-town { color: var(--muted); font-weight: 600; }
.cal-ev-row { display: flex; flex-wrap: wrap; gap: .15rem .6rem; color: #475569; }
.cal-ev-row .k { color: var(--muted); }
/* "Pack for" pill — shared by Calendar bars, Directory cards and Pipeline
   cards: a bordered neutral chip so the value reads as its own datum. */
.packfor-pill {
  font-size: .68rem; font-weight: 700; color: #334155;
  background: #f1f5f9; border: 1px solid #cbd5e1; border-radius: 999px;
  padding: .02rem .45rem; white-space: nowrap; align-self: center;
}
/* Calendar placement: right end of the Mkt-timings row, clearly separated
   from the times beside it. */
.cal-ev-packfor { margin-left: auto; }
.cal-ev-span { font-size: .68rem; color: var(--muted); font-weight: 600; }

/* Booked lane — always row 0, reserved exclusively for red-dot (Booked/Paid) events. Empty when none exist. */
.cal-lane-booked { background: #fff; border-radius: 6px; outline: 1.5px dashed #555; min-height: 28px; }
.cal-lane-booked .cal-ev { grid-row: 1; }

/* Booking status dot — three states: empty (hollow), interested (blue), booked (red). */
.dot { width: 12px; height: 12px; border-radius: 999px; flex: 0 0 12px; display: inline-block; cursor: pointer; background: transparent; border: 2px solid rgba(100,116,139,.35); transition: transform .1s; }
.dot:hover { transform: scale(1.3); }
.dot.booked { background: #dc2626; border: none; box-shadow: 0 0 0 2px rgba(220,38,38,.25); }
.dot.interested { background: #3b82f6; border: none; box-shadow: 0 0 0 2px rgba(59,130,246,.25); }

/* ============================================================
   Week head: 3 sub-rows — DOW bar (Row 1) / count row (Row 2) / date bar (Row 3)
   DOW bar and count row share the same .cal-week-daycounts grid so columns align.
   ============================================================ */

/* Row 1 — DOW labels */
.cal-dow-bar {
  display: flex;
  align-items: center;
  padding: 3px 6px 0;
}
/* .cal-dow inside .cal-dow-bar reuses .cal-week-daycounts grid cells */
.cal-dow-bar .cal-dow {
  display: flex; align-items: center; justify-content: center;
  height: 1.1rem; /* same height as .cwdc-cell so centres align */
}
/* State colours for DOW labels (in cal-dow-bar, not inside cal-daynum) */
.cal-dow.other { color: #cbd5e1; }
.cal-dow.past  { color: #cbd5e1; }
/* Invisible spacer matching the chevron button width so DOW columns align with count columns */
.cal-dow-spacer {
  flex: 0 0 auto;
  display: inline-block;
  width: 1.6rem; /* matches .cal-week-toggle-btn total width */
}
/* ⓘ info icon button — sits where the spacer was, same width for alignment */
.cal-info-btn {
  flex: 0 0 auto;
  width: 1.6rem;
  height: 1.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: none;
  padding: 0;
  cursor: pointer;
  color: #94a3b8;
  font-size: 0.82rem;
  border-radius: 3px;
  transition: color .15s;
}
.cal-info-btn:hover { color: var(--brand); }

/* Row 3 (bottom) — count row + chevron */
.cal-week-summary {
  display: flex;
  align-items: center;
  padding: 0 6px 3px;
  border-top: 1px solid var(--line);
  background: #f8fafc;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
}
.cal-week-summary:hover .cwdc-cell.has-events { color: var(--ink); }
.cal-week-daycounts {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
}
.cwdc-cell {
  text-align: center;
  font-size: .65rem;
  font-weight: 600;
  color: transparent; /* zeros invisible */
  line-height: 1;
  height: 1.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.cwdc-cell.has-events { color: var(--muted); }
.cal-week-toggle-btn {
  flex: 0 0 auto;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--muted);
  padding: .1rem .3rem;
  display: flex;
  align-items: center;
  border-radius: 4px;
  line-height: 1;
  transition: color .15s, background .15s;
}
.cal-week-toggle-btn:hover { color: var(--ink); background: rgba(15,23,42,.06); }
.cal-week-toggle-btn svg { display: block; transition: transform .2s ease; }
.cal-week-toggle-btn.expanded svg { transform: rotate(180deg); }

/* Row 2 — date numbers + eye buttons */
.cal-date-bar {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  padding: 4px 6px 2px;
}

/* (The old bespoke .date-picker/.dp-* popup was retired in v0.62 —
   every picker is now the shared .mdp control defined further down.) */

@media (max-width: 720px) {
  .calendar { overflow-x: auto; }
  .cal-week { min-width: 760px; }
  .cal-ev { font-size: .72rem; }
}

/* ============================================================
   DETAIL MODAL
   ============================================================ */
/* Flex + margin:auto centring (not grid place-items:center): a card taller
   than the viewport must clamp to the top and stay reachable by scrolling
   the backdrop — centred overflow clips the close × above the screen top
   (seen on Android). dvh tracks the VISIBLE mobile viewport (vh includes the
   area behind the browser chrome); the vh line is the older-Safari fallback. */
.modal { position: fixed; inset: 0; background: rgba(15,23,42,.5); display: flex; z-index: 50; padding: 1rem; overflow-y: auto; }
.modal-card {
  background: var(--surface); width: 100%; max-width: 960px; max-height: 90vh; max-height: 90dvh; overflow-y: auto;
  margin: auto;
  border-radius: 16px; padding: 1.5rem; position: relative; box-shadow: 0 20px 50px rgba(0,0,0,.3);
  overscroll-behavior: contain;
}

/* Two-column layout for the detail modal on wide screens */
.detail-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  align-items: start;
}
.detail-col { min-width: 0; }
.detail-col:first-child { padding-right: 1.75rem; border-right: 1px solid var(--line); }
.detail-col:last-child  { padding-left: 1.75rem; }
.detail-col:first-child > .detail-panel:first-child,
.detail-col:last-child  > .detail-panel:first-child { margin-top: 0; }
/* Coloured section panels — each section in the detail modal gets its own card */
.detail-panel {
  border-radius: 10px;
  padding: 1rem;
  border: 1px solid var(--line);
  margin-top: 1rem;
}
.detail-panel > h3 {
  font-size: .95rem;
  font-weight: 700;
  margin: 0 0 .6rem;
}
.detail-panel--address { background: #f8fafc; border-color: var(--line); }
.detail-panel--address > h3 { color: var(--text); }
.detail-panel--address .detail-grid { background: none; border: none; border-radius: 0; padding: 0; }
.detail-panel--events  { background: #faf5ff; border-color: #e9d5ff; }
.detail-panel--events > h3  { color: #6b21a8; }
.detail-panel--booking { background: #f0fdfa; border-color: #99f6e4; }
.detail-panel--booking > h3 { color: #0f766e; }
.detail-panel--booking.dot-entry { border: 3px solid #dc2626; box-shadow: 0 0 0 1px #dc2626; }

/* Double-booking conflict panel */
.booking-conflict { background: #fff7ed; border: 1px solid #fed7aa; border-radius: 8px; padding: .75rem; margin-top: .5rem; }
.b-conflict-hdr { font-weight: 700; color: #c2410c; margin: 0 0 .25rem; font-size: .85rem; }
.b-conflict-sub { color: #78350f; font-size: .78rem; margin: 0 0 .65rem; }
.b-conflict-opts { display: flex; gap: .6rem; }
.b-conflict-card { flex: 1; background: #fff; border: 1px solid #e2e8f0; border-radius: 6px; padding: .5rem .6rem; display: flex; flex-direction: column; gap: .3rem; }
.b-conflict-lbl { font-size: .65rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 700; }
.b-conflict-card strong { font-size: .82rem; }
.b-conflict-card .btn { margin-top: .25rem; font-size: .8rem; }

.detail-panel--email   { background: #f0f9ff; border-color: #bae6fd; }
.detail-panel--email > h3   { color: #0369a1; }
.detail-panel--notes   { background: #f7fee7; border-color: #d9f99d; }
.detail-panel--notes > h3   { color: #3f6212; }

/* ---- Organiser detail modal ----
   Same panel layout/structure as the Event Card, but re-skinned so the two
   modals are never mistaken for one another even mid-scroll. */
.modal-card--organiser { border-top: 6px solid var(--organiser-accent); }
.detail-panel--organiser-address { background: var(--organiser-accent-light); border-color: var(--organiser-accent-line); }
.detail-panel--organiser-address > h3 { color: #4338ca; }
.detail-panel--organiser-address .detail-grid { background: none; border: none; border-radius: 0; padding: 0; }
.org-ev-list { display: flex; flex-direction: column; gap: .35rem; max-height: calc(8 * 2.6rem); overflow-y: auto; }
.org-ev-row {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  padding: .45rem .6rem; border: 1px solid var(--line); border-radius: 8px;
  background: #fff; cursor: pointer; font-size: .88rem;
}
.org-ev-row:hover { background: #f8fafc; border-color: var(--organiser-accent-line); }
.org-ev-row .muted { font-size: .78rem; }

/* Organiser Card's Booking Pipeline panel — permanent, but faded/inert until
   at least one event is linked (bookings are keyed to a single market_id). */
.detail-panel--booking.is-empty { opacity: .5; }
/* Address panel action buttons */
.detail-grid-actions { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-top: 1.2rem; }
.detail-grid-actions .btn { flex: 1; justify-content: center; }
.dg-status { font-size: .75rem; color: var(--muted); margin-top: .35rem; margin-bottom: 0; text-align: center; }
/* Wide variant for the completeness editor */
.modal-wide { max-width: min(1200px, 94vw); max-height: 90vh; max-height: 90dvh; display: flex; flex-direction: column; padding: 0; overflow: hidden; }
.edit-modal-head { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.25rem .75rem; border-bottom: 1px solid var(--line); flex-shrink: 0; }
.edit-modal-head h2 { font-size: 1rem; margin: 0; }
.edit-modal-head .modal-close { position: static; }
.edit-modal-body { flex: 1; overflow: auto; padding: .9rem 1.25rem 1.25rem; display: flex; flex-direction: column; gap: .75rem; }

/* Column toggle chips */
.col-toggles { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; flex-shrink: 0; }
.col-toggles-label { font-size: .78rem; color: var(--muted); margin-right: .15rem; }
.col-toggle { font-size: .75rem; padding: .18rem .6rem; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); cursor: pointer; color: var(--muted); transition: background .15s, color .15s; }
.col-toggle.active { background: var(--brand); border-color: var(--brand); color: #fff; }
.col-toggle:hover:not(.active) { background: var(--hover, #f1f5f9); }

/* Spreadsheet table */
.edit-table-wrap { overflow: auto; flex: 1; border: 1px solid var(--line); border-radius: var(--radius); }
.edit-table { border-collapse: collapse; font-size: .82rem; min-width: 100%; }
.edit-table th { background: #f8fafc; border: 1px solid var(--line); padding: .4rem .55rem; text-align: left; white-space: nowrap; position: sticky; top: 0; z-index: 2; font-size: .76rem; text-transform: uppercase; letter-spacing: .02em; color: var(--muted); }
.edit-table td { border: 1px solid var(--line); padding: .28rem .45rem; vertical-align: middle; }
.edit-table tr.row-missing > td { background: #fef3c740; }
.edit-table th.col-focus, .edit-table td.col-focus { background: #eff6ff; }
.edit-table tr.row-missing > td.col-focus { background: #fde68a; }
.et-input { width: 100%; min-width: 80px; border: 1px solid var(--line); border-radius: 4px; padding: .22rem .4rem; font-size: .82rem; background: #fff; font-family: inherit; }
.et-input:focus { outline: 2px solid var(--brand); border-color: transparent; }
/* Column resize handle */
.edit-table th { position: relative; user-select: none; }
.col-resizer { position: absolute; right: 0; top: 0; width: 6px; height: 100%; cursor: col-resize; z-index: 1; }
.col-resizer:hover, .col-resizer:active { background: var(--brand); opacity: .35; }

/* Website link cells */
.ws-td { cursor: pointer; }
.ws-view { font-size: .82rem; min-height: 1.4em; }
.ws-link { color: var(--brand); text-decoration: none; word-break: break-all; }
.ws-link:hover { text-decoration: underline; }
.ws-none { color: var(--muted); font-style: italic; }
.ws-td .ws-input { display: none; width: 100%; }
.ws-td.ws-editing .ws-view { display: none; }
.ws-td.ws-editing .ws-input { display: inline-block; }

/* Auto-save feedback states */
.et-input.et-saving { outline: 2px solid #94a3b8; border-color: transparent; }
.et-input.et-saved  { outline: 2px solid var(--brand); border-color: transparent; transition: outline .4s ease-out; }
.et-input.et-error  { outline: 2px solid #dc2626; border-color: transparent; }

/* Clickable bars / progress rows */
.bar-row.clickable, .prog-row.clickable { cursor: pointer; border-radius: 4px; padding: .1rem .25rem; margin: -.1rem -.25rem; transition: background .12s; }
.bar-row.clickable:hover, .prog-row.clickable:hover { background: var(--hover, #f1f5f9); }

/* Booking funnel panel — whole panel is clickable */
#funnel-panel { cursor: pointer; transition: box-shadow .15s; }
#funnel-panel:hover { box-shadow: 0 0 0 2px var(--brand); }

/* Website column header + Auto Complete button */
.website-th { white-space: nowrap; }
.btn-autocomplete { font-size: .7rem; padding: .18rem .45rem; background: var(--brand); color: #fff; border: none; border-radius: 4px; cursor: pointer; margin-left: .4rem; white-space: nowrap; }
.btn-autocomplete:hover:not(:disabled) { background: var(--brand-d, #15803d); }
.btn-autocomplete:disabled { opacity: .55; cursor: default; }
.modal-close { position: absolute; top: .75rem; right: 1rem; border: 0; background: none; font-size: 1.8rem; line-height: 1; color: var(--muted); cursor: pointer; }
.detail-head { display: flex; justify-content: space-between; border-left: 4px solid; padding-left: .75rem; margin-bottom: 1.5rem; padding-bottom: 1rem; border-bottom: 1px solid var(--line); }
/* Event ⇄ Organiser navigation icons (2026-07-27): → beside the Event Card's
   Organiser field, ← at the front of the Organiser Card header (order:-1 keeps
   the title div as :first-child for its flex rule). Indigo = organiser accent. */
.dl-org-row { display: flex; align-items: center; gap: .4rem; }
.dl-org-row .dl-input { flex: 1 1 auto; min-width: 0; }
.org-goto-btn, .org-back-btn {
  border: 0; background: #eef2ff; color: #4338ca; cursor: pointer;
  border-radius: 8px; display: grid; place-items: center; flex-shrink: 0;
}
.org-goto-btn { width: 1.9rem; height: 1.9rem; }
.org-back-btn { width: 2.1rem; height: 2.1rem; order: -1; align-self: flex-start; margin-right: .6rem; }
.org-goto-btn:hover, .org-back-btn:hover { background: #e0e7ff; }
.org-goto-btn svg { width: 1rem; height: 1rem; }
.org-back-btn svg { width: 1.15rem; height: 1.15rem; }
.detail-head .meta { margin-top: .35rem; }

/* Inline title editor (v0.64) — the ✎ pencil at the end of both modal titles
   swaps the heading for an in-place input with Save / Cancel. */
.title-edit-btn {
  background: none; border: none; cursor: pointer; padding: 0 .2rem;
  font-size: 1.05rem; line-height: 1; color: var(--muted);
  margin-left: .45rem; vertical-align: middle;
}
.title-edit-btn:hover { color: var(--brand-d); }
.title-edit-row { display: inline-flex; align-items: center; gap: .5rem; flex-wrap: wrap; max-width: 100%; }
.title-edit-input {
  font: inherit; font-weight: 700; font-size: 1.05rem;
  padding: .25rem .55rem; border: 1px solid var(--line); border-radius: 8px;
  flex: 1 1 220px; min-width: 0;
}
.title-edit-row .btn { flex: 0 0 auto; }
.title-edit-msg {
  display: block; font-size: .78rem; font-weight: 500; color: #b91c1c;
  margin-top: .35rem; text-transform: none; letter-spacing: 0;
}
.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem 1.25rem; margin-bottom: 0; background: #f8fafc; border: 1px solid var(--line); border-radius: 10px; padding: 1rem 1rem .75rem; }
.detail-grid > div { font-size: .9rem; }
.dl { display: block; font-size: .72rem; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); margin-bottom: .15rem; }
.dl-input { width: 100%; padding: .35rem .5rem; border: 1px solid var(--line); border-radius: 7px; font: inherit; font-size: .9rem; background: #fff; }
.dl-msg { font-size: .72rem; color: var(--brand-d); margin-left: .3rem; }
.dl-website-link { text-transform: none; font-size: .78rem; font-weight: 500; margin-left: .4rem; color: var(--brand); letter-spacing: 0; }
.dl-hint { text-transform: none; letter-spacing: 0; font-weight: 400; font-style: italic; margin-left: .35rem; }
.detail-grid-full { grid-column: 1 / -1; }

.booking-row { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; margin-bottom: 1.2rem; }
.booking-row label { display: flex; flex-direction: column; gap: .25rem; font-size: .78rem; color: var(--muted); }
.booking-row select, .booking-row input { padding: .45rem .55rem; border: 1px solid var(--line); border-radius: 7px; font-size: .9rem; min-width: 0; width: 100%; box-sizing: border-box; }
.booking-actions { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.booking-actions .btn { flex: 1; justify-content: center; }

.note-form { display: flex; gap: .6rem; margin-bottom: .9rem; align-items: flex-start; }
.note-form textarea { flex: 1; padding: .55rem .65rem; border: 1px solid var(--line); border-radius: 8px; font: inherit; resize: vertical; }
.notes-list { display: flex; flex-direction: column; }
.notes-archive-hdr { display: flex; align-items: center; justify-content: space-between; padding: .25rem 0 .4rem; border-bottom: 1px solid var(--line); margin-bottom: .25rem; }
.notes-archive-lbl { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.note-dl-all-btn, .note-dl-btn { background: none; border: none; cursor: pointer; color: var(--muted); padding: .15rem; display: flex; align-items: center; border-radius: 4px; flex-shrink: 0; }
.note-dl-all-btn:hover, .note-dl-btn:hover { color: var(--brand); background: rgba(0,0,0,.05); }
.note-archive-row { display: flex; align-items: center; gap: .4rem; padding: .35rem .3rem; border-radius: 6px; cursor: pointer; font-size: .87rem; min-width: 0; }
.note-archive-row:hover, .note-archive-row.active { background: rgba(0,0,0,.05); }
.note-preview { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.note-ts { font-size: .7rem; color: var(--muted); white-space: nowrap; flex-shrink: 0; }
.note-archive-body { padding: .45rem .45rem .45rem 1.9rem; margin-bottom: .2rem; border-bottom: 1px solid var(--line); }
.note-archive-body p { margin: 0 0 .35rem; font-size: .88rem; white-space: pre-wrap; }
.note-meta { display: flex; align-items: center; gap: .75rem; font-size: .75rem; color: var(--muted); }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 720px) {
  .topbar { gap: .5rem; row-gap: 0; }
  .topbar-actions { display: flex; }

  /* Hamburger drawer — nav tabs + user box (email + sign out) drop below the
     bar, full width, only while the menu is open. */
  .tabs, .user-box { flex-basis: 100%; width: 100%; display: none; order: 5; }
  body.m-nav-open .tabs {
    display: flex; flex-direction: column; gap: .15rem;
    margin-top: .4rem; padding-top: .5rem; border-top: 1px solid var(--line);
  }
  body.m-nav-open .tabs .tab-btn { text-align: left; padding: .6rem .75rem; }
  body.m-nav-open .user-box {
    display: flex; justify-content: space-between;
    margin-top: .4rem; padding-top: .5rem; border-top: 1px solid var(--line);
  }

  /* Search/filter icons only apply on tabs that have filters. */
  .topbar-actions .filters-only { display: none; }
  body.tab-has-filters .topbar-actions .filters-only { display: inline-grid; }

  /* Filters bar collapses behind the filter/search icons; full-width when open. */
  .filters { position: static; top: 0; flex-direction: column; align-items: stretch; }
  .filters:not(.hidden) { display: none; }
  body.m-filters-open .filters:not(.hidden) { display: flex; }
  .filters #f-search, .filters select { width: 100%; min-width: 0; }
  .dir-count { margin-left: 0; }

  /* Filters bar is static here, so the Calendar toolbar ties directly to the
     bottom of the sticky topbar — previously it kept the 112px desktop offset
     and floated mid-screen on iPhone portrait, masking event rows. */
  .cal-toolbar { top: var(--topbar-h, 53px); }

  .detail-grid, .booking-row { grid-template-columns: 1fr; }
  .detail-cols { grid-template-columns: 1fr; }
  .detail-col:first-child { padding-right: 0; border-right: none; }
  .detail-col:last-child  { padding-left: 0; }
  .bar-row, .prog-row { grid-template-columns: 90px 1fr auto; }
  /* On phones the Auto-fill pill takes its own right-aligned line under the bar. */
  .prog-row .btn-autofill, .prog-row .btn-autofill-spacer { grid-column: 1 / -1; justify-self: end; }
  .prog-row .btn-autofill-spacer { display: none; }

  /* Email attachments: the fixed-width label (10rem) + status (8rem) columns
     overflow a phone-width panel — wrap each slot instead: label on its own
     line, then input + Test button, status underneath. */
  .attach-slot { flex-wrap: wrap; }
  .attach-label { flex-basis: 100%; }
  .attach-slot .ef-input { flex: 1 1 auto; min-width: 0; }
  .attach-status { flex-basis: 100%; min-width: 0; }

  .note-form { flex-direction: column; }
  .note-form .btn { width: 100%; }
  #map { height: 60vh; }
}

/* ============================================================
   EMAIL COMPOSE (detail modal)
   ============================================================ */
.email-compose {
  display: flex;
  flex-direction: column;
  gap: .65rem;
}
.email-field {
  display: flex;
  align-items: baseline;
  gap: .6rem;
}
.ef-label {
  flex: 0 0 5rem;
  font-size: .78rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.ef-value { font-size: .9rem; color: var(--ink); }
.ef-from  { color: var(--muted); font-style: italic; font-size: .8rem; padding-left: .7rem; }
.ef-input {
  flex: 1;
  padding: .42rem .7rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: .9rem;
  background: var(--surface);
  color: var(--ink);
  transition: border-color .15s;
}
.ef-input:focus { outline: none; border-color: var(--brand); }
.ef-body-field { align-items: flex-start; }
/* Message label column: MESSAGE label with the "Use text as default" tick box
   stacked beneath it (v0.53). */
.ef-label-stack { flex: 0 0 5rem; display: flex; flex-direction: column; gap: .55rem; }
.ef-label-stack .ef-label { flex: none; }
.ef-default-toggle { display: flex; align-items: flex-start; gap: .3rem; font-size: .68rem; color: var(--muted); cursor: pointer; line-height: 1.35; }
.ef-default-toggle input { margin: .1rem 0 0; flex: none; }
.ef-body {
  flex: 1;
  padding: .5rem .7rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-family: inherit;
  font-size: .88rem;
  line-height: 1.55;
  color: var(--ink);
  background: var(--surface);
  resize: vertical;
  min-height: 180px;
  transition: border-color .15s;
}
.ef-body:focus { outline: none; border-color: var(--brand); }
.email-attachments {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem .9rem;
  padding: .5rem .2rem;
  font-size: .78rem;
}
.email-attachments label {
  display: flex;
  align-items: center;
  gap: .35rem;
  cursor: pointer;
  color: var(--ink);
}
.email-actions {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
}
.email-actions .btn { flex: 1; justify-content: center; }
.em-status        { font-size: .85rem; color: var(--muted); }
.em-status-ok     { color: #15803d; font-weight: 600; }
.em-status-error  { color: #b91c1c; font-weight: 600; }
.email-collapsed .email-compose { display: none; }

/* ============================================================
   ATTACHMENT SLOTS (Dashboard tab)
   ============================================================ */
/* Lives inside .insight-grid, to the right of Data completeness — spans two
   grid slots so the filename inputs keep a usable width. */
.insight-grid .attach-panel { grid-column: span 2; }
/* When the grid collapses to a single column the span would overflow it. */
@media (max-width: 760px) {
  .insight-grid .attach-panel { grid-column: auto; }
}
.attach-slot {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .55rem 0;
  border-bottom: 1px solid var(--line);
}
.attach-slot:last-child { border-bottom: 0; }
.attach-label {
  flex: 0 0 10rem;
  font-size: .88rem;
  font-weight: 600;
  color: var(--ink);
}
.attach-slot .ef-input { flex: 1; }
.attach-test { flex: 0 0 auto; white-space: nowrap; }
.attach-status { font-size: .82rem; min-width: 8rem; color: var(--muted); }

/* ============================================================
   ADD A CARD — FAB + MODAL
   ============================================================ */

/* Floating action button */
.fab {
  position: fixed;
  bottom: 2rem;
  right: 2rem;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  border: none;
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(21,128,61,.35);
  z-index: 40;
  display: grid;
  place-items: center;
  transition: transform .15s, box-shadow .15s, background .15s;
  padding: 0;
}
.fab:hover {
  background: var(--brand-d);
  transform: scale(1.1);
  box-shadow: 0 6px 24px rgba(21,128,61,.45);
}

/* "Add a Card" modal */
.add-modal-card { max-width: 440px; }
.add-modal-title {
  margin: 0 0 1.25rem;
  font-size: 1.1rem;
  padding-right: 2rem;
}
.add-form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .7rem 1rem;
}
.add-field { display: flex; flex-direction: column; gap: .3rem; }
.add-field-full { grid-column: 1 / -1; }
.add-label { font-size: .8rem; color: var(--muted); font-weight: 500; }
.add-req { color: #dc2626; }
.add-input {
  padding: .45rem .7rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: .9rem;
  font-family: inherit;
  color: var(--ink);
  background: var(--surface);
  width: 100%;
}
.add-input:focus {
  outline: 2px solid var(--brand);
  outline-offset: 1px;
  border-color: var(--brand);
}
.add-form-actions {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin-top: 1.1rem;
  flex-wrap: wrap;
}
.am-status { font-size: .82rem; color: var(--muted); margin: .4rem 0 0; }
.am-status.am-ok  { color: #16a34a; }
.am-status.am-err { color: #dc2626; }

/* Source-powered cards (v0.51) — URL/image drop box, activity spinner, missing-field nudge */
.add-hint { font-size: .72rem; color: var(--muted); line-height: 1.35; }
.add-drop {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: .6rem;
  min-height: 130px;
  padding: .8rem;
  border: 2px dashed var(--line);
  border-radius: 10px;
  background: var(--surface);
}
.add-drop.drag-over {
  border-color: var(--brand);
  background: color-mix(in srgb, var(--brand) 7%, var(--surface));
}
.add-drop-label {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .7rem;
  color: var(--muted);
  font-size: .85rem;
}
.add-drop-browse {
  flex: 0 0 auto;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  padding: .45rem .7rem;
  font-size: 1.7rem;
  cursor: pointer;
  line-height: 1;
}
.add-drop-browse:hover { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 6%, var(--surface)); }
.add-img-chip {
  display: flex;
  align-items: center;
  gap: .7rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .4rem .6rem;
  min-width: 0;
}
.add-img-chip img { width: 72px; height: 72px; object-fit: cover; border-radius: 6px; flex: 0 0 auto; }
.add-img-chip span {
  font-size: .82rem; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.add-img-chip button {
  margin-left: auto; flex: 0 0 auto;
  background: none; border: 0; cursor: pointer;
  font-size: 1.1rem; color: var(--muted); line-height: 1; padding: .1rem .3rem;
}
.add-img-chip button:hover { color: #dc2626; }
.am-status.am-busy::before {
  content: "";
  display: inline-block;
  width: 13px; height: 13px;
  margin-right: .45rem;
  vertical-align: -2px;
  border: 2px solid var(--brand);
  border-top-color: transparent;
  border-radius: 50%;
  animation: am-spin .8s linear infinite;
}
@keyframes am-spin { to { transform: rotate(360deg); } }
.add-input.add-missing {
  border-color: #dc2626;
  box-shadow: 0 0 0 2px rgba(220, 38, 38, .12);
}

/* Add-a-Card fuzzy duplicate chooser */
.am-dup-panel {
  margin-top: .8rem;
  border: 1px solid #f59e0b;
  background: #fffbeb;
  border-radius: 10px;
  padding: .7rem .8rem;
}
.am-dup-title { margin: 0 0 .6rem; font-size: .85rem; font-weight: 600; color: #92400e; }
.am-dup-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .6rem;
  flex-wrap: wrap;
  padding: .45rem 0;
  border-top: 1px solid #fde68a;
}
.am-dup-info { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; min-width: 0; }
.am-dup-meta { font-size: .78rem; color: var(--muted); }
.am-dup-actions { display: flex; gap: .4rem; flex: 0 0 auto; }
.am-dup-global {
  display: flex;
  gap: .5rem;
  flex-wrap: wrap;
  margin-top: .6rem;
  padding-top: .6rem;
  border-top: 1px solid #fde68a;
}

/* Bin icon on Directory cards */
.card-del-btn {
  background: none;
  border: 0;
  padding: .2rem .25rem;
  cursor: pointer;
  color: var(--muted);
  border-radius: 4px;
  line-height: 1;
  opacity: 0;
  transition: opacity .15s, color .15s;
  flex-shrink: 0;
}
.market-card:hover .card-del-btn,
.organiser-card:hover .card-del-btn { opacity: 1; }
.card-del-btn:hover { color: #b91c1c; }

/* ============================================================
   PRINT
   ============================================================ */
@media print {
  /* Hide all navigation chrome so only the active tab content prints. */
  .topbar, #filters, .modal, #login-screen { display: none !important; }
  /* Remove sticky positioning so pages flow naturally. */
  .topbar, #filters { position: static; }
  /* Let content fill the page. */
  .content { padding: 0; max-width: 100%; }
  /* Calendar: keep week rows together where possible. */
  .cal-week { page-break-inside: avoid; break-inside: avoid; }
  /* Pipeline: keep columns together. */
  .kcol { page-break-inside: avoid; break-inside: avoid; }
  /* Remove shadows and hover effects. */
  * { box-shadow: none !important; }
}

/* ============================================================
   IMPORT / EXPORT (impex.js) — v0.46
   ============================================================ */
.impex-export-card { max-width: 520px; }
.impex-import-card { max-width: min(980px, 94vw); max-height: 92vh; overflow-y: auto; }

.impex-ds-toggle { margin-bottom: 1rem; }
.impex-filter-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem 1rem; margin-bottom: .75rem; }
.impex-filter-grid .add-input { margin-top: .25rem; width: 100%; }
.impex-disabled { opacity: .45; pointer-events: none; }

/* Step indicator */
.impex-steps { display: flex; align-items: center; flex-wrap: wrap; gap: .35rem; margin: .25rem 0 1rem; font-size: .82rem; color: var(--muted); }
.impex-step { padding: .2rem .6rem; border-radius: 999px; background: #f1f5f9; }
.impex-step-cur { background: var(--brand); color: #fff; font-weight: 700; }
.impex-step-done { background: #dcfce7; color: var(--brand-d); }
.impex-step-sep { color: #cbd5e1; }

/* Dropzone */
.impex-drop { border: 2px dashed var(--line); border-radius: var(--radius); padding: 2.2rem 1rem; text-align: center; transition: border-color .15s, background .15s; }
.impex-drop-hot { border-color: var(--brand); background: #f0fdf4; }
.impex-browse { display: inline-block; margin: .5rem 0; cursor: pointer; }
.impex-drop .hint { margin: .75rem auto 0; max-width: 46ch; }

/* Mapping / preview tables */
.impex-scroll { overflow: auto; max-height: 42vh; border: 1px solid var(--line); border-radius: 8px; }
.impex-scroll-tall { max-height: 48vh; }
.impex-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.impex-table th { position: sticky; top: 0; background: #f8fafc; text-align: left; padding: .5rem .65rem; border-bottom: 1px solid var(--line); font-size: .75rem; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); z-index: 1; }
.impex-table td { padding: .45rem .65rem; border-bottom: 1px solid #f1f5f9; vertical-align: top; }
.impex-row-warn { background: #fffbeb; }
.impex-row-off { opacity: .45; }
.impex-src { font-weight: 700; }
.impex-samples span { display: block; color: var(--muted); font-size: .78rem; max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.impex-target { width: 100%; min-width: 160px; }
.impex-note { color: var(--muted); font-size: .74rem; margin-top: .15rem; }
.impex-empty-note { color: var(--muted); font-size: .8rem; font-style: italic; }
.impex-ok-note { color: var(--brand-d); font-size: .8rem; }

/* Confidence badges */
.impex-conf { display: inline-block; font-size: .72rem; font-weight: 700; padding: .18rem .55rem; border-radius: 999px; white-space: nowrap; }
.impex-conf-ok { background: #dcfce7; color: var(--brand-d); }
.impex-conf-warn { background: #fef3c7; color: #92400e; border: 1px solid #fbbf24; cursor: pointer; }
.impex-conf-warn:hover { background: #fde68a; }
.impex-conf-skip { background: #f1f5f9; color: var(--muted); }
.impex-conf-new { background: var(--organiser-accent-light); color: var(--organiser-accent); }

/* New DB columns panel — deliberately its own bordered box (separate panel). */
.impex-newcols { border: 1px solid var(--organiser-accent-line); background: var(--organiser-accent-light); border-radius: var(--radius); padding: .75rem 1rem; margin: 1rem 0; }
.impex-newcols h4 { margin: 0 0 .5rem; font-size: .9rem; color: var(--organiser-accent); }
.impex-newcols-sub { font-weight: 400; color: var(--muted); font-size: .78rem; }
.impex-newcol-row { display: flex; align-items: center; gap: .5rem; margin: .35rem 0; }
.impex-newcol-name { max-width: 240px; font-family: ui-monospace, monospace; font-size: .82rem; }
.impex-newcol-del { padding: .15rem .5rem; }
.impex-arrow { color: var(--muted); }

.impex-problems p { color: #92400e; background: #fef3c7; border-radius: 6px; padding: .35rem .6rem; margin: .3rem 0; font-size: .82rem; }

/* Preview: type + issues */
.impex-type-sel { border-radius: 999px; font-size: .74rem; font-weight: 700; padding: .18rem .4rem; border: 1px solid var(--line); }
.impex-type-event { background: #dcfce7; color: var(--brand-d); }
.impex-type-organiser { background: var(--organiser-accent-light); color: var(--organiser-accent); }
.impex-type-unsure { border: 2px solid #fbbf24; }
.impex-issues { max-width: 34ch; }
.impex-issue { display: block; font-size: .76rem; color: #92400e; margin: .12rem 0; }
.impex-issue-err { color: #b91c1c; font-weight: 700; }
.impex-dup { display: block; font-size: .78rem; margin: .2rem 0; }
.impex-dup-ask { color: #92400e; }
.impex-dup-btns { display: inline-flex; gap: .35rem; margin-left: .3rem; }
.impex-dup-btn { font-size: .72rem; padding: .12rem .5rem; border-radius: 999px; border: 1px solid var(--line); background: #fff; cursor: pointer; }
.impex-dup-btn:hover { background: #f8fafc; }
.impex-dup-on { background: var(--brand); border-color: var(--brand); color: #fff; }
.impex-pending { color: #92400e; font-weight: 700; }

/* Dashboard "Manage filter lists" panel (v0.53) */
.vocab-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1rem; }
.vocab-col h4 { margin: 0 0 .45rem; font-size: .82rem; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.vocab-list { border: 1px solid var(--line); border-radius: 8px; padding: .25rem .4rem; max-height: 240px; overflow: auto; }
.vocab-row { display: flex; align-items: center; gap: .45rem; padding: .28rem .3rem; border-bottom: 1px solid #f1f5f9; font-size: .85rem; }
.vocab-row:last-child { border-bottom: none; }
.vocab-val { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.vocab-count { font-size: .7rem; color: var(--muted); white-space: nowrap; }
.vocab-btn { border: 1px solid var(--line); background: #fff; border-radius: 6px; font-size: .75rem; padding: .1rem .4rem; cursor: pointer; }
.vocab-btn:hover { background: #f8fafc; }
.vocab-btn-del:hover { background: #fef2f2; border-color: #fca5a5; }
.vocab-rename-input { flex: 1; min-width: 0; font-size: .85rem; padding: .15rem .4rem; }
.vocab-add { display: flex; gap: .45rem; margin-top: .5rem; }
.vocab-add .dl-input { flex: 1; min-width: 0; }

/* Global Select All bar on the preview step (v0.53) */
.impex-selall-bar { display: flex; flex-wrap: wrap; gap: .35rem 1.1rem; align-items: center; margin: .35rem 0 .5rem; padding: .4rem .6rem; border: 1px solid var(--line); border-radius: 8px; background: #f8fafc; font-size: .8rem; }
.impex-selall-bar label { display: inline-flex; gap: .35rem; align-items: center; cursor: pointer; white-space: nowrap; }
.impex-selall-bar input:disabled + *, .impex-selall-bar label:has(input:disabled) { opacity: .45; cursor: default; }
.impex-selall-busy { opacity: .55; }

/* Saved import maps bar (v0.67) — dropdown · Use · name · Save · delete */
.impex-maps-bar { display: flex; flex-wrap: wrap; gap: .45rem; align-items: center; margin: .45rem 0 .6rem; padding: .45rem .6rem; border: 1px solid var(--line); border-radius: 8px; background: #f8fafc; }
.impex-maps-bar select { max-width: 220px; }
.impex-map-name { width: 170px; }
.impex-maps-bar .btn { white-space: nowrap; }
.impex-map-offer { margin: .15rem 0 .5rem; padding: .35rem .6rem; font-size: .8rem; color: #1e40af; background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 6px; }
.impex-map-confirm { margin: .15rem 0 .5rem; padding: .35rem .6rem; font-size: .8rem; color: #92400e; background: #fef3c7; border: 1px solid #fbbf24; border-radius: 6px; display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.impex-map-msg { margin: .15rem 0 .5rem; font-size: .8rem; color: #166534; }
.impex-map-msg-err { color: #b91c1c; }

/* "Update existing" confirmation lists (v0.53) — overwrites + blank-clears */
.impex-upd-confirm { margin-top: .9rem; padding: .7rem .85rem; border: 1px solid #fcd34d; background: #fffbeb; border-radius: 10px; }
.impex-upd-confirm h4 { margin: 0 0 .5rem; font-size: .85rem; color: #92400e; }
.impex-upd-list { margin: .55rem 0 0; padding: .5rem .6rem; border: 1px solid var(--line); border-radius: 8px; background: #fff; }
.impex-upd-head { display: flex; flex-wrap: wrap; gap: .25rem .75rem; align-items: baseline; margin-bottom: .3rem; }
.impex-upd-head label { font-size: .8rem; cursor: pointer; }
.impex-upd-item { display: flex; gap: .45rem; align-items: baseline; font-size: .78rem; padding: .18rem 0 .18rem .9rem; cursor: pointer; }
.impex-upd-item:hover { background: #f8fafc; }

/* Run log + summary */
.impex-runlog { max-height: 38vh; overflow: auto; border: 1px solid var(--line); border-radius: 8px; padding: .5rem .75rem; font-size: .82rem; }
.impex-runlog p { margin: .2rem 0; }
.impex-log-err { color: #b91c1c; }
.impex-summary { margin-top: 1rem; padding-top: .75rem; border-top: 1px solid var(--line); }

/* Blocked-but-clickable wizard buttons + attention flash (v0.46 UX fix) */
.impex-btn-blocked { opacity: .55; cursor: not-allowed; }
.impex-flash { animation: impex-flash-kf 1.2s ease-out 2; }
@keyframes impex-flash-kf {
  0% { background: #fef3c7; box-shadow: 0 0 0 3px #fbbf24; }
  100% { background: transparent; box-shadow: none; }
}
.impex-problems-inline { color: #92400e; background: #fef3c7; border: 1px solid #fbbf24; border-radius: 6px; padding: .4rem .6rem; margin: .5rem 0 0; font-size: .8rem; }
.impex-problems-inline code { background: #fde68a; padding: 0 .25rem; border-radius: 3px; }
.impex-newcol-fixed { font-family: ui-monospace, monospace; font-size: .85rem; background: #fff; border: 1px solid var(--organiser-accent-line); border-radius: 6px; padding: .3rem .55rem; }
.impex-newcol-add { padding: .3rem .8rem; }

/* ============================================================
   STAR RATING WIDGET (Event Card + Organiser Card)
   ============================================================ */
.star-widget { display: inline-flex; gap: 1px; font-size: .85rem; line-height: 1; }
.star-widget .star { color: var(--line); }
.star-widget .star-filled { color: #f59e0b; }
.star-interactive { font-size: 1.15rem; gap: 2px; }
.star-interactive .star { cursor: pointer; transition: transform .1s; }
.star-interactive .star:hover { transform: scale(1.2); }
.detail-star-row { flex: 0 0 auto; align-self: flex-start; padding-top: .1rem; }

/* ============================================================
   DASHBOARD TAB — "Add a field" panel
   ============================================================ */
/* .fields-panel vertical spacing comes from the shared #tab-dashboard > .panel rule */
.fields-form { display: flex; align-items: flex-end; gap: .75rem; flex-wrap: wrap; }
.fields-form .add-label { display: flex; flex-direction: column; gap: .3rem; }
.fields-form #fp-add { flex: 0 0 auto; }
.dg-status-ok  { color: #15803d; }
.dg-status-err { color: #b91c1c; }

/* ============================================================
   DASHBOARD TAB — "Find & replace" panel (v0.55)
   ============================================================ */
/* Shared subtitle style — Card Types / Find / Replace With / field-group headings */
.fr-sub { margin: 0; font-size: .82rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.fr-scope { display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; margin: 0 0 .8rem; font-size: .85rem; }
.fr-scope label { display: flex; gap: .35rem; align-items: center; cursor: pointer; }
.fr-block { display: flex; flex-direction: column; gap: .4rem; margin: 0 0 .9rem; }
.fr-block > .add-input { max-width: 560px; }
.fr-matchopts { display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; font-size: .85rem; }
.fr-matchopts label { display: flex; gap: .35rem; align-items: center; cursor: pointer; }
.fr-refines { display: flex; flex-direction: column; gap: .4rem; margin-top: .35rem; }
.fr-refine-hint { margin: 0; font-size: .78rem; color: var(--muted); }
.fr-refine { display: flex; gap: .5rem; flex-wrap: wrap; max-width: 560px; }
.fr-refine select { flex: 0 1 200px; }
.fr-refine input { flex: 1 1 180px; min-width: 0; }
.fr-fields-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1rem; }
.fr-master { display: flex; gap: .4rem; align-items: center; cursor: pointer; margin-bottom: .45rem; }
.fr-field-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .2rem .75rem; border: 1px solid var(--line); border-radius: 8px; padding: .5rem .6rem; font-size: .85rem; }
.fr-field-list label { display: flex; gap: .35rem; align-items: center; cursor: pointer; overflow-wrap: anywhere; }
.fr-actions { display: flex; gap: .6rem; margin-top: .85rem; }

/* ============================================================
   IMPORT — Data conversion ("if this then that"), expandable per column
   ============================================================ */
.impex-rule-row { display: flex; align-items: flex-start; gap: .5rem; margin: .4rem 0; flex-wrap: wrap; }
.impex-rule-if { font-size: .78rem; color: var(--muted); font-style: italic; padding-top: .45rem; }
.impex-rule-row .impex-arrow { padding-top: .4rem; }
.impex-rule-matches { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; flex: 1; min-width: 14rem; }
.impex-chip {
  display: inline-flex; align-items: center; gap: .2rem;
  background: #fff; border: 1px solid var(--brand); color: var(--brand);
  border-radius: 999px; padding: .15rem .3rem .15rem .6rem;
  font-size: .78rem; font-weight: 600;
}
.impex-chip-x { border: none; background: none; cursor: pointer; color: inherit; font-size: .95rem; line-height: 1; padding: 0 .15rem; }
.impex-chip-x:hover { color: #b91c1c; }
.impex-rule-addsel { max-width: 11rem; font-size: .78rem; width: auto; }
.impex-rule-addtxt { max-width: 10rem; font-size: .78rem; width: auto; }
.impex-rule-out { max-width: 10rem; width: auto; }
.impex-rule-outtxt { max-width: 12rem; width: auto; }
.impex-rule-del { padding: .2rem .5rem; font-size: .75rem; }
.impex-rule-add { margin-top: .4rem; font-size: .78rem; padding: .25rem .6rem; }
.impex-target-wrap { display: flex; align-items: center; gap: .3rem; }
.impex-target-wrap .impex-target { flex: 1; min-width: 8rem; width: auto; }
.impex-conv-btn {
  flex: 0 0 auto;
  border: 1px solid var(--line); background: #fff; border-radius: 6px;
  cursor: pointer; padding: .2rem .45rem;
  font-size: .85rem; line-height: 1;
}
.impex-conv-btn:hover { background: #f8fafc; }
.impex-conv-active { border-color: var(--brand); color: var(--brand); }
.impex-conv-warn { border-color: #fbbf24; background: #fef3c7; color: #92400e; }
.impex-conv-openbtn { background: var(--brand); border-color: var(--brand); color: #fff; }
.impex-concat-on { background: var(--brand); border-color: var(--brand); color: #fff; }
.impex-conv-row td { padding: 0 .5rem .5rem; }
.impex-conv-box { border: 1px dashed var(--line); border-radius: 8px; padding: .5rem .75rem; background: #f8fafc; }
.impex-conv-title { margin: 0 0 .4rem; font-size: .78rem; color: var(--muted); }
.impex-conv-star-note { display: block; margin-top: .15rem; color: #92400e; }

/* Star semantics reminder next to the interactive widget */
.star-hint { display: block; font-size: .68rem; color: var(--muted); text-align: right; margin-top: .2rem; }

/* Compact "4★" badge — sits under the HIDE pill on cards + calendar bars */
.ctr-stack { display: flex; flex-direction: column; align-items: center; gap: .15rem; }
/* Directory-card variant: HIDE / star / group pill, right-aligned as a stack
   (the group chip is the widest element, so the others hug the right edge). */
.ctr-stack-grouped { align-items: flex-end; }
/* Base fallback for the card group pill — the real colours come from the
   groupChipStyle() inline style (hashed per group name), which overrides this. */
.chip-cardgroup { background: #e2e8f0; color: #334155; }
.star-badge {
  font-size: .72rem; font-weight: 700; color: #b45309;
  background: #fffbeb; border: 1px solid #fde68a; border-radius: 999px;
  padding: .05rem .45rem; line-height: 1.3; white-space: nowrap;
}

/* Prominent Star Rating block at the top of the Event Card's Address panel */
.detail-star-block {
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  background: #fffbeb; border: 1px solid #fde68a; border-radius: 8px;
  padding: .5rem .75rem; margin: .25rem 0 .75rem;
}
.detail-star-label { font-size: .72rem; font-weight: 700; letter-spacing: .03em; color: #92400e; }
.detail-star-block .star-interactive { font-size: 1.6rem; }

/* ============================================================
   Seed Search panel — Dashboard tab (docs/prd-seed-search.md)
   ============================================================ */
.seed-panel { margin-bottom: 1rem; }
.seed-prompt { width: 100%; resize: vertical; min-height: 3.2rem; margin-top: .25rem; }
.seed-controls { display: flex; align-items: center; gap: .75rem; margin-top: .6rem; flex-wrap: wrap; }
.seed-cap-label { display: flex; align-items: center; gap: .4rem; font-size: .8rem; color: var(--muted); }
.seed-cap { width: 4.5rem; }
.seed-last { margin-top: .6rem; }
.seed-run-prompt { font-weight: 600; font-size: .9rem; margin: .25rem 0 .6rem; }
.seed-phase { font-size: .8rem; color: var(--muted); margin: .4rem 0 0; }
.seed-run-stats { display: flex; justify-content: space-between; font-size: .78rem; color: var(--muted); margin-top: .3rem; }
.seed-progress-track { height: 8px; background: #e2e8f0; border-radius: 999px; overflow: hidden; }
.seed-progress-fill { height: 100%; background: #0ea5e9; border-radius: 999px; transition: width .5s ease; }
.seed-gate-head { font-size: .82rem; color: var(--muted); margin: .25rem 0 .6rem; }

/* Candidate rows (gate 1) — one label per row so the whole row toggles the tick */
.seed-cand-list { display: flex; flex-direction: column; gap: .3rem; max-height: 22rem; overflow-y: auto; }
.seed-cand-row {
  display: flex; align-items: center; gap: .55rem; cursor: pointer;
  padding: .35rem .55rem; border: 1px solid #e2e8f0; border-radius: 8px;
  font-size: .84rem; background: #fff;
}
.seed-cand-row:hover { background: #f8fafc; }
.seed-cand-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.seed-cand-conf { font-weight: 700; font-size: .78rem; color: #0369a1; }
.seed-kind {
  font-size: .62rem; font-weight: 800; letter-spacing: .04em;
  border-radius: 4px; padding: .1rem .35rem; white-space: nowrap;
}
.seed-kind-event { color: #166534; background: #dcfce7; }
.seed-kind-organiser { color: #3730a3; background: #e0e7ff; }
.seed-dedup {
  font-size: .68rem; color: var(--muted); background: #f1f5f9;
  border-radius: 999px; padding: .08rem .5rem; white-space: nowrap;
}
.seed-dedup-update { color: #92400e; background: #fef3c7; border: 1px solid #fde68a; }

/* Seed Search — gate 2 (final confirmation) */
.seed-g2-list { display: flex; flex-direction: column; gap: .6rem; max-height: 30rem; overflow-y: auto; }
.seed-g2-card { border: 1px solid #e2e8f0; border-radius: 10px; padding: .6rem .75rem; background: #fff; }
.seed-g2-failed { background: #fafaf9; }
.seed-g2-bad { border-color: #dc2626; box-shadow: 0 0 0 2px #fecaca; }
.seed-g2-head { display: flex; align-items: center; gap: .55rem; }
.seed-g2-title { flex: 1; min-width: 8rem; font-weight: 600; }
.seed-g2-refined { font-size: .72rem; padding: .25rem .5rem; white-space: nowrap; }
.seed-g2-meta { display: flex; align-items: center; flex-wrap: wrap; gap: .6rem; margin-top: .45rem; }
.seed-g2-count { font-size: .74rem; font-weight: 700; color: #0369a1; }
.seed-g2-sel { display: flex; align-items: center; gap: .35rem; font-size: .74rem; color: var(--muted); }
.seed-g2-sel .add-input { padding: .2rem .4rem; font-size: .78rem; width: auto; }
.seed-g2-details { margin-top: .45rem; font-size: .78rem; }
.seed-g2-details summary { cursor: pointer; color: var(--muted); }
.seed-g2-fields { display: grid; grid-template-columns: auto 1fr; gap: .15rem .8rem; margin: .4rem 0 0; }
.seed-g2-fields dt { color: var(--muted); text-transform: capitalize; }
.seed-g2-fields dd { margin: 0; overflow-wrap: anywhere; }

/* ---- v0.62: multi-day bookings, greyed group blocks, date range add ---- */
/* A multi-day calendar block with ≥1 booked day stays in place, greyed out;
   its booked days appear as their own single-day bars in the red lane. */
.cal-ev.greyed { filter: grayscale(1); opacity: .62; }
.cal-ev.greyed .cal-ev-name { color: #64748b; }

/* Address-panel labels that carry an info icon: the icon sits right-justified
   on the same horizontal centre line as the subtitle text. */
.dl-info { display: flex; align-items: center; }
.dl-info .cal-info-btn { margin-left: auto; }

/* Shared multi-date picker (Events add + Booking panel) —
   tap toggles a day, dragging sweeps a consecutive run. */
.mdp { position: relative; display: inline-block; min-width: 165px; flex: 1; }
.mdp-field { display: flex; align-items: stretch; width: 100%; }
.mdp-input { flex: 1; min-width: 0; border-top-right-radius: 0; border-bottom-right-radius: 0; }
.mdp-input.bad { border-color: #dc2626; background: #fef2f2; }
.mdp-btn { border: 1px solid #cbd5e1; border-left: 0; background: #f8fafc; border-radius: 0 8px 8px 0; cursor: pointer; padding: 0 .5rem; font-size: .85rem; line-height: 1; }
.mdp-btn:hover { background: #e2e8f0; }
.mdp-pop { position: fixed; z-index: 80; background: #fff; border: 1px solid #cbd5e1; border-radius: 10px; box-shadow: 0 8px 24px rgba(15, 23, 42, .18); padding: .55rem; width: 240px; }
.mdp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .35rem; }
.mdp-title { font-size: .8rem; font-weight: 600; }
.mdp-nav { border: 0; background: none; cursor: pointer; font-size: 1.05rem; padding: .1rem .5rem; }
.mdp-dow, .mdp-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.mdp-dow span { font-size: .62rem; color: #64748b; text-align: center; }
.mdp-grid { touch-action: none; }
.mdp-day { border: 0; background: none; border-radius: 6px; font-size: .74rem; padding: .3rem 0; cursor: pointer; }
.mdp-day:hover { background: #e2e8f0; }
.mdp-day.past { color: #94a3b8; }
.mdp-day.today { color: #dc2626; font-weight: 700; }
.mdp-day.sel { background: #2563eb; color: #fff; }
.mdp-day.sel.past { color: #e2e8f0; }
.mdp-foot { display: flex; justify-content: space-between; align-items: center; margin-top: .4rem; gap: .5rem; }
.mdp-hint { font-size: .62rem; color: #94a3b8; }
.mdp-clear { border: 0; background: none; color: #2563eb; cursor: pointer; font-size: .72rem; }

/* Multi-date conflict panel */
.b-conflict-list { margin: .3rem 0 .5rem; padding-left: 1.1rem; font-size: .82rem; }
.b-conflict-opts-multi { display: flex; flex-direction: column; gap: .35rem; }

/* ============================================================
   Revenue (v0.63) — Dashboard Revenue panel + Event Card revenue cards
   ============================================================ */
/* First panel on the Dashboard tab — cancel the shared stacked-panel
   margin-top (nothing above it) and keep the KPI row's rhythm below. */
#tab-dashboard > .revenue-panel { margin-top: 0; margin-bottom: 1.25rem; }

.rev-controls { display: flex; align-items: flex-end; gap: .9rem; flex-wrap: wrap; margin-bottom: .6rem; }
.rev-ctl { display: flex; flex-direction: column; gap: .3rem; font-size: .72rem; font-weight: 600; color: #475569; text-transform: uppercase; letter-spacing: .03em; }
.rev-ctl input { width: 110px; padding: .35rem .5rem; border: 1px solid var(--line); border-radius: 7px; font: inherit; font-size: .9rem; background: #fff; text-transform: none; letter-spacing: 0; font-weight: 400; }
.rev-ctl .mdp { min-width: 165px; flex: 0 1 auto; }
.rev-controls #rev-export { margin-left: auto; }
.rev-period { font-size: .78rem; margin: 0 0 .8rem; }

.rev-metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: .75rem; }
.rev-metric {
  border: 1px solid var(--line); border-radius: var(--radius); background: #f8fafc;
  padding: .7rem .8rem; display: flex; flex-direction: column; gap: .1rem; align-items: flex-start;
  cursor: pointer; font: inherit; text-align: left; transition: box-shadow .15s, border-color .15s;
}
.rev-metric:hover { border-color: #94a3b8; box-shadow: var(--shadow); }
.rev-metric.active { border-color: var(--brand); background: #f0fdf4; box-shadow: var(--shadow); }
.rev-metric .rev-v { font-size: 1.35rem; font-weight: 800; color: var(--brand-d); font-variant-numeric: tabular-nums; }
.rev-metric .rev-v.neg { color: #b91c1c; }
.rev-metric .rev-k { font-size: .74rem; font-weight: 600; color: #475569; }
.rev-metric.rev-profit { background: #fefce8; }
.rev-metric.rev-profit.active { background: #fef9c3; }

.rev-breakdown-head { display: flex; align-items: center; justify-content: space-between; margin: .9rem 0 .4rem; }
.rev-breakdown-head h4 { font-size: .85rem; }
.rev-table-box { overflow-x: auto; border: 1px solid var(--line); border-radius: 8px; }
.rev-table { width: 100%; border-collapse: collapse; font-size: .8rem; }
.rev-table th { text-align: left; background: #f1f5f9; padding: .4rem .6rem; font-size: .7rem; text-transform: uppercase; letter-spacing: .03em; color: #475569; }
.rev-table td { padding: .35rem .6rem; border-top: 1px solid var(--line); }
.rev-table td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.rev-table tfoot td { font-weight: 700; background: #f8fafc; }
.rev-table .rev-empty { color: var(--muted); text-align: center; padding: .8rem; }
.rev-note { font-size: .78rem; color: #475569; margin: .5rem 0 .4rem; }
.rev-note-click { cursor: pointer; color: #b45309; }
.rev-note-click:hover { text-decoration: underline; }
.rev-cell-input { width: 110px; padding: .25rem .4rem; border: 1px solid var(--line); border-radius: 6px; font: inherit; font-size: .8rem; }

/* Event Card revenue cards — one per Booked/Paid date, bottom of the
   Booking pipeline panel. */
.rev-card { border: 1px solid var(--line); border-radius: 8px; background: #f8fafc; padding: .6rem .7rem; margin-top: .55rem; }
.rev-card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .45rem; }
.rev-card-date { font-size: .8rem; font-weight: 700; color: var(--brand-d); }
.rev-card-del { border: 0; background: none; cursor: pointer; color: #94a3b8; padding: .15rem; line-height: 0; }
.rev-card-del:hover { color: #b91c1c; }
/* ⟳ recalc-mileage button in the Revenue section header */
.rev-refresh { border: 0; background: none; cursor: pointer; color: var(--muted); padding: .15rem; line-height: 0; border-radius: 4px; flex-shrink: 0; }
.rev-refresh:hover { color: #0f172a; }
.rev-refresh:disabled { opacity: .45; cursor: default; }
.rev-refresh svg { width: .9rem; height: .9rem; }
.rev-card-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem .8rem; }
.rev-card-grid label { display: flex; flex-direction: column; gap: .25rem; font-size: .68rem; font-weight: 600; color: #475569; text-transform: uppercase; letter-spacing: .03em; }
.rev-card-grid input { padding: .3rem .45rem; border: 1px solid var(--line); border-radius: 6px; font: inherit; font-size: .85rem; background: #fff; }
.rev-mileage { display: flex; flex-direction: column; gap: .25rem; font-size: .8rem; }
.rev-mileage .rev-lbl { font-size: .68rem; font-weight: 600; color: #475569; text-transform: uppercase; letter-spacing: .03em; }
.rev-restore { border: 0; background: none; color: #2563eb; cursor: pointer; font-size: .75rem; text-decoration: underline; padding: 0 .15rem; }

/* Revenue export modal */
.rev-export-card { max-width: 440px; }
.rev-exp-opt { display: flex; gap: .5rem; align-items: flex-start; font-size: .85rem; padding: .45rem .3rem; cursor: pointer; }
.rev-exp-opt input { margin-top: .2rem; }
@media (max-width: 560px) {
  .rev-card-grid { grid-template-columns: 1fr; }
  .rev-controls #rev-export { margin-left: 0; }
}

/* ============================================================
   Auth, sessions & activity log (v0.65)
   ============================================================ */

/* Login dialogue — users 1–3 with hints; clicking a row fills the email. */
.login-users { display: flex; flex-direction: column; gap: .4rem; margin-top: .35rem; }
.login-users-lbl { font-size: .72rem; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; margin: 0 0 .1rem; }
.login-user {
  display: flex; flex-direction: column; gap: .15rem; text-align: left;
  border: 1px solid var(--line); border-radius: 8px; background: #f8fafc;
  padding: .45rem .6rem; cursor: pointer; font: inherit;
}
.login-user:hover { background: #f1f5f9; border-color: #cbd5e1; }
.lu-main { display: flex; align-items: baseline; gap: .5rem; justify-content: space-between; }
.lu-email { font-size: .82rem; font-weight: 600; color: #0f172a; }
.lu-role { font-size: .68rem; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.lu-hint { font-size: .75rem; color: #64748b; }

/* Admin single-session takeover panel (inside the login card) */
.login-takeover { border: 1px solid #fcd34d; background: #fffbeb; border-radius: 8px; padding: .6rem .7rem; margin-top: .3rem; }
.lt-title { font-size: .82rem; font-weight: 700; color: #92400e; margin: 0 0 .35rem; }
.lt-row { font-size: .78rem; color: #78350f; margin: 0 0 .25rem; }
.lt-sub { font-size: .74rem; color: #92400e; margin: .3rem 0 .5rem; }
.lt-actions { display: flex; gap: .5rem; flex-wrap: wrap; }

/* 👤 account icon + My Account modal */
.account-btn { font-size: .95rem; line-height: 1; }
.account-card { max-width: 440px; }
.account-grid { display: flex; flex-direction: column; gap: .7rem; }

/* Active sessions + Activity log panels (admin-only) */
.sessions-table .btn, .actlog-table .btn { font-size: .72rem; padding: .2rem .5rem; }
.actlog-filters { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin-bottom: .6rem; }
.actlog-filters select { max-width: 230px; }
.actlog-count { font-size: .78rem; margin-left: auto; }
.actlog-table .al-when { white-space: nowrap; }
.actlog-table .al-detail { max-width: 480px; overflow-wrap: anywhere; }
#al-more { margin-top: .6rem; }

/* Read-only public account — hide the write affordances CSS can reach; the
   api.js fetch guard (and RLS server-side) blocks everything else. */
body.read-only #fab-add,
body.read-only #import-btn,
body.read-only .dir-actions,
body.read-only .vocab-panel,
body.read-only .fields-panel,
body.read-only .replace-panel,
body.read-only .seed-panel { display: none !important; }

/* ============================================================
   v0.70 — three-tier card model (Organiser → Venue → Event)
   ============================================================ */

/* ---- Venue Card: unmistakable against an Event Card ---- */
:root { --venue-accent: #475569; --venue-accent-light: #94a3b8; }
.venue-card { border-color: #cbd5e1; }
.venue-card:hover { box-shadow: 0 6px 16px rgba(71,85,105,.2); }
/* Striped slate bar — the same device the Organiser Card uses, in a different
   hue, so all three card types read apart at a glance. */
.card-bar-venue {
  background: repeating-linear-gradient(135deg,
    var(--venue-accent) 0 5px,
    var(--venue-accent-light) 5px 10px) !important;
}
.badge-venue {
  display: inline-block; background: var(--venue-accent); color: #fff;
  font-size: .6rem; font-weight: 800; letter-spacing: .05em;
  padding: .1rem .4rem; border-radius: 5px;
}
.badge-venue-lg {
  font-size: .68rem; padding: .18rem .6rem; border-radius: 6px;
  margin-left: .6rem; vertical-align: middle;
}
.modal-card--venue { border-top: 6px solid var(--venue-accent); }
.ve-count { color: var(--muted); font-size: .74rem; }
.tag-eventdate { background: #ecfdf5; color: #065f46; font-weight: 700; }
.chip-eventdate {
  background: #ecfdf5; color: #065f46; font-weight: 700;
  padding: .15rem .55rem; border-radius: 999px; font-size: .75rem;
}

/* ---- Triptych spine: Event ⇄ Venue ⇄ Organiser ---- */
.tri-spine { display: flex; gap: .4rem; margin: 0 0 1rem; flex-wrap: wrap; }
.tri-seg {
  flex: 1 1 0; min-width: 0; text-align: left;
  display: flex; flex-direction: column; gap: .15rem;
  border: 1px solid var(--line); border-left: 4px solid var(--line);
  border-radius: 8px; padding: .4rem .55rem; background: var(--surface);
  font: inherit; color: inherit;
}
button.tri-seg { cursor: pointer; transition: transform .12s, box-shadow .12s; }
button.tri-seg:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(15,23,42,.14); }
.tri-kind {
  font-size: .58rem; font-weight: 800; letter-spacing: .08em;
  color: var(--muted); text-transform: uppercase;
}
.tri-name {
  font-size: .8rem; font-weight: 600; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tri-count {
  background: var(--line); color: var(--muted); border-radius: 999px;
  padding: 0 .3rem; font-size: .58rem; margin-left: .2rem;
}
.tri-seg--event { border-left-color: #10b981; }
.tri-seg--venue { border-left-color: var(--venue-accent); }
.tri-seg--organiser { border-left-color: var(--organiser-accent); }
.tri-seg.is-current { background: #f8fafc; box-shadow: inset 0 0 0 1px var(--line); }
.tri-seg.is-current .tri-name { font-weight: 800; }
.tri-seg.is-empty { opacity: .55; }
.tri-seg.is-empty .tri-name { font-weight: 500; font-style: italic; }
.tri-list { display: flex; flex-direction: column; gap: .15rem; max-height: 6.5rem; overflow-y: auto; }
.tri-item {
  text-align: left; background: none; border: 0; padding: .1rem 0; cursor: pointer;
  font: inherit; font-size: .76rem; color: var(--brand-ink, #0f172a);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tri-item:hover { text-decoration: underline; }
.tri-more { font-size: .68rem; color: var(--muted); }
@media (max-width: 620px) {
  .tri-seg { flex: 1 1 100%; }
  .tri-list { max-height: 5rem; }
}

/* ---- Organiser panel on a Venue / Event Card ---- */
.detail-panel--organiser { border-left: 4px solid var(--organiser-accent); }
.org-goto-big {
  display: flex; align-items: center; gap: .6rem; width: 100%;
  background: var(--organiser-accent); color: #fff; border: 0; cursor: pointer;
  border-radius: 10px; padding: .7rem .9rem; margin-bottom: .8rem;
  font: inherit; text-align: left;
  transition: filter .12s, transform .12s;
}
.org-goto-big:hover { filter: brightness(1.08); transform: translateY(-1px); }
.org-goto-big svg { width: 20px; height: 20px; margin-left: auto; flex: 0 0 20px; }
.ogb-label { font-size: .62rem; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; opacity: .85; }
.ogb-name { font-size: .92rem; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.org-none { margin: 0 0 .8rem; }

/* ---- County dropdown + "Other" free-text box ---- */
.dl-county-row { display: flex; flex-direction: column; gap: .3rem; }
.dl-county-other { border-color: var(--organiser-accent-line, #c7d2fe); }

/* ---- Venue Card's list of Event Cards ---- */
.ve-list { display: flex; flex-direction: column; gap: .25rem; max-height: 22rem; overflow-y: auto; }
.ve-row {
  display: flex; align-items: center; gap: .6rem; width: 100%; text-align: left;
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
  padding: .4rem .6rem; cursor: pointer; font: inherit;
}
.ve-row:hover { border-color: var(--venue-accent-light); box-shadow: 0 2px 8px rgba(15,23,42,.1); }
.ve-row.past { opacity: .55; }
.ve-row.past:hover { opacity: 1; }
.ve-date { font-weight: 700; font-size: .8rem; flex: 0 0 auto; }
.ve-name { font-size: .78rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ve-stage {
  margin-left: auto; flex: 0 0 auto; font-size: .68rem; font-weight: 700;
  padding: .12rem .45rem; border-radius: 999px; background: #e2e8f0; color: #334155;
}
.ve-stage-none { background: transparent; color: var(--muted); }

/* ---- Booking panel: the event's own fixed date ---- */
.b-fixed-date {
  display: inline-block; font-weight: 700; padding: .35rem 0;
}
.rev-note-unstaged { color: var(--muted); font-size: .72rem; margin: .5rem 0 0; }
.rev-card-permanent { border-style: solid; }

/* ---- Shared confirm dialogue ---- */
.ll-confirm {
  position: fixed; inset: 0; z-index: 1200;
  background: rgba(15,23,42,.5);
  display: flex; overflow-y: auto; padding: 1rem;
}
.ll-confirm-card {
  background: var(--surface); margin: auto; width: 100%; max-width: 460px;
  border-radius: 14px; padding: 1.25rem; box-shadow: 0 20px 50px rgba(0,0,0,.3);
}
.ll-confirm-card h3 { margin: 0 0 .6rem; font-size: 1.02rem; }
.ll-confirm-body p { margin: .4rem 0; font-size: .88rem; }
.ll-confirm-actions { display: flex; gap: .5rem; margin-top: 1.1rem; flex-wrap: wrap; }

/* ---- Closest-organiser chooser ---- */
.org-match-list { display: flex; flex-direction: column; gap: .3rem; margin: .5rem 0 .8rem; }
.org-match {
  display: flex; align-items: center; gap: .6rem; width: 100%; text-align: left;
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
  padding: .45rem .65rem; cursor: pointer; font: inherit;
}
.org-match:hover { border-color: var(--organiser-accent); background: #eef2ff; }
.om-name { font-weight: 600; font-size: .85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.om-score { margin-left: auto; flex: 0 0 auto; font-size: .7rem; color: var(--muted); }

/* ---- v0.70 fix: permanent modal chrome, scrolling body only ----
   The close X and the tab bar must stay put while the panels scroll under
   them. The card becomes a flex column that owns the height; #detail-body is
   the only scroller (min-height:0 is required or the flex child refuses to
   shrink and the card scrolls as a whole again). */
#detail-modal .modal-card {
  display: flex; flex-direction: column;
  overflow: hidden; padding: 0;
}
#detail-modal .detail-chrome {
  flex: 0 0 auto; position: relative;
  padding: .9rem 1.5rem .6rem;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  border-radius: 16px 16px 0 0;
}
#detail-modal #detail-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  /* v0.78b: the card never scrolls sideways. It is sized to fit at every
     breakpoint and long text truncates; a horizontal scrollbar here has only
     ever meant something escaped its column. `scrollbar-gutter: stable`
     reserves the vertical scrollbar's width whether or not it is showing, so
     the panels below keep one width instead of jumping ~15px as content grows. */
  overflow-x: hidden;
  scrollbar-gutter: stable;
  padding: 1.1rem 1.5rem 1.5rem;
  overscroll-behavior: contain;
}
/* The X is positioned against the chrome strip now, not the whole card. */
#detail-modal .detail-chrome .modal-close { top: .6rem; right: 1rem; }
/* The spine lives in the chrome — drop its bottom margin there. */
#detail-modal .detail-chrome .tri-spine { margin: 0; padding-right: 2.2rem; }
@media (max-width: 620px) {
  #detail-modal .detail-chrome { padding: .8rem 1rem .5rem; }
  #detail-modal #detail-body { padding: 1rem 1rem 1.25rem; }
}

/* ---- v0.70 fix: Directory tile overflow ----
   A long group chip (.chip is nowrap) pushed the right-hand stack wide, which
   squeezed the title into three lines and shoved the chip past the card edge.
   The title now takes the slack and the chip truncates instead. */
.card-top h3 { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.card-top-right { flex: 0 1 auto; min-width: 0; max-width: 48%; align-items: flex-start; }
.ctr-stack, .ctr-stack-grouped { min-width: 0; max-width: 100%; }
.ctr-stack .chip, .ctr-stack .tag, .ctr-stack .packfor-pill {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; display: block;
}
/* VENUE / ARCHIVED badges belong in the stack, not floating beside the title. */
.card-top-right > .badge-venue,
.card-top-right > .badge-archived { flex: 0 0 auto; align-self: flex-start; }

/* ---- v0.71: modal tab bar (Organiser | Venue | Events) ---- */
/* v0.78b: no right padding. The 2.4rem was there to clear the close ✕, but the
   ✕ sits on the title line ABOVE this bar, so the gap only made the headers stop
   short of the panels beneath them. The bar now runs the full width of the
   chrome and therefore slightly OVERSHOOTS the panel columns, which is
   deliberate: the panels sit inside a scroll gutter, and a tab bar that tracked
   their width would change size whenever the gutter did. */
.detail-tabs { display: flex; gap: .4rem; }
.detail-tab {
  flex: 1 1 0; min-width: 0; text-align: left; cursor: pointer;
  display: flex; flex-direction: column; gap: .1rem;
  border: 1px solid var(--line); border-bottom: 3px solid transparent;
  border-radius: 8px 8px 0 0; padding: .35rem .55rem .3rem;
  background: #f8fafc; font: inherit; color: inherit;
}
.detail-tab:hover:not(:disabled) { background: #fff; }
.detail-tab:disabled { opacity: .45; cursor: default; }

/* ---- v0.75: kind pills in the tab bar ----
   The tab headers used muted grey text while the tiles used coloured kind
   pills, so the same four tiers read as two different vocabularies. The bar now
   speaks the tile language: Organiser indigo, Venue slate, Event green. */
.dt-pill {
  display: inline-block;
  font-size: .55rem; font-weight: 800; letter-spacing: .06em;
  padding: .1rem .42rem; border-radius: 999px; color: #fff;
  line-height: 1.5; white-space: nowrap;
}
.dt-pill--organiser  { background: var(--organiser-accent); }
.dt-pill--venue      { background: var(--venue-accent); }
.dt-pill--events     { background: #10b981; }
.dt-pill--eventcards { background: #0c4a6e; }
/* kept: earlier markup used the singular class */
.dt-pill--event      { background: #10b981; }

/* An EMPTY tier is offered, not disabled — a FAB-created card has no venue yet
   and the tab is the only route to adding one. Dashed border + faded pill say
   "nothing here" while staying obviously clickable. */
.detail-tab.is-empty { border-style: dashed; }
.detail-tab.is-empty .dt-pill { opacity: .5; }
.detail-tab.is-empty .dt-name { color: var(--brand); font-weight: 700; }
.detail-tab.is-empty:hover { background: #fff; border-color: var(--brand); }
.detail-tab.is-empty:hover .dt-pill { opacity: 1; }
.dt-add {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: var(--brand); font-weight: 700; text-align: left;
}
.dt-add:hover { text-decoration: underline; }

/* ---- v0.76: ＋ on the plural tiers ----
   An organiser runs events at several venues, and a venue hosts several events,
   so both pills carry a persistent ＋ — not one that only appears when the tier
   is empty. */
.dt-plus {
  background: none; border: 1px solid var(--line); border-radius: 999px;
  width: 1.15rem; height: 1.15rem; line-height: 1; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; color: var(--brand); font-weight: 800; font-size: .7rem;
  flex: 0 0 auto;
}
.dt-plus:hover { background: var(--brand); color: #fff; border-color: var(--brand); }
.dt-none { color: var(--muted); font-style: italic; }

/* "All" is pinned to the right of its own header row so it sits in the same
   place whatever the pill, count and ＋ in front of it happen to measure. */
.dt-all { margin-left: auto; }

/* ---- v0.76: Hide / Archive against every line and every tile ---- */
.dt-row { display: flex; align-items: center; gap: .25rem; }
.dt-row .dt-item { flex: 1 1 auto; min-width: 0; }
.dt-tools { display: inline-flex; gap: .15rem; flex: 0 0 auto; }
/* v0.77b: bigger and darker. At .68rem/.45 these read as smudges against the
   tinted segment washes — they are controls, not decoration, so they carry
   their own weight now. The glyphs are emoji, which ignore `color`, so
   `opacity` plus a contrast nudge is what actually darkens them. */
.dt-tool {
  background: none; border: 0; padding: 0 .18rem; cursor: pointer;
  font-size: .84rem; line-height: 1; opacity: .78; border-radius: 4px;
  filter: contrast(1.2) saturate(.9);
}
.dt-tool:hover { opacity: 1; filter: none; background: var(--line); }
.dt-tool.is-archived { opacity: .95; }
.dt-row.is-archived .dt-item { text-decoration-style: dashed; opacity: .6; }
.dt-row.is-hidden .dt-item { opacity: .55; font-style: italic; }

/* The tile archive control sits under the eye in the same right-hand stack. */
.arch-btn {
  background: none; border: 1px solid var(--line); border-radius: 999px;
  font-size: .5rem; font-weight: 800; letter-spacing: .04em;
  padding: .06rem .3rem; cursor: pointer; color: var(--muted);
}
.arch-btn:hover { background: #334155; border-color: #334155; color: #fff; }
.arch-btn.is-archived { background: #334155; border-color: #334155; color: #fff; }

/* Per-tier completeness sections under the events rows. */
.comp-tiers { margin-top: 1rem; border-top: 1px solid var(--line); padding-top: .6rem; }
.comp-tier { margin-bottom: .9rem; }
.comp-tier h4 {
  margin: 0 0 .35rem; font-size: .78rem; font-weight: 800;
  letter-spacing: .03em; color: var(--ink);
}
.comp-tier h4 .muted { font-weight: 600; }
.comp-tier .comp-note { margin: .3rem 0 0; font-size: .72rem; }

/* Ely Markets Ltd runs twelve events; the list must stay readable rather than
   growing without limit. The height cap lives on the single .dt-list rule
   further down — these are just the visible-scrollbar affordances, because a
   list that scrolls silently looks like a list that is simply truncated. */
/* The list is a flex COLUMN with a height cap, so its items default to
   flex-shrink:1 and silently compress — twelve of Ely's events squeezed into
   6.7px rows each, unreadable, and the container never scrolled because
   nothing overflowed. Pinning the items to their natural height is what makes
   the scrollbar appear at all. */
.dt-list > .dt-item { flex: 0 0 auto; }
.dt-list { overscroll-behavior: contain; scrollbar-width: thin; padding-right: 2px; }
.dt-list::-webkit-scrollbar { width: 6px; }
.dt-list::-webkit-scrollbar-thumb { background: var(--line); border-radius: 999px; }
.dt-list::-webkit-scrollbar-thumb:hover { background: var(--muted); }

/* Each event title is UNDERSCORED to say it opens further dates — "Summer Craft
   Markets" is a series with three dates behind it, not a single occurrence.
   Event Cards are underlined too: each opens that one staged date's card. */
.detail-tab--events .dt-item,
.detail-tab--eventcards .dt-item {
  text-decoration: underline;
  text-decoration-style: solid;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}
.detail-tab--events .dt-item.is-current,
.detail-tab--eventcards .dt-item.is-current { text-decoration-thickness: 2px; }

/* Four segments now, so the bar wraps rather than squeezing them. */
.detail-tabs { flex-wrap: wrap; row-gap: .35rem; }
.detail-tab--eventcards.is-active { border-bottom-color: #0c4a6e; }

/* Prompt dialogue (naming a venue) — inherits the confirm card's chrome. */
.ll-prompt-label {
  display: block; margin-top: .6rem; font-size: .75rem; font-weight: 700;
  color: var(--muted);
}
.ll-prompt-input {
  display: block; width: 100%; margin-top: .3rem;
  padding: .45rem .55rem; border: 1px solid var(--line); border-radius: 6px;
  font: inherit; color: var(--ink);
}
.ll-prompt-input:focus { outline: 2px solid var(--brand); outline-offset: 1px; }
.detail-tab.is-active { background: #fff; }
.detail-tab--organiser.is-active { border-bottom-color: var(--organiser-accent); }
.detail-tab--venue.is-active { border-bottom-color: var(--venue-accent); }
.detail-tab--events.is-active { border-bottom-color: #10b981; }
/* v0.78b: flex on EVERY segment, not just EVENT. `.dt-all { margin-left: auto }`
   is what pushes the All pill to the right margin, and margin-auto only does
   anything inside a flex container — so on the VENUE header, whose .dt-kind was
   still a plain inline box, All sat wherever the pill and count happened to
   leave it. Asked for twice; this is why it did not take the first time. */
.dt-kind {
  font-size: .56rem; font-weight: 800; letter-spacing: .08em; color: var(--muted);
  display: flex; align-items: center; gap: .3rem;
}
.dt-count { background: var(--line); border-radius: 999px; padding: 0 .28rem; }
.dt-name {
  font-size: .8rem; font-weight: 700; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.detail-tab.is-active .dt-name { font-weight: 800; }
@media (max-width: 560px) { .dt-name { font-size: .72rem; } }

/* ---- Event picker list (EVENTS tab with nothing chosen) ---- */
.ev-pick-list { display: flex; flex-direction: column; gap: .4rem; }
.ev-pick {
  display: flex; flex-direction: column; gap: .15rem; width: 100%; text-align: left;
  background: var(--surface); border: 1px solid var(--line); border-left: 4px solid #10b981;
  border-radius: 8px; padding: .55rem .75rem; cursor: pointer; font: inherit;
}
.ev-pick:hover { box-shadow: 0 4px 12px rgba(15,23,42,.12); transform: translateY(-1px); }
.evp-name { font-weight: 700; font-size: .92rem; }
.evp-meta { font-size: .76rem; color: var(--muted); }
.evp-cards { font-size: .7rem; font-weight: 700; color: #065f46; }
/* v0.76: colour the LARGE headline badges by scoping to .badge-venue-lg.
   This used to be a blanket `.badge-eventcard { background:#10b981 !important }`
   intended for the headline, but !important also beat
   `.badge-kind.badge-eventcard`, so EVENT and EVENT CARD *tiles* both rendered
   the same green and the two tiers were indistinguishable at a glance. */
.badge-venue-lg.badge-event     { background: #10b981; color: #fff; }
.badge-venue-lg.badge-eventcard { background: #0c4a6e; color: #fff; }

/* ============================================================
   v0.72 — fixed headline, unified tile pills, wider group chip
   ============================================================ */

/* The title line lives in the permanent chrome with the X and the tab bar, so
   all three stay put while only the panels scroll. */
#detail-headline .detail-head {
  margin-bottom: .6rem; padding-bottom: .55rem;
  padding-right: 2.2rem;   /* clear of the close X */
}
#detail-headline .detail-head h2 { font-size: 1.15rem; }
#detail-headline .detail-head .meta { margin-top: .25rem; }

/* ---- EVENTS tab: the full clickable list, current one highlighted ---- */
.detail-tab--events { cursor: default; }
.detail-tab--events .dt-kind { display: flex; align-items: center; gap: .3rem; }
.dt-all {
  margin-left: auto; border: 1px solid var(--line); background: #fff;
  border-radius: 999px; padding: 0 .4rem; font-size: .56rem; font-weight: 800;
  letter-spacing: .06em; cursor: pointer; color: var(--muted);
}
.dt-all:hover { border-color: #10b981; color: #065f46; }
/* Four entries visible, the fifth part-shown so more is obviously below. */
.dt-list { display: flex; flex-direction: column; gap: .1rem; max-height: 5.6rem; overflow-y: auto; margin-top: .1rem; }
.dt-item {
  text-align: left; background: none; border: 0; padding: .08rem .25rem; cursor: pointer;
  font: inherit; font-size: .74rem; border-radius: 4px; color: #0f172a;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dt-item:hover { background: #ecfdf5; }
/* v0.76: the current entry is marked by WEIGHT, not by a filled green bar.
   A solid highlight across the whole line shouted louder than the pills and
   fought with the tab bar's own colour language; bold does the job. */
.dt-item.is-current { font-weight: 800; color: var(--ink); }
.detail-tab--events.is-empty { opacity: .55; }

/* ================= v0.77: the Event File Manager (EFM) =================
   The four-tab wrapper round the card modal. Three changes here: each tier
   gets its own translucent wash, the EVENT CARDS tier becomes a selector, and
   every segment is a fixed size so nothing moves as tabs are switched. */

/* ---- A wash per tier, taken from the pill colours ----
   All four segments shared one flat #f8fafc, so the only thing telling them
   apart was the pill. Mixing each accent into white at 8% keeps the text
   contrast the flat background had while making the four tiers readable as four
   separate places at a glance; the active one deepens to 15%, hover to 18%.
   Every rule below carries enough specificity to beat the two generic rules
   further up — `.detail-tab:hover:not(:disabled)` and `.detail-tab.is-empty:hover`
   both set a flat #fff and both otherwise win, which would strip the colour off
   a tab at the exact moment it is being pointed at. */
/* --efm-wash-eventcards is CYAN, not the pill's teal. Emerald #10b981 and teal
   #0d9488 are neighbours on purpose — Event and Event Card are parent and child,
   and the pills say so. But at wash strength those two are the same colour: 8%
   mixes measured (0.925, 0.978, 0.960) against (0.924, 0.966, 0.963), a
   difference no eye will find. The pill still names the tier in teal; the wash
   only has to separate four regions of one bar, so it takes the next hue along. */
:root {
  --efm-wash-organiser:  var(--organiser-accent);
  --efm-wash-venue:      var(--venue-accent);
  --efm-wash-events:     #10b981;
  --efm-wash-eventcards: #0284c7;
}
.detail-tab--organiser  { background: color-mix(in srgb, var(--efm-wash-organiser) 14%, #fff); }
.detail-tab--venue      { background: color-mix(in srgb, var(--efm-wash-venue) 14%, #fff); }
.detail-tab--events     { background: color-mix(in srgb, var(--efm-wash-events) 14%, #fff); }
.detail-tab--eventcards { background: color-mix(in srgb, var(--efm-wash-eventcards) 14%, #fff); }
.detail-tab--organiser.is-active  { background: color-mix(in srgb, var(--efm-wash-organiser) 24%, #fff); }
.detail-tab--venue.is-active      { background: color-mix(in srgb, var(--efm-wash-venue) 24%, #fff); }
.detail-tab--events.is-active     { background: color-mix(in srgb, var(--efm-wash-events) 24%, #fff); }
.detail-tab--eventcards.is-active { background: color-mix(in srgb, var(--efm-wash-eventcards) 24%, #fff); }
.detail-tab--organiser:hover:not(:disabled),
.detail-tab--organiser.is-empty:hover  { background: color-mix(in srgb, var(--efm-wash-organiser) 30%, #fff); }
.detail-tab--venue:hover:not(:disabled),
.detail-tab--venue.is-empty:hover      { background: color-mix(in srgb, var(--efm-wash-venue) 30%, #fff); }
.detail-tab--events:hover:not(:disabled),
.detail-tab--events.is-empty:hover     { background: color-mix(in srgb, var(--efm-wash-events) 30%, #fff); }
.detail-tab--eventcards:hover:not(:disabled),
.detail-tab--eventcards.is-empty:hover { background: color-mix(in srgb, var(--efm-wash-eventcards) 30%, #fff); }
/* Older engines with no color-mix() fall back to the flat #f8fafc set on
   .detail-tab, which is the pre-v0.77 appearance — degraded, not broken. */

/* ---- Every segment is selectable, empty or not ----
   .detail-tab--events used to set `cursor: default` because only its inner
   entries did anything. The whole header is a click target now. */
.detail-tab--events,
.detail-tab--venue,
.detail-tab--eventcards { cursor: pointer; }
.detail-tab[data-seg]:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }

/* ---- One height for every segment ----
   Four entries tall, fixed rather than capped, so all four segments measure the
   same whatever they hold and a fifth venue produces a scrollbar instead of a
   taller bar. --efm-list-h is four .dt-item rows; --efm-seg-h adds the pill row
   and the segment's own padding. */
:root { --efm-list-h: 5.6rem; --efm-seg-h: 7.6rem; --efm-head-h: 4rem; }
.dt-list { height: var(--efm-list-h); max-height: none; }
.detail-tab { min-height: var(--efm-seg-h); }
/* The organiser is a single name with no list — push it to the top so its pill
   lines up with the other three rather than centring in the empty space. */
.detail-tab--organiser { justify-content: flex-start; }

/* ---- The title line is a fixed height too ----
   A two-line title used to push the tab bar (and everything under it) down. */
#detail-headline { height: var(--efm-head-h); overflow: hidden; }
#detail-headline .detail-head h2 {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  padding-right: .2rem;
}

/* ---- EVENT CARDS: a selector, not a list ---- */
.dt-select {
  width: 100%; font: inherit; font-size: .74rem;
  border: 1px solid var(--line); border-radius: 6px;
  padding: .12rem .25rem; margin-top: .15rem;
  background: #fff; color: #0f172a; cursor: pointer;
  overflow: hidden; text-overflow: ellipsis;
}
.dt-select:focus { outline: 2px solid #0c4a6e; outline-offset: 1px; }
/* With no list to hang them on, the chosen card's hide/archive tools sit under
   the selector — the v0.76 promise that every tier carries both tools wherever
   it is named still holds. */
.dt-row--single { margin-top: .2rem; justify-content: flex-end; }
@media (max-width: 620px) {
  :root { --efm-list-h: 4.2rem; --efm-seg-h: 6.2rem; --efm-head-h: 3.4rem; }
}

/* ---- One pill style for all three card kinds, colour-coded ---- */
.badge-kind {
  font-size: .58rem; font-weight: 800; letter-spacing: .05em;
  padding: .12rem .45rem; border-radius: 999px; color: #fff;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.badge-kind.badge-organiser { background: var(--organiser-accent); }
.badge-kind.badge-venue     { background: var(--venue-accent); }
.badge-kind.badge-event     { background: #10b981; }
.badge-kind.badge-eventcard { background: #0c4a6e; }

/* ---- Group chip: show at least the first word before truncating ---- */
.card-top-right { max-width: 58%; }
.ctr-stack .chip-cardgroup {
  min-width: 6.5rem; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block;
  text-align: right;
}
@media (max-width: 480px) {
  .card-top-right { max-width: 50%; }
  .ctr-stack .chip-cardgroup { min-width: 5rem; }
}

/* ---- v0.73: the card modal sits at the TOP, never vertically centred ----
   `.modal-card { margin: auto }` (v0.66, for Android) centres a short card, so
   the title bar drifted down the screen and moved as content changed height.
   Pinning it to the top keeps the title, the X and the tab bar in one fixed
   place whatever the card contains. The horizontal `auto` margins are kept so
   the card stays centred left-to-right, and `align-self: flex-start` stops the
   flex container stretching it. */
#detail-modal .modal-card {
  margin: 0 auto;
  align-self: flex-start;
}

/* ================= v0.77b: GitHub 60-day rotation panel =================
   First panel on the Dashboard tab, and deliberately quiet until it matters —
   a warning that shouts for fifty days gets ignored on the day it counts. The
   level classes are set by renderGithubPanel() from the time remaining. */
.gh-panel { border-left: 4px solid var(--line); }
.gh-panel.gh-ok      { border-left-color: #94a3b8; }
.gh-panel.gh-warn    { border-left-color: #f59e0b; background: #fffbeb; }
.gh-panel.gh-urgent,
.gh-panel.gh-over    { border-left-color: #dc2626; background: #fef2f2; }
.gh-panel.gh-unknown { border-left-color: var(--line); }

.gh-row { display: flex; gap: 1.25rem; align-items: stretch; flex-wrap: wrap; }
.gh-explain { flex: 1 1 22rem; min-width: 0; }
.gh-explain p { margin: 0 0 .5rem; font-size: .85rem; line-height: 1.45; }
.gh-explain .gh-meta { font-size: .78rem; margin-bottom: 0; }

/* The "large button" — big enough to read the clock across the room. */
.gh-big {
  flex: 0 0 auto; min-width: 15rem;
  display: flex; flex-direction: column; gap: .2rem; align-items: flex-start;
  padding: 1rem 1.25rem; cursor: pointer; font: inherit; text-align: left;
  border: 2px solid var(--line); border-radius: 12px; background: #fff;
  color: var(--ink);
}
.gh-big:hover { border-color: var(--brand); background: #f8fafc; }
.gh-ok     .gh-big { border-color: #cbd5e1; }
.gh-warn   .gh-big { border-color: #f59e0b; }
.gh-urgent .gh-big,
.gh-over   .gh-big { border-color: #dc2626; }
.gh-big-label { font-size: .72rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.gh-big-sub   { font-size: .74rem; color: var(--muted); }
.gh-clock {
  font-size: 1.9rem; font-weight: 800; line-height: 1.1;
  font-variant-numeric: tabular-nums;   /* the digits must not jitter as it ticks */
}
.gh-warn   .gh-clock { color: #b45309; }
.gh-urgent .gh-clock,
.gh-over   .gh-clock { color: #b91c1c; }
@media (max-width: 620px) {
  .gh-big { width: 100%; min-width: 0; }
  .gh-clock { font-size: 1.6rem; }
}

/* ================= v0.78: delete an EFM collection =================
   Bins in the tab-header rows and beside each card title, plus the Dashboard
   panel that holds what they removed. BIN_ICON is an SVG using currentColor,
   so unlike the emoji tools these take a real colour. */
.dt-tool--del { color: #b91c1c; opacity: .7; filter: none; display: inline-flex; align-items: center; }
.dt-tool--del:hover { opacity: 1; background: #fee2e2; }

/* Sits immediately after the ✎ — edit and delete are the two things you do to
   a card as a whole, so they read as one pair. */
.title-del-btn {
  background: none; border: 0; padding: 0 .3rem; cursor: pointer;
  color: #b91c1c; opacity: .6; vertical-align: middle; line-height: 1;
}
.title-del-btn:hover { opacity: 1; }
.title-del-btn:disabled { opacity: .3; cursor: default; }

/* The two-step warning. `del-warn` is the line naming what cannot be undone. */
.del-list { margin: .35rem 0 .6rem 1.1rem; padding: 0; font-size: .88rem; }
.del-warn {
  background: #fef2f2; border: 1px solid #fecaca; border-radius: 6px;
  padding: .45rem .6rem; color: #991b1b; font-size: .85rem; margin: .5rem 0;
}

/* ---- Dashboard panel ---- */
.del-row {
  display: grid; gap: .3rem .75rem; align-items: center;
  grid-template-columns: 1fr auto auto;
  padding: .6rem 0; border-top: 1px solid var(--line);
}
.del-row:first-child { border-top: 0; }
.del-row-main { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; min-width: 0; }
.del-row-title { font-weight: 700; font-size: .9rem; }
.del-row-sub { font-size: .78rem; color: var(--muted); }
.del-row-meta { font-size: .76rem; color: var(--muted); white-space: nowrap; }
.del-row-actions { display: flex; gap: .4rem; flex: 0 0 auto; }
.del-row-actions .btn { padding: .28rem .6rem; font-size: .8rem; }
.del-forever { color: #b91c1c; border-color: #fecaca; }
.del-forever:hover:not(:disabled) { background: #fef2f2; border-color: #dc2626; }
.del-row-msg { grid-column: 1 / -1; margin: 0; font-size: .78rem; color: #991b1b; }
.del-row-msg:empty { display: none; }
@media (max-width: 620px) {
  .del-row { grid-template-columns: 1fr; }
  .del-row-actions { justify-content: flex-start; }
}

/* ---- v0.78c: EVENT CARDS is a list again, with a ＋ dialogue ---- */
/* A card with no pipeline stage is DIMMED, not hidden. The earlier rule removed
   it from the list, so a card you had just created disappeared the moment you
   looked away — which reads as "it didn't save". Rolling back out of the
   pipeline is still visible; it just no longer costs you the row. */
.dt-row.is-unstaged .dt-item { opacity: .6; font-style: italic; }
.dt-row.is-unstaged .dt-item::after { content: " ·"; opacity: .6; }

/* The ＋ dialogue's dropdown, matching .ll-prompt-input. */
.ll-prompt-select {
  display: block; width: 100%; margin-top: .3rem;
  font: inherit; padding: .4rem .5rem;
  border: 1px solid var(--line); border-radius: 6px; background: #fff;
}
.ll-prompt-select:focus { outline: 2px solid var(--brand); outline-offset: 1px; }
.ll-prompt-msg { margin: .45rem 0 0; font-size: .8rem; color: #991b1b; }
.ll-prompt-msg:empty { display: none; }
