/* jam — white mail on a cool grey page, Jelly's colours. See DESIGN.md.

   Loaded after rastrillo's tokens.css, so the :root blocks below win
   at equal specificity and every ui partial (fields, pills, buttons)
   takes the warm palette without being touched. */

/* ── Tokens ────────────────────────────────────────────────────────── */
/* The palette is Jelly's: cool neutral greys, strawberry as the one
   primary, blueberry for the team's notes, cherry for danger, and the
   fruit scales for labels — all at Jelly's HSL steps. Messages are
   white; the page around them is a shade darker, never beige. */
:root,
:root[data-theme="light"] {
  color-scheme: light;
  --rst-font: "Source Sans 3", "Helvetica Neue", Arial, sans-serif;
  --jam-serif: "Source Serif 4", Georgia, "Times New Roman", serif;
  --rst-fs-base: 0.9375rem;
  --rst-fs-sm: 0.8125rem;
  --rst-fs-xs: 0.75rem;
  /* The framework paints with var(--rst-radius*) but never defines
     them, so every consumer fell back to square. Jam's corners. */
  --rst-radius: 12px;
  --rst-radius-sm: 8px;
  --rst-radius-pill: 999px;

  --rst-bg: hsl(240 5% 98.5%);          /* the page: barely off white */
  --rst-surface: #ffffff;               /* a message */
  --rst-surface-2: hsl(240 5% 95.5%);
  --rst-line: hsl(240 5% 90%);
  --rst-line-strong: hsl(240 5% 65%);
  --rst-text: hsl(240 5% 15%);          /* gray-800 */
  --rst-text-muted: hsl(240 5% 38%);
  --rst-text-faint: hsl(240 5% 48%);

  --rst-accent: hsl(342 75% 55%);       /* strawberry-600 */
  --rst-accent-strong: hsl(342 70% 46%); /* strawberry-700 */
  --rst-accent-soft: hsl(342 95% 95%);  /* strawberry-50 */
  --rst-on-accent: #ffffff;

  --rst-tone-neutral-fg: hsl(240 5% 25%);  --rst-tone-neutral-bg: hsl(240 5% 92%);
  --rst-tone-positive-fg: hsl(135 88% 26%); --rst-tone-positive-bg: hsl(135 90% 92%);
  --rst-tone-warning-fg: hsl(45 88% 26%);   --rst-tone-warning-bg: hsl(45 90% 92%);
  --rst-tone-negative-fg: hsl(2 70% 46%);   --rst-tone-negative-bg: hsl(2 90% 92%);
  --rst-shadow-pop: 0 10px 28px hsl(240 5% 12% / 0.14);

  --jam-note: hsl(205 90% 93%);
  --jam-note-well: hsl(205 85% 97%);   /* the editor field inside the note card */         /* blueberry-100: a team note */
  --jam-note-line: hsl(205 80% 80%);
  --jam-note-ink: hsl(205 88% 22%);
  --jam-out: hsl(342 95% 98.5%);        /* your own mail: the faintest strawberry */
  --jam-av-bg: hsl(240 5% 92%);
  --jam-av-ink: hsl(240 5% 30%);
  --jam-shadow-sheet: 0 1px 2px hsl(240 5% 12% / 0.08), 0 3px 8px hsl(240 5% 12% / 0.07), 0 14px 32px -16px hsl(240 5% 12% / 0.35);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --rst-bg: hsl(240 5% 6%); --rst-surface: hsl(240 5% 12%); --rst-surface-2: hsl(240 5% 10%);
    --rst-line: hsl(240 5% 19%); --rst-line-strong: hsl(240 5% 40%);
    --rst-text: hsl(240 5% 95%); --rst-text-muted: hsl(240 5% 72%); --rst-text-faint: hsl(240 5% 62%);
    --rst-accent: hsl(342 80% 65%); --rst-accent-strong: hsl(342 80% 72%); --rst-accent-soft: hsl(342 88% 17%); --rst-on-accent: #ffffff;
    --rst-tone-neutral-fg: hsl(240 5% 85%); --rst-tone-neutral-bg: hsl(240 5% 20%);
    --rst-tone-positive-fg: hsl(135 80% 72%); --rst-tone-positive-bg: hsl(135 88% 14%);
    --rst-tone-warning-fg: hsl(45 80% 72%);   --rst-tone-warning-bg: hsl(45 88% 14%);
    --rst-tone-negative-fg: hsl(2 80% 72%);   --rst-tone-negative-bg: hsl(2 88% 17%);
    --rst-shadow-pop: 0 10px 28px rgba(0, 0, 0, 0.55);
    --jam-note: hsl(205 88% 15%); --jam-note-well: hsl(205 60% 10%); --jam-note-line: hsl(205 80% 30%); --jam-note-ink: hsl(205 85% 88%);
    --jam-out: hsl(342 18% 14%);
    --jam-av-bg: hsl(240 5% 22%); --jam-av-ink: hsl(240 5% 88%);
    --jam-shadow-sheet: 0 1px 2px rgba(0, 0, 0, 0.4), 0 3px 8px rgba(0, 0, 0, 0.3), 0 14px 32px -16px rgba(0, 0, 0, 0.8);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --rst-bg: hsl(240 5% 6%); --rst-surface: hsl(240 5% 12%); --rst-surface-2: hsl(240 5% 10%);
  --rst-line: hsl(240 5% 19%); --rst-line-strong: hsl(240 5% 40%);
  --rst-text: hsl(240 5% 95%); --rst-text-muted: hsl(240 5% 72%); --rst-text-faint: hsl(240 5% 62%);
  --rst-accent: hsl(342 80% 65%); --rst-accent-strong: hsl(342 80% 72%); --rst-accent-soft: hsl(342 88% 17%); --rst-on-accent: #ffffff;
  --rst-tone-neutral-fg: hsl(240 5% 85%); --rst-tone-neutral-bg: hsl(240 5% 20%);
  --rst-tone-positive-fg: hsl(135 80% 72%); --rst-tone-positive-bg: hsl(135 88% 14%);
  --rst-tone-warning-fg: hsl(45 80% 72%);   --rst-tone-warning-bg: hsl(45 88% 14%);
  --rst-tone-negative-fg: hsl(2 80% 72%);   --rst-tone-negative-bg: hsl(2 88% 17%);
  --rst-shadow-pop: 0 10px 28px rgba(0, 0, 0, 0.55);
  --jam-note: hsl(205 88% 15%); --jam-note-well: hsl(205 60% 10%); --jam-note-line: hsl(205 80% 30%); --jam-note-ink: hsl(205 85% 88%);
  --jam-out: hsl(342 18% 14%);
  --jam-av-bg: hsl(240 5% 22%); --jam-av-ink: hsl(240 5% 88%);
  --jam-shadow-sheet: 0 1px 2px rgba(0, 0, 0, 0.4), 0 3px 8px rgba(0, 0, 0, 0.3), 0 14px 32px -16px rgba(0, 0, 0, 0.8);
}

/* ── Base: the browser surfaces carry the palette too ─────────────── */
html { font-size: 16px; }
/* Buttons are pills, matching the segmented nav the app settled on:
   the framework's buttons keep their padding and weights, only the
   radius is the app's. Icon tiles (toolbar, more-buttons) stay square. */
.rst-btn, [rst-btn] { border-radius: 999px; }
/* Inputs share the editors' gentle corner (the search stays a pill). */
.rst-input, [rst-input], .rst-textarea, [rst-textarea],
.jam-settings input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]),
.jam-settings select, .jam-settings textarea,
.jam-line select, .jam-compose textarea, .jam-compose-note textarea,
.jam-person__card input:not([type="checkbox"]):not([type="radio"]),
.jam-person__card select, .jam-person__card textarea,
.jam-editor-dialog input[type="url"] { border-radius: 10px; }
/* Jam's type scale: the v2 framework tokens default to a 14px base,
   which is too small for an app people read mail in all day. This
   loads after tokens.css, so the override is the app's to keep. */
:root {
  --rst-fs-base: 1rem;      /* 16px */
  --rst-fs-sm: 0.875rem;    /* 14px — the floor for component text */
  --rst-fs-xs: 0.75rem;     /* 12px — hints, fine print, caps only */
}
body { font-family: var(--rst-font); font-size: var(--rst-fs-base); line-height: 1.55; -webkit-font-smoothing: antialiased; }
::selection { background: var(--rst-accent-soft); color: var(--rst-text); }
:focus-visible { outline: 2px solid var(--rst-accent); outline-offset: 2px; }
* { scrollbar-width: thin; scrollbar-color: var(--rst-line-strong) transparent; }
input, textarea, select, button { font-family: inherit; caret-color: var(--rst-accent); }
a { color: var(--rst-accent-strong); text-decoration-thickness: 1px; text-underline-offset: 0.15em; }
.jam-serif { font-family: var(--jam-serif); }
.jam-muted { color: var(--rst-text-muted); }
.jam-count { font-size: var(--rst-fs-sm); color: var(--rst-text-faint); font-weight: 500; font-variant-numeric: tabular-nums; }

/* ── Top bar ───────────────────────────────────────────────────────── */
.jam-top { display: flex; align-items: center; gap: 1.25rem; padding: 0.6rem 1.5rem; border-bottom: 1px solid var(--rst-line); background: var(--rst-bg); }
.jam-top .jam-search { flex: 1; max-width: 22rem; margin: 0 0 0 auto; }
.jam-top__compose { white-space: nowrap; }
.jam-menu { position: relative; }
.jam-menu summary { list-style: none; display: inline-flex; align-items: center; gap: 0.35rem; cursor: pointer; padding: 0.2rem 0.4rem 0.2rem 0.2rem; border-radius: 999px; }
.jam-menu summary::-webkit-details-marker { display: none; }
.jam-menu summary:hover, .jam-menu[open] summary { background: var(--rst-surface-2); }
.jam-menu__caret { color: var(--rst-text-faint); font-size: 0.7rem; }
.jam-menu__panel { position: absolute; right: 0; top: calc(100% + 0.4rem); z-index: 30; min-width: 14rem; background: var(--rst-surface); border: 1px solid var(--rst-line); border-radius: 12px; padding: 0.5rem; box-shadow: var(--rst-shadow-pop); display: grid; }
.jam-menu__who { margin: 0.25rem 0.6rem 0.5rem; padding-bottom: 0.5rem; border-bottom: 1px solid var(--rst-line); font-size: var(--rst-fs-sm); font-weight: 600; }
.jam-menu__who .jam-muted { font-weight: 400; }
.jam-menu__panel a, .jam-menu__panel button { display: block; width: 100%; text-align: left; padding: 0.45rem 0.6rem; border-radius: 8px; text-decoration: none; color: var(--rst-text); background: none; border: none; font: inherit; cursor: pointer; }
.jam-menu__panel a:hover, .jam-menu__panel button:hover { background: var(--rst-surface-2); }
.jam-menu__panel form { display: contents; }
/* Availability lives in the account menu: four rows, the current one
   ticked, and the avatar wears an amber ring while you are away. */
.jam-menu__label { margin: 0.35rem 0.6rem 0.1rem; font-size: var(--rst-fs-xs); color: var(--rst-text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
/* Availability is a submenu: the summary names the current status with
   its icon; open, four rows of icon + words, the current one ticked. */
.jam-menu__sub > summary { list-style: none; cursor: pointer; }
.jam-menu__sub > summary::-webkit-details-marker { display: none; }
.jam-menu__panel .jam-menu__subsum { display: flex; align-items: center; gap: 0.55rem; width: 100%; box-sizing: border-box; padding: 0.45rem 0.6rem; border-radius: 8px; color: var(--rst-text); }
.jam-menu__subsum:hover, .jam-menu__sub[open] > .jam-menu__subsum { background: var(--rst-surface-2); }
.jam-menu__subsum > svg:first-child { width: 1rem; height: 1rem; flex: none; color: var(--rst-tone-positive-fg); }
.jam-menu__subsum.is-away > svg:first-child { color: var(--rst-tone-warning-fg); }
.jam-menu__subsum > span { flex: 1; min-width: 0; }
.jam-menu__subsum .jam-chev { color: var(--rst-text-faint); transition: transform 140ms; }
.jam-menu__sub[open] > .jam-menu__subsum .jam-chev { transform: rotate(180deg); }
.jam-menu__subbody { padding: 0.15rem 0 0.25rem 0.9rem; }
.jam-menu__subbody form { display: contents; }
.jam-menu__panel .jam-menu__avbtn { display: flex; align-items: center; gap: 0.55rem; width: 100%; box-sizing: border-box; padding: 0.4rem 0.6rem; border-radius: 8px; color: var(--rst-text); font-size: var(--rst-fs-sm); }
.jam-menu__avbtn > svg { width: 1rem; height: 1rem; flex: none; color: var(--rst-text-muted); }
.jam-menu__avbtn > span { flex: 1; }
.jam-menu__panel .jam-menu__avbtn[aria-checked="true"] { font-weight: 600; }
.jam-menu__panel .jam-menu__avbtn[aria-checked="true"]::after { content: "✓"; color: var(--rst-accent-strong); font-weight: 600; }
.jam-menu__avbtn--available[aria-checked="true"] > svg { color: var(--rst-tone-positive-fg); }
.jam-menu__avbtn:not(.jam-menu__avbtn--available)[aria-checked="true"] > svg { color: var(--rst-tone-warning-fg); }
.jam-menu__panel hr { border: 0; border-top: 1px solid var(--rst-line); margin: 0.35rem 0; }
.jam-menu--away > summary .jam-av { box-shadow: 0 0 0 2px var(--rst-surface), 0 0 0 4px var(--rst-tone-warning-fg); }
.jam-menu__away { font-size: var(--rst-fs-sm); color: var(--rst-tone-warning-fg); font-weight: 600; }
.jam-brand { font-family: var(--jam-serif); font-weight: 600; font-size: 1.15rem; text-decoration: none; color: var(--rst-text); letter-spacing: -0.01em; }
.jam-brand::before { content: ""; display: inline-block; width: 0.55em; height: 0.55em; border-radius: 50% 50% 50% 0; background: var(--rst-accent); margin-right: 0.45em; transform: rotate(-45deg) translateY(-1px); }
.jam-nav { display: flex; gap: 0.15rem; }
.jam-nav a { text-decoration: none; color: var(--rst-text-muted); padding: 0.3rem 0.65rem; border-radius: 999px; font-weight: 500; }
.jam-nav a:hover { color: var(--rst-text); background: var(--rst-surface-2); }
.jam-nav a[aria-current="page"] { color: var(--rst-accent-strong); background: var(--rst-accent-soft); }
.jam-bell { display: inline-block; min-width: 1.15rem; padding: 0 0.3rem; border-radius: 999px; background: var(--rst-accent); color: var(--rst-on-accent); font-size: 0.68rem; text-align: center; line-height: 1.15rem; vertical-align: 1px; margin-left: 0.15rem; }

/* ── Public pages (sign-in, invitation, 404) ───────────────────────── */
.jam-auth { max-width: 26rem; margin: 4rem auto 0; }
.jam-auth__title { font-family: var(--jam-serif); font-weight: 600; font-size: 1.9rem; margin: 0 0 0.75rem; text-wrap: balance; letter-spacing: -0.01em; }
.jam-auth__lede { color: var(--rst-text-muted); margin: 0 0 1.25rem; }
.jam-auth__google { display: inline-block; width: 100%; box-sizing: border-box; text-align: center; }
.jam-auth__or { text-align: center; color: var(--rst-text-faint); margin: 0.75rem 0; font-size: var(--rst-fs-sm); }
.jam-auth__note { font-size: var(--rst-fs-sm); color: var(--rst-text-muted); }
.jam-recovery { margin-top: 1.5rem; }
.jam-recovery summary { cursor: pointer; color: var(--rst-text-muted); }

/* ── Settings-ish pages ────────────────────────────────────────────── */
/* ── Settings ──────────────────────────────────────────────────────── */
/* One framework for every settings page: a section is a heading, a
   lede, then either a form or a list. A list row is lead · main ·
   side; a row that can be edited is a details whose summary is the
   row and whose body is the editor, so nothing needs a script and
   nothing leaves the page. Adding is the same editor behind "＋". */
.jam-settings { min-width: 0; }
.jam-settings input:not([type="checkbox"]):not([type="radio"]), .jam-settings select, .jam-settings textarea { box-sizing: border-box; max-width: 100%; }
.jam-setlist__title { display: inline-flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.jam-lede { margin: 0 0 1rem; color: var(--rst-text-muted); font-size: var(--rst-fs-sm); max-width: 60ch; }
.jam-fine { color: var(--rst-text-faint); font-size: var(--rst-fs-xs); margin: 0.75rem 0 0; }
/* Forms follow the framework's: rst-form owns the block rhythm,
   rst-field-row puts two fields side by side, rst-form-foot closes
   with the actions — the primary first, the destructive one alone at
   the far right as a quiet red link. What is left here is the two
   places a form lives inside a card of ours (a setlist editor, a
   person card): the box-sizing floor, and the release of rst-form's
   44rem cap so a form fills the card it was given. */
.jam-setlist__editor, .jam-person__card { min-width: 0; }
.jam-setlist__editor input:not([type="checkbox"]):not([type="radio"]), .jam-setlist__editor select, .jam-setlist__editor textarea,
.jam-person__card input:not([type="checkbox"]):not([type="radio"]), .jam-person__card select, .jam-person__card textarea { box-sizing: border-box; width: 100%; max-width: 100%; }
.jam-setlist__editor[rst-form], .jam-setlist__editor [rst-form], .jam-person__card [rst-form] { max-inline-size: none; }
.jam-setlist__danger { display: flex; align-items: center; gap: 0.75rem; margin-left: auto; }
.jam-setlist__danger .jam-fine { margin: 0; }
.jam-danger-link { margin-left: auto; border: 0; background: none; padding: 0.35rem 0.25rem; font: inherit; font-size: var(--rst-fs-sm); color: var(--rst-danger, #c62828); cursor: pointer; text-decoration: none; }
.jam-danger-link:hover { text-decoration: underline; }
.jam-setlist__foot form { display: contents; }
.jam-setlist__foot form.jam-setlist__danger { display: flex; }
.jam-setlist { list-style: none; margin: 0; padding: 0; border: 1px solid var(--rst-line); border-radius: 12px; background: var(--rst-surface); overflow: hidden; }
.jam-setlist__item + .jam-setlist__item { border-top: 1px solid var(--rst-line); }
.jam-setlist__item.is-off .jam-setlist__main { color: var(--rst-text-muted); }
.jam-setlist__row { display: flex; align-items: center; gap: 0.9rem; padding: 0.75rem 1rem; list-style: none; cursor: pointer; min-height: 3.25rem; }
.jam-setlist__row::-webkit-details-marker { display: none; }
.jam-setlist__row--static { cursor: default; }
.jam-setlist__d[open] > .jam-setlist__row { background: var(--rst-surface-2); }
.jam-setlist__row:hover { background: var(--rst-surface-2); }
.jam-setlist__lead { flex: none; display: grid; place-items: center; width: 1.75rem; height: 1.75rem; color: var(--rst-text-muted); }
.jam-setlist__main { flex: 1; min-width: 0; display: grid; gap: 0.1rem; }
.jam-setlist__main strong { font-weight: 600; }
.jam-setlist__meta { color: var(--rst-text-muted); font-size: var(--rst-fs-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jam-setlist__side { flex: none; display: inline-flex; align-items: center; gap: 0.6rem; }
.jam-setlist__side .jam-av + .jam-av { margin-left: -0.5rem; box-shadow: 0 0 0 2px var(--rst-surface); }
.jam-setlist__edit { display: inline-flex; align-items: center; gap: 0.3rem; font-size: var(--rst-fs-sm); color: var(--rst-text-muted); }
.jam-setlist__d[open] .jam-setlist__edit .jam-chev { transform: rotate(180deg); }
.jam-setlist__editor { padding: 1rem 1rem 1.1rem 3.65rem; border-top: 1px dashed var(--rst-line); background: var(--rst-surface); }
/* In-place row editing (the subject-rename pattern): open, the form
   takes the row's own footprint; the row's pencil shows on hover. */
.jam-setlist__d--inline[open] > summary { display: none; }
.jam-setlist__inline { padding: 0.55rem 1rem 0.65rem; background: var(--rst-surface); }
.jam-setlist__row .jam-thread__pencil { opacity: 0; }
.jam-setlist__row:hover .jam-thread__pencil, .jam-setlist__row:focus-visible .jam-thread__pencil { opacity: 1; }
.jam-setlist__editor [rst-form] { margin: 0; }
.jam-setlist__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: 0.25rem; }
.jam-setlist__foot .jam-fine { margin: 0; }
.jam-setlist__empty { padding: 1rem; color: var(--rst-text-muted); font-size: var(--rst-fs-sm); }
.jam-setlist__add { margin-top: 0.6rem; }
.jam-setlist__add > summary { list-style: none; }
.jam-setlist__add > summary::-webkit-details-marker { display: none; }
.jam-setlist__add[open] > summary { background: var(--rst-surface-2); border-color: var(--rst-line); }
.jam-setlist__add > .jam-setlist__editor { margin-top: 0.5rem; border: 1px solid var(--rst-line); border-radius: 12px; padding: 1rem 1.1rem; }
/* A line form: label, control, button on one row — the editor a
   setlist row discloses. rst-field-row is the framework's answer to
   two fields side by side, and it stacks each label above its control,
   which is right for a page-level form and twice the height for a
   one-control row editor. This is the inline-label variant the
   framework does not ship. The row wraps only when a phone forces it. */
.jam-line { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.9rem; }
.jam-line [rst-field] { display: flex; flex-wrap: nowrap; align-items: center; gap: 0.45rem; margin: 0; flex: 1 1 12rem; min-width: 0; max-width: 24rem; }
.jam-line [rst-field]:has(select) { flex: 0 1 auto; }
.jam-line [rst-field-label] { margin: 0; white-space: nowrap; }
.jam-line [rst-field] input, .jam-line [rst-field] select { flex: 1 1 6rem; min-width: 0; width: auto; }
.jam-line [rst-field]:has([rst-field-help], [rst-field-error]) { flex-wrap: wrap; }
.jam-line [rst-field-help], .jam-line [rst-field-error] { flex-basis: 100%; margin: 0; }
.jam-line [rst-btn] { flex: none; }
.jam-line > .jam-danger-link { margin-left: auto; }
.jam-line__note { flex: 1 1 100%; margin: 0; }
.jam-setlist__editor--line { padding-top: 0.7rem; padding-bottom: 0.8rem; }
/* Native selects in a line form dress like the inputs beside them. */
.jam-line select { appearance: none; -webkit-appearance: none; border: 1px solid var(--rst-line-strong); border-radius: var(--rst-radius-sm); padding: 0.45rem 1.9rem 0.45rem 0.6rem; font: inherit; color: inherit; background: var(--rst-surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10'%3E%3Cpath d='M2 3.5l3 3 3-3' fill='none' stroke='%23999' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 0.6rem center; cursor: pointer; }
.jam-line select:hover { border-color: var(--rst-text-faint); }
.jam-upload { display: grid; gap: 0.3rem; margin-top: 0.75rem; max-width: 34rem; }
.jam-upload[hidden] { display: none; }
.jam-upload__bar { width: 100%; height: 0.6rem; accent-color: var(--rst-accent); }
.jam-upload__note { margin: 0; }
.jam-colourpick__ctl { display: inline-flex; align-items: center; gap: 0.45rem; }
.jam-colourpick__ctl select { flex: none; text-transform: capitalize; }
.jam-colourpick__ctl .jam-swatch { flex: none; width: 1.15rem; height: 1.15rem; }
.jam-swatch { display: inline-block; width: 1.05rem; height: 1.05rem; border-radius: 50%; background: var(--jam-label); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08); }
.jam-memberlist { list-style: none; margin: 0 0 0.75rem; padding: 0; display: flex; flex-wrap: wrap; gap: 0.35rem; }
.jam-memberlist__btn { display: inline-flex; align-items: center; gap: 0.45rem; padding: 0.25rem 0.6rem 0.25rem 0.3rem; border: 1px solid var(--rst-line); border-radius: 999px; background: var(--rst-surface); font: inherit; font-size: var(--rst-fs-sm); color: var(--rst-text); cursor: pointer; }
.jam-memberlist__btn:hover { border-color: var(--rst-line-strong); background: var(--rst-surface-2); }
.jam-memberlist__btn.is-in { background: var(--rst-accent-soft); border-color: transparent; color: var(--rst-accent-strong); }
.jam-memberlist__state { font-size: var(--rst-fs-sm); color: var(--rst-text-faint); }
.jam-memberlist__btn.is-in .jam-memberlist__state { color: var(--rst-accent-strong); }
.jam-switchrow { display: flex; align-items: center; gap: 0.6rem; margin: 0 0 1rem; font-size: var(--rst-fs-sm); }
.jam-switch { position: relative; width: 2.3rem; height: 1.3rem; border-radius: 999px; border: 0; background: var(--rst-line-strong); cursor: pointer; padding: 0; transition: background-color 160ms; }
.jam-switch[aria-checked="true"] { background: var(--rst-accent); }
.jam-switch__knob { position: absolute; top: 0.15rem; left: 0.15rem; width: 1rem; height: 1rem; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); transition: transform 160ms; }
.jam-switch[aria-checked="true"] .jam-switch__knob { transform: translateX(1rem); }
.jam-switch:focus-visible { outline: 2px solid var(--rst-accent); outline-offset: 2px; }
/* The rule editor: When (field · contains), Then (each action a
   block; its extra choice appears once the action is picked). */
/* A choice card's title reads at the same size as the toggle labels
   beside it; the framework sets it a step small. */
.rst-choice__title, [rst-choice-title] { font-size: var(--rst-fs-base); }
.rst-choice__desc, [rst-choice-desc] { font-size: var(--rst-fs-sm); }
.jam-rule fieldset { border: 0; padding: 0; margin: 0 0 0.75rem; }
.jam-rule legend { margin: 0 0 0.4rem; }
.jam-rule__acts { display: grid; gap: 0.35rem 1.25rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.jam-rule__act--checks { display: grid; gap: 0.35rem; align-content: start; }
.jam-rule__more { display: none; margin: -0.5rem 0 0.75rem 0.25rem; }
.jam-rule__act:has(select[name="mailbox"] option:checked:not([value=""])) .jam-rule__more { display: block; }
.jam-rule__act--checks:has(input[name="forward_on"]:checked) .jam-rule__more--forward { display: block; margin: 0.25rem 0 0 1.6rem; }
.jam-rule__preview { min-height: 1.2em; margin: 0.25rem 0 0.75rem; padding: 0.55rem 0.8rem; border-radius: 8px; background: var(--rst-surface-2); color: var(--rst-text-muted); font-size: var(--rst-fs-sm); }
.jam-rule__preview:empty { display: none; }
.jam-rule__preview strong { color: var(--rst-text); }
@media (max-width: 720px) {
  .jam-setlist__editor { padding-left: 1rem; }
  .jam-setlist__meta { white-space: normal; }
}

.jam-section { margin-top: 2.25rem; }
.jam-section h2 { font-family: var(--jam-serif); font-weight: 600; font-size: 1.25rem; margin: 0 0 0.5rem; }
.jam-inline { display: inline-flex; gap: 0.4rem; align-items: center; margin: 0 0.25rem 0.25rem 0; }
.jam-actions { white-space: nowrap; }
.jam-table { width: 100%; border-collapse: collapse; }
.jam-table th, .jam-table td { text-align: left; padding: 0.6rem 0.8rem; vertical-align: top; border-bottom: 1px solid var(--rst-line); }
.jam-table th { font-size: var(--rst-fs-xs); text-transform: uppercase; letter-spacing: 0.08em; color: var(--rst-text-faint); font-weight: 600; }
.jam-plain-list { list-style: none; padding: 0; margin: 0; }
.jam-plain-list li { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 0.45rem 0; border-bottom: 1px solid var(--rst-line); }
.jam-codes { columns: 2; list-style: none; padding: 0; margin: 0 0 1.5rem; }
.jam-codes li { padding: 0.25rem 0; }
.jam-codes code { font-size: 1.05rem; }
.jam-switches { display: grid; gap: 0.4rem; margin: 0.5rem 0 1rem; }
/* A section's second-rank heading: the small caps label DESIGN.md
   names, not a smaller serif heading — one heading per section is
   the composition, and this is a divider inside one. */
.jam-section h3 { font-weight: 600; font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--rst-text-muted); margin: 1.5rem 0 0.5rem; }
/* The Jelly import's progress panel is a callout carrying the
   framework's own meter. The meter is inline-flex and sizes to its
   content, so a width is what makes the bar readable at a glance;
   the fraction beside it says the same thing in words, because a bar
   alone is a state told in colour and length. */
.jam-import [rst-meter] { width: min(22rem, 100%); margin-right: 0.4rem; vertical-align: middle; }

/* ── The inbox: sidebar + list ─────────────────────────────────────── */
.jam-shell { display: grid; grid-template-columns: 13rem minmax(0, 1fr); gap: 2.5rem; max-width: 74rem; margin: 0 auto; padding: 1.5rem 1.5rem 4rem; }
@media (max-width: 720px) { .jam-shell { grid-template-columns: 1fr; gap: 1rem; } .jam-side { position: static; } }
.jam-side { position: sticky; top: 1rem; align-self: start; }
.jam-search input { width: 100%; box-sizing: border-box; padding: 0.45rem 0.8rem; border: 1px solid var(--rst-line); border-radius: 999px; font: inherit; background: var(--rst-surface); color: inherit; }
.jam-search input::placeholder { color: var(--rst-text-faint); }
.jam-side__list { list-style: none; padding: 0; margin: 0 0 1rem; }
.jam-side__list a { display: flex; align-items: center; gap: 0.5rem; padding: 0.35rem 0.6rem; border-radius: 8px; text-decoration: none; color: var(--rst-text-muted); }
.jam-side__list a .jam-count { margin-left: auto; }
.jam-side__list a:hover { color: var(--rst-text); background: var(--rst-surface-2); }
.jam-side__list a[aria-current="page"] { color: var(--rst-accent-strong); background: var(--rst-accent-soft); font-weight: 600; }
.jam-side__list a[aria-current="page"] .jam-count { color: var(--rst-accent-strong); }
/* An applied scope (a chosen mailbox) is not a page: bold with a tick, no fill. */
.jam-side__list a[data-scope="on"] { color: var(--rst-text); font-weight: 600; }
.jam-side__list a[data-scope="on"]::after { content: "✓"; margin-left: auto; color: var(--rst-accent-strong); font-size: var(--rst-fs-sm); }
.jam-list-head__lead { display: inline-flex; align-items: baseline; gap: 0.6rem; min-width: 0; }
.jam-scope { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.15rem 0.6rem; border-radius: 999px; border: 1px solid var(--rst-line); background: var(--rst-surface); color: var(--rst-text-muted); font-size: var(--rst-fs-sm); font-weight: 500; text-decoration: none; white-space: nowrap; transform: translateY(-0.2rem); }
.jam-scope__x { color: var(--rst-text-faint); font-size: 1rem; line-height: 1; }
.jam-scope:hover { border-color: var(--rst-line-strong); color: var(--rst-text); }
.jam-scope:hover .jam-scope__x { color: var(--rst-accent-strong); }
.jam-side__title { font-size: var(--rst-fs-xs); text-transform: uppercase; letter-spacing: 0.1em; color: var(--rst-text-faint); font-weight: 600; margin: 1.25rem 0 0.4rem 0.6rem; }
.jam-dot { display: inline-block; width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--jam-label, var(--rst-line-strong)); }

.jam-list-head h1 { font-family: var(--jam-serif); font-weight: 600; font-size: 1.75rem; margin: 0 0 0.5rem; letter-spacing: -0.01em; }
/* The heading's box, named beside the heading: its line box, and the
   gap under it the h1's own margin makes. The bulk bar stands in the
   same box, so selecting does not step the list down a few pixels. */
.jam-main { --jam-head-line: calc(1.75rem * 1.55); --jam-head-gap: 0.5rem; }
/* The ledger: a section is a serif heading over a rule — typographic,
   not a container — and a conversation is an open line between
   hairlines, with a margin column for the unread mark. Air between
   lines and more between sections is what keeps it legible. */
.jam-panel { margin: 0 0 0.75rem; }
/* A section head is a band the full width of the pane, like the rows. */
.jam-section-title { font-family: var(--jam-serif); font-weight: 600; font-size: 1.05rem; text-transform: none; letter-spacing: 0; color: var(--rst-text); margin: 0 -1.5rem 0.25rem; padding: 0.45rem 1.5rem; background: var(--jam-sec, var(--rst-surface-2)); border-bottom: 1px solid var(--rst-line); box-shadow: inset 3px 0 0 var(--jam-sec-ink, var(--rst-line-strong)); display: flex; align-items: baseline; gap: 0.6rem; }
/* Each inbox section wears a colour the app already speaks: blush for
   what wants action, blueberry for yours, lemon for pending, stone for
   everyone else's. The wash is the band's alone; rows stay plain. */
.jam-section-title[data-section="new"] { --jam-sec: var(--rst-accent-soft); --jam-sec-ink: var(--rst-accent); }
.jam-section-title[data-section="mine"] { --jam-sec: var(--jam-note); --jam-sec-ink: var(--jam-note-ink); }
.jam-section-title[data-section="unassigned"] { --jam-sec: var(--rst-tone-warning-bg); --jam-sec-ink: var(--rst-tone-warning-fg); }
.jam-row__follow { display: inline-flex; color: var(--rst-text-faint); }
.jam-row__follow .jam-mi { width: 13px; height: 13px; }
.jam-following-fact { display: inline-flex; align-items: center; gap: 0.3rem; }
.jam-following-fact .jam-mi { width: 13px; height: 13px; color: var(--rst-text-faint); }
/* Who follows: a quiet footer under the reply, words only. */
.jam-followers { display: flex; align-items: baseline; gap: 0.45rem; margin: 1.1rem 0 0; font-size: var(--rst-fs-sm); color: var(--rst-text-muted); }
.jam-followers .jam-mi { color: var(--rst-text-faint); flex: none; transform: translateY(2px); }

/* The help line: one muted sentence under a header, "Got it" right
   beside it, until the member dismisses it. */
.jam-hint { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; margin: 0 0 0.25rem; padding: 0.15rem 0 0.4rem; font-size: var(--rst-fs-sm); color: var(--rst-text-muted); border-bottom: 1px solid var(--rst-line); }
/* A note under a list, saying what the list is not showing. Quiet,
   and never a control: the answer is in the search box, not here. */
.jam-list-note { margin: 0.6rem 0 0; padding: 0.55rem 0 0; border-top: 1px solid var(--rst-line); font-size: var(--rst-fs-sm); color: var(--rst-text-muted); }
.jam-hint form { display: contents; }
.jam-hint button { border: 0; background: none; padding: 0; font: inherit; font-size: var(--rst-fs-sm); font-weight: 500; color: var(--rst-accent-strong); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; white-space: nowrap; }
.jam-hint button:hover { color: var(--rst-accent); }
.jam-section-title .jam-count { font-weight: 400; font-size: var(--rst-fs-sm); background: none; padding: 0; color: var(--rst-text-muted); }
.jam-rows { list-style: none; padding: 0; margin: 0; }
/* The row's vertical measures live here, not inline in the rules
   that use them: the mark column has to add them up to find the
   subject's line, and a number it cannot see would drift. */
.jam-row { --jam-row-pad-y: 0.55rem; --jam-row-gap: 0.1rem; --jam-row-lh: 1.35; border-bottom: 1px solid var(--rst-line); }
.jam-row:last-child { border-bottom: none; }
/* The link runs the full width of the pane — its padding is the pane's
   padding, so the text stays aligned with the headings. */
.jam-row__link { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.9rem; padding: var(--jam-row-pad-y) 1.5rem; margin: 0 -1.5rem; text-decoration: none; color: inherit; position: relative; border-radius: 0; }
.jam-row__link:hover { background: var(--rst-surface-2); }
.jam-row--cursor .jam-row__link { background: var(--rst-surface-2); outline: 2px solid var(--rst-accent); outline-offset: -2px; }
.jam-row__body { display: grid; gap: var(--jam-row-gap); min-width: 0; }
.jam-row__top { display: flex; justify-content: space-between; gap: 1rem; align-items: center; }
.jam-row__side { display: inline-flex; align-items: center; gap: 0.35rem; flex: none; }
/* Row type: three roles at three sizes. The subject is the only full-size line;
   who and snippet step down a size and a colour each, and unread lifts every
   role by one step (weight for the subject, colour for the other two). */
.jam-row__body { gap: var(--jam-row-gap); }
.jam-row__who { font-size: var(--rst-fs-sm); font-weight: 500; line-height: var(--jam-row-lh); color: var(--rst-text-muted); }
.jam-row__when { font-size: var(--rst-fs-sm); color: var(--rst-text-faint); white-space: nowrap; font-variant-numeric: tabular-nums; margin-left: 0.4rem; min-width: 3rem; text-align: right; }
.jam-row__subject { font-family: var(--rst-font); font-size: var(--rst-fs-base); font-weight: 600; line-height: var(--jam-row-lh); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jam-row__subject .jam-count { display: inline-block; font-size: var(--rst-fs-sm); font-weight: 700; color: var(--rst-text); background: var(--rst-surface-2); border: 1px solid var(--rst-line); border-radius: 999px; padding: 0 0.4rem; line-height: 1.25rem; min-width: 1.25rem; text-align: center; vertical-align: 0.1em; margin-left: 0.3rem; }
.jam-row__snippet { font-size: var(--rst-fs-sm); line-height: var(--jam-row-lh); min-height: calc(var(--rst-fs-sm) * var(--jam-row-lh)); color: var(--rst-text-faint); max-width: 72ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jam-row__snippet mark { background: var(--rst-accent-soft); color: inherit; padding: 0 0.1em; border-radius: 3px; }
.jam-row--unread .jam-row__who { color: var(--rst-text); font-weight: 600; }
.jam-row--unread .jam-row__subject { font-weight: 700; }
.jam-row--unread .jam-row__snippet { color: var(--rst-text-muted); }


.jam-draft-mark { font-size: var(--rst-fs-sm); text-transform: uppercase; letter-spacing: 0.06em; color: var(--rst-tone-warning-fg); background: var(--rst-tone-warning-bg); padding: 0.05rem 0.4rem; border-radius: 4px; vertical-align: middle; font-family: var(--rst-font); }

.jam-av { display: inline-grid; place-items: center; width: 2.5rem; height: 2.5rem; border-radius: 50%; background: var(--jam-av-bg); color: var(--jam-av-ink); font-weight: 600; font-size: 0.8rem; letter-spacing: 0.02em; flex: none; }
.jam-av--out { background: var(--rst-accent-soft); color: var(--rst-accent-strong); }
.jam-av--sm { width: 1.5rem; height: 1.5rem; font-size: 0.58rem; }
.jam-av--md { width: 1.9rem; height: 1.9rem; font-size: 0.68rem; }
.jam-av img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block; }
.jam-av--lg { width: 3.5rem; height: 3.5rem; font-size: 1.1rem; }
/* An API token has no face. It gets a square, not a circle, and a
   plain "API" tag beside its name: the shape says at a glance that a
   program did this, and the tag says it in words for anyone the shape
   does not reach (state is never colour or shape alone). */
.jam-av--token { border-radius: var(--rst-radius-sm, 0.25rem); background: var(--rst-surface-2); color: var(--rst-text-faint); }
.jam-av--token svg { width: 60%; height: 60%; }
.jam-tokenmark { display: inline-block; padding: 0 0.3em; border: 1px solid var(--rst-border); border-radius: var(--rst-radius-sm, 0.25rem); font-size: 0.62rem; font-weight: 600; letter-spacing: 0.06em; color: var(--rst-text-faint); vertical-align: 0.1em; }
/* The mailbox checkboxes under a token's visibility radio. */
.jam-token-boxes { margin-top: 0.6rem; padding-left: 0.2rem; }
/* An away member's avatar goes quiet — grey face, faint initials — and
   wears a small amber badge with the status's icon at its corner. */
.jam-av--away { position: relative; overflow: visible; background: var(--rst-surface-2); color: var(--rst-text-faint); }
.jam-av--away img { filter: grayscale(1); opacity: 0.55; }
.jam-av__badge { position: absolute; right: -12%; bottom: -12%; width: 58%; height: 58%; min-width: 0.85rem; min-height: 0.85rem; border-radius: 50%; background: var(--rst-tone-warning-bg); color: var(--rst-tone-warning-fg); display: grid; place-items: center; box-shadow: 0 0 0 1.5px var(--rst-surface); }
.jam-av__badge svg { width: 72%; height: 72%; }

.jam-chip { display: inline-block; font-size: var(--rst-fs-sm); padding: 0.1rem 0.55rem; border-radius: 999px; background: var(--jam-label, var(--rst-tone-neutral-bg)); color: var(--jam-label-ink, var(--rst-tone-neutral-fg)); border: none; font-weight: 500; line-height: 1.5; font-family: var(--rst-font); }
.jam-chip--btn { cursor: pointer; }
[data-colour="apricot"] { --jam-label: hsl(20 80% 72%); --jam-label-ink: hsl(20 88% 17%); }
[data-colour="gooseberry"] { --jam-label: hsl(85 80% 68%); --jam-label-ink: hsl(85 88% 14%); }
[data-colour="grape"] { --jam-label: hsl(255 80% 76%); --jam-label-ink: hsl(255 88% 17%); }
[data-colour="blueberry"] { --jam-label: hsl(205 80% 72%); --jam-label-ink: hsl(205 88% 15%); }
[data-colour="cherry"] { --jam-label: hsl(2 80% 74%); --jam-label-ink: hsl(2 88% 17%); }
[data-colour="lime"] { --jam-label: hsl(105 75% 66%); --jam-label-ink: hsl(105 88% 14%); }
[data-colour="lemon"] { --jam-label: hsl(45 85% 66%); --jam-label-ink: hsl(45 88% 14%); }
[data-colour="peach"] { --jam-label: hsl(30 85% 74%); --jam-label-ink: hsl(30 88% 17%); }
[data-colour="plum"] { --jam-label: hsl(275 80% 76%); --jam-label-ink: hsl(275 88% 17%); }
[data-colour="mint"] { --jam-label: hsl(135 75% 68%); --jam-label-ink: hsl(135 88% 14%); }
[data-colour="fig"] { --jam-label: hsl(320 55% 72%); --jam-label-ink: hsl(320 70% 17%); }
[data-colour="raspberry"] { --jam-label: hsl(342 80% 72%); --jam-label-ink: hsl(342 88% 17%); }
[data-colour="olive"] { --jam-label: hsl(70 50% 62%); --jam-label-ink: hsl(70 70% 14%); }
[data-colour="juniper"] { --jam-label: hsl(180 80% 68%); --jam-label-ink: hsl(180 88% 14%); }
[data-colour="huckleberry"] { --jam-label: hsl(225 80% 74%); --jam-label-ink: hsl(225 88% 17%); }

/* ── The conversation ──────────────────────────────────────────────── */
.jam-conv { display: grid; grid-template-columns: minmax(0, 1fr) 15rem; gap: 3rem; max-width: 72rem; margin: 0 auto; padding: 1.5rem 1.5rem 5rem; }
@media (max-width: 860px) { .jam-conv { grid-template-columns: 1fr; gap: 1.5rem; } }
.jam-thread { min-width: 0; }
.jam-crumb { margin: 0 0 0.75rem; font-size: var(--rst-fs-sm); }
.jam-crumb a { text-decoration: none; color: var(--rst-text-faint); }
.jam-crumb a:hover { color: var(--rst-accent-strong); }
.jam-thread__subject { font-family: var(--jam-serif); font-weight: 600; font-size: 2rem; margin: 0 0 0.5rem; line-height: 1.15; text-wrap: balance; letter-spacing: -0.015em; }
/* Renaming in place: the heading is the summary; a pencil appears
   beside it under the pointer; open, an input set in the heading's
   own type takes its place. */
.jam-thread__title-summary { list-style: none; cursor: text; display: flex; align-items: baseline; gap: 0.5rem; }
.jam-thread__title-summary::-webkit-details-marker { display: none; }
.jam-thread__pencil { color: var(--rst-text-faint); opacity: 0; transition: opacity 120ms; flex: none; align-self: center; }
.jam-thread__title-summary:hover .jam-thread__pencil, .jam-thread__title-summary:focus-visible .jam-thread__pencil { opacity: 1; }
.jam-thread__title[open] > .jam-thread__title-summary { display: none; }
.jam-thread__rename { margin: 0 0 0.5rem; }
.jam-thread__subject--input { display: block; width: 100%; box-sizing: border-box; margin: 0; padding: 0 0 0.15rem; border: 0; border-bottom: 2px solid var(--rst-accent); border-radius: 0; background: transparent; color: var(--rst-text); outline: none; }
.jam-thread__rename-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: 0.6rem; }
.jam-thread__rename-foot [rst-btn] { font-size: var(--rst-fs-sm); padding: 0.32rem 0.75rem; }
.jam-thread__rename-foot small { font-size: var(--rst-fs-xs); }
.jam-thread__facts { display: flex; flex-wrap: wrap; gap: 0.5rem 0.9rem; align-items: center; font-size: var(--rst-fs-sm); color: var(--rst-text-muted); margin-bottom: 0.9rem; }
.jam-assignees { display: inline-flex; align-items: center; gap: 0.35rem; color: var(--rst-text); }
/* The action row: who has it (one pill), then thin ink buttons with a
   drawn icon each, the rest behind More. Menus share the row menu's
   list styling. */
.jam-actions-bar { display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; padding: 0.5rem 0; border-top: 1px solid var(--rst-line); border-bottom: 1px solid var(--rst-line); }
.jam-actions-bar__gap { flex: 1; }
.jam-actions-bar__rule { width: 1px; height: 1.4rem; background: var(--rst-line); margin: 0 0.35rem; }
.jam-actions-bar > .jam-pop, .jam-actions-bar > .jam-inline { display: inline-flex; align-items: center; }
/* `.jam-pop summary` sets inline-block; these summaries are flex rows. */
.jam-pop > summary.jam-act-btn, .jam-pop > summary.jam-assign__pill { display: inline-flex; }
/* A busy button that carries an icon shows the spinner in the icon's
   place, at the icon's size, so the buttons beside it never shift.
   The shim puts the spinner in as the first child, just before the
   icon; rastrillo's own icons are already 1em, the spinner's size. */
button[aria-busy="true"] > [rst-spin] + .jam-mi, button[aria-busy="true"] > [rst-spin] + .icon { display: none; }
button[aria-busy="true"] > [rst-spin]:has(+ .jam-mi) { box-sizing: border-box; width: 16px; height: 16px; flex: none; margin: 0; vertical-align: middle; }
.jam-row__follow button[aria-busy="true"] > [rst-spin]:has(+ .jam-mi) { width: 13px; height: 13px; }
.jam-act-btn { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.38rem 0.75rem 0.38rem 0.6rem; vertical-align: middle; border: 1px solid transparent; border-radius: 999px; background: none; font: inherit; font-size: var(--rst-fs-sm); font-weight: 500; color: var(--rst-text); cursor: pointer; list-style: none; line-height: 1.2; white-space: nowrap; }
.jam-act-btn::-webkit-details-marker { display: none; }
.jam-act-btn .jam-mi { color: var(--rst-text-muted); }
.jam-act-btn:hover { background: var(--rst-surface-2); border-color: var(--rst-line); }
.jam-act-btn:hover .jam-mi { color: var(--rst-text); }
.jam-pop[open] > .jam-act-btn { background: var(--rst-accent-soft); color: var(--rst-accent-strong); }
.jam-pop[open] > .jam-act-btn .jam-mi { color: var(--rst-accent-strong); }
.jam-act-btn:focus-visible, .jam-assign__pill:focus-visible { outline: 2px solid var(--rst-accent); outline-offset: 2px; }
.jam-chev { flex: none; color: var(--rst-text-faint); margin-left: -0.15rem; }
/* The assignment pill: faces and names when someone has it; a soft
   strawberry pill saying so when nobody does. */
.jam-assign__pill { display: inline-flex; align-items: center; gap: 0.45rem; padding: 0.25rem 0.65rem 0.25rem 0.3rem; border-radius: 999px; border: 1px solid var(--rst-line); background: var(--rst-surface); font-size: var(--rst-fs-sm); font-weight: 600; color: var(--rst-text); cursor: pointer; list-style: none; line-height: 1.2; }
.jam-assign__pill::-webkit-details-marker { display: none; }
.jam-assign__pill:hover { border-color: var(--rst-line-strong); background: var(--rst-surface-2); }
/* The pill wears the accent only when the conversation is yours; other
   people's assignments and no assignment at all read in the default colour. */
.jam-assign[data-unassigned] .jam-assign__pill { padding-left: 0.6rem; }
.jam-assign[data-mine] .jam-assign__pill { background: var(--rst-accent-soft); color: var(--rst-accent-strong); border-color: transparent; }
.jam-assign[data-mine] .jam-assign__pill .jam-mi, .jam-assign[data-mine] .jam-chev { color: var(--rst-accent-strong); }
.jam-assign[open] .jam-assign__pill { border-color: var(--rst-accent); }
.jam-assign .jam-assignees { gap: 0.2rem; }
.jam-assign .jam-assignees .jam-av { box-shadow: 0 0 0 2px var(--rst-surface); }
.jam-assign .jam-assignees .jam-av + .jam-av { margin-left: -0.5rem; }
.jam-assign__names { margin-left: 0.25rem; }
.jam-menu-list__primary { color: var(--rst-accent-strong); font-weight: 600; }
.jam-menu-list__primary .jam-mi { color: var(--rst-accent-strong); }
.jam-menu-list__on { margin-left: auto; color: var(--rst-accent-strong); font-weight: 600; }
.jam-menu-list kbd { margin-left: auto; font: inherit; font-size: var(--rst-fs-xs); color: var(--rst-text-faint); border: 1px solid var(--rst-line); border-radius: 4px; padding: 0 0.3rem; }
.jam-menu-list__row { display: flex; gap: 0.4rem; align-items: center; padding: 0.3rem 0.6rem; }
.jam-menu-list__row input { flex: 1; min-width: 0; font: inherit; font-size: var(--rst-fs-sm); padding: 0.3rem 0.5rem; border: 1px solid var(--rst-line); border-radius: 6px; background: var(--rst-surface); color: inherit; }
.jam-menu-list__row [rst-btn] { font-size: var(--rst-fs-sm); padding: 0.3rem 0.7rem; }
/* A menu row with two doors: the check (stays open) and the name
   (closes). The check draws as a box; on, it fills with the accent. */
.jam-mrow { display: flex; align-items: center; }
.jam-mrow form:last-child { flex: 1; min-width: 0; display: flex; }
.jam-mrow__check { appearance: none; border: 0; background: none; padding: 0.4rem 0.35rem 0.4rem 0.6rem; margin: 0; cursor: pointer; display: grid; place-items: center; border-radius: 6px; }
.jam-mrow__check::before { content: ""; width: 1rem; height: 1rem; border: 1.5px solid var(--rst-line-strong); border-radius: 4px; background: var(--rst-surface); }
.jam-mrow__check:hover::before { border-color: var(--rst-accent); }
.jam-mrow__check.is-on::before { border-color: var(--rst-accent); background: var(--rst-accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 6.5l2.4 2.4L9.5 3.6' fill='none' stroke='white' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center no-repeat; }
.jam-mrow__check.is-some::before { border-color: var(--rst-accent); background: var(--rst-accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 6h6' fill='none' stroke='white' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E") center no-repeat; }
.jam-mrow__check.is-busy::before { border: 2px solid var(--rst-line); border-top-color: var(--rst-accent); border-radius: 50%; background: none; animation: jam-spin 0.6s linear infinite; }
@keyframes jam-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .jam-mrow__check.is-busy::before { animation: none; border-style: dotted; } }
.jam-mrow__name { flex: 1; min-width: 0; display: flex; align-items: center; gap: 0.5rem; border: 0; background: none; font: inherit; font-size: var(--rst-fs-sm); color: var(--rst-text); text-align: left; padding: 0.4rem 0.65rem 0.4rem 0.35rem; margin: 0; border-radius: 6px; cursor: pointer; }
.jam-mrow__name:hover { background: var(--rst-surface-2); }
.jam-mrow__count { margin-left: auto; color: var(--rst-text-faint); font-size: var(--rst-fs-xs); }
.jam-menu-list__label { display: block; padding: 0.3rem 0.6rem 0; font-size: var(--rst-fs-xs); color: var(--rst-text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.jam-menu-list__empty { margin: 0; padding: 0.4rem 0.6rem; color: var(--rst-text-muted); font-size: var(--rst-fs-sm); white-space: normal; }
.jam-menu-list .jam-rename small { display: block; padding: 0 0.6rem 0.3rem; white-space: normal; max-width: 18rem; }
.jam-menu-list .jam-av--sm { flex: none; }
.jam-pop { position: relative; display: inline-block; }
/* Flipped placement (scripts measure on open): above the button, or
   hugging the other side, whenever the default would be cut off. */
[data-flip-y] > .jam-pop__body { top: auto; bottom: calc(100% + 0.3rem); margin-top: 0; }
[data-flip-y] > .jam-menu__panel { top: auto; bottom: calc(100% + 0.4rem); }
[data-flip-y] > .rst-row-menu__panel, [data-flip-y] > [rst-row-menu-panel],
[data-flip-y] > .rst-dropdown__menu, [data-flip-y] > [rst-dropdown-menu] { top: auto; bottom: calc(100% + 4px); }
[data-flip-x] > .jam-pop__body { left: auto; right: 0; }
.jam-pop--right[data-flip-x] > .jam-pop__body { right: auto; left: 0; }
/* Menus sit above everything. The cards are stacking contexts (each
   message carries z-index so its sheet shadow layers), which traps a
   menu's own z-index inside its card — so while a menu is open, the
   card holding it lifts above its siblings. The row menus already do
   this; this is the same rule for the whole pop pattern. */
.jam-pop[open] { z-index: 31; }
.jam-msg:has(.jam-pop[open]), .jam-note:has(.jam-pop[open]),
.jam-entries > :has(.jam-pop[open]), .jam-thread__folds > :has(.jam-pop[open]) { position: relative; z-index: 30; }
.jam-pop summary { list-style: none; cursor: pointer; display: inline-block; }
.jam-pop summary::-webkit-details-marker { display: none; }
.jam-pop__body { position: absolute; z-index: 30; top: 100%; left: 0; margin-top: 0.3rem; background: var(--rst-surface); border: 1px solid var(--rst-line); border-radius: 10px; padding: 0.6rem; display: flex; gap: 0.5rem; align-items: center; box-shadow: var(--rst-shadow-pop); white-space: nowrap; }
.jam-pop--right .jam-pop__body { left: auto; right: 0; }
.jam-pop__body--col { flex-direction: column; align-items: stretch; gap: 0.1rem; padding: 0.35rem; }
.jam-pop__body--col form { display: contents; }
/* Buttons in a menu are menu items, not buttons: no pill, no border,
   quiet hover — whatever element they happen to be. */
.jam-pop__body--col [rst-btn] { border: 0; border-radius: 6px; background: none; box-shadow: none; width: 100%; justify-content: flex-start; text-align: left; font-weight: 450; font-size: var(--rst-fs-sm); padding: 0.4rem 0.65rem; color: var(--rst-text); }
.jam-pop__body--col [rst-btn]:hover { background: var(--rst-surface-2); color: var(--rst-text); }

/* The timeline: a spine on the left; every entry hangs off it with a
   node — the sender's or author's face, the actor's for activity. */
/* One axis for every face: the spine runs under the centre of a
   message's avatar (1.5rem in, 2.5rem wide → 2.75rem), and the notes'
   and activity's faces sit on it. */
.jam-entries { list-style: none; padding: 0 0 0 3.75rem; margin: 1.5rem 0 0; display: grid; gap: 1rem; position: relative; }
/* Grid items may shrink: a collapsed head's nowrap snippet must
   ellipsise inside the pane, never widen every card in the column. */
.jam-entries > * { min-width: 0; }
.jam-entries::before { content: ""; position: absolute; left: calc(2rem - 1px); top: 1.2rem; bottom: 0; width: 2px; background: var(--rst-line); border-radius: 1px; }
.jam-msg, .jam-note, .jam-act { position: relative; }
/* A message sits on top of the line, edge to edge, its face inside. */
.jam-msg { margin-left: -3.75rem; z-index: 1; }
.jam-node { position: absolute; left: -3rem; top: 0.9rem; width: 2.5rem; display: flex; justify-content: center; }
.jam-node .jam-av { width: 1.9rem; height: 1.9rem; font-size: 0.68rem; }
.jam-node .jam-av { box-shadow: 0 0 0 3px var(--rst-bg); }
.jam-node--note { top: 0.65rem; }
.jam-node--act { top: -0.1rem; }
.jam-node__dot { width: 0.6rem; height: 0.6rem; border-radius: 50%; background: var(--rst-line-strong); box-shadow: 0 0 0 3px var(--rst-bg); margin-top: 0.45rem; }
@media (prefers-reduced-motion: no-preference) {
  .jam-msg, .jam-note { animation: jam-rise 0.5s cubic-bezier(0.16, 1, 0.3, 1) both; }
  @keyframes jam-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
}
.jam-msg { background: var(--rst-surface); border: 1px solid var(--rst-line); border-radius: 12px; padding: 0.75rem 1.5rem 1.4rem; box-shadow: var(--jam-shadow-sheet); }
.jam-msg--out { background: var(--jam-out); }
/* The head reaches 0.75rem into the rail so the sender's avatar sits
   on it (centre 2rem, like the spine and the nodes); the body's left
   edge stays where it was. */
.jam-msg__head { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr) auto; gap: 0.85rem; align-items: start; margin-bottom: 1rem; margin-left: -0.75rem; }
.jam-msg__head > .jam-av { justify-self: center; }
.jam-msg__from { display: grid; gap: 0.1rem; min-width: 0; font-size: var(--rst-fs-sm); }
.jam-msg__from strong { font-size: var(--rst-fs-base); color: var(--rst-text); }
.jam-msg__addr { color: var(--rst-text-faint); }
.jam-msg__to { color: var(--rst-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jam-msg__when { font-size: var(--rst-fs-sm); color: var(--rst-text-faint); white-space: nowrap; font-variant-numeric: tabular-nums; padding-top: 0.2rem; }
.jam-msg__body { font-family: var(--jam-serif); font-size: 1.02rem; line-height: 1.6; max-width: 68ch; overflow-wrap: anywhere; color: var(--rst-text); }
.jam-msg__body p { margin: 0 0 0.85em; }
.jam-msg__body p:last-child { margin-bottom: 0; }
.jam-msg__body img { max-width: 100%; height: auto; }
.jam-msg__body a { color: var(--rst-accent-strong); }
.jam-msg__body blockquote { border-left: 1px solid var(--rst-line-strong); margin: 0.6em 0; padding-left: 0.9em; color: var(--rst-text-muted); }
.jam-msg__body pre { font-size: 0.85rem; overflow-x: auto; }

/* ── Quoted text ───────────────────────────────────────────────────── */
/* The history a reply carries under it, folded behind an ellipsis
   pill. A <details> opens without JavaScript and takes the keyboard
   for free, so there is nothing here but the look of the thing. */
.jam-quote { margin-top: 0.6em; }
.jam-quote__toggle { list-style: none; display: inline-block; cursor: pointer; padding: 0 0.55rem; border-radius: var(--rst-radius-pill); background: var(--rst-line); color: var(--rst-text-faint); font-family: var(--rst-font); font-size: var(--rst-fs-sm); font-weight: 600; line-height: 1.6; letter-spacing: 0.08em; }
.jam-quote__toggle::-webkit-details-marker { display: none; }
.jam-quote__toggle:hover { background: var(--rst-accent-soft); color: var(--rst-accent); }
.jam-quote__toggle:focus-visible { outline: 2px solid var(--rst-accent); outline-offset: 2px; }
.jam-quote__body { margin-top: 0.6em; padding-left: 0.9rem; border-left: 1px solid var(--rst-line); color: var(--rst-text-muted); }
.jam-quote__body blockquote { border-left-color: var(--rst-line); }

.jam-shelf { list-style: none; padding: 0.8rem 0 0; margin: 1rem 0 0; border-top: 1px dashed var(--rst-line); display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; font-size: var(--rst-fs-sm); font-family: var(--rst-font); }
.jam-shelf a { text-decoration: none; font-weight: 500; }

.jam-note { position: relative; background: var(--jam-note); border: 1px solid var(--jam-note-line); border-radius: 10px; padding: 0.55rem 0.9rem 0.6rem; margin-left: 0; color: var(--jam-note-ink); }
.jam-note:has(.jam-note__fold:not([open])) { padding-top: 0.35rem; padding-bottom: 0.35rem; }
.jam-note__menu { position: absolute; top: 0.3rem; right: 0.4rem; }
.jam-note__menu .jam-more-btn { color: var(--jam-note-ink); opacity: 0.7; }
.jam-note__menu[open] .jam-more-btn, .jam-note__menu .jam-more-btn:hover { opacity: 1; }
.jam-note__head { padding-right: 2rem; }
.jam-note__permalink { color: inherit; text-decoration: none; }
.jam-note__permalink:hover time { text-decoration: underline; text-underline-offset: 2px; }
.jam-pop__body--col .jam-note__delete { color: var(--rst-danger, #c62828); }
/* The menu owns editing now; the editwrap's own summary is only the
   scriptless way in. */
.js .jam-note__editwrap > summary { display: none; }
.jam-note__head { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.45rem; font-size: var(--rst-fs-sm); min-width: 0; }
.jam-note__head strong { color: inherit; }
.jam-note__tag { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 600; opacity: 0.75; margin-left: 0.25rem; }
.jam-note__head time { margin-left: auto; color: inherit; opacity: 0.7; }
.jam-note__body { font-size: var(--rst-fs-base); line-height: 1.55; }
/* An imported note whose author is not a member here says so on its
   first line — quieter than the note, and never mistaken for it. */
.jam-note__origin { font-size: var(--rst-fs-sm); opacity: 0.75; margin: 0 0 0.5em; }
.jam-note__body p { margin: 0 0 0.5em; }
.jam-note__body p:last-child { margin-bottom: 0; }
.jam-note .jam-av { background: var(--jam-note-line); color: var(--jam-note-ink); }
.jam-note__tag { color: var(--jam-note-ink); }
.jam-mention { font-weight: 600; color: var(--rst-accent-strong); }
.jam-note__edited { font-size: var(--rst-fs-sm); color: var(--jam-note-ink); opacity: 0.7; font-style: italic; }
.jam-note__editwrap { margin-top: 0.5rem; }
.jam-note__editbtn { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 0.3rem; font-size: var(--rst-fs-sm); color: var(--jam-note-ink); opacity: 0.75; }
.jam-note__editbtn::-webkit-details-marker { display: none; }
.jam-note__editbtn:hover { opacity: 1; text-decoration: underline; }
.jam-note__editwrap[open] > .jam-note__editbtn { display: none; }
.jam-note__body:has(+ .jam-note__editwrap[open]) { display: none; }
.jam-note .jam-mention { color: inherit; text-decoration: underline; text-decoration-color: var(--jam-note-line); text-underline-offset: 0.15em; }

/* A note's small controls, on one line under the body: "Copy link"
   always, "Edit" while it is still the author's to change. Opening the
   editor takes the whole row, and the copy link steps aside. */
.jam-note__tools { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 1rem; margin-top: 0.5rem; }
.jam-note__tools > .jam-note__editwrap { margin-top: 0; }
a.jam-note__editbtn { text-decoration: none; }
.jam-note__tools:has(.jam-note__editwrap[open]) { display: block; }
.jam-note__tools:has(.jam-note__editwrap[open]) > a.jam-note__editbtn { display: none; }
.jam-note__body:has(+ .jam-note__tools .jam-note__editwrap[open]) { display: none; }

/* A note's reactions: one chip per team member who reacted, in the
   order they did, and a quiet "add a reaction" popover after them. */
.jam-note__reactions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; margin-top: 0.6rem; }
.jam-reaction { display: inline-flex; align-items: center; gap: 0.3rem; font-size: var(--rst-fs-sm); line-height: 1; padding: 0.2rem 0.5rem 0.2rem 0.2rem; border-radius: 999px; background: var(--rst-surface); border: 1px solid var(--jam-note-line); }
form.jam-reaction { background: none; border: 0; padding: 0; margin: 0; }
.jam-reaction--mine button { display: inline-flex; align-items: center; gap: 0.3rem; font: inherit; line-height: 1; padding: 0.2rem 0.5rem 0.2rem 0.2rem; border-radius: 999px; background: var(--rst-accent-soft); border: 1px solid var(--rst-accent-strong); color: inherit; cursor: pointer; }
.jam-reaction--mine button:hover { background: var(--rst-line); }
.jam-reaction .jam-av, .jam-reaction--mine .jam-av { box-shadow: none; }
.jam-reaction-add { list-style: none; cursor: pointer; display: inline-flex; align-items: center; padding: 0.25rem 0.4rem; border-radius: 999px; opacity: 0.6; }
.jam-reaction-add::-webkit-details-marker { display: none; }
.jam-reaction-add:hover, .jam-reaction-pop[open] > .jam-reaction-add { opacity: 1; background: var(--rst-surface); }

/* The reaction picker: search plus Jelly-style named categories, built
   on the same filter-as-you-type list the assign and label menus use
   (jam-menu-list__filter/__scroll/__none in shortcuts.js) so search,
   viewport clamping and Enter-to-pick all come for free. Emoji are
   plain characters — no artwork, no CDN — so the set can be generous. */
.jam-reaction-palette { width: 17rem; max-width: calc(100vw - 2.5rem); }
.jam-reaction-palette .jam-menu-list__scroll { display: flex; flex-wrap: wrap; align-content: flex-start; gap: 0.05rem; }
.jam-reaction-palette .jam-menu-list__scroll form { display: contents; }
.jam-reaction-cat { flex: 1 0 100%; margin: 0.55rem 0 0.15rem; padding: 0 0.15rem; font-size: var(--rst-fs-xs); font-weight: 600; color: var(--rst-text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.jam-reaction-cat:first-child { margin-top: 0; }
.jam-reaction-palette button { font-size: 1.15rem; line-height: 1; padding: 0.3rem; border-radius: 6px; background: none; border: 0; cursor: pointer; }
.jam-reaction-palette button:hover { background: var(--rst-accent-soft); }
/* Visually hidden, not aria-hidden: a picker button's accessible name
   (and what the search box matches) beside the glyph. */
.jam-vh { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

/* ── Following a link to one message or note ────────────────────────
   The sheet takes a soft accent tint that fades away over a couple of
   seconds, so the eye lands on the thing the link named and the page
   then looks like any other. Scripts off there is nothing to fade it,
   so :target holds the tint for as long as the fragment is in the
   URL — and with scripts on, that same rule would never let go, which
   is why it is scoped to html:not(.js). Under reduced motion the
   script keeps the class instead of removing it: the tint stays. */
/* An outline rather than a box-shadow: a sheet already has one, and
   the tint must not flatten it for the two seconds it is up. */
.jam-msg, .jam-note { outline: 2px solid transparent; outline-offset: 2px; transition: outline-color 700ms ease-out, background-color 700ms ease-out; }
.jam-entry--flash,
html:not(.js) .jam-msg:target, html:not(.js) .jam-note:target,
html:not(.js) .jam-entry--focus { outline-color: var(--rst-accent); transition: none; }
.jam-msg.jam-entry--flash, html:not(.js) .jam-msg:target, html:not(.js) .jam-msg.jam-entry--focus { background-color: var(--rst-accent-soft); }
@media (prefers-reduced-motion: reduce) { .jam-msg, .jam-note { transition: none; } }
.jam-act { font-size: var(--rst-fs-sm); color: var(--rst-text-muted); padding: 0.15rem 0 0.15rem 0; min-height: 1.5rem; }
.jam-act__who { font-weight: 600; color: var(--rst-text-muted); }

.jam-compose-note { display: grid; gap: 0.5rem; margin-top: 0.75rem; }
/* The two forms fold closed: a pill each, on the spine. */
.jam-thread__folds { position: relative; }
.jam-thread__folds::before { content: ""; position: absolute; left: calc(2rem - 1px); top: -1rem; bottom: 1.6rem; width: 2px; background: var(--rst-line); border-radius: 1px; }
.jam-thread__folds > * { position: relative; }

/* Presence: who else has this conversation open. Quiet by design —
   small muted text under the things you would write with, an avatar
   each, and a word for what they are doing. The one time it raises
   its voice is a clash: you are writing a reply and so is somebody
   else, which is the whole reason the bar exists. */
/* The last item on the timeline: faces on the rail like any other
   node, words beside them. */
.jam-presence { display: none; position: relative; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin: 1rem 0 0 3.75rem; min-height: 1.9rem; font-size: var(--rst-fs-sm); color: var(--rst-text-muted); }
/* The first face sits on the spine exactly where a lone one would
   (0.3rem is the slack a 1.9rem avatar leaves in the 2.5rem node);
   the rest of the stack flows rightwards, and the words step aside
   when it does. */
/* The faces sit in flow, pulled left so the first lands on the spine:
   however many there are, the words start after the last face rather
   than underneath it. */
.jam-presence .jam-node { position: static; width: auto; min-width: 2.5rem; justify-content: flex-start; margin-left: -3rem; padding-left: 0.3rem; }
.jam-presence:has(.jam-av) { display: flex; }
.jam-presence__faces { display: inline-flex; }
.jam-presence__faces .jam-av { margin-left: -0.55rem; }
.jam-presence__faces .jam-av:first-child { margin-left: 0; }
.jam-presence__says { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }
.jam-presence__group { display: inline-flex; align-items: center; gap: 0.35rem; }
.jam-presence__group .jam-mi { color: var(--rst-text-faint); }
.jam-presence__sep { color: var(--rst-text-faint); }
.jam-presence__clash { padding: 0.15rem 0.5rem; border-radius: 999px; background: var(--rst-tone-warning-bg); color: var(--rst-tone-warning-fg); font-weight: 500; }
.jam-presence__clash .jam-mi { color: inherit; }
.jam-fold [rst-field-label] { color: var(--rst-text-muted); font-size: var(--rst-fs-sm); }
.jam-fold { position: relative; margin: 1rem 0 0 3.75rem; }
.jam-fold summary { list-style: none; cursor: pointer; display: flex; align-items: center; margin-left: -0.15rem; }
.jam-fold summary::-webkit-details-marker { display: none; }
.jam-fold__pill { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.9rem; border-radius: 999px; background: var(--rst-surface-2); color: var(--rst-text-muted); font-weight: 500; border: 1px solid var(--rst-line); }
.jam-fold__pill kbd { font: inherit; font-size: 0.7rem; border: 1px solid var(--rst-line-strong); border-radius: 4px; padding: 0 0.35rem; color: var(--rst-text-faint); }
.jam-fold__pill--primary { background: var(--rst-accent); color: var(--rst-on-accent); border-color: var(--rst-accent); font-weight: 600; font-size: 1rem; padding: 0.6rem 1.2rem; }
.jam-fold__pill--primary kbd { color: var(--rst-on-accent); border-color: rgba(255, 255, 255, 0.5); }
/* Open, the pill gives way to the form (scripts on; without them the
   pill stays as the only way to close). */
.js .jam-fold[open] > summary { display: none; }
.jam-fold[open] > summary { margin-bottom: 0.6rem; }
.jam-fold__actions { display: flex; gap: 0.5rem; align-items: center; }
.jam-entry--cursor { outline: 2px solid var(--rst-accent); outline-offset: 3px; border-radius: 12px; }
.jam-fold--reply { margin-left: 0; }
.jam-fold--reply .jam-compose { margin-top: 0; }
.jam-fold--note .jam-node { top: 0.15rem; }
.jam-compose-note [rst-field-label] { color: var(--jam-note-ink); }

.jam-compose-note textarea { width: 100%; box-sizing: border-box; padding: 0.7rem 0.9rem; border: 1px solid var(--jam-note-line); background: var(--jam-note); color: var(--jam-note-ink); border-radius: 10px; font: inherit; line-height: 1.5; }
.jam-compose-note textarea::placeholder { color: var(--jam-note-ink); opacity: 0.55; }

.jam-contact__name { font-family: var(--jam-serif); font-weight: 600; font-size: 1.15rem; margin: 0.6rem 0 0.1rem; }
.jam-contact p { margin: 0 0 0.35rem; font-size: var(--rst-fs-sm); color: var(--rst-text-muted); }
.jam-contact__sub { font-size: var(--rst-fs-xs); text-transform: uppercase; letter-spacing: 0.08em; color: var(--rst-text-faint); font-weight: 600; margin: 1.1rem 0 0.4rem; padding-left: 0.5rem; }
.jam-contact__convs { list-style: none; padding: 0; margin: 0; }
.jam-contact__convs li { display: grid; gap: 0.1rem; padding: 0.45rem 0.5rem; border-radius: 6px; font-size: var(--rst-fs-sm); }
.jam-contact__convs li.is-current { background: var(--rst-accent-soft); }
.jam-contact__convs a { text-decoration: none; color: var(--rst-text); font-family: var(--jam-serif); font-size: 0.95rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.jam-contact__convs li:hover { background: var(--rst-surface-2); }
.jam-contact__convs time { font-size: var(--rst-fs-sm); color: var(--rst-text-faint); }

/* ── Compose ───────────────────────────────────────────────────────── */
.jam-compose { margin-top: 1.5rem; background: var(--rst-surface); border: 1px solid var(--rst-line); border-radius: 12px; padding: 1.1rem 1.5rem 1.2rem; box-shadow: var(--jam-shadow-sheet); }
.jam-compose__title { font-family: var(--jam-serif); font-weight: 600; font-size: 1.15rem; margin: 0 0 0.4rem; }
.jam-compose__prov { font-size: var(--rst-fs-sm); margin: 0 0 0.6rem; }
/* The read-only draft: the same sheet, the fields as a quiet list, the
   words as they would read in the thread, and one button. */
.jam-compose__preview-fields { margin: 0; padding: 0; }
.jam-compose__preview-fields > div { display: grid; grid-template-columns: 4rem minmax(0, 1fr); gap: 0.5rem; padding: 0.4rem 0; border-bottom: 1px solid var(--rst-line); }
.jam-compose__preview-fields dt { font-size: var(--rst-fs-sm); color: var(--rst-text-faint); }
.jam-compose__preview-fields dd { margin: 0; overflow-wrap: anywhere; }
.jam-compose__preview-body { padding: 0.75rem 0 0.25rem; }
.jam-compose--preview .jam-compose__foot { margin-top: 0.75rem; }
/* The editor that lost its lock: the words stay for copying, but
   nothing about them can be sent. */
.jam-compose__lost { margin: 0 0 0.75rem; }
.jam-compose__row { display: grid; grid-template-columns: 4rem minmax(0, 1fr); align-items: center; gap: 0.5rem; padding: 0.25rem 0; border-bottom: 1px solid var(--rst-line); }
.jam-compose__row label { font-size: var(--rst-fs-sm); color: var(--rst-text-faint); }
.jam-compose__row input, .jam-compose__row select { border: none; background: transparent; font: inherit; padding: 0.35rem 0; width: 100%; color: inherit; }
.jam-compose__row input:focus, .jam-compose__row select:focus { outline: none; }
.jam-compose__editor { margin-top: 0.5rem; }
/* ── The editor ─────────────────────────────────────────────────── */
/* One toolbar for every editor: drawn icons in groups, pressed state
   from the cursor's formatting, dialogs (link, saved replies) under
   it, the @mention list beside the caret. */
/* Every editor is one bordered box: toolbar, hairline, field. The note fold
   only recolours this shape. */
.jam-editor-wrap { position: relative; display: block; width: 100%; min-width: 0; border: 1px solid var(--rst-line); border-radius: 10px; background: var(--rst-surface); }
.jam-editor-wrap:focus-within { border-color: var(--rst-accent); box-shadow: 0 0 0 3px var(--rst-accent-soft); }
.jam-editor-dialog[hidden], .jam-mentions[hidden], .jam-mentions li[hidden] { display: none; }
.jam-editor-wrap textarea { width: 100%; box-sizing: border-box; border: 0; border-radius: 10px; background: transparent; padding: 0.6rem 0.75rem; font: inherit; outline: none; resize: vertical; }
[data-editor-files].is-enhanced input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; }
.jam-toolbar { display: flex; flex-wrap: wrap; gap: 0.15rem 0.5rem; align-items: center; padding: 0.35rem 0.6rem; border-bottom: 1px solid var(--rst-line); border-radius: 10px 10px 0 0; }
.jam-toolbar__group { display: inline-flex; gap: 0.1rem; padding-right: 0.5rem; border-right: 1px solid var(--rst-line); }
.jam-toolbar__group:last-of-type { border-right: 0; }
.jam-toolbar [data-tool] { -webkit-appearance: none; appearance: none; display: grid; place-items: center; width: 1.85rem; height: 1.85rem; border: 1px solid transparent; border-radius: 6px; background: none; color: var(--rst-text-muted); cursor: pointer; padding: 0; margin: 0; font: inherit; line-height: 1; }
.jam-toolbar [data-tool]:hover { color: var(--rst-text); background: var(--rst-surface-2); }
.jam-toolbar [data-tool][aria-pressed="true"] { color: var(--rst-accent-strong); background: var(--rst-accent-soft); }
.jam-toolbar [data-tool]:focus-visible { outline: 2px solid var(--rst-accent); outline-offset: 1px; }
.jam-toolbar__phone { display: none !important; }
.jam-toolbar__status { margin-left: auto; font-size: var(--rst-fs-xs); color: var(--rst-text-faint); }
/* A dialog (the link form, the saved-reply list) floats over the
   text where it would otherwise sit, below the toolbar: top is left
   auto, so the static position places it, and nothing below moves. */
.jam-editor-dialog { position: absolute; z-index: 8; left: 0.4rem; right: 0.4rem; display: flex; gap: 0.4rem; align-items: center; margin: 0.2rem 0 0.5rem; padding: 0.5rem 0.6rem; border: 1px solid var(--rst-line); border-radius: 9px; background: var(--rst-surface); box-shadow: var(--rst-shadow-pop); }
.jam-editor-dialog input[type="url"] { flex: 1; min-width: 0; font: inherit; font-size: var(--rst-fs-sm); padding: 0.35rem 0.6rem; border: 1px solid var(--rst-line); border-radius: 6px; background: var(--rst-surface); color: inherit; }
.jam-editor-dialog [rst-btn] { font-size: var(--rst-fs-sm); padding: 0.32rem 0.7rem; }
.jam-editor-dialog--list { display: grid; gap: 0.1rem; padding: 0.35rem; max-height: 16rem; overflow: auto; }
.jam-editor-dialog--list button, .jam-editor-dialog--list li { display: flex; align-items: center; gap: 0.6rem; width: 100%; padding: 0.4rem 0.6rem; border: 0; border-radius: 6px; background: none; font: inherit; font-size: var(--rst-fs-sm); color: var(--rst-text); text-align: left; cursor: pointer; }
.jam-editor-dialog--list button:hover, .jam-editor-dialog--list li:hover, .jam-editor-dialog--list li[aria-selected="true"] { background: var(--rst-surface-2); }
.jam-editor-dialog--list button strong { font-weight: 600; }
.jam-editor-dialog--list button[data-saved-reply] { display: grid; gap: 0.05rem; min-width: 0; }
.jam-editor-dialog--list button[data-saved-reply] strong .jam-muted { font-weight: 400; margin-left: 0.35rem; }
.jam-editor-dialog__snip { font-size: var(--rst-fs-xs); color: var(--rst-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jam-setlist__meta-lead { color: var(--rst-text); }
.jam-editor-dialog--list .jam-muted { font-size: var(--rst-fs-xs); }
/* The @mention list floats over the note at the caret rather than
   sitting in the flow, so opening it never shifts the content. */
.jam-mentions { list-style: none; position: absolute; z-index: 8; margin: 0; min-width: 16rem; max-width: calc(100% - 0.5rem); max-height: 14rem; overflow: auto; }
/* Heights, by kind: a couple of lines more than the text usually
   needs, so writing never starts in a slot. The reply is the page's
   business; a note is short; the rest (signature, autoresponder, a
   saved reply) sit between. */
.jam-editor { position: relative; width: 100%; box-sizing: border-box; min-height: 9rem; padding: 0.6rem 0.75rem; border: 0; border-radius: 0 0 10px 10px; background: transparent; font-size: 1rem; line-height: 1.55; outline: none; overflow-wrap: anywhere; }
.jam-editor:empty::before, .jam-editor[data-placeholder]:has(> div:only-child > br:only-child)::before { content: attr(data-placeholder); color: var(--rst-text-faint); position: absolute; pointer-events: none; }
.jam-editor-wrap--reply .jam-editor { min-height: 12rem; font-family: var(--jam-serif); font-size: 1.02rem; line-height: 1.6; }
.jam-editor-wrap--note .jam-editor { min-height: 7.5rem; }
/* Writing a note looks like the note it becomes — and shaped like
   Jelly's comment form: the whole form on the blueberry card, the
   toolbar and field one bordered box on a lighter well, the author's
   avatar holding the rail while it is open. Placed after the base
   editor rules on purpose: same specificity, later order wins. */
.jam-fold--note .jam-compose-note { background: var(--jam-note); border-radius: 12px; padding: 0.85rem 1rem 1rem; gap: 0.65rem; margin-top: 0; }
/* The note fold recolours the shared one-box editor; no overflow:hidden —
   the @mention list floats out of the wrap. */
.jam-fold--note .jam-editor-wrap { border-color: var(--jam-note-line); background: var(--jam-note-well, var(--rst-surface)); }
.jam-fold--note .jam-editor-wrap:focus-within { border-color: var(--jam-note-ink); box-shadow: 0 0 0 3px var(--jam-note-line); }
.jam-fold--note .jam-toolbar { border-bottom-color: var(--jam-note-line); }
.jam-fold--note .jam-editor { color: var(--jam-note-ink); min-height: 7.5rem; }
.jam-fold--note .jam-editor::before { color: var(--jam-note-ink); opacity: 0.6; }
.js .jam-fold--note[open] > summary { display: block; margin: 0; height: 0; }
.jam-fold--note[open] .jam-fold__pill { display: none; }
.jam-editor a { color: var(--rst-accent-strong); }
.jam-editor pre { background: var(--rst-surface-2); border-radius: 6px; padding: 0.5rem 0.7rem; font-size: 0.92em; overflow: auto; }
.jam-editor .jam-signature { color: var(--rst-text-muted); }
.jam-editor img { max-width: 100%; height: auto; border-radius: 4px; cursor: default; }
.jam-editor img:focus { outline: 2px solid var(--rst-accent); outline-offset: 2px; }
.jam-editor-wrap .squire-image-resize-container { pointer-events: none; }
.jam-editor-wrap .squire-image-resize-container > * { pointer-events: auto; width: 10px; height: 10px; background: var(--rst-surface); border: 2px solid var(--rst-accent); border-radius: 2px; }
.jam-msg__body img, .jam-note__body img { max-width: 100%; height: auto; }
.jam-compose__filelist { font-size: var(--rst-fs-xs); color: var(--rst-text-muted); }
@media (max-width: 720px) {
  .jam-toolbar__phone { display: grid !important; }
  .jam-toolbar { gap: 0.1rem 0.25rem; }
  .jam-toolbar__group { padding-right: 0.25rem; gap: 0; }
  .jam-toolbar [data-tool] { width: 1.65rem; height: 1.65rem; }
  .jam-toolbar [data-tool] svg { width: 14px; height: 14px; }
  .jam-toolbar [data-tool="undo"], .jam-toolbar [data-tool="redo"] { display: none !important; }
  .jam-fold--note [rst-field-label] { color: var(--rst-text-muted); }
  .jam-thread__folds::before { left: calc(0.9rem - 1px); }
  .jam-editor { font-size: 0.95rem; }
}
.jam-toolbar--old { display: flex; gap: 0.25rem; align-items: center; padding: 0.35rem 0; }
.jam-toolbar button { border: 1px solid var(--rst-line); background: var(--rst-surface-2); border-radius: 6px; padding: 0.2rem 0.55rem; font: inherit; font-size: var(--rst-fs-sm); cursor: pointer; color: var(--rst-text-muted); }
.jam-toolbar button:hover { color: var(--rst-text); border-color: var(--rst-line-strong); }
.jam-toolbar button:disabled { opacity: 0.38; cursor: default; }
.jam-toolbar button:disabled:hover { color: inherit; border-color: var(--rst-line); }
.jam-toolbar [data-compose-status] { margin-left: auto; font-size: var(--rst-fs-xs); }
.jam-editor blockquote { border-left: 1px solid var(--rst-line-strong); margin: 0.6em 0; padding-left: 0.9em; color: var(--rst-text-muted); }
.jam-compose textarea { width: 100%; box-sizing: border-box; font: inherit; padding: 0.7rem; border: 1px solid var(--rst-line); border-radius: 8px; background: var(--rst-surface); color: inherit; }
.jam-compose__foot { display: flex; gap: 0.5rem; flex-wrap: wrap; padding-top: 0.7rem; border-top: 1px solid var(--rst-line); margin-top: 0.5rem; }
.jam-signature { color: var(--rst-text-muted); }

/* ── Keyboard help ─────────────────────────────────────────────────── */
.jam-help { position: fixed; right: 1.25rem; bottom: 1.25rem; z-index: 20; width: 18rem; background: var(--rst-surface); border: 1px solid var(--rst-line); border-radius: 12px; padding: 1rem 1.25rem; box-shadow: var(--rst-shadow-pop); }
.jam-help h2 { font-family: var(--jam-serif); font-size: 1rem; margin: 0 0 0.5rem; }
.jam-help dl { display: grid; grid-template-columns: auto 1fr; gap: 0.25rem 0.75rem; margin: 0; font-size: var(--rst-fs-sm); }
.jam-help dt { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--rst-accent-strong); }
.jam-help dd { margin: 0; }

/* ── Notifications ─────────────────────────────────────────────────── */
.jam-notifs .jam-row__link { grid-template-columns: 1.5rem minmax(0, 1fr); align-items: center; }

/* ── Narrow screens ────────────────────────────────────────────────── */
.jam-brand { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 40vw; }
.jam-compose__row input, .jam-compose__row select { min-width: 0; }
@media (max-width: 900px) {
  .jam-top { flex-wrap: wrap; gap: 0.5rem 0.75rem; padding: 0.6rem 1rem; }
  .jam-brand { max-width: 60vw; order: 1; }
  .jam-menu { margin-left: auto; order: 2; }
  .jam-nav { order: 3; flex: 1; overflow-x: auto; scrollbar-width: none; margin: 0; }
  .jam-top__compose { order: 4; }
  .jam-top .jam-search { order: 5; flex-basis: 100%; max-width: none; margin: 0; }
  /* The sidebar becomes a strip of views above the list, so the mail
     is the first thing on a phone. */
  .jam-side { display: flex; align-items: center; gap: 0.25rem; overflow-x: auto; scrollbar-width: none; margin: 0 -1rem; padding: 0 1rem; }
  .jam-side__list { display: flex; gap: 0.25rem; margin: 0; }
  .jam-side__list a { white-space: nowrap; }
  .jam-side__title { display: none; }
  .jam-nav a { white-space: nowrap; }
  .jam-conv, .jam-shell { padding: 1rem 1rem 4rem; }
  .jam-thread__subject { font-size: 1.6rem; }
  .jam-msg { padding: 1rem 1.1rem 1.1rem; }
  .jam-entries { padding-left: 2.6rem; }
  .jam-node { left: -2.6rem; }
  /* The spine follows the avatars: centres sit at 1.25rem here. */
  .jam-entries::before, .jam-thread__folds::before { left: calc(1.25rem - 1px); }
  .jam-msg { margin-left: -2.6rem; }
  .jam-fold { margin-left: 2.6rem; }
  .jam-fold--reply { margin-left: 0; }
  .jam-presence { margin-left: 2.6rem; }
  .jam-compose { padding: 1rem 1.1rem; }
}

/* ── Contacts ──────────────────────────────────────────────────────── */
/* ── Contacts ──────────────────────────────────────────────────────── */
/* The directory: a segmented Everyone/Blocked, a search, then rows —
   face, name and address, last heard from on the right. */
/* These pages have little intrinsic width; the page column is a flex
   item that would shrink to it, so the page itself is sized. */
.jam-page--wide { width: 52rem; max-width: 100%; }
/* ── Settings: a sidebar of pages beside the one being read ─────────
   The sidebar is the inbox's, in miniature: group titles in caps, the
   current page filled. On a phone it turns into a strip across the
   top that scrolls sideways, and settings.js scrolls the current item
   into view. */
.jam-page--settings { width: 68rem; max-width: 100%; }
.jam-setshell { display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: 2.75rem; align-items: start; }
.jam-setnav { position: sticky; top: 1rem; }
.jam-setnav__head { font-family: var(--jam-serif); font-weight: 600; font-size: 1.25rem; margin: 0 0 0.25rem 0.6rem; }
.jam-setnav__title { font-size: var(--rst-fs-xs); text-transform: uppercase; letter-spacing: 0.1em; color: var(--rst-text-faint); font-weight: 600; margin: 1rem 0 0.3rem 0.6rem; }
.jam-setnav__list { list-style: none; padding: 0; margin: 0; }
.jam-setnav__list a { display: flex; align-items: center; padding: 0.3rem 0.6rem; border-radius: 8px; text-decoration: none; color: var(--rst-text-muted); font-size: var(--rst-fs-sm); }
.jam-setnav__list a:hover { color: var(--rst-text); background: var(--rst-surface-2); }
.jam-setnav__list a[aria-current="page"] { color: var(--rst-accent-strong); background: var(--rst-accent-soft); font-weight: 600; }
.jam-settings [rst-page-header] + .jam-section, .jam-section--first { margin-top: 0; }
@media (max-width: 720px) {
  .jam-setshell { grid-template-columns: 1fr; gap: 1rem; }
  .jam-setnav { position: static; display: flex; align-items: center; gap: 0.25rem; overflow-x: auto; scrollbar-width: none; padding-bottom: 0.6rem; border-bottom: 1px solid var(--rst-line); }
  .jam-setnav::-webkit-scrollbar { display: none; }
  .jam-setnav__head { display: none; }
  .jam-setnav__title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; margin: 0; }
  .jam-setnav__list { display: flex; gap: 0.25rem; flex: none; }
  .jam-setnav__list:not(:first-of-type) { border-left: 1px solid var(--rst-line); padding-left: 0.5rem; margin-left: 0.25rem; }
  .jam-setnav__list a { padding: 0.3rem 0.7rem; border-radius: 999px; white-space: nowrap; }
}
.jam-dir, .jam-person { width: 100%; min-width: 0; }
.jam-dir__bar { display: flex; gap: 0.75rem; align-items: center; margin: 1rem 0 0.75rem; flex-wrap: wrap; }
.jam-seg { display: inline-flex; border: 1px solid var(--rst-line); border-radius: 999px; padding: 0.15rem; background: var(--rst-surface); }
.jam-seg a { padding: 0.3rem 0.85rem; border-radius: 999px; font-size: var(--rst-fs-sm); font-weight: 500; color: var(--rst-text-muted); text-decoration: none; }
.jam-seg a:hover { color: var(--rst-text); }
.jam-seg a[aria-current="page"] { background: var(--rst-accent-soft); color: var(--rst-accent-strong); }
.jam-dir__search { flex: 1; min-width: 14rem; display: flex; align-items: center; gap: 0.5rem; padding: 0 0.8rem; border: 1px solid var(--rst-line); border-radius: 999px; background: var(--rst-surface); color: var(--rst-text-faint); }
.jam-dir__search:focus-within { border-color: var(--rst-accent); color: var(--rst-text-muted); }
.jam-dir__search input { flex: 1; border: 0; background: none; padding: 0.5rem 0; font: inherit; font-size: var(--rst-fs-sm); color: var(--rst-text); outline: none; min-width: 0; }
.jam-dir__list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--rst-line); border-radius: 12px; background: var(--rst-surface); overflow: hidden; }
.jam-dir__list li + li { border-top: 1px solid var(--rst-line); }
.jam-dir__row { display: flex; align-items: center; gap: 0.9rem; padding: 0.7rem 1rem; text-decoration: none; color: inherit; }
.jam-dir__row:hover { background: var(--rst-surface-2); }
.jam-dir__row:focus-visible { outline: 2px solid var(--rst-accent); outline-offset: -2px; }
.jam-dir__main { flex: 1; min-width: 0; display: grid; gap: 0.1rem; }
.jam-dir__main strong { font-weight: 600; }
.jam-dir__meta { color: var(--rst-text-muted); font-size: var(--rst-fs-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jam-dir__side { flex: none; display: inline-flex; align-items: center; gap: 0.6rem; }
.jam-dir__side time { font-size: var(--rst-fs-sm); color: var(--rst-text-faint); font-variant-numeric: tabular-nums; min-width: 3rem; text-align: right; }
/* One person: who they are, what the team can do, their conversations
   beside what the team knows about them. */
.jam-person__crumb { margin: 0 0 0.75rem; font-size: var(--rst-fs-sm); }
.jam-person__crumb a { display: inline-flex; align-items: center; gap: 0.3rem; color: var(--rst-text-muted); text-decoration: none; }
.jam-person__crumb a:hover { color: var(--rst-accent-strong); }
.jam-person__head { display: flex; gap: 1.1rem; align-items: center; margin: 0 0 0.9rem; }
.jam-av--xl { width: 4.25rem; height: 4.25rem; font-size: 1.3rem; }
.jam-person__name { font-family: var(--jam-serif); font-weight: 600; font-size: 1.9rem; line-height: 1.15; margin: 0 0 0.2rem; letter-spacing: -0.01em; text-wrap: balance; }
.jam-person__facts { margin: 0; font-size: var(--rst-fs-sm); display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }
.jam-person__facts a { color: var(--rst-text-muted); text-decoration: none; }
.jam-person__facts a:hover { color: var(--rst-accent-strong); }
.jam-person__actions [rst-btn~="primary"] { display: inline-flex; align-items: center; gap: 0.45rem; padding: 0.38rem 0.85rem 0.38rem 0.7rem; font-size: var(--rst-fs-sm); }
.jam-person__actions [rst-btn~="primary"] .jam-mi { color: inherit; }
.jam-person__cols { display: grid; grid-template-columns: minmax(0, 1fr) 19rem; gap: 2rem; margin-top: 1.5rem; }
.jam-person__h2 { font-family: var(--jam-serif); font-weight: 600; font-size: 1.15rem; margin: 0 0 0.6rem; }
.jam-person__panel { border: 1px solid var(--rst-line); border-radius: 12px; background: var(--rst-surface); padding: 0 1.5rem; }
.jam-person__panel .jam-rows { margin: 0; }
.jam-person__card { border: 1px solid var(--rst-line); border-radius: 12px; background: var(--rst-surface); padding: 0.9rem 1rem 0.5rem; }
.jam-person__card [rst-form] { max-inline-size: none; }
.jam-person__card input, .jam-person__card textarea { box-sizing: border-box; max-width: 100%; }
@media (max-width: 860px) { .jam-person__cols { grid-template-columns: 1fr; gap: 1.5rem; } }
@media (max-width: 720px) { .jam-person__head { gap: 0.8rem; } .jam-av--xl { width: 3.25rem; height: 3.25rem; font-size: 1rem; } .jam-person__name { font-size: 1.5rem; } .jam-person__panel { padding: 0 1rem; } }
.jam-contact__name a { text-decoration: none; color: inherit; }
.jam-contact__name a:hover { color: var(--rst-accent-strong); }
.jam-compose__row--files input { padding: 0.3rem 0; }
.jam-compose__row--files { border-bottom: 0; }
/* The row the editor sits under closes the address block; no hairline. */
.jam-compose__row:has(+ .jam-editor-wrap), .jam-compose__row:has(+ noscript + .jam-editor-wrap) { border-bottom: 0; }
.jam-rule-cond { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
.jam-caps { font-size: var(--rst-fs-xs); text-transform: uppercase; letter-spacing: 0.08em; color: var(--rst-text-faint); font-weight: 600; margin: 1rem 0 0.25rem; }
.jam-badge-auto { font-size: var(--rst-fs-sm); text-transform: uppercase; letter-spacing: 0.08em; background: var(--rst-tone-neutral-bg); color: var(--rst-tone-neutral-fg); padding: 0.05rem 0.4rem; border-radius: 4px; }

/* ── Folded messages and notes (Jelly's collapse) ───────────────────── */
.jam-msg { position: relative; }
.jam-msg__fold > summary, .jam-note__fold > summary { list-style: none; cursor: pointer; }
.jam-msg__fold > summary::-webkit-details-marker, .jam-note__fold > summary::-webkit-details-marker { display: none; }
.jam-msg__snip, .jam-note__snip { display: none; color: var(--rst-text-muted); font-weight: 400; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jam-msg__fold:not([open]) .jam-msg__to { display: none; }
.jam-msg__fold:not([open]) .jam-msg__snip { display: block; }
.jam-msg__fold:not([open]) .jam-msg__from > span:first-child { display: inline; }
.jam-note__fold:not([open]) .jam-note__snip { display: block; flex: 1; min-width: 0; margin-left: 0.4rem; }
.jam-msg:has(.jam-msg__fold:not([open])) { padding-top: 0.7rem; padding-bottom: 0.7rem; box-shadow: none; }
.jam-msg:has(.jam-msg__fold:not([open])) .jam-msg__head > .jam-av { width: 1.9rem; height: 1.9rem; font-size: 0.68rem; }
.jam-msg:has(.jam-msg__fold:not([open])) .jam-msg__head { align-items: center; margin-bottom: 0; }
.jam-msg__menu { position: absolute; top: 0.75rem; right: 0.75rem; }
.jam-msg:has(.jam-msg__fold:not([open])) .jam-msg__menu { top: 0.55rem; }
.jam-msg__head { padding-right: 2.4rem; }
/* "Show N more" sits on the spine: a small node of three dots at the
   line, the words beside it. */
.jam-hidden { display: flex; justify-content: flex-start; padding: 0.2rem 0 0.4rem; margin-left: -1.75rem; }
.jam-hidden a { display: inline-flex; align-items: center; gap: 0.6rem; font-size: var(--rst-fs-sm); color: var(--rst-text-muted); text-decoration: none; padding: 0.3rem 0.9rem 0.3rem 0; }
.jam-hidden a::before { content: ""; flex: none; width: 1.25rem; height: 1.25rem; margin-left: -0.625rem; border-radius: 50%; background: var(--rst-surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='4' r='1.3' fill='%23888'/%3E%3Ccircle cx='8' cy='8' r='1.3' fill='%23888'/%3E%3Ccircle cx='8' cy='12' r='1.3' fill='%23888'/%3E%3C/svg%3E") center / 14px no-repeat; border: 1px solid var(--rst-line-strong); box-shadow: 0 0 0 3px var(--rst-bg); }
.jam-hidden a:hover { color: var(--rst-text); }
.jam-hidden a:hover::before { border-color: var(--rst-accent); }

/* ── Remote images held back ───────────────────────────────────────── */
.jam-msg__images { margin: 0.25rem 0 0.75rem; font-size: var(--rst-fs-sm); }
.jam-msg__body img[data-jam-src] { display: none; }

/* ── Gmail ─────────────────────────────────────────────────────────── */
/* Google's button, per its branding: white, a hairline, the G. */
.jam-google-btn { display: inline-flex; align-items: center; gap: 0.75rem; margin-top: 0.75rem; padding: 0.55rem 1rem 0.55rem 0.8rem; border: 1px solid #dadce0; border-radius: 6px; background: #fff; color: #1f1f1f; font-weight: 500; text-decoration: none; font-size: var(--rst-fs-base); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08); }
.jam-google-btn:hover { background: #f8f9fa; box-shadow: 0 1px 3px rgba(60, 64, 67, 0.3); }
.jam-check-row { display: flex; align-items: center; gap: 0.5rem; padding: 0.35rem 0; }
.jam-settings-page .jam-crumb { display: block; }
.jam-list-head__title { font-family: var(--jam-serif); font-weight: 600; font-size: 1.75rem; margin: 0 0 0.25rem; }

/* ── Development sign-in ───────────────────────────────────────────── */
.jam-dev { max-width: 64rem; margin: 3rem auto 0; padding-top: 2rem; border-top: 1px dashed var(--rst-line-strong); }
.jam-dev__title { font-family: var(--jam-serif); font-size: 1.25rem; margin: 0 0 0.25rem; }
.jam-dev__fresh { display: grid; gap: 0.4rem; margin: 1rem 0 1.5rem; padding: 0.9rem 1rem; border: 1px solid var(--rst-line); border-radius: 8px; background: var(--rst-surface); font-size: var(--rst-fs-sm); }
.jam-dev__fresh input { font: inherit; padding: 0.4rem 0.6rem; border: 1px solid var(--rst-line-strong); border-radius: 6px; min-width: 16rem; background: var(--rst-surface); color: inherit; }
.jam-dev__teams { display: grid; grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); gap: 1.25rem; margin-top: 1rem; }
.jam-dev__team h3 { font-size: var(--rst-fs-sm); text-transform: uppercase; letter-spacing: 0.08em; color: var(--rst-text-faint); margin: 0 0 0.4rem; }
.jam-dev__file { text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--rst-text-faint); margin-left: 0.4rem; }
.jam-dev__people { list-style: none; padding: 0; margin: 0; }
.jam-dev__person { display: flex; align-items: center; gap: 0.5rem; width: 100%; text-align: left; background: none; border: none; padding: 0.3rem 0.4rem; border-radius: 8px; font: inherit; color: inherit; cursor: pointer; }
.jam-dev__person:hover { background: var(--rst-surface); }
.jam-dev__person .jam-muted { font-size: var(--rst-fs-xs); }
.jam-flash { position: relative; }
/* The toast: what just happened, and the way back out of it, on a
   raised sheet above the panes. It leaves on its own — a CSS
   animation, so it leaves with scripts off too, and shortcuts.js
   takes the node away when the animation ends so the z key stops
   undoing something nobody can see. It is the app's one other moment
   of motion; a reader who asked for less gets the sheet without the
   travel, and still gets it going away. */
.jam-toast { position: fixed; z-index: 60; left: 1rem; right: 1rem; bottom: 1.5rem; margin-inline: auto; width: fit-content; display: flex; align-items: center; gap: 0.9rem; max-width: min(34rem, 100%); padding: 0.6rem 0.7rem 0.6rem 1rem; background: var(--rst-surface); border: 1px solid var(--rst-line); border-radius: 12px; box-shadow: 0 8px 24px hsl(240 5% 12% / 0.16), 0 2px 6px hsl(240 5% 12% / 0.08); animation: jam-toast-in 200ms cubic-bezier(0.2, 0.8, 0.2, 1) both, jam-toast-out 240ms ease-in 9s forwards; }
.jam-toast__text { margin: 0; font-size: var(--rst-fs-sm); color: var(--rst-text); }
.jam-toast__undo { margin: 0; flex: none; }
.jam-toast__undo button { display: inline-flex; align-items: center; padding: 0.3rem 0.7rem; border: 0; border-radius: 8px; background: var(--rst-accent-soft); color: var(--rst-accent-strong); font: inherit; font-size: var(--rst-fs-sm); font-weight: 600; cursor: pointer; }
.jam-toast__undo button:hover { background: var(--rst-accent); color: var(--rst-on-accent); }
.jam-toast__undo .jam-key { border-color: currentColor; opacity: 0.65; }
@keyframes jam-toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes jam-toast-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(4px); visibility: hidden; } }
@keyframes jam-toast-gone { to { opacity: 0; visibility: hidden; } }
@media (prefers-reduced-motion: reduce) {
  .jam-toast { animation: jam-toast-gone 1ms linear 9s forwards; }
}
.jam-chip--box { background: var(--rst-surface-2); border: 1px solid var(--rst-line); color: var(--rst-text-muted); }
.jam-pop__label { font-size: var(--rst-fs-sm); min-width: 6rem; }

/* ── Select mode / bulk actions ────────────────────────────────────── */
.jam-list-head { display: flex; align-items: baseline; justify-content: space-between; }
/* Selecting is not a mode: the bar is in the page from the start and
   shows itself the moment something is checked, taking the heading's
   place. CSS does it, so it happens with scripts off too. */
.jam-bulk { display: contents; }
.jam-bulkbar { display: none; }
.jam-main:has(.jam-selbox input:checked) .jam-bulkbar { display: flex; }
.jam-main:has(.jam-selbox input:checked) .jam-list-head { display: none; }
.jam-bulkbar { flex-wrap: nowrap; align-items: center; gap: 0.4rem 0.6rem; box-sizing: border-box; min-height: var(--jam-head-line); padding: 0.3rem 0.75rem; margin: 0 0 var(--jam-head-gap); background: var(--rst-accent-soft); border-radius: 12px; }
.jam-bulkbar__close { display: inline-grid; place-items: center; width: 1.8rem; height: 1.8rem; border-radius: 50%; color: var(--rst-accent-strong); }
.jam-bulkbar__close:hover { background: var(--rst-surface); }
.jam-bulkbar__count { font-size: var(--rst-fs-base); }
.jam-bulkbar__scope { font-size: var(--rst-fs-sm); color: var(--rst-accent-strong); text-decoration: underline; text-underline-offset: 2px; }
.jam-bulkbar__grow { flex: 1; }
.jam-bulkbar > * { flex: none; }
/* The bar never clips: Label and ⋯ hang their menus below it, and an
   overflow of anything but visible on either axis clips both. The bar
   has no scroll to lose — it sheds verbs until it fits, which
   TestBrowserSelectingDoesNotMoveTheList holds it to at every width. */
/* A narrower window sheds the second-rank verbs rather than wrapping:
   Read, Unread and the scope link are all in the ⋯ menu as well, and
   the bar has to stay exactly as tall as the heading it replaces. */
@media (max-width: 1000px) { .jam-bulkbar__spare, .jam-bulkbar__scope { display: none; } }
.jam-bulkbar [rst-btn] { font-size: var(--rst-fs-sm); padding: 0.3rem 0.8rem; background: var(--rst-surface); }
.jam-pop__body--col .jam-danger { color: var(--rst-danger, #c62828); }
.jam-bulkpop__head { margin: 0.1rem 0 0.25rem; padding: 0.3rem 0.65rem 0; font-size: var(--rst-fs-xs); font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--rst-text-muted); }
.jam-bulkpop .jam-mrow__name { font-weight: 450; }
.jam-key { font: inherit; font-size: var(--rst-fs-xs); line-height: 1.5; color: var(--rst-text-faint); border: 1px solid var(--rst-line); border-radius: 4px; padding: 0 0.32rem; margin-left: 0.35rem; }
.jam-act-btn .jam-key, .jam-bulkbar .jam-key { border-color: var(--rst-line-strong); }
html:not(.js) .jam-key { display: none; }
/* No pointer, most likely no keyboard: the hint would be furniture. */
@media (hover: none) { .jam-key { display: none; } }
/* The mark column. Every triage row reserves it, so nothing shifts
   sideways when a checkbox appears: it holds the unread dot at rest,
   and the checkbox under the pointer, under the keyboard cursor, on
   focus, when the row is selected, or once anything in the list is.
   Absolute, inside the padding the link already reserves — the row
   stays one column, and no other list that uses .jam-row is touched. */
.jam-row { position: relative; }
.jam-rows--pick > .jam-row > .jam-row__link { padding-left: calc(var(--jam-row-bleed) + 1.9rem); }
/* On the subject — the line the eye reads the row by — and measured
   from the bottom, never the top. The first line is as tall as
   whatever sits in it (an assignee's avatar, a mailbox chip, or
   nothing), so an offset from the top lands somewhere different on
   every row; below the subject there is only the snippet, one line of
   one size, so the sum is exact: the padding, the snippet, the gap
   and half a subject line, less half this box. */
.jam-selbox { position: absolute; left: 0; bottom: calc(var(--jam-row-pad-y) + var(--rst-fs-sm) * var(--jam-row-lh) + var(--jam-row-gap) + var(--rst-fs-base) * var(--jam-row-lh) / 2 - 0.75rem); z-index: 1; display: grid; place-items: center; width: 1.5rem; height: 1.5rem; }
.jam-selbox input { grid-area: 1 / 1; accent-color: var(--rst-accent); width: 1.05rem; height: 1.05rem; margin: 0; cursor: pointer; opacity: 0; }
.jam-selbox__dot { grid-area: 1 / 1; width: 0.45rem; height: 0.45rem; border-radius: 50%; background: var(--rst-accent); opacity: 0; }
.jam-row--unread .jam-selbox__dot { opacity: 1; }
.jam-row:hover .jam-selbox input,
.jam-row--cursor .jam-selbox input,
.jam-selbox input:focus,
.jam-selbox input:checked,
.jam-main:has(.jam-selbox input:checked) .jam-selbox input { opacity: 1; }
.jam-row:hover .jam-selbox__dot,
.jam-row--cursor .jam-selbox__dot,
.jam-selbox:focus-within .jam-selbox__dot,
.jam-main:has(.jam-selbox input:checked) .jam-selbox__dot { opacity: 0; }
/* No pointer to hover with: the box is simply there. */
@media (hover: none) { .jam-selbox input { opacity: 1; } .jam-row .jam-selbox__dot { opacity: 0; } }
.jam-row--selected .jam-row__link { background: var(--rst-accent-soft); }
/* The ··· on a row: Jelly's menu. Sits beside the link (an interactive
   element cannot live inside one), shows on hover, focus or when open. */
/* The button sits in the link's bleed (the gutter the row's hover
   background runs into), 0.75rem in from the pane's edge, on the
   row's first line; the link keeps 3rem clear so the time never
   runs under it. The summary itself is a plain block — WebKit puts a
   summary's text in its marker box when the summary is a grid — and
   the circle is a span inside it. */
.jam-row { --jam-row-bleed: 1.5rem; }
.jam-row__menu { position: absolute; top: 0.42rem; right: calc(0.75rem - var(--jam-row-bleed)); z-index: 2; }
.jam-row__menu[open] { z-index: 20; }
/* The menu's panel is fetched by script when it opens (partial_row_menu.html);
   with scripts off there is nothing to open, so the button is not there. */
html:not(.js) .jam-row__menu { display: none; }
.jam-row__menu .jam-pop__body { right: 1rem; }
.jam-row:has(.jam-row__menu[open]) { z-index: 20; }
.jam-row__more { list-style: none; display: block; cursor: pointer; border-radius: 50%; }
.jam-row__more::-webkit-details-marker { display: none; }
.jam-more-btn { display: grid; place-items: center; width: 1.75rem; height: 1.75rem; border-radius: 50%; border: 1px solid var(--rst-line); background: var(--rst-surface); color: var(--rst-text-faint); box-shadow: 0 1px 2px hsl(240 5% 12% / 0.06); transition: color 120ms, background-color 120ms, border-color 120ms; }
.jam-row__more:hover .jam-more-btn { color: var(--rst-text); background: var(--rst-surface-2); border-color: var(--rst-line-strong); }
.jam-row__menu[open] .jam-more-btn { color: var(--rst-accent-strong); background: var(--rst-accent-soft); border-color: transparent; }
.jam-row__more:focus-visible { outline: none; }
.jam-row__more:focus-visible .jam-more-btn { outline: 2px solid var(--rst-accent); outline-offset: 2px; }
.jam-rows > .jam-row > .jam-row__link { padding-right: 3rem; }
.jam-menu-list { flex-direction: column; align-items: stretch; gap: 0; min-width: 16rem; padding: 0.35rem; white-space: nowrap; }
.jam-menu-list form { display: block; }
.jam-menu-list button, .jam-menu-list a, .jam-menu-list .jam-sub > summary { display: flex; align-items: center; gap: 0.65rem; width: 100%; padding: 0.42rem 0.6rem; border: 0; border-radius: 7px; background: none; font: inherit; font-size: var(--rst-fs-base); color: var(--rst-text); text-align: left; text-decoration: none; cursor: pointer; }
.jam-menu-list button:hover, .jam-menu-list a:hover, .jam-menu-list .jam-sub > summary:hover { background: var(--rst-surface-2); }
.jam-menu-list hr { border: 0; border-top: 1px solid var(--rst-line); margin: 0.35rem 0; }
/* A long menu filters and scrolls inside itself rather than growing past
   the viewport: the list gets a filter box (only past ten items, from the
   template), a scrolling middle whose height shortcuts.js clamps to the
   space below the button, and a fixed footer for the manage link. */
.jam-menu-list__filter { display: block; box-sizing: border-box; width: 100%; margin: 0.15rem 0 0.35rem; padding: 0.4rem 0.6rem; font: inherit; font-size: var(--rst-fs-sm); border: 1px solid var(--rst-line); border-radius: 7px; background: var(--rst-surface); color: inherit; }
.jam-menu-list__filter:focus { outline: 2px solid var(--rst-accent); outline-offset: 1px; border-color: transparent; }
.jam-menu-list__scroll { overflow-y: auto; max-height: var(--jam-menu-max, 60vh); overscroll-behavior: contain; scrollbar-width: thin; }
.jam-menu-list__scroll form[hidden] { display: none; }
.jam-menu-list__none { display: none; margin: 0; padding: 0.4rem 0.6rem; color: var(--rst-text-muted); font-size: var(--rst-fs-sm); }
.jam-menu-list__scroll:has(> :is(form, .jam-mrow):not([hidden])) + .jam-menu-list__none { display: none; }
.jam-menu-list__scroll:not(:has(> :is(form, .jam-mrow):not([hidden]))) + .jam-menu-list__none { display: block; }
.jam-menu-list__manage { color: var(--rst-text-muted); font-size: var(--rst-fs-sm); }
.jam-menu-list__manage .jam-mi { color: var(--rst-text-muted); }
.jam-menu-list .jam-mi { flex: none; color: var(--rst-text-muted); }
.jam-menu-list .jam-menu-list__danger { color: var(--rst-danger, #c62828); }
.jam-sub > summary { list-style: none; }
.jam-sub > summary::-webkit-details-marker { display: none; }
.jam-sub__chev { margin-left: auto; color: var(--rst-text-faint); font-size: 1.1em; }
.jam-sub[open] > summary { background: var(--rst-surface-2); }
.jam-sub__body { padding: 0.2rem 0 0.3rem 1.6rem; max-height: 14rem; overflow: auto; }
.jam-sub__body button { padding: 0.32rem 0.6rem; font-size: var(--rst-fs-sm); }
.jam-row--selected .jam-av { background: var(--rst-surface); box-shadow: inset 0 0 0 1px var(--rst-accent); }

/* ── Message menu, rename, split, forward ──────────────────────────── */
.jam-msg__side { display: flex; align-items: center; gap: 0.35rem; }
.jam-msg__more { list-style: none; display: block; cursor: pointer; border-radius: 50%; }
.jam-msg__more::-webkit-details-marker { display: none; }
.jam-msg__more:hover .jam-more-btn { color: var(--rst-text); background: var(--rst-surface-2); border-color: var(--rst-line-strong); }
.jam-msg__menu[open] .jam-more-btn { color: var(--rst-accent-strong); background: var(--rst-accent-soft); border-color: transparent; }
.jam-msg__more:focus-visible { outline: none; }
.jam-msg__more:focus-visible .jam-more-btn { outline: 2px solid var(--rst-accent); outline-offset: 2px; }
.jam-msg__menu [rst-btn] { text-decoration: none; text-align: left; }
.jam-thread__split { margin: -0.4rem 0 0.6rem; font-size: var(--rst-fs-sm); color: var(--rst-text-muted); }
.jam-elsewhere { margin: 0 0 0.75rem; padding: 0.45rem 0.8rem; border-radius: 6px; background: var(--rst-tone-warning-bg); color: var(--rst-tone-warning-fg); font-size: var(--rst-fs-sm); }
.jam-elsewhere a { color: inherit; font-weight: 600; }
.jam-rename { display: grid; gap: 0.35rem; padding: 0.25rem 0.5rem 0.6rem; border-bottom: 1px solid var(--rst-line); margin-bottom: 0.35rem; min-width: 18rem; }
.jam-rename input { font: inherit; padding: 0.35rem 0.5rem; border: 1px solid var(--rst-line-strong); border-radius: 6px; background: var(--rst-sheet); color: inherit; }
.jam-forwarded { border-left: 2px solid var(--rst-line-strong); padding-left: 0.9rem; margin-top: 0.75rem; color: var(--rst-text); }

/* ── Send later ────────────────────────────────────────────────────── */
.jam-later summary { list-style: none; }
.jam-later summary::-webkit-details-marker { display: none; }
.jam-later__body { display: grid; gap: 0.5rem; padding: 0.75rem; min-width: 16rem; font-size: var(--rst-fs-sm); }
.jam-later__body input { font: inherit; padding: 0.35rem 0.5rem; border: 1px solid var(--rst-line-strong); border-radius: 6px; background: var(--rst-sheet); color: inherit; }
/* A quiet fact, not an alarm: when this sends, and who set it. */
.jam-scheduled { flex: 1; margin: 0; padding: 0.55rem 0.85rem; border: 1px solid var(--rst-line); background: var(--rst-surface-2); border-radius: 10px; color: var(--rst-text); font-size: var(--rst-fs-sm); display: flex; flex-wrap: wrap; gap: 0.35rem 0.6rem; align-items: center; }
.jam-scheduled time { font-weight: 600; }
.jam-scheduled [rst-btn] { margin-left: auto; font-size: var(--rst-fs-sm); }
.jam-msg__via { font-size: var(--rst-fs-xs); color: var(--rst-text-faint); margin-left: 0.4rem; }

/* ── Team activity ─────────────────────────────────────────────────── */
/* ── Team activity ─────────────────────────────────────────────────── */
/* A feed read by day: what to show as a segment, who and which label
   as small pickers; then each day's entries — a face wearing a badge
   for the verb, the sentence with the conversation as a quiet link,
   an excerpt, the time. */
.jam-activity { width: 100%; padding-bottom: 3rem; }
.jam-activity__filters { display: flex; flex-wrap: wrap; gap: 0.6rem 1rem; align-items: center; margin: 1rem 0 1.25rem; }
/* The segment never wraps its tabs; on a narrow screen it scrolls sideways
   instead, and the two picks move to the next line as one unit. */
.jam-activity__filters .jam-seg { flex: 0 1 auto; min-width: 0; max-width: 100%; overflow-x: auto; scrollbar-width: none; white-space: nowrap; }
.jam-activity__filters .jam-seg::-webkit-scrollbar { display: none; }
.jam-activity__filters .jam-seg a { flex: none; }
.jam-activity__picks { display: flex; flex-wrap: wrap; gap: 0.6rem 1rem; align-items: center; }
@media (max-width: 720px) {
  .jam-activity__filters .jam-seg { flex-basis: 100%; }
  .jam-activity__picks { flex-basis: 100%; }
  .jam-activity__pick { flex: 1 1 10rem; }
  .jam-activity__pick select { flex: 1; min-width: 0; }
}
.jam-activity__pick { display: inline-flex; align-items: center; gap: 0.4rem; font-size: var(--rst-fs-sm); color: var(--rst-text-muted); }
.jam-activity__pick select { font: inherit; font-size: var(--rst-fs-sm); color: var(--rst-text); border: 1px solid var(--rst-line); border-radius: 999px; padding: 0.3rem 1.6rem 0.3rem 0.7rem; background: var(--rst-surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10'%3E%3Cpath d='M2 3.5l3 3 3-3' fill='none' stroke='%23999' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 0.6rem center; appearance: none; -webkit-appearance: none; cursor: pointer; }
.jam-activity__pick select:hover { border-color: var(--rst-line-strong); }
.jam-activity__apply { border-color: var(--rst-line); }
.jam-activity__apply[hidden] { display: none; }
.jam-activity__filters .jam-seg a { padding: 0.28rem 0.7rem; }
.jam-activity__pick select { padding: 0.28rem 1.5rem 0.28rem 0.6rem; }
.jam-feed__day { margin: 0 0 1.25rem; }
.jam-feed__date { font-family: var(--jam-serif); font-weight: 600; font-size: 1.05rem; margin: 0 0 0.25rem; padding: 0.4rem 0; position: sticky; top: 0; background: var(--rst-bg); z-index: 1; display: flex; align-items: center; gap: 0.75rem; }
.jam-feed__date::after { content: ""; flex: 1; height: 1px; background: var(--rst-line); }
.jam-feed { list-style: none; padding: 0; margin: 0; }
/* No rule between rows: the avatars, verbs and day headers carry the
   rhythm, and the sheets set replies and notes apart on their own. */
.jam-feed__item { display: grid; grid-template-columns: 2.2rem minmax(0, 1fr) auto; gap: 0.85rem; align-items: start; padding: 0.8rem 0.25rem; }
.jam-feed__who { position: relative; display: block; width: 1.9rem; height: 1.9rem; margin-top: 0.05rem; }
.jam-feed__badge { position: absolute; right: -0.35rem; bottom: -0.35rem; width: 1.05rem; height: 1.05rem; border-radius: 50%; background: var(--rst-surface); border: 1px solid var(--rst-line); display: grid; place-items: center; color: var(--rst-text-muted); }
.jam-feed__badge .jam-mi { width: 11px; height: 11px; }
.jam-feed__item[data-verb="commented"] .jam-feed__badge { color: var(--jam-note-ink); background: var(--jam-note); border-color: var(--jam-note-line); }
.jam-feed__item[data-verb="received"] .jam-feed__badge, .jam-feed__item[data-verb="sent"] .jam-feed__badge { color: var(--rst-accent-strong); background: var(--rst-accent-soft); border-color: transparent; }
.jam-feed__body { display: grid; gap: 0.15rem; min-width: 0; }
.jam-feed__line { line-height: 1.4; }
/* Every conversation link in a feed line dresses the same, wherever
   the sentence was built. */
.jam-feed__subject, .jam-feed__line a { color: var(--rst-text); font-weight: 500; text-decoration: none; border-bottom: 1px solid var(--rst-line-strong); }
.jam-feed__subject:hover, .jam-feed__line a:hover { color: var(--rst-accent-strong); border-bottom-color: var(--rst-accent-strong); }
/* What was said is the point: a reply or a message sits on a small
   sheet, a note on a note-coloured one, two lines at most. */
.jam-feed__excerpt { display: block; margin-top: 0.35rem; padding: 0.55rem 0.85rem; border: 1px solid var(--rst-line); border-radius: 9px; background: var(--rst-surface); color: var(--rst-text); font-size: var(--rst-fs-base); line-height: 1.45; box-shadow: 0 1px 2px hsl(240 5% 12% / 0.05); }
.jam-feed__excerpt-text { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.jam-feed__item[data-verb="commented"] .jam-feed__excerpt { background: var(--jam-note); border-color: var(--jam-note-line); color: var(--jam-note-ink); }
.jam-feed__when { font-size: var(--rst-fs-sm); color: var(--rst-text-faint); font-variant-numeric: tabular-nums; padding-top: 0.15rem; }
@media (max-width: 720px) {
  .jam-activity__filters .jam-seg { max-width: 100%; overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none; }
  .jam-activity__filters .jam-seg::-webkit-scrollbar { display: none; }
  .jam-activity__filters .jam-seg a { white-space: nowrap; }
  .jam-feed__item { grid-template-columns: 2.2rem minmax(0, 1fr); }
  .jam-feed__when { grid-column: 2; padding-top: 0; }
}

/* ── Panes ─────────────────────────────────────────────────────────────
   Two panes by default: the views, and the list. Opening a
   conversation adds a third that slides in from the right and covers
   the list, which slides over the views; each leaves 100px showing.
   A covered pane peeks out under the pointer and stays usable: its
   links click and it scrolls. The move is a cross-document view
   transition, so it needs no script; with none, the panes simply are
   where they should be. */
body { min-height: 100vh; display: flex; flex-direction: column; margin: 0; }
.jam-top { view-transition-name: top-bar; flex: none; position: relative; z-index: 40; }
.jam-brand--toggle, .jam-menu-backdrop { display: none; }
/* A short screen — a phone on its side — has no height to spare for
   a header. It folds into its logo, a small pill at the top left;
   tapping it opens the whole header as a menu over the page, and the
   panes have the height to themselves. */
@media (max-height: 560px) and (max-width: 1100px) {
  .jam-brand--toggle { display: inline-flex; position: fixed; top: 0.45rem; left: 0.6rem; z-index: 52; align-items: center; padding: 0.25rem 0.7rem 0.25rem 0.55rem; border: 1px solid var(--rst-line); border-radius: 999px; background: var(--rst-surface); box-shadow: 0 1px 2px hsl(240 5% 12% / 0.08); cursor: pointer; font-size: 1rem; }
  .jam-menu-backdrop { display: block; position: fixed; inset: 0; z-index: 48; background: rgba(20, 20, 24, 0.25); opacity: 0; pointer-events: none; transition: opacity 160ms; }
  body:has(#jam-menu:checked) .jam-menu-backdrop { opacity: 1; pointer-events: auto; }
  .jam-top { position: fixed; top: 0.45rem; left: 0.6rem; z-index: 50; width: min(22rem, calc(100vw - 1.2rem)); padding: 0; border: 0; background: none; flex-direction: column; align-items: stretch; gap: 0; max-height: calc(100vh - 1rem); overflow: auto; pointer-events: none; }
  .jam-top > * { display: none; }
  body:has(#jam-menu:checked) .jam-top { pointer-events: auto; padding: 3rem 0.75rem 0.75rem; border: 1px solid var(--rst-line); border-radius: 14px; background: var(--rst-surface); box-shadow: var(--rst-shadow-pop); gap: 0.5rem; }
  body:has(#jam-menu:checked) .jam-top > * { display: flex; }
  body:has(#jam-menu:checked) .jam-top > .jam-brand, body:has(#jam-menu:checked) .jam-top > .jam-views-btn { display: none; }
  body:has(#jam-menu:checked) .jam-top .jam-nav { flex-direction: column; align-items: stretch; gap: 0; }
  body:has(#jam-menu:checked) .jam-top .jam-nav a { padding: 0.5rem 0.6rem; border-radius: 8px; }
  body:has(#jam-menu:checked) .jam-top .jam-search { order: 0; margin: 0; max-width: none; flex-basis: auto; }
  body:has(#jam-menu:checked) .jam-top .jam-top__compose { order: 0; justify-content: center; }
  body:has(#jam-menu:checked) .jam-top .jam-menu { order: 0; }
  body:has(#jam-menu:checked) .jam-top .jam-menu__panel { position: static; box-shadow: none; border: 0; padding: 0.25rem 0 0; min-width: 0; }
  body:has(#jam-menu:checked) .jam-brand--toggle { background: var(--rst-accent-soft); border-color: transparent; color: var(--rst-accent-strong); }
  .jam-panes .jam-pane.jam-pane--nav, .jam-panes.jam-panes--open .jam-pane.jam-pane--list { padding-top: 3.4rem; }
  body:has(#jam-menu:checked) .jam-top .jam-nav { order: -1; }
  body:has(#jam-menu:checked) .jam-top .jam-menu { align-self: flex-start; }
}
.jam-panes { position: relative; flex: 1; min-height: 0; overflow: hidden; }
/* The panes are the page; nothing may scroll the document sideways. */
body:has(> .jam-panes) { overflow: hidden; }
.jam-pane { position: absolute; top: 0; bottom: 0; overflow-y: auto; overflow-x: hidden; box-sizing: border-box; background: var(--rst-bg); }
.jam-pane--nav { left: 0; width: 15rem; padding: 1.25rem 0.75rem 3rem; border-right: 1px solid var(--rst-line); view-transition-name: pane-nav; }
.jam-pane--list { left: 15rem; right: 0; padding: 1.25rem 1.5rem 3rem; view-transition-name: pane-list; transition: transform var(--jam-slide-ms, 320ms) var(--jam-slide-ease, cubic-bezier(0.2, 0.8, 0.2, 1)); }
/* The list slides to x=100px when a conversation opens; the conversation
   pane starts --jam-list-strip further right, which is exactly how much
   of the list stays visible (the dev menu tunes it). */
.jam-pane--conv { left: calc(100px + var(--jam-list-strip, 100px)); right: 64px; padding: 0; background: var(--rst-bg); view-transition-name: pane-conv; transition: transform var(--jam-slide-ms, 240ms) var(--jam-slide-ease, cubic-bezier(0.2, 0.8, 0.2, 1)); }
/* A covered pane peeks out under the pointer: the panes above it shift
   right a little, so more of it can be read before you commit. */
.jam-panes--open:has(.jam-pane--nav:hover) .jam-pane--list { transform: translateX(min(0px, calc(100px - 15rem + var(--jam-peek, 8rem)))); transition-delay: var(--jam-peek-delay, 150ms); }
.jam-panes--open:has(.jam-pane--nav:hover) .jam-pane--conv { transform: translateX(var(--jam-peek, 8rem)); transition-delay: var(--jam-peek-delay, 150ms); }
.jam-panes--open:has(.jam-pane--list:hover) .jam-pane--conv { transform: translateX(calc(var(--jam-peek, 8rem) + 2rem)); transition-delay: var(--jam-peek-delay, 150ms); }
/* The same peek when the keyboard's focus lands on a covered pane. */
.jam-panes--open.jam-panes--peek-nav .jam-pane--list { transform: translateX(min(0px, calc(100px - 15rem + var(--jam-peek, 8rem)))); }
.jam-panes--open.jam-panes--peek-nav .jam-pane--conv { transform: translateX(var(--jam-peek, 8rem)); }
.jam-panes--open.jam-panes--peek-list .jam-pane--conv { transform: translateX(calc(var(--jam-peek, 8rem) + 2rem)); }
.jam-link--cursor { outline: 2px solid var(--rst-accent); outline-offset: -2px; border-radius: 6px; }
.jam-panes--still .jam-pane { transition: none; }
/* The contact: a fourth pane at the far right, folded to a 64px tab
   the full height of the window — avatar, the name running down the
   tab, and a "»»" cue — opening under the pointer or on a click
   (focus); clicking back into the conversation folds it away. */
.jam-pane--contact { right: 0; width: calc(18rem + 64px); padding: 0; display: grid; grid-template-columns: 64px minmax(0, 1fr); background: var(--rst-surface); border-left: 1px solid var(--rst-line); box-shadow: -10px 0 28px -14px rgba(40, 30, 20, 0.35); transform: translateX(18rem); transition: transform var(--jam-slide-ms, 240ms) var(--jam-slide-ease, cubic-bezier(0.2, 0.8, 0.2, 1)); view-transition-name: pane-contact; outline: none; overflow: hidden; }
/* Hovering the tab nudges the pane out by --jam-contact-nudge (the dev
   menu tunes it) as an invitation; a click, or keyboard focus, opens it. */
.jam-pane--contact:hover { transform: translateX(calc(18rem - var(--jam-contact-nudge, 40px))); }
.jam-pane--contact:focus-within, .jam-pane--contact:focus, .jam-pane--contact.jam-contact--pinned { transform: none; cursor: default; }
.jam-contact__hint { margin-top: auto; writing-mode: vertical-rl; font-size: var(--rst-fs-xs); color: var(--rst-text-faint); letter-spacing: 0.04em; white-space: nowrap; }
.jam-contact__hint-unpin, .jam-contact--pinned .jam-contact__hint-pin { display: none; }
.jam-contact--pinned .jam-contact__hint-unpin { display: inline; }
.jam-contact__tab { display: flex; flex-direction: column; align-items: center; gap: 0.9rem; padding: 1.1rem 0 1.25rem; border-right: 1px solid var(--rst-line); color: var(--rst-text-muted); cursor: pointer; }
.jam-contact__tab .jam-av--lg { width: 2.75rem; height: 2.75rem; font-size: 0.9rem; }
.jam-contact__vname { writing-mode: vertical-rl; font-family: var(--jam-serif); font-weight: 600; font-size: 1.05rem; color: var(--rst-text); white-space: nowrap; max-height: 40vh; overflow: hidden; text-overflow: ellipsis; letter-spacing: 0.01em; }
.jam-contact__more { color: var(--rst-text-faint); margin-top: 0.25rem; }
.jam-contact__body { position: relative; padding: 1.25rem 1.25rem 3rem 1rem; overflow-y: auto; opacity: 0; transition: opacity 180ms ease 80ms; }
/* A quiet way out at the top right of each open pane. */
/* The conversation's close rides the top of the pane, above the scroll. */
.jam-pane__close--conv { position: sticky; top: 0; display: flex; justify-content: flex-end; height: 0; overflow: visible; padding: 1rem 1.25rem 0 0; box-sizing: border-box; }
.jam-pane__close { position: absolute; top: 1rem; right: 1.25rem; border: 0; padding: 0; background: none; font: inherit; font-size: var(--rst-fs-xs); font-weight: 500; letter-spacing: 0.02em; color: var(--rst-text-faint); text-decoration: none; cursor: pointer; z-index: 5; }
.jam-pane__close:hover { color: var(--rst-text); }
.jam-contact__close { top: 1.1rem; right: 1.1rem; }
.jam-contact__body > .jam-av--lg { display: none; }
.jam-contact__vname, .jam-contact__more { transition: opacity 140ms ease; }
/* Opening: the name running down the tab fades out as the card, with
   the name set straight, fades in. */
.jam-pane--contact:focus-within .jam-contact__body, .jam-pane--contact:focus .jam-contact__body, .jam-contact--pinned .jam-contact__body { opacity: 1; }
/* The vertical name stays through the hover nudge and only fades once
   the pane is actually open — and only after the slide has landed. */
.jam-pane--contact:focus-within .jam-contact__vname, .jam-pane--contact:focus .jam-contact__vname,
.jam-pane--contact:focus-within .jam-contact__more, .jam-pane--contact:focus .jam-contact__more, .jam-contact--pinned .jam-contact__vname, .jam-contact--pinned .jam-contact__more { opacity: 0; transition-delay: var(--jam-slide-ms, 240ms); }
.jam-contact__name { margin-top: 0.1rem; }
@media (prefers-reduced-motion: reduce) { .jam-contact__body, .jam-contact__vname, .jam-contact__more { transition: none; } }
.jam-pane--conv .jam-conv { max-width: none; grid-template-columns: minmax(0, 1fr); }
.jam-panes--open .jam-pane--list { transform: translateX(calc(100px - 15rem)); }
.jam-panes--open .jam-pane--list, .jam-pane--conv { box-shadow: -10px 0 28px -14px rgba(40, 30, 20, 0.35); border-left: 1px solid var(--rst-line); }
.jam-pane--conv .jam-conv { max-width: none; }
.jam-row--open .jam-row__link { background: var(--rst-accent-soft); }
/* On a conversation page the list pane is the way back: a link the
   size of the pane sits under the rows, so a click on anything that
   is not a conversation returns to the list. */
.jam-pane__back { position: absolute; inset: 0; z-index: 0; }
.jam-panes--open .jam-pane--list > .jam-main { position: relative; z-index: 1; pointer-events: none; }
.jam-panes--open .jam-pane--list > .jam-main a, .jam-panes--open .jam-pane--list > .jam-main button, .jam-panes--open .jam-pane--list > .jam-main input, .jam-panes--open .jam-pane--list > .jam-main select, .jam-panes--open .jam-pane--list > .jam-main label { pointer-events: auto; }
.jam-crumb { display: none; }
.jam-side { position: static; }
@view-transition { navigation: auto; }
/* An open menu is captured apart from the bar it hangs off: its ink
   overflows the bar's box, and a navigation would stretch the joint
   snapshot into the bar's frame — the ghost-shape flash. Named on its
   own, it simply fades. (Two menus open at once abort the transition,
   which degrades to no animation, not a wrong one.) */
details[open] > .jam-menu__panel, details[open] > .jam-pop__body, details[open] > .rst-row-menu__panel, details[open] > [rst-row-menu-panel] { view-transition-name: open-menu; }
::view-transition-group(pane-list), ::view-transition-group(pane-conv), ::view-transition-group(pane-contact) { animation-duration: var(--jam-slide-ms, 320ms); animation-timing-function: var(--jam-slide-ease, cubic-bezier(0.2, 0.8, 0.2, 1)); }
/* The views and the list only move; they never crossfade. */
::view-transition-old(pane-nav), ::view-transition-old(pane-list) { display: none; }
::view-transition-new(pane-nav), ::view-transition-new(pane-list) { animation: none; }
::view-transition-new(pane-conv):only-child, ::view-transition-new(pane-contact):only-child { animation: var(--jam-slide-ms, 320ms) var(--jam-slide-ease, cubic-bezier(0.2, 0.8, 0.2, 1)) both var(--jam-enter, jam-pane-in); }
::view-transition-old(pane-conv):only-child, ::view-transition-old(pane-contact):only-child { animation: calc(var(--jam-slide-ms, 320ms) * 0.8) cubic-bezier(0.4, 0, 1, 1) both var(--jam-leave, jam-pane-out); }
@keyframes jam-pane-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes jam-pane-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes jam-pane-slide-fade-in { from { transform: translateX(40%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes jam-pane-slide-fade-out { from { transform: none; opacity: 1; } to { transform: translateX(40%); opacity: 0; } }
@keyframes jam-pane-none { from { opacity: 1; } to { opacity: 1; } }
@keyframes jam-pane-in { from { transform: translateX(100%); } }
@keyframes jam-pane-out { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; } .jam-pane--list, .jam-pane--conv, .jam-pane--contact { transition: none; } }
.jam-views-btn { display: none; }
.jam-side__list--pages { display: none; }
@media (max-width: 900px) {
  .jam-side { display: block; margin: 0; padding: 0; overflow: visible; }
  .jam-side__list { display: block; }
  .jam-side__title { display: block; }
  .jam-pane--nav { width: 12rem; }
  .jam-pane--list { left: 12rem; padding: 1rem 1rem 3rem; }
  .jam-row { --jam-row-bleed: 1rem; }
  .jam-row__link { padding: var(--jam-row-pad-y) 1rem; margin: 0 -1rem; }
  .jam-section-title { margin: 0 -1rem 0.25rem; padding: 0.45rem 1rem; }
  .jam-panes--open .jam-pane--list { transform: translateX(calc(100px - 12rem)); }
}
/* ── The phone: the same stack, one pane wide ─────────────────────────
   The list fills the screen and the views are a drawer off its left
   edge (the header's button flips a checkbox; no script). Opening a
   conversation covers the list, leaving a 28px sliver that is purely
   the way back — there is no pointer to peek with. The contact folds to
   a 44px tab that opens over the conversation. */
@media (max-width: 720px) {
  .jam-views-btn { display: inline-flex; align-items: center; justify-content: center; width: 2.25rem; height: 2.25rem; border-radius: 8px; color: var(--rst-text-muted); cursor: pointer; margin-right: -0.25rem; }
  .jam-views-btn:hover { background: var(--rst-surface-2); color: var(--rst-text); }
  .jam-pane--nav { left: 0; width: min(17rem, 85vw); transform: translateX(-100%); transition: transform var(--jam-slide-ms, 240ms) var(--jam-slide-ease, cubic-bezier(0.2, 0.8, 0.2, 1)); z-index: 8; box-shadow: 10px 0 28px -14px rgba(0, 0, 0, 0.35); border-right: 1px solid var(--rst-line); background: var(--rst-surface); }
  body:has(#jam-views:checked) .jam-pane--nav { transform: none; }
  body:has(#jam-views:checked) .jam-panes::after { content: ""; position: absolute; inset: 0; background: rgba(20, 20, 24, 0.25); z-index: 7; }
  .jam-pane--list { left: 0; right: 0; padding: 0.75rem 1rem 3rem; }
  .jam-panes--open .jam-pane--list { transform: none; }
  .jam-panes--open:has(.jam-pane--nav:hover) .jam-pane--list, .jam-panes--open.jam-panes--peek-nav .jam-pane--list { transform: none; }
  /* The conversation alone: the list and the contact pane step aside;
     the crumb leads back and names the contact. */
  .jam-pane--conv { left: 0; right: 0; }
  .jam-panes--open .jam-pane--list, .jam-pane--contact { display: none; }
  .jam-crumb { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin: 0 0 0.6rem; }
  .jam-crumb a { display: inline-flex; align-items: center; gap: 0.3rem; color: var(--rst-text-muted); }
  .jam-crumb__contact { font-weight: 600; color: var(--rst-text); }
  .jam-nav { display: none; }
  .jam-side__list--pages { display: block; border-top: 1px solid var(--rst-line); padding-top: 0.5rem; margin-top: 0.5rem; }
  .jam-panes--open:has(.jam-pane--nav:hover) .jam-pane--conv, .jam-panes--open:has(.jam-pane--list:hover) .jam-pane--conv,
  .jam-panes--open.jam-panes--peek-nav .jam-pane--conv, .jam-panes--open.jam-panes--peek-list .jam-pane--conv { transform: none; }
  /* The sliver is the way back and nothing else: rows do not receive
     the tap through it. */
  .jam-panes--open .jam-pane--list > .jam-main a, .jam-panes--open .jam-pane--list > .jam-main button, .jam-panes--open .jam-pane--list > .jam-main input, .jam-panes--open .jam-pane--list > .jam-main select, .jam-panes--open .jam-pane--list > .jam-main label { pointer-events: none; }
  .jam-pane--contact { width: min(calc(18rem + 44px), calc(100% - 28px)); grid-template-columns: 44px minmax(0, 1fr); transform: translateX(calc(100% - 44px)); }
  .jam-pane--contact:hover, .jam-pane--contact:focus-within, .jam-pane--contact:focus { transform: none; }
  .jam-contact__tab { padding: 0.9rem 0 1rem; gap: 0.7rem; }
  .jam-contact__tab .jam-av--lg { width: 2rem; height: 2rem; font-size: 0.7rem; }
  .jam-contact__vname { font-size: 0.9rem; max-height: 32vh; }
  /* The conversation on a phone: the head keeps its margin, the
     messages run edge to edge, notes and activity keep to the spine. */
  .jam-pane--conv .jam-conv { padding: 0.75rem 0 4rem; }
  .jam-thread__head, .jam-thread__folds { padding-left: 0.9rem; padding-right: 0.9rem; }
  .jam-thread__folds::before { left: calc(0.9rem + 0.95rem - 1px); }
  .jam-entries { padding-right: 0.9rem; }
  .jam-entries::before { left: calc(0.9rem + 0.95rem - 1px); }
  .jam-entries { padding-left: calc(0.9rem + 2.2rem); }
  .jam-msg { margin-left: calc(-0.9rem - 2.2rem); margin-right: -0.9rem; border-radius: 0; border-left: 0; border-right: 0; padding: 1rem 0.9rem 1.1rem; }
  .jam-hidden { margin-left: -1.75rem; }
  .jam-thread__subject { font-size: 1.35rem; }
  .jam-msg__head { grid-template-columns: 2rem minmax(0, 1fr); }
  .jam-msg__head .jam-av { width: 2rem; height: 2rem; font-size: 0.65rem; }
  .jam-msg__side { grid-column: 2; justify-self: start; }
  .jam-node { left: -2.2rem; width: 1.9rem; }
  .jam-fold { margin-left: 2.2rem; }
  .jam-fold--reply { margin-left: 0; }
  .jam-presence { margin-left: 2.2rem; }
  .jam-actions-bar { gap: 0.2rem; }
  .jam-act-btn { padding: 0.34rem 0.55rem 0.34rem 0.45rem; }
  .jam-actions-bar__rule { margin: 0 0.15rem; }
}

/* ── Development menu ──────────────────────────────────────────────── */
.jam-devmenu { position: fixed; left: 0.75rem; bottom: 0.75rem; z-index: 60; font-size: var(--rst-fs-xs); }
.jam-devmenu > summary { list-style: none; cursor: pointer; width: 2rem; height: 2rem; display: grid; place-items: center; border-radius: 50%; background: var(--rst-surface); border: 1px solid var(--rst-line); color: var(--rst-text-muted); box-shadow: var(--rst-shadow-pop); opacity: 0.55; }
.jam-devmenu > summary::-webkit-details-marker { display: none; }
.jam-devmenu > summary:hover, .jam-devmenu[open] > summary { opacity: 1; }
.jam-devmenu__body { position: absolute; left: 0; bottom: 2.5rem; width: 17rem; padding: 0.8rem 0.9rem; background: var(--rst-surface); border: 1px solid var(--rst-line); border-radius: 10px; box-shadow: var(--rst-shadow-pop); display: grid; gap: 0.6rem; }
.jam-devmenu__body h3 { margin: 0; font-size: var(--rst-fs-sm); }
.jam-devmenu__body label { display: grid; gap: 0.2rem; }
.jam-devmenu__body label > span { display: flex; justify-content: space-between; color: var(--rst-text-muted); }
.jam-devmenu__body select, .jam-devmenu__body input[type="range"] { width: 100%; font: inherit; }
.jam-devmenu__body button { justify-self: start; font: inherit; font-size: var(--rst-fs-xs); background: none; border: 1px solid var(--rst-line); border-radius: 6px; padding: 0.2rem 0.5rem; cursor: pointer; color: var(--rst-text-muted); }

/* ── Type on a phone ────────────────────────────────────────────────── */
/* A phone, upright or on its side, reads at a slightly smaller root
   size so the rem-based layout tightens with it; the reading sizes
   (messages, the editor) hold at one rem. */
/* The 15px root is for phones — portrait by width, landscape by the
   height arm, which is gated on a coarse pointer so a short desktop
   window keeps the full 16px scale. */
@media (max-width: 720px), ((max-height: 560px) and (pointer: coarse)) {
  html { font-size: 15px; }
  .jam-msg__body, .jam-editor-wrap--reply .jam-editor { font-size: 1rem; line-height: 1.55; }
  .jam-list-head h1 { font-size: 1.45rem; }
  .jam-main { --jam-head-line: calc(1.45rem * 1.55); }
  /* A smaller heading is a smaller box, so the bar's controls come
     down to fit it — it still has to be the same height. */
  .jam-bulkbar { height: var(--jam-head-line); }
  .jam-bulkbar [rst-btn] { padding: 0.15rem 0.6rem; }
  .jam-section-title { font-size: 1rem; }
  .jam-note__body { font-size: 0.95rem; }
}
