:root {
  /* Tokens follow design-system.md (light palette): warm neutrals, single
     Twenty-blue accent, the chip palette carries the color. */
  --page: #FBFBFB;          /* page background (warm off-white) */
  --bg: #FFFFFF;            /* surface: cards, table, topbar, inputs */
  --bg-soft: #F8F9FB;       /* hover / inset tint */
  --text: #1A1A20;          /* ink */
  --text-muted: #7C7C86;    /* muted */
  --faint: #A8A8B0;         /* faint (dashes, placeholders) */
  --border: #EAEAEC;        /* hairline */
  --border-soft: #F2F2F3;   /* inner cell line */
  --accent: #1961ED;        /* Twenty-blue */
  --accent-hover: #134FC9;  /* accent, ~15% darker, for button hover */
  --accent-soft: #E9F0FE;   /* accent background tint */
  --shadow-card: 0 1px 2px rgba(0,0,0,0.04), 0 1px 3px rgba(0,0,0,0.04);
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  font-feature-settings: 'cv11', 'ss01';
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  background: var(--page);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* topbar */
.topbar {
  display: flex; align-items: center;
  height: 56px; padding: 0 24px;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  position: sticky; top: 0; z-index: 10;
}
.topbar .brand {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 600; font-size: 15px; color: var(--text);
  letter-spacing: -0.01em; margin-right: 32px;
}
.topbar .brand:hover { text-decoration: none; }
/* #282: the brand carries the Home icon; it tints to the accent when the
   home dashboard is the active section (mirrors the .navlink.active cue). */
.topbar .brand svg { width: 16px; height: 16px; opacity: 0.85; }
.topbar .brand.active svg { color: var(--accent); opacity: 1; }
.topnav { display: flex; align-items: center; gap: 4px; flex: 1; }
.navlink {
  display: inline-flex; align-items: center; gap: 6px;
  height: 56px; padding: 0 12px;
  color: var(--text-muted); font-size: 13px; font-weight: 500;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.navlink:hover { color: var(--text); text-decoration: none; }
.navlink.active { color: var(--text); border-bottom-color: var(--accent); }
.navlink svg { width: 14px; height: 14px; opacity: 0.85; }

/* main wrapper */
main { padding: 24px 24px 64px; max-width: 1280px; margin: 0 auto; }

/* page header */
.page-header {
  display: flex; align-items: center; gap: 12px;
  margin: 8px 0 20px;
  flex-wrap: wrap;
}
.page-header h1 {
  margin: 0; font-size: 22px; font-weight: 600;
  letter-spacing: -0.015em; color: var(--text);
}
.page-subtitle {
  color: var(--text-muted); font-size: 13px;
  border-left: 1px solid var(--border); padding-left: 12px;
}
.page-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; }

/* list-unit toolbar: the record count sits directly above the table, inside
   the single #<entity>-list-block swap unit (Twenty-native pattern), so a
   search/delete re-render keeps the count in sync with the rows by construction. */
.list-toolbar { display: flex; align-items: center; margin: 0 0 8px; min-height: 20px; }
.list-count { color: var(--text-muted); font-size: 13px; font-variant-numeric: tabular-nums; }

/* search input */
.search-input {
  position: relative; display: inline-flex; align-items: center;
}
.search-input svg {
  position: absolute; left: 10px; width: 14px; height: 14px;
  color: var(--text-muted); pointer-events: none;
}
.search-input input {
  padding: 7px 12px 7px 32px;
  border: 1px solid var(--border); border-radius: 6px;
  font: inherit; font-size: 13px;
  background: var(--bg);
  color: var(--text);
  width: 240px;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.search-input input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.search-input input::placeholder { color: var(--text-muted); }

/* buttons */
.button {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px; border-radius: 6px;
  font: inherit; font-size: 13px; font-weight: 500;
  cursor: pointer; border: 1px solid transparent;
  text-decoration: none;
  transition: background-color 0.15s, border-color 0.15s;
}
.button svg { width: 14px; height: 14px; }
.button-primary {
  background: var(--accent); color: white;
  border-color: var(--accent);
}
.button-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); text-decoration: none; }
.button-secondary {
  background: var(--bg); color: var(--text); border-color: var(--border);
}
.button-secondary:hover { background: var(--bg-soft); }
/* destructive action recedes: neutral at rest (reads like secondary), the
   danger color appears only on hover/focus, right before the click. */
.button-danger {
  background: var(--bg); color: var(--text); border-color: var(--border);
}
.button-danger:hover, .button-danger:focus-visible {
  background: #FCF1F1; color: #D14343; border-color: #E7B7B7;
}
.button-disabled {
  background: var(--bg-soft); color: var(--text-muted);
  border-color: var(--border); cursor: not-allowed;
  pointer-events: none;
}

/* detail-page action buttons (Edit / Delete in the header) */
.detail-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; }
.detail-actions form { display: inline; margin: 0; padding: 0; }

/* tables (dense, single-line) */
.data-table {
  width: 100%; border-collapse: collapse;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  font-size: 13px;
}
.data-table thead th {
  background: var(--bg-soft);
  text-align: left;
  padding: 10px 12px;
  font-size: 11px; font-weight: 500;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.data-table tbody td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--border-soft);
  vertical-align: middle;
  white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  max-width: 320px;
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover td { background: var(--bg-soft); }
.data-table .cell-avatar { width: 32px; padding-right: 0; }
.data-table .cell-name a { color: var(--text); font-weight: 500; }
.data-table .cell-name a:hover { color: var(--accent); }
.data-table .cell-email { color: var(--text-muted); }
.data-table .cell-empty {
  text-align: center; color: var(--text-muted);
  padding: 32px 12px; font-style: italic;
}

/* avatar */
.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%;
  font-size: 10px; font-weight: 600;
  flex-shrink: 0;
}
/* Avatar initials cycle the design-system chip palette (blue/green/orange/
   red/purple) plus three harmonizing soft tints. No indigo (it would collide
   with the Twenty-blue accent). */
.avatar-tint-1 { background: #DCE8FB; color: #1D5BC4; } /* blue */
.avatar-tint-2 { background: #DBF2E3; color: #1A7A47; } /* green */
.avatar-tint-3 { background: #FCEAD9; color: #9A5414; } /* orange */
.avatar-tint-4 { background: #FBE0E0; color: #B23B3B; } /* red */
.avatar-tint-5 { background: #ECE4F7; color: #6B3FA0; } /* purple */
.avatar-tint-6 { background: #D7EEF4; color: #1D6E86; } /* teal */
.avatar-tint-7 { background: #FBE8F1; color: #A83A6F; } /* pink */
.avatar-tint-8 { background: #E7E9EC; color: #4A4A52; } /* slate */

/* relation chip (design-system): a related entity (e.g. company) as a neutral
   rounded-rect with a small colored logo square (its initial) + the name.
   Twenty's signature chip identity. */
.relation-chip {
  display: inline-flex; align-items: center; gap: 6px;
  max-width: 100%; vertical-align: middle;
  padding: 2px 8px 2px 3px; border-radius: 6px;
  background: #F1F1F3; color: #3A3A42; border: 1px solid #E6E6E9;
  font-size: 12.5px; font-weight: 500; line-height: 1.5;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.relation-chip:hover { text-decoration: none; background: #ECECEE; border-color: #D7D7DB; }
/* keep the chip's neutral text when it sits in a .detail-sub line, whose
   generic link-hover rule would otherwise repaint it accent-blue. */
.detail-title .detail-sub a.relation-chip:hover { color: #3A3A42; }
.relation-logo {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 3px; flex-shrink: 0;
  font-size: 9px; font-weight: 700; color: #fff;
}
.relation-logo.brand-1 { background: #1961ED; }
.relation-logo.brand-2 { background: #1A7A47; }
.relation-logo.brand-3 { background: #B5651D; }
.relation-logo.brand-4 { background: #B23B3B; }
.relation-logo.brand-5 { background: #6B3FA0; }
.relation-logo.brand-6 { background: #1D6E86; }

/* pills (source tags) */
.pill {
  display: inline-flex; align-items: center;
  padding: 2px 8px; border-radius: 6px;
  font-size: 11.5px; font-weight: 500; line-height: 1.5;
}
.pill-source-referral { background: #DCE8FB; color: #1D5BC4; } /* blue */
.pill-source-customer { background: #DBF2E3; color: #1A7A47; } /* green */
.pill-source-inbound  { background: #FCEAD9; color: #9A5414; } /* orange */
.pill-source-manual   { background: #EEEEF0; color: #56565E; } /* neutral */

/* #145 login-access (auth_role) status pills. admin = elevated (purple),
   user = has access (blue), none = no access (neutral). Reuse the existing
   palette pairs so contrast matches the rest of the chip system. */
.pill-role-admin { background: #ECE4F7; color: #6B3FA0; } /* purple */
.pill-role-user  { background: #DCE8FB; color: #1D5BC4; } /* blue */
.pill-role-none  { background: #EEEEF0; color: #56565E; } /* neutral */

/* #103 merge-field reference chips on the compose screen. Soft neutral chips
   (Inter, NOT mono — a token is a field name, design-system §Chips); the token
   text reads as a labelled reference the author can copy. */
.merge-fields {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin: 4px 0 20px;
}
.merge-fields-label { color: var(--text-muted); font-size: 13px; }
/* #112: the "Event:" group sub-label before the event-tagged chip set. A hair
   stronger than the row label, with a little left breathing room from the
   compliance chip it follows. */
.merge-fields-sublabel { margin-left: 6px; font-weight: 600; }
/* #110: chips are now <button> (click-to-insert at the caret). Strip native
   button chrome but keep the PR1 soft Twenty-blue chip identity; .pill owns
   the sizing/shape so we only inherit the font family and add the cursor. */
.merge-field-chip {
  background: #E9F0FE; color: #1961ED;
  border: 0; font-family: inherit; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.merge-field-chip:hover { background: #DCE8FB; }
.merge-field-chip:focus-visible { outline: 2px solid #1961ED; outline-offset: 1px; }
.merge-fields-help {
  flex-basis: 100%; color: var(--text-muted); font-size: 12px; margin-top: 2px;
}

/* #110 compose/save-time merge-lint panel. Inter throughout — the {{field}}
   tokens are author field names, NOT IDs, so they are not mono (CLAUDE.md mono
   rule). Colors from design-system.md: warn #C8860A, error #D14343. */
.merge-lint { margin: 0 0 16px; display: flex; flex-direction: column; gap: 8px; }
.merge-lint-item {
  border: 1px solid; border-radius: 8px; padding: 10px 12px; font-size: 13px;
}
.merge-lint-warn  { background: #FDF6EA; border-color: #EAD6A6; color: #6B5212; }
.merge-lint-block { background: #FCF1F1; border-color: #E7B7B7; color: #8A2F2F; }
.merge-lint-head { display: block; font-weight: 600; margin-bottom: 4px; }
.merge-lint-warn  .merge-lint-head { color: #C8860A; }
.merge-lint-block .merge-lint-head { color: #D14343; }
.merge-lint-item p  { margin: 0 0 6px; }
.merge-lint-item ul { margin: 0; padding-left: 18px; }
.merge-lint-item li { margin: 2px 0; }
.merge-lint-token {
  font-weight: 600;                 /* Inter, NOT mono */
  background: rgba(0, 0, 0, 0.04); padding: 0 4px; border-radius: 4px;
}
/* slice 3: compact confirm-panel notice (informational, not a hard gate). */
.merge-lint-confirm {
  font-size: 13px; color: #6B5212; background: #FDF6EA;
  border: 1px solid #EAD6A6; border-radius: 6px; padding: 8px 10px; margin: 4px 0;
}
.merge-lint-confirm-block {
  color: #8A2F2F; background: #FCF1F1; border-color: #E7B7B7;
}

/* #43 event public-visibility pills */
.pill-draft     { background: #EEEEF0; color: #56565E; }
.pill-published { background: #DBF2E3; color: #1A7A47; }

/* channel membership status pills (person-detail Channels consent panel).
   Same palette as send/outcome pills: subscribed=green, unsubscribed=neutral,
   bounced=red, complained=deep red. */
.pill-channel-subscribed   { background: #DBF2E3; color: #1A7A47; }
.pill-channel-unsubscribed { background: #EEEEF0; color: #56565E; }
.pill-channel-bounced      { background: #FBE0E0; color: #B23B3B; }
.pill-channel-complained   { background: #F6D5D5; color: #8A2F2F; }

/* send-status pills (collection -> email send) */
.pill-status-draft   { background: #EEEEF0; color: #56565E; }
.pill-status-sending { background: #FCEAD9; color: #9A5414; }
.pill-status-sent    { background: #DBF2E3; color: #1A7A47; }
.pill-status-failed  { background: #FBE0E0; color: #B23B3B; }

/* per-recipient delivery-outcome pills (derived from ses_events). Mirror
   the send-status palette: greens = good, reds = bounce/complaint/failed,
   amber = soft/in-flight/unknown, grey = pending/suppressed. */
.pill-outcome-delivered  { background: #DBF2E3; color: #1A7A47; } /* green */
.pill-outcome-sent       { background: #DBF2E3; color: #1A7A47; }
.pill-outcome-bounced    { background: #FBE0E0; color: #B23B3B; } /* red */
.pill-outcome-complaint  { background: #ECE4F7; color: #6B3FA0; } /* purple (distinct from bounce) */
.pill-outcome-failed     { background: #FBE0E0; color: #B23B3B; }
.pill-outcome-soft       { background: #FCEAD9; color: #9A5414; } /* orange */
.pill-outcome-unknown    { background: #FCEAD9; color: #9A5414; }
.pill-outcome-suppressed { background: #EEEEF0; color: #56565E; } /* neutral */
.pill-outcome-pending    { background: #EEEEF0; color: #56565E; }

/* event invitee-roster pills (#41). RSVP funnel: green=accepted,
   amber=tentative, red=declined, grey=no-response. Invited + attended are
   accent/green affirmatives; the not-yet states recede to a muted dash. */
.pill-rsvp-accepted   { background: #DBF2E3; color: #1A7A47; } /* green */
.pill-rsvp-tentative  { background: #FCEAD9; color: #9A5414; } /* orange */
.pill-rsvp-declined   { background: #FBE0E0; color: #B23B3B; } /* red */
.pill-rsvp-none       { background: #EEEEF0; color: #56565E; } /* neutral */
.pill-invited         { background: #E9F0FE; color: #1961ED; } /* accent family = "current" */
.pill-current         { background: #E9F0FE; color: #1961ED; } /* "current/now" = accent */
.pill-attended        { background: #DBF2E3; color: #1A7A47; }
.roster-none          { color: var(--faint, #A8A8B0); }

/* #438 roster seed in-flight state. htmx puts .htmx-request on the submitting
   seed form and on .roster-seed (hx-indicator) for as long as the pull runs,
   and disables every seed control (hx-disabled-elt). The button swaps to its
   in-progress label, the status line appears, and the roster table dims so a
   multi-second pull never looks hung. No spinner (design-system.md §Motion). */
.roster-seed .seed-idle { display: inline-flex; align-items: center; gap: inherit; }
.roster-seed .seed-busy { display: none; }
.roster-seed form.htmx-request .seed-idle { display: none; }
.roster-seed form.htmx-request .seed-busy { display: inline; }
.roster-seed-status { display: none; margin: 6px 0 0; }
.roster-seed.htmx-request .roster-seed-status { display: block; }
.section:has(> .roster-seed.htmx-request) button[disabled],
.section:has(> .roster-seed.htmx-request) select[disabled] {
  opacity: 0.6; cursor: progress;
}
/* Sort/filter/load-more links are anchors, which hx-disabled-elt cannot
   disable, and each one swaps the WHOLE roster block — re-enabling Send
   invites mid-seed (codex + grok review). Freeze them for the pull. */
.section:has(> .roster-seed.htmx-request) a { pointer-events: none; }
.section:has(> .roster-seed.htmx-request) .data-table {
  opacity: 0.5; transition: opacity 150ms ease-out;
}

/* roster rollup summary line: small inline funnel counts under the heading */
.roster-rollup { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 10px; }
.roster-rollup .pill { font-weight: 500; }

/* #294 clickable status-filter pills, directly above the roster table. Each is
   a real <button>; the active pill uses the accent ("current state" = accent,
   design-system.md). Inter + tabular counts, not the reserved monospace. */
.roster-pills {
  display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 10px;
}
.roster-pill {
  display: inline-flex; align-items: center;
  padding: 3px 10px; border-radius: 999px;
  font-size: 13px; font-weight: 500; line-height: 1.4;
  color: var(--text); background: #EEEEF0;
  border: 1px solid transparent; cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.roster-pill:hover { background: #E3E3E7; }
.roster-pill-active {
  background: var(--accent-soft); color: var(--accent);
  border-color: var(--accent);
}
.roster-pill-active:hover { background: var(--accent-soft); }
/* compact per-row RSVP setter in the roster actions column */
.roster-rsvp-set { display: inline-flex; gap: 4px; align-items: center; }
/* Compact per-row RSVP editor: a narrow auto-submitting <select>. The funnel
   state itself is shown by the read-only RSVP column pill; this is just the
   (small) editor, so it doesn't repeat the three options inline. */
.roster-rsvp-set select {
  padding: 3px 8px; border: 1px solid var(--border); border-radius: 6px;
  font: inherit; font-size: 12px; color: var(--text); background: var(--bg);
  cursor: pointer;
}
.roster-rsvp-set select:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}

/* right-aligned numeric column (counts) — Inter tabular-nums, not mono */
.cell-num { text-align: right; font-variant-numeric: tabular-nums; }

/* -------- #292: CSS-only count breakdown popover (GENERIC pattern) --------
   .count-popover-anchor wraps a count in any list cell; the breakdown is
   server-rendered inline (hidden) and revealed on :hover / :focus-within
   (the anchor carries tabindex=0 so keyboard focus works). Spans only —
   valid inline content for a <td>; rows become blocks here. Panel per
   design-system.md: surface bg, hairline border, radius 8px, 12.5px text
   (tokens, so a future dark palette flows through automatically). */
.count-popover-anchor {
  position: relative;
  display: inline-block;
  cursor: default;
  font-variant-numeric: tabular-nums;
}
.count-popover {
  display: none;
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 60;
  min-width: 180px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow-card);
  padding: 8px 12px;
  font-size: 12.5px;
  font-weight: 400;
  color: var(--text);
  text-align: left;
  white-space: nowrap;
}
.count-popover-anchor:hover .count-popover,
.count-popover-anchor:focus-within .count-popover { display: block; }
.count-popover-row { display: block; padding: 2px 0; }
/* a td hosting a popover must not clip it (data-table cells default to
   overflow:hidden for ellipsis) */
.data-table td.cell-popover-host { overflow: visible; text-overflow: clip; }
/* codex #292: the cell override alone is not enough — .data-table itself has
   overflow:hidden (rounded-corner clip), which would clip a downward popover
   on the LAST row. Relax it ONLY on a table that actually hosts a popover
   (:has, supported in current Chrome); every other table keeps its clip. */
.data-table:has(td.cell-popover-host) { overflow: visible; }
.cell-when { color: var(--text-muted); font-size: 13px; }
/* a count that should draw the eye when non-zero (bounces, complaints) */
.cell-alert { color: #B91C1C; font-weight: 600; }

/* ID-like cell (tracking numbers, slugs, ids) — Geist Mono per the
   design system's reserved mono role; never used for names/emails. */
.cell-mono {
  font-family: ui-monospace, 'Geist Mono', SFMono-Regular, Menlo, monospace;
  font-size: 12px; color: var(--text-muted);
}

/* inline monospace run (an ID/slug embedded in proportional prose) — the
   reserved mono role, without the table-cell color/size of .cell-mono. */
.mono { font-family: ui-monospace, 'Geist Mono', SFMono-Regular, Menlo, monospace; }

/* monospace text input — mirrors .cell-mono for editing ID-like attrs
   (tracking numbers, tokens) per the design system's mono allowance. */
.input-mono {
  font-family: ui-monospace, 'Geist Mono', SFMono-Regular, Menlo, monospace;
  font-size: 12px;
}

/* raw message-source preview (HTML/text body) — technical output, so
   monospace is in-bounds per the design system's mono allowance. */
.code-block {
  font-family: ui-monospace, 'Geist Mono', SFMono-Regular, Menlo, monospace;
  font-size: 12.5px; line-height: 1.5;
  background: var(--bg-soft); border: 1px solid var(--border);
  border-radius: 6px; padding: 12px;
  white-space: pre-wrap; word-break: break-word; overflow-x: auto;
}

/* inline icon (e.g. building next to company name) */
.cell-with-icon { display: inline-flex; align-items: center; gap: 6px; }
.cell-with-icon svg { width: 13px; height: 13px; color: var(--text-muted); flex-shrink: 0; }
/* #347: the company building icon as a CSS mask — one element per row instead of
   a 12-element inline <svg>. The glyph is *icon-paths* :building verbatim (a test
   compares it); a mask uses alpha only, so the stroke is an opaque 'black' and the
   colour comes from background-color, which follows the theme. */
.icon-building {
  display: inline-block; width: 13px; height: 13px; flex-shrink: 0;
  background-color: var(--text-muted);
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='4' y='2' width='16' height='20' rx='2' ry='2'/><path d='M9 22v-4h6v4'/><path d='M8 6h.01'/><path d='M16 6h.01'/><path d='M12 6h.01'/><path d='M12 10h.01'/><path d='M12 14h.01'/><path d='M16 10h.01'/><path d='M16 14h.01'/><path d='M8 10h.01'/><path d='M8 14h.01'/></svg>");
  mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='4' y='2' width='16' height='20' rx='2' ry='2'/><path d='M9 22v-4h6v4'/><path d='M8 6h.01'/><path d='M16 6h.01'/><path d='M12 6h.01'/><path d='M12 10h.01'/><path d='M12 14h.01'/><path d='M16 10h.01'/><path d='M16 14h.01'/><path d='M8 10h.01'/><path d='M8 14h.01'/></svg>");
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: 13px 13px; mask-size: 13px 13px;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}

/* row-action buttons (HTMX-driven): edit pencil + delete x */
.cell-row-actions { width: 56px; padding-right: 8px; text-align: right; white-space: nowrap; }
.cell-row-actions form { display: inline; margin: 0; padding: 0; }
.cell-row-actions .row-edit-pencil { margin-right: 2px; }
/* #347: the roster row's RSVP setter + Remove (a class, not a per-row inline style). */
.roster-row-actions { display: flex; gap: 8px; align-items: center; justify-content: flex-end; }
.row-delete-x, .row-edit-pencil {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; padding: 0;
  background: transparent; border: 1px solid transparent; border-radius: 4px;
  color: var(--text-muted); cursor: pointer;
  font-size: 14px; line-height: 1;
}
.row-edit-pencil svg { width: 14px; height: 14px; stroke-width: 2; }
.row-delete-x:hover {
  background: #FEF2F2; color: #B91C1C; border-color: #FECACA;
}
.row-edit-pencil:hover {
  background: #EFF6FF; color: #1D4ED8; border-color: #BFDBFE;
}
.row-delete-x.button-disabled {
  cursor: not-allowed; pointer-events: none; opacity: 0.4;
}

/* utility */
.muted { color: var(--text-muted); font-size: 13px; }
.spacer { flex: 1; }
.empty-state { padding: 48px 24px; text-align: center; color: var(--text-muted); }

/* HTMX modal overlay (slice 7). The shell server writes its content
   into #modal-root via hx-target. Empty #modal-root means no modal.
   Cancel buttons clear #modal-root via plain JS; backdrop click does
   the same. Successful submit returns HX-Redirect so HTMX navigates
   to the new entity's detail page. */
.modal-overlay {
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, 0.45);
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 80px;
  z-index: 200;
}
.modal-dialog {
  background: var(--bg);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.18), 0 4px 10px rgba(0,0,0,0.06);
  width: 100%; max-width: 520px;
  max-height: calc(100vh - 120px);
  overflow: auto;
}
.modal-dialog .form-card {
  border: none; border-radius: 0;
  max-width: none; padding: 24px;
}

/* HTMX in-flight indicator: thin progress bar under the topbar.
   HTMX adds the htmx-request class to body while a request is in
   flight; targeting #indicator off body.htmx-request lets a single
   layout-level element react to any request without per-trigger
   hx-indicator wiring. */
#indicator {
  position: fixed; top: 56px; left: 0; right: 0;
  height: 2px; background: var(--accent);
  opacity: 0;
  transform-origin: left;
  transform: scaleX(0);
  transition: opacity 0.2s ease, transform 0.4s ease;
  z-index: 100;
  pointer-events: none;
}
body.htmx-request #indicator {
  opacity: 1;
  transform: scaleX(0.7);
}

/* forms */
.form-card {
  max-width: 520px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 24px;
}
.form-card h1 { margin: 0 0 4px; font-size: 20px; font-weight: 600; letter-spacing: -0.01em; }
.form-card .form-help { color: var(--text-muted); font-size: 13px; margin: 0 0 20px; }
.form-card label {
  display: block; margin-bottom: 4px;
  font-size: 12px; font-weight: 500; color: var(--text);
}
/* #365: `select` joins input/textarea here. It was omitted, so any <select>
   dropped into a form-card rendered as a bare native control — visibly out of
   family, and (because it then had no margin-bottom) the following .field-hint's
   -10px top margin pulled the hint text up THROUGH it. Caught by the event-form
   screenshot when the Channel picker landed. */
.form-card input, .form-card textarea, .form-card select {
  display: block; width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--border); border-radius: 6px;
  font: inherit; font-size: 14px;
  background: var(--bg); color: var(--text);
  margin-bottom: 14px;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.form-card textarea { resize: vertical; min-height: 80px; }
.form-card input:focus, .form-card textarea:focus, .form-card select:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.form-card .form-actions { display: flex; gap: 8px; margin-top: 8px; }
/* de-emphasized field (e.g. auto-generated URL slug) — secondary, not the focus */
.form-card label.label-muted { color: var(--text-muted); font-weight: normal; }
.form-card .field-hint {
  display: block; color: var(--text-muted); font-size: 11px;
  margin: -10px 0 14px;
}
/* inline checkbox + label (e.g. the "major change" RSVP-reset toggle) */
.form-card label.label-check {
  display: flex; align-items: center; gap: 8px;
  font-weight: normal; margin: 4px 0;
}
.form-card label.label-check input {
  display: inline-block; width: auto; margin: 0;
}

/* #101 compose: widen just this form-card so editor + live preview fit
   side by side. The rest of the form (subject/from/plain-text/save) stays
   single-column inside the wider card. */
.form-card.form-card-wide { max-width: 960px; }

.compose-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;                          /* design-system lg spacing */
  align-items: stretch;
  margin-bottom: 14px;                /* match the cadence of stacked fields */
}
.compose-split > * { min-width: 0; }  /* let columns shrink; no overflow */
.compose-split .compose-editor { display: flex; flex-direction: column; }
.compose-split .compose-editor textarea {
  flex: 1 1 auto; min-height: 320px;
  margin-bottom: 0;                   /* the grid gap owns spacing here */
}

.compose-preview { display: flex; flex-direction: column; }
/* the preview heading is a <span>, not a <label> (an iframe isn't a
   labelable control) — mirror the form's label rhythm so both columns read
   as labeled fields. */
.compose-preview .compose-preview-label {
  display: block; margin-bottom: 4px;
  font-size: 12px; font-weight: 500; color: var(--text);
}
.compose-preview .compose-preview-frame {
  flex: 1 1 auto; width: 100%; min-height: 320px;
  border: 1px solid var(--border); border-radius: 6px;
  background: #FFFFFF;                /* recipient canvas is white regardless of app */
}
.compose-preview .compose-preview-caption {
  font-size: 11px; color: var(--text-muted); margin: 6px 0 0;
}

/* Narrow: stack preview beneath the editor (design-system: collapse the
   secondary column before the phone breakpoint). */
@media (max-width: 900px) {
  .compose-split { grid-template-columns: 1fr; }
  .form-card.form-card-wide { max-width: 520px; }
}

/* flash */
.flash {
  padding: 10px 14px; margin: 0 0 16px;
  border-radius: 6px; font-size: 13px;
  border: 1px solid transparent;
}
.flash.error { background: #FEF2F2; color: #B91C1C; border-color: #FECACA; }
.flash.ok    { background: #F0FDF4; color: #15803D; border-color: #BBF7D0; }
/* #363: the third state — not a failure the operator just caused (.error), not
   a confirmation (.ok), but a standing condition worth acting on: a published
   event with no invitation body. Same 50/700/200 ramp as its siblings, amber. */
.flash.warning { background: #FFFBEB; color: #B45309; border-color: #FDE68A; }
.flash.warning a { color: inherit; text-decoration: underline; }

/* T9: floating flash-toast (success confirmation after modal save).
   #flash sits in with-layout (fixed top-right); each modal save
   OOB-swaps a fresh .flash-toast into it. The CSS animation drives
   the show + fade-out lifecycle in ~4s with no JS timer. */
#flash {
  position: fixed; top: 16px; right: 16px;
  z-index: 1000;
  pointer-events: none;
}
.flash-toast {
  background: #15803D; color: white;
  padding: 10px 14px; border-radius: 6px;
  font-size: 13px; font-weight: 500;
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  animation: flash-toast-show-fade 4s ease-in-out forwards;
  pointer-events: auto;
}
@keyframes flash-toast-show-fade {
  0%   { opacity: 0; transform: translateY(-12px); }
  10%  { opacity: 1; transform: translateY(0); }
  85%  { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-12px); }
}

/* detail page sections */
.detail-header {
  display: flex; align-items: flex-start; gap: 16px;
  margin: 8px 0 24px;
}
.detail-header .avatar { width: 40px; height: 40px; font-size: 14px; }
.detail-title { display: flex; flex-direction: column; }
.detail-title h1 {
  margin: 0; font-size: 22px; font-weight: 600; letter-spacing: -0.015em;
}
.detail-title .detail-sub { color: var(--text-muted); font-size: 13px; margin-top: 2px; }
.detail-title .detail-sub a { color: var(--text-muted); }
.detail-title .detail-sub a:hover { color: var(--accent); }

.section { margin: 24px 0; }
.section h2 {
  font-size: 14px; font-weight: 600; letter-spacing: 0.01em;
  text-transform: uppercase; color: var(--text-muted);
  margin: 0 0 12px;
}

/* person address block (SF import #8) — proportional plain text, not the
   browser-default italic <address> rendering, and not mono (per design-system). */
.person-address {
  font-style: normal; color: var(--text); font-size: 14px; line-height: 1.5;
}
.person-address div { margin: 0; }

/* #296 detail field grid (design-system: header → field grid; cells 6px×11px,
   11px labels, 12.5px values). Proportional Inter throughout — values here are
   phone/address, which are NEVER mono. Colors ride the theme vars, so light
   and dark both work. */
.field-grid {
  display: grid; grid-template-columns: max-content 1fr;
  margin: 0; max-width: 480px;
}
.field-grid dt {
  padding: 6px 11px 6px 0;
  font-size: 11px; font-weight: 500; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--text-muted);
  align-self: baseline;
}
.field-grid dd {
  margin: 0; padding: 6px 0 6px 11px;
  font-size: 12.5px; color: var(--text); line-height: 1.45;
}
.field-grid dd a { color: var(--text); }
.field-grid dd a:hover { color: var(--accent); }
.field-grid dd div { margin: 0; }

/* notes */
.notes-list { list-style: none; padding: 0; margin: 0; }
.notes-list li {
  padding: 12px 14px; border: 1px solid var(--border-soft);
  border-radius: 6px; margin-bottom: 8px; background: var(--bg-soft);
}
.notes-list .note-text { margin: 0 0 4px; color: var(--text); font-size: 14px; }
.notes-list .note-time { color: var(--text-muted); font-size: 12px; }

/* inline add-note + add-attendee forms (shared visual treatment) */
.add-note,
.add-attendee {
  margin-top: 12px;
  border: 1px solid var(--border); border-radius: 6px;
  padding: 12px 14px; background: var(--bg);
}
.add-note textarea {
  width: 100%; border: none; resize: vertical; min-height: 48px;
  font: inherit; font-size: 14px; outline: none;
  padding: 0; background: transparent;
}
.add-note .add-note-actions { display: flex; justify-content: flex-end; margin-top: 8px; }

/* attendance / attendees mini-table */
.mini-table { font-size: 13px; }
.mini-table .cell-name a { color: var(--text); font-weight: 500; }

/* pagination */
.pagination {
  display: flex; gap: 8px; align-items: center;
  margin-top: 16px; font-size: 13px; color: var(--text-muted);
}

/* #11 — event images
   object-fit: contain so the user's uploaded image is never silently
   cropped. Box is still capped at 600x300 so tall portraits don't
   push the page around; off-aspect images get letterboxed instead. */
.event-image-banner {
  width: 100%; max-width: 600px; max-height: 300px;
  object-fit: contain; border-radius: 8px; margin-bottom: 16px;
}
.event-list-thumb {
  width: 32px; height: 32px; object-fit: cover;
  border-radius: 4px; vertical-align: middle; margin-right: 8px;
}
.image-upload-form {
  margin-top: 16px; padding: 12px;
  border: 1px solid var(--border); border-radius: 6px;
}
.image-upload-form h3 { font-size: 14px; font-weight: 600; }

/* #12 — column visibility dropdown */
.table-controls {
  position: relative;
  display: flex; justify-content: flex-end;
  padding: 4px 0;
}
.gear-button {
  background: transparent; border: none; padding: 4px;
  cursor: pointer; color: var(--text-muted);
}
.gear-button:hover { color: var(--text); }
.cols-dropdown {
  position: absolute; right: 0; top: 32px; z-index: 50;
  background: var(--bg); border: 1px solid var(--border);
  border-radius: 6px; padding: 12px;
  box-shadow: 0 4px 10px rgba(0,0,0,.08);
  min-width: 160px;
}
.cols-dropdown h4 {
  font-size: 12px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-muted);
  margin: 0 0 8px 0;
}
.cols-dropdown label {
  display: block; margin-bottom: 6px; cursor: pointer; font-size: 14px;
}
.cols-dropdown input[disabled] + * { color: var(--text-muted); cursor: not-allowed; }

/* #13 — sortable column headers */
.data-table thead th a {
  color: inherit; text-decoration: none;
  display: inline-flex; align-items: center; gap: 4px;
  cursor: pointer;
}
.data-table thead th a:hover { color: var(--accent); }
.sort-indicator { font-size: 10px; color: var(--text-muted); }
.sort-indicator.active { color: var(--accent); }

/* #14 — column headers. The browser-native `resize: horizontal` was removed:
   it paints a permanent diagonal resize glyph in every header cell (visual
   noise that fights the clean Twenty look), and there is no CSS-only way to
   show the handle only on the column border / on hover. Natural sizing reads
   cleaner; a hover-border drag handle would be a small JS follow-up. */
.data-table thead th { min-width: 60px; }

/* #15 — datetime-local pickers */
.tz-hint {
  color: var(--text-muted); font-size: 11px; margin-left: 4px;
  font-weight: normal;
}
input[type="datetime-local"] { font: inherit; }

/* small inline link next to a field label, e.g. "set to start + 1 hr" */
.field-action {
  color: var(--text-muted); font-size: 11px;
  text-decoration: none; font-weight: normal;
  margin-left: 4px;
}
.field-action:hover { color: var(--accent); text-decoration: underline; }

/* #23 / #282 — signed-in chrome on the topbar right: an account menu
   anchored on the user's email. The .topnav (flex:1) pushes this to the
   far right, so no margin-left:auto is needed here. */
.user-menu { position: relative; display: inline-flex; align-items: center; }
.user-menu-trigger {
  display: inline-flex; align-items: center; gap: 6px;
  height: 32px; padding: 0 8px;
  background: none; border: 1px solid transparent; border-radius: 6px;
  font: inherit; font-size: 13px; font-weight: 500; color: var(--text);
  cursor: pointer;
}
.user-menu-trigger:hover,
.user-menu.open .user-menu-trigger { background: var(--bg-soft); }
.user-menu-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.user-menu-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.user-menu-trigger svg {
  width: 14px; height: 14px; opacity: 0.7;
  transition: transform 120ms ease-out;
}
.user-menu.open .user-menu-trigger svg { transform: rotate(180deg); }
.user-menu-email { color: var(--text); }

.user-menu-panel {
  display: none;
  position: absolute; top: calc(100% + 6px); right: 0;
  min-width: 184px; padding: 4px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: var(--shadow-card);
  z-index: 20;
}
.user-menu.open .user-menu-panel { display: block; }
.user-menu-panel form { margin: 0; }
.user-menu-item {
  display: block; width: 100%; text-align: left;
  padding: 7px 10px; border-radius: 6px;
  font: inherit; font-size: 13px; color: var(--text);
  background: none; border: none; cursor: pointer;
}
.user-menu-item:hover { background: var(--bg-soft); text-decoration: none; }
.button-small { padding: 4px 8px; font-size: 12px; }


/* -------- subset-send compose filter (issue #30) -------- */
.send-filter {
  border: 1px solid var(--border); border-radius: 8px;
  padding: 14px 16px; margin: 0 0 16px;
  background: var(--bg-soft);
}
.send-filter > legend {
  font-size: 12px; font-weight: 600; color: var(--text-muted);
  padding: 0 6px;
}
.send-filter .filter-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-bottom: 10px;
}
.send-filter .filter-row > label {
  margin: 0; min-width: 132px; font-size: 12px; font-weight: 500;
}
.send-filter select, .send-filter input {
  display: inline-block; width: auto; margin: 0;
  padding: 6px 10px; font-size: 13px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--bg); color: var(--text);
}
.send-filter .filter-count {
  margin: 12px 0 4px; font-size: 13px; color: var(--text);
}
.send-filter .filter-count .muted, .filter-count .muted { color: var(--text-muted); }
.send-filter .send-mode {
  display: flex; flex-direction: column; gap: 6px;
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border);
}
.send-filter .send-mode-opt {
  display: flex; align-items: center; gap: 6px;
  margin: 0; font-size: 13px; font-weight: 500; color: var(--text);
}
.send-filter .send-mode-opt input { width: auto; }

/* -------- Option C draft refinement (issue #67) -------- */
/* Collapsed inline recipients panel: a <details> whose summary is the
   "To N recipients" line. Inline expand, no drawer/JS. */
.recipients-panel {
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-soft); padding: 0; margin: 0 0 12px;
}
.recipients-panel > summary {
  cursor: pointer; list-style: none;
  padding: 12px 14px; font-size: 14px; font-weight: 600; color: var(--text);
  font-variant-numeric: tabular-nums;
  display: flex; align-items: baseline; gap: 8px;
}
.recipients-panel > summary::-webkit-details-marker { display: none; }
.recipients-panel > summary::before {
  content: "▸"; color: var(--text-muted); font-size: 11px; font-weight: 400;
}
.recipients-panel[open] > summary::before { content: "▾"; }
.recipients-panel > summary .muted { font-weight: 400; font-size: 12.5px; }
.recipients-panel > summary:hover { color: var(--accent); }
/* the panel body sits below the summary with a hairline divider */
.recipients-panel[open] > summary { border-bottom: 1px solid var(--border); }
.recipients-panel .recipient-search { padding: 12px 14px 0; }
.recipients-panel .recipient-search input {
  display: block; width: 100%; padding: 7px 10px; font-size: 13px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--bg); color: var(--text);
}
.recipients-panel .data-table { margin: 12px 0 0; }
.recipient-pager {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px; font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
.recipient-pager .muted { margin-right: auto; }

/* The three explicit, separately-labelled audience-population modes
   (whole collection / specific people / matching a filter). Stacked, each
   its own card — never side-by-side radios. */
.add-recipients {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px; padding: 14px;
}
.add-recipients .add-mode {
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg); padding: 12px;
}
.add-recipients .add-mode h3 {
  margin: 0 0 8px; font-size: 12px; font-weight: 600; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.03em;
}
.add-recipients .add-mode select,
.add-recipients .add-mode input[type="text"],
.add-recipients .add-mode input[type="search"] {
  display: block; width: 100%; padding: 6px 9px; font-size: 13px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--bg); color: var(--text); margin-bottom: 8px;
}
/* same accent focus affordance as the other pickers/fields */
.add-recipients .add-mode select:focus,
.add-recipients .add-mode input[type="text"]:focus,
.add-recipients .add-mode input[type="search"]:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.add-recipients .add-mode .filter-row {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.add-recipients .add-mode .filter-row > * { flex: 1; min-width: 80px; margin-bottom: 8px; }

/* Always-confirm fire control (#67, decision 3). */
#send-control { margin-top: 16px; }
.send-confirm {
  border: 1px solid var(--accent); border-radius: 8px;
  background: var(--accent-soft); padding: 14px 16px;
}
.send-confirm p { margin: 0 0 8px; font-variant-numeric: tabular-nums; }
.send-confirm .form-help { margin-bottom: 12px; }

/* ===================================================================
   #43 — Public events surface (/e/*). Chrome-free, Twenty-clean, Inter,
   reuses the app design tokens (light). No master-detail shell here —
   this is the outward-facing marketing-ish read surface.
   =================================================================== */
.public-page { background: var(--bg-soft); min-height: 100vh; }
.public-header {
  display: flex; align-items: center; justify-content: space-between;
  max-width: 880px; margin: 0 auto; padding: 16px 24px;
}
.public-brand { font-weight: 700; font-size: 18px; color: var(--text); letter-spacing: -0.02em; }
.public-brand:hover { text-decoration: none; }
.public-nav { display: flex; gap: 16px; }
.public-nav a { font-size: 13px; font-weight: 500; color: var(--text-muted); }
.public-nav a:hover { color: var(--accent); text-decoration: none; }
.public-main { max-width: 880px; margin: 0 auto; padding: 8px 24px 48px; }
.public-page-title { font-size: 24px; font-weight: 700; letter-spacing: -0.02em; color: var(--text); margin: 12px 0 20px; }
.public-page-foot { margin-top: 28px; font-size: 13px; }

/* card list — #143 image-forward landing (webex-frappe parity): a scrollable
   column of LARGE hero images, each over its title, summary, and a prominent
   request-invite CTA. */
.public-card-list { display: flex; flex-direction: column; gap: 24px; }
.public-card {
  display: flex; flex-direction: column; background: var(--bg);
  border: 1px solid var(--border); border-radius: 10px; overflow: hidden;
  box-shadow: var(--shadow-card);
}
.public-card-image { display: block; }
.public-card-image:hover { text-decoration: none; }
/* Large hero. object-fit: contain (matching the #104 detail-banner rule) shows
   the FULL uploaded graphic — never cropped — letterboxed on a soft field, so
   posters/flyers with text stay readable while every card reads big + uniform. */
.public-card-banner {
  width: 100%; max-height: 360px; object-fit: contain; display: block;
  background: var(--bg-soft); border-bottom: 1px solid var(--border);
}
.public-card-body { display: flex; flex-direction: column; gap: 6px; padding: 18px 20px; min-width: 0; }
.public-card-title { font-size: 20px; font-weight: 700; letter-spacing: -0.02em; margin: 0; }
.public-card-title a { color: var(--text); }
.public-card-title a:hover { color: var(--accent); text-decoration: none; }
.public-card-desc { font-size: 14px; line-height: 1.6; color: var(--text); margin: 6px 0 0; }
.public-card-more { font-weight: 600; white-space: nowrap; }
.public-card-actions { margin-top: 14px; }
.public-when { font-size: 12.5px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
/* #112: the viewer-local time block, on the detail page AND on every list card.
   It holds exactly ONE line — the time in the viewer's own zone, labeled — so
   the wrapper is only here to be a stable swap target. */
.public-when-wrap { display: flex; flex-direction: column; gap: 2px; }
.public-speaker { font-size: 12.5px; color: var(--text-muted); }
/* #48 social-proof "N people attending" (shown only when N >= 10) */
.public-attending {
  font-size: 12.5px; font-weight: 600; color: var(--accent);
  margin: 2px 0 0; font-variant-numeric: tabular-nums;
}
.public-empty { color: var(--text-muted); font-size: 14px; padding: 24px 0; }

/* pager */
.public-pager { display: flex; justify-content: space-between; margin-top: 28px; }
.public-pager a { font-size: 13px; font-weight: 500; }
.public-pager-next { margin-left: auto; }

/* detail */
/* object-fit: contain so the uploaded graphic is shown in full, never
   cropped (matches the #11 edit-page banner rule). max-height caps tall
   portraits while still letting a standard 16:9 banner fill the column
   width (≈468px at the 832px content width) edge-to-edge. */
.public-detail-banner { width: 100%; max-height: 480px; object-fit: contain; border-radius: 10px; margin: 8px 0 20px; }
.public-detail { background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 24px; box-shadow: var(--shadow-card); }
.public-detail-title { font-size: 26px; font-weight: 700; letter-spacing: -0.02em; color: var(--text); margin: 0 0 8px; }
.public-detail .public-when { font-size: 14px; }
.public-detail .public-speaker { font-size: 14px; color: var(--text-muted); margin: 4px 0 0; }
.public-detail .public-attending { font-size: 14px; margin: 12px 0 0; }
.public-description { margin-top: 18px; }
.public-description p { font-size: 14px; line-height: 1.6; color: var(--text); white-space: pre-wrap; }

/* actions + CTAs */
.public-actions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-top: 24px; }
.public-cta {
  display: inline-block; background: var(--accent); color: #fff; font-size: 13px; font-weight: 600;
  padding: 9px 16px; border-radius: 6px;
}
.public-cta:hover { background: var(--accent-hover); text-decoration: none; }
.public-cta-secondary {
  display: inline-block; background: var(--bg); color: var(--text); border: 1px solid var(--border);
  font-size: 13px; font-weight: 500; padding: 9px 16px; border-radius: 6px;
}
.public-cta-secondary:hover { background: var(--bg-soft); text-decoration: none; }

/* #141 gated add-to-calendar (shown ONLY on the request-invite confirmation,
   never to anonymous visitors). The note is deliberately honest about per-
   provider de-dupe: Google merges by UID, Apple/Outlook may not. */
.public-add-to-calendar { margin: 20px 0 4px; }
.public-add-to-calendar-note {
  font-size: 12px; line-height: 1.5; color: var(--text-muted); margin: 10px 0 0; max-width: 480px;
}

/* #47 public request-invite form. Inside .public-detail; matches the public
   card aesthetic (Inter, accent blue, 6px radius, soft borders). Single column,
   comfortable touch targets — this is the one public WRITE affordance. */
.public-request-invite {
  margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--border-soft);
}
.public-request-invite-title {
  font-size: 16px; font-weight: 700; letter-spacing: -0.01em; color: var(--text);
  margin: 0 0 4px;
}
.public-request-invite-help {
  font-size: 13px; line-height: 1.5; color: var(--text-muted); margin: 0 0 14px;
}
.public-request-invite-form { display: flex; flex-direction: column; gap: 4px; max-width: 420px; }
.public-request-invite-form label {
  font-size: 12px; font-weight: 500; color: var(--text-muted); margin-top: 8px;
}
.public-request-invite-form input {
  width: 100%; padding: 9px 12px; border: 1px solid var(--border); border-radius: 6px;
  font: inherit; font-size: 14px; background: var(--bg); color: var(--text);
  outline: none; transition: border-color 0.15s, box-shadow 0.15s;
}
.public-request-invite-form input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft, rgba(37, 99, 235, 0.15));
}
/* #395 /join/ signup: honeypot kept off-screen (not display:none, which some
   bots skip), and the consent wording as a quiet note above the button. */
.public-hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.public-request-invite-form .public-consent-note {
  font-size: 12px; line-height: 1.5; color: var(--text-muted); margin: 12px 0 0;
}
.public-request-invite-form .public-cta {
  margin-top: 16px; align-self: flex-start; border: none; cursor: pointer;
}
.public-form-error {
  font-size: 13px; font-weight: 500; color: var(--danger, #dc2626);
  background: var(--danger-soft, #fef2f2); border: 1px solid var(--danger-border, #fecaca);
  border-radius: 6px; padding: 10px 12px; margin: 0 0 16px;
}

/* share */
.public-share { display: flex; align-items: center; gap: 12px; margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--border-soft); }
.public-share-label { font-size: 12px; font-weight: 500; color: var(--text-muted); }
.public-share-link { font-size: 12.5px; font-weight: 500; }

/* footer */
.public-footer { max-width: 880px; margin: 0 auto; padding: 24px; font-size: 11px; color: var(--text-muted); border-top: 1px solid var(--border); }

@media (max-width: 640px) {
  .public-card-banner { max-height: 240px; }
  .public-card-body { padding: 14px 16px; }
  .public-card-title { font-size: 18px; }
}

/* company combobox (pure-HTMX picker; lane b). Floating results popup, no
   reserved space; chip for the committed selection. Shared classes so the
   other pickers can reuse them later. */
.combobox { position: relative; }
/* The search input is field-styled here so the picker looks right even outside
   a .form-card (e.g. the company-people / event-roster "add" blocks). */
.combobox > input[type="search"] {
  width: 100%; margin-bottom: 0;
  padding: 7px 12px; border: 1px solid var(--border); border-radius: 6px;
  font: inherit; font-size: 13px; background: var(--bg); color: var(--text);
  outline: none; transition: border-color 0.15s, box-shadow 0.15s;
}
.combobox > input[type="search"]:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.combobox > input[type="search"]::placeholder { color: var(--text-muted); }
.combobox-popup {
  position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 50;
  margin: 0; padding: 4px; list-style: none;
  max-height: 260px; overflow-y: auto;
  background: var(--bg); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.12), 0 2px 6px rgba(0,0,0,0.06);
}
.combobox-popup:empty { display: none; }
.combobox-option {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 10px; border: none; border-radius: 6px; background: none;
  font: inherit; font-size: 14px; color: var(--text); text-align: left; cursor: pointer;
}
.combobox-option:hover, .combobox-option:focus {
  background: var(--accent-soft); outline: none;
}
.combobox-option:focus { box-shadow: inset 0 0 0 1px var(--accent); }
/* #107 roving keyboard nav: the .is-active class lands on the
   <li role="option">; mirror :hover/:focus on its inner button so arrow-key
   navigation reads identically to pointer hover (focus stays on the input,
   which carries aria-activedescendant). */
li[role="option"].is-active > .combobox-option {
  background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent);
}
.combobox-option.is-create {
  color: var(--accent); font-weight: 500; border-top: 1px solid var(--border-soft);
}
.combobox-option.is-create .plus {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 5px;
  background: var(--accent-soft); color: var(--accent); font-weight: 700; line-height: 1;
}
/* Selected state reads as a FILLED FIELD matching the sibling .form-card
   inputs (white bg, same height/padding/border/radius, full width, 14px
   bottom rhythm). The label is the only flexible/ellipsizing region; the ×
   is a fixed, non-shrinking end slot so long names never crowd it. */
.combobox-chip {
  display: flex; align-items: center; width: 100%; box-sizing: border-box;
  min-height: 36px; padding: 8px 12px; margin-bottom: 14px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--bg); color: var(--text);
  font: inherit; font-size: 14px; line-height: 1.4;
}
.combobox-chip .chip-label {
  flex: 1 1 auto; min-width: 0;             /* min-width:0 = the ellipsis fix */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.combobox-chip .chip-x {
  flex: 0 0 auto; margin-left: 8px;
  width: 24px; height: 24px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; border-radius: 4px; background: none; cursor: pointer;
  color: var(--text-muted); font-size: 18px; line-height: 1;
  transition: background 0.12s, color 0.12s;
}
.combobox-chip .chip-x:hover { background: var(--bg-soft); color: var(--text); }
.combobox-chip .chip-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* "create new company" variant: an accent border + a leading "+ New" badge,
   plus an explicit hint below so it's clear a NEW company is created on save.
   The badge is fixed-width (flex:0 0 auto) and BEFORE the label, so a long
   typed name still ellipsizes and never pushes the badge off. */
.combobox-chip.is-new { border-color: var(--accent); }
.combobox-chip .chip-new {
  flex: 0 0 auto; margin-right: 8px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.01em;
  color: var(--accent); background: var(--accent-soft);
  border-radius: 4px; padding: 1px 7px; white-space: nowrap;
}
.combobox-hint {
  display: block; margin: -10px 0 14px;
  font-size: 11px; color: var(--accent);
}

/* Collection picker rows (#102): name on the left, "N members · kind" as a
   muted meta line on the right. The whole option stays one flex row; the name
   ellipsizes so a long campaign name never pushes the count off. */
.combobox-option-name {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.combobox-option-meta {
  flex: 0 0 auto; margin-left: 8px;
  font-size: 12px; color: var(--text-muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.combobox-option-meta .tnum { font-variant-numeric: tabular-nums; }
.combobox-option-kind { color: var(--text-muted); }
/* Non-selectable rows: no-match, truncation footer, empty state. Muted, not a
   button, no hover affordance — Tab/Enter land only on real options. */
.combobox-empty {
  padding: 8px 10px; font-size: 13px; color: var(--text-muted); cursor: default;
}
.compose-blank-hint { margin-top: -8px; }

/* #100 quick-add-person form — the inline "Add new person" form revealed
   under the collection member picker. Lives outside a .form-card, so it
   restates the standard field styling (Inter, 6px-radius inputs, 8px rhythm)
   to match the rest of the surface per design-system.md. */
.quick-add-form {
  margin-top: 8px; padding: 12px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-soft);
}
.quick-add-form label {
  display: block; margin-bottom: 4px;
  font-size: 12px; font-weight: 500; color: var(--text);
}
.quick-add-form input {
  display: block; width: 100%; box-sizing: border-box;
  padding: 8px 12px;
  border: 1px solid var(--border); border-radius: 6px;
  font: inherit; font-size: 14px;
  background: var(--bg); color: var(--text);
  margin-bottom: 12px;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.quick-add-form input:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.quick-add-form input::placeholder { color: var(--text-muted); }
.quick-add-actions { display: flex; gap: 8px; }

/* Pager controls: "Load N more" and, when more than one page remains,
   "Load all N" sit side by side in the load-more row (2026-08-01). Both are
   .button-small; the gap matches .quick-add-actions so the pair reads as one
   control group rather than two stray buttons. */
.list-load-more-actions {
  display: inline-flex; gap: 8px; align-items: center; justify-content: center;
}

/* ===================================================================
   AI Agility public site (ai.agilelnl.com) — src/web-ai-agility.lisp
   Two surfaces on the chrome-free public layout: the membership landing
   (.aia-*) and the 729-workflow browse (.wf-*). Same tokens as the rest
   of the app: Inter, the single accent, hairlines, 8px rhythm. The browse
   is a four-column drill-down (Firm | Specialty | Workflow | panel) that
   the server renders completely; hx-boost swaps the board in place.
   =================================================================== */
.aia-page { background: var(--page); }
.aia-header { max-width: 1280px; gap: 16px; }
.aia-header .public-brand { white-space: nowrap; }
.aia-header .public-nav { flex-wrap: wrap; justify-content: flex-end; row-gap: 4px; }

/* The AgileLnL account site (my.agilelnl.com): the AI Agility page frame with
   the account nav. Sign out is a POST form whose button reads as a nav link. */
.acct-nav { align-items: center; }
.acct-signout { display: inline; margin: 0; }
.acct-signout button {
  font: inherit; font-size: 13px; font-weight: 500; color: var(--text-muted);
  background: none; border: 0; padding: 0; cursor: pointer;
}
.acct-signout button:hover { color: var(--accent); }
.acct-signout button { line-height: inherit; vertical-align: baseline; }
/* Body column lines up with the 1280px header + footer (the browse board is that wide). */
.acct-page .public-main { max-width: 1280px; }
/* The account home (T6): a compact list of attended sessions, date over title,
   and the member box on the inset tint (same frame as the AI Agility CTA band). */
.acct-home > * { max-width: 720px; }
.acct-signed-in { font-size: 14px; color: var(--text-muted); margin: -8px 0 20px; }
.acct-member-box { background: var(--bg-soft); border: 1px solid var(--border); border-radius: 8px; padding: 16px 20px; margin: 0 0 24px; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.acct-member-lead { margin: 0; font-size: 15px; font-weight: 600; color: var(--text); }
.acct-member-box .public-cta { font-size: 14px; padding: 9px 16px; }
.acct-session-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--border); }
.acct-session { display: flex; flex-direction: column; gap: 2px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.acct-session-date { font-size: 12.5px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.acct-session-title { font-size: 15px; font-weight: 600; color: var(--text); }
a.acct-session-title:hover { color: var(--accent); text-decoration: none; }
/* The current tab (#519). */
.acct-nav a[aria-current="page"] { color: var(--text); font-weight: 600; text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 2px; text-underline-offset: 6px; }
/* Your membership (#519): one card per benefit, each with its action. */
.acct-membership > * { max-width: 760px; }
.acct-membership-lead { font-size: 15px; color: var(--text-muted); margin: -8px 0 24px; }
.acct-benefits { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.acct-benefit { background: var(--bg); box-shadow: var(--shadow-card); border: 1px solid var(--border); border-radius: 8px; padding: 18px 20px; display: flex; flex-direction: column; }
.acct-benefit:first-child { grid-column: 1 / -1; background: var(--bg-soft); }
.acct-benefit-title { font-size: 16px; font-weight: 600; letter-spacing: -0.01em; color: var(--text); margin: 0 0 6px; }
.acct-benefit-desc { font-size: 14px; line-height: 1.55; color: var(--text); margin: 0 0 14px; }
.acct-benefit-action { margin-top: auto; }
.acct-benefit-action .public-cta, .acct-benefit-action .public-cta-secondary { font-size: 14px; padding: 9px 16px; }
.acct-benefit-detail { font-size: 13px; color: var(--text-muted); margin: 10px 0 0; font-variant-numeric: tabular-nums; }
.acct-membership-join { margin: 24px 0 0; }
@media (max-width: 600px) {
  .acct-benefits { grid-template-columns: minmax(0, 1fr); }
}
/* The Member library (#519; the Videos tab, #516): one block per video, title, description, then a row
   per version (end card / no branding) with its length and download links. */
.acct-videos > * { max-width: 760px; }
.acct-videos-lead { font-size: 15px; color: var(--text-muted); margin: -8px 0 24px; }
.acct-video-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--border); }
.acct-video { padding: 20px 0; border-bottom: 1px solid var(--border); }
.acct-video-title { font-size: 16px; font-weight: 600; letter-spacing: -0.01em; color: var(--text); margin: 0 0 6px; }
.acct-video-desc { font-size: 14px; color: var(--text); margin: 0 0 12px; }
.acct-video-meta { margin: 0; }
.acct-video-version { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; padding: 6px 0; }
.acct-video-version-label { font-size: 13px; font-weight: 600; color: var(--text); min-width: 210px; }
.acct-video-length { font-size: 12.5px; color: var(--text-muted); font-variant-numeric: tabular-nums; min-width: 32px; }
.acct-video-links { display: flex; flex-wrap: wrap; gap: 6px 16px; }
.acct-video-link { font-size: 13.5px; font-weight: 500; }
.acct-video-size { margin-left: 4px; font-size: 12px; font-weight: 400; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.acct-videos .acct-member-box .public-actions { margin: 0; }
@media (max-width: 600px) {
  .acct-video-version-label { min-width: 0; }
  .acct-video-links { width: 100%; }
}
/* Session recordings (2026-10-26): the Member library's list (reuses the attended-sessions rows),
   then one page per session: player, links, summary, transcript. */
.acct-recordings { margin-top: 32px; }
.acct-recordings-title { font-size: 18px; font-weight: 600; letter-spacing: -0.01em; color: var(--text); margin: 0 0 6px; }
.acct-recordings-lead { font-size: 14px; color: var(--text-muted); margin: 0 0 16px; }
.acct-recording > * { max-width: 880px; }
.acct-recording-back { font-size: 13px; margin: 0 0 8px; }
.acct-recording-meta { font-size: 14px; color: var(--text-muted); margin: -8px 0 16px; font-variant-numeric: tabular-nums; }
.acct-recording-player { display: block; width: 100%; aspect-ratio: 16 / 9; background: #000; border-radius: 8px; }
.acct-recording-links { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 16px; margin: 12px 0 24px; }
.acct-recording-section { border-top: 1px solid var(--border); padding: 20px 0 8px; }
.acct-recording-h2 { font-size: 16px; font-weight: 600; letter-spacing: -0.01em; color: var(--text); margin: 0 0 10px; }
.acct-recording-h3 { font-size: 14px; font-weight: 600; color: var(--text); margin: 16px 0 6px; }
.acct-summary-p { font-size: 14px; line-height: 1.6; color: var(--text); margin: 0 0 10px; max-width: 72ch; }
.acct-summary-list, .acct-summary-actions { font-size: 14px; line-height: 1.55; color: var(--text); margin: 0 0 12px; padding-left: 20px; max-width: 72ch; }
.acct-summary-list li, .acct-summary-actions li { margin: 0 0 4px; }
.acct-transcript { list-style: none; margin: 0; padding: 0; max-height: 520px; overflow-y: auto; border: 1px solid var(--border); border-radius: 8px; }
.acct-cue { display: grid; grid-template-columns: 64px minmax(0, 1fr); column-gap: 12px; padding: 8px 12px; border-bottom: 1px solid var(--border); font-size: 13.5px; line-height: 1.5; color: var(--text); }
.acct-cue:last-child { border-bottom: 0; }
/* the cue's start time is a timestamp: the one mono use here (design-system.md) */
.acct-cue-time { grid-row: 1 / span 2; font-family: ui-monospace, 'Geist Mono', SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--text-muted); padding-top: 1px; }
.acct-cue-speaker { font-weight: 600; font-size: 13px; }
.acct-cue-text { min-width: 0; overflow-wrap: anywhere; }
@media (max-width: 600px) {
  .acct-cue { grid-template-columns: 52px minmax(0, 1fr); column-gap: 8px; }
}
@media (max-width: 600px) {
  .acct-header { flex-wrap: wrap; row-gap: 8px; }
  .acct-header .acct-nav { width: 100%; justify-content: flex-start; column-gap: 16px; }
}

/* hero: a full-width band on the inset tint, chips for the facts, one lead */
.aia-hero-band { background: var(--bg-soft); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.aia-hero { max-width: 720px; margin: 0 auto; padding: 40px 24px 36px; }
.aia-h1 { font-size: 44px; font-weight: 700; letter-spacing: -0.03em; color: var(--text); margin: 0 0 14px; line-height: 1.05; }
.aia-when { font-size: 14px; font-weight: 500; color: var(--text-muted); margin: 0 0 8px; font-variant-numeric: tabular-nums; }
.aia-lead { font-size: 21px; line-height: 1.45; color: var(--text); margin: 0 0 12px; max-width: 30em; }
.aia-bridge { font-size: 16px; line-height: 1.65; color: var(--text); margin: 14px 0 8px; max-width: 40em; }
.aia-hero .public-actions { margin: 20px 0 0; }
.aia-hero .public-cta, .aia-cta-band .public-cta { font-size: 14px; padding: 11px 18px; }

/* sections */
.aia-main { max-width: 720px; padding-top: 8px; }
.aia-section { padding: 36px 0 8px; border-top: 1px solid var(--border); }
.aia-section:first-child { border-top: 0; }
.aia-section h2 { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; color: var(--text); margin: 0 0 14px; }
.aia-section p, .aia-section li { font-size: 16px; line-height: 1.65; color: var(--text); }
.aia-section p { margin: 0 0 14px; }
.aia-section ul { margin: 0 0 14px; padding-left: 22px; }
.aia-section li { margin-bottom: 8px; }
.aia-section .public-actions { margin-top: 4px; }

/* the four session types */
.aia-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 4px 0 18px; }
.aia-card { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 14px 16px; box-shadow: var(--shadow-card); }
.aia-card h3 { font-size: 14px; font-weight: 600; margin: 0 0 4px; color: var(--text); }
.aia-card p { font-size: 14px; line-height: 1.55; margin: 0; color: var(--text-muted); }

/* the tractor story */
.aia-story { background: var(--bg); border-left: 3px solid var(--accent); border-radius: 0 8px 8px 0; padding: 14px 18px; box-shadow: var(--shadow-card); margin: 0 0 14px; }
.aia-story p:last-child { margin-bottom: 0; }

/* the things-I-use-AI-for list: two columns of checked items */
.aia-checks { list-style: none; padding: 0; margin: 4px 0 18px; display: grid; grid-template-columns: 1fr 1fr; gap: 8px 16px; }
.aia-checks li {
  position: relative; padding: 10px 12px 10px 34px; margin: 0; font-size: 14.5px; line-height: 1.5;
  background: var(--bg); border: 1px solid var(--border); border-radius: 8px;
}
.aia-checks li::before {
  content: ""; position: absolute; left: 12px; top: 14px; width: 14px; height: 14px; border-radius: 4px;
  background: var(--accent-soft) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231961ED' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12.5l4.5 4.5L19 7.5'/></svg>") center/10px no-repeat;
}
.aia-pull { font-size: 19px; font-weight: 500; letter-spacing: -0.01em; color: var(--text); padding: 6px 0 6px 18px; border-left: 3px solid var(--accent); margin: 8px 0 18px; }

/* CTA bands */
.aia-cta-band { background: var(--bg-soft); border: 1px solid var(--border); border-radius: 8px; padding: 18px 20px; margin: 18px 0 8px; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.aia-cta-lead { margin: 0; font-size: 15px; line-height: 1.5; color: var(--text); flex: 1 1 280px; }
.aia-cta { margin: 18px 0 6px; }

/* tables: the schedule with date chips, the details in a card */
.aia-table { width: 100%; border-collapse: collapse; margin: 4px 0 14px; }
.aia-table th, .aia-table td { text-align: left; vertical-align: top; padding: 12px 12px 12px 0; border-bottom: 1px solid var(--border); font-size: 15px; line-height: 1.55; }
.aia-table th { width: 96px; font-weight: 600; color: var(--text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.aia-schedule th { width: 84px; padding-top: 14px; color: #1D5BC4; font-size: 13px; font-weight: 600; }
.aia-details { background: var(--bg); border: 1px solid var(--border); border-radius: 8px; box-shadow: var(--shadow-card); border-collapse: separate; border-spacing: 0; overflow: hidden; }
.aia-details th, .aia-details td { padding: 12px 16px; }
.aia-details th { background: var(--bg-soft); width: 110px; }
.aia-details tr:last-child th, .aia-details tr:last-child td { border-bottom: 0; }
.aia-sign { font-weight: 600; margin-top: 20px; }
.aia-footer { max-width: 1280px; margin-top: 24px; font-size: 12.5px; }
.aia-footer-brand { font-weight: 600; color: var(--text); }

/* the browse board */
.wf-board { max-width: 1280px; margin: 0 auto; padding: 0 24px 48px; }
.wf-crumbs { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding: 8px 0 16px; font-size: 14px; }
.wf-crumb { color: var(--text); font-weight: 500; }
.wf-crumb--placeholder { color: var(--faint); font-weight: 400; }
.wf-crumb--current { font-weight: 600; }
.wf-crumb-sep { color: var(--faint); }
.wf-total { margin-left: auto; font-size: 12.5px; font-weight: 500; color: var(--accent); font-variant-numeric: tabular-nums; }
.wf-cols {
  display: grid; grid-template-columns: 1.1fr 1.2fr 1.2fr minmax(280px, 1fr);
  background: var(--bg); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: var(--shadow-card); overflow: hidden; min-height: 520px;
}
.wf-col { min-width: 0; display: flex; flex-direction: column; border-right: 1px solid var(--border); }
.wf-col:last-child { border-right: 0; }
.wf-col-head {
  display: flex; align-items: center; gap: 8px; height: 36px; padding: 0 16px;
  background: var(--bg-soft); border-bottom: 1px solid var(--border);
  font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted);
}
.wf-count { margin-left: auto; letter-spacing: 0; font-variant-numeric: tabular-nums; }
.wf-col-body { flex: 1; min-height: 0; }
.wf-item {
  display: block; padding: 10px 16px; border-bottom: 1px solid var(--border-soft);
  border-left: 3px solid transparent; color: var(--text);
}
.wf-item:hover { background: var(--bg-soft); text-decoration: none; }
.wf-item--active { background: var(--accent-soft); border-left-color: var(--accent); }
.wf-item-name { display: block; font-size: 14px; font-weight: 500; letter-spacing: -0.005em; }
.wf-item-meta { display: block; margin-top: 2px; font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.wf-empty { display: flex; align-items: center; justify-content: center; height: 100%; min-height: 200px; padding: 32px 24px; text-align: center; }
.wf-empty p { margin: 0; font-size: 13.5px; color: var(--faint); max-width: 22em; }
.wf-detail { padding: 24px 24px 32px; }
.wf-label { font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.wf-title { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.25; margin: 8px 0 6px; color: var(--text); }
.wf-detail-meta { font-size: 13px; color: var(--text-muted); margin: 0 0 16px; }
.wf-detail p { font-size: 14px; line-height: 1.6; margin: 0 0 12px; color: var(--text); }
.wf-detail .public-cta { margin-top: 6px; }

/* Phone: one column at a time — the deepest level chosen — with the crumbs as
   the way back. data-depth on the board is the selected level (0 firm … 3 panel). */
@media (max-width: 800px) {
  .wf-cols { grid-template-columns: 1fr; min-height: 0; }
  .wf-col { border-right: 0; }
  .wf-board .wf-col { display: none; }
  .wf-board[data-depth="0"] .wf-col[data-level="0"],
  .wf-board[data-depth="1"] .wf-col[data-level="1"],
  .wf-board[data-depth="2"] .wf-col[data-level="2"],
  .wf-board[data-depth="3"] .wf-col[data-level="3"] { display: flex; }
  .wf-total { display: none; }
  .aia-h1 { font-size: 34px; }
  .aia-lead { font-size: 18px; }
  .aia-hero { padding: 28px 16px 28px; }
  .aia-grid, .aia-checks { grid-template-columns: 1fr; }
  .aia-details th { width: 84px; }
}

/* Coming soon workflows (2026-09-28): the placeholders waiting on real
   versions. The row recedes to muted; the panel carries the orange chip. */
.wf-item--soon .wf-item-name { color: var(--text-muted); }
.pill-coming-soon { background: #FCEAD9; color: #9A5414; } /* orange */

/* agilelnl.com home site (agsignup phase 2): Carrd's page in the events style.
   Hero = words + three buttons beside the AgileLnL logo; the logo is white
   "agile" over a red "LnL" box on transparent, so it sits on a dark tile. */
.site-hero { display: flex; gap: 32px; align-items: center; justify-content: space-between;
  padding: 24px 0 32px; flex-wrap: wrap; }
.site-hero-text { flex: 1 1 320px; min-width: 0; }
.site-eyebrow { font-size: 12px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 8px; }
.site-title { font-size: 40px; font-weight: 700; letter-spacing: -0.03em; color: var(--text); margin: 0 0 12px; }
.site-lede { font-size: 18px; line-height: 1.55; color: var(--text); margin: 0 0 24px; max-width: 34ch; }
.site-buttons { display: flex; flex-wrap: wrap; gap: 12px; }
.site-logo-tile { flex: 0 0 auto; background: #181b1f; border-radius: 16px; padding: 28px 32px;
  box-shadow: var(--shadow-card); }
.site-logo { display: block; width: 180px; height: auto; max-width: 100%; }
.site-signup { scroll-margin-top: 16px; }
.site-signup .public-detail-title { font-size: 22px; margin-bottom: 16px; }
@media (max-width: 560px) {
  .site-title { font-size: 32px; }
  .site-logo-tile { padding: 20px 24px; }
  .site-logo { width: 132px; }
}

/* #38 scheduled sends. Warning pill = the design-system warn semantic
   (#C8860A) as a soft chip, same pair the merge-lint warning panel uses; the
   schedule box, the Upcoming strip and the scheduler status line reuse the
   existing type scale and hairlines. Times are Inter (a clock time is not an
   ID or an ISO timestamp, so it is not mono). */
.pill-status-warning { background: #FDF6EA; color: #6B5212; }
.schedule-state { display: flex; flex-direction: column; gap: 6px; }
.schedule-state p { margin: 0; }
.schedule-line { font-size: 13px; }
.schedule-time { font-weight: 600; font-variant-numeric: tabular-nums; }
.schedule-warning { color: #8A5A07; }
a.schedule-warning { text-decoration: underline; }
.schedule-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.schedule-form {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 6px 0;
}
.schedule-form label { margin: 0; font-size: 13px; }
.schedule-form input[type="datetime-local"] { width: auto; }
.send-confirm-or { margin: 8px 0 0; }
.scheduler-status { font-size: 12.5px; margin: -4px 0 12px; }
.upcoming .data-table { margin-bottom: 8px; }
