/* ============================================================================
   FEATURES - polls, events, canvases, topics, forum, later, status,
   notifications, integrations, message extras, shortcuts, bookmarks, snippets.

   These surfaces appear in two places: inline in the message list (on --c-bg)
   and inside the right panel (on --c-surface). So every card here carries its
   own background AND a hairline, and never assumes what is behind it.

   ---------------------------------------------------------------- SPECIFICITY
   Every feature module in web/js/features/*.js still calls injectStyles() and
   appends a <style> to document.head at runtime. That style element lands AFTER
   this file's <link>, so a plain `.poll-card {}` here would LOSE the tie to the
   legacy `.poll-card {}` there - and the legacy rules reference dead variables
   (--line, --panel2, --dim) which resolve to nothing and wipe the property out
   entirely. Prefixing with `:root` adds one class-level of specificity, which is
   the cheapest honest way to win without a single !important. It is also
   harmless the day those injected styles are deleted.

   Colour, spacing, radius, shadow, type and motion all come from tokens.css.
   Anything inside the rail or the sidebar uses --c-nav-*; everything here is
   content, except the two topics-nav rules that say so explicitly.
   ========================================================================= */

:root {
  /* Derived tints. These are only ever used as FILLS and BORDERS, never as a
     text colour: --c-accent, --c-warn and --c-success all drop below WCAG AA
     as small text once they sit on anything other than --c-bg, so status here
     is carried by a tinted chip behind --c-text rather than by coloured text. */
  --fx-accent-fill: color-mix(in srgb, var(--c-accent) 13%, transparent);
  --fx-accent-fill-strong: color-mix(in srgb, var(--c-accent) 26%, transparent);
  --fx-warn-edge: color-mix(in srgb, var(--c-warn) 40%, transparent);
  --fx-danger-edge: color-mix(in srgb, var(--c-danger) 45%, transparent);
  --fx-success-edge: color-mix(in srgb, var(--c-success) 40%, transparent);
}

/* ============================================================================
   SHARED - the card and the segmented control.
   Two shapes recur across five features. Defining them once is what keeps a
   poll, an event and a link preview looking like one product.
   ========================================================================= */

/* ------------------------------------------------------------------ card
   overflow-wrap is reset here on purpose. .body sets `anywhere`, which is right
   for a pasted URL in a paragraph but ruinous inside a card: `anywhere` lowers
   a box's min-content width to one character, so a flex item next to a fixed
   one collapses and the title renders one letter per line. */
:root .poll-card,
:root .ev-card,
:root .mx-link,
:root .mx-ack,
:root .forum-card {
  overflow-wrap: break-word;
  word-break: normal;
}

:root .poll-card,
:root .ev-card,
:root .mx-link,
:root .forum-card {
  background: var(--c-surface-2);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  box-shadow: var(--e-1);
}

/* ---------------------------------------------------------- segmented control
   One pattern for RSVP, the events filter, availability and notification
   levels: joined cells with the chosen one lifted out in the accent colour. */
:root .ev-rsvp,
:root .ev-toggle,
:root .hstatus-seg,
:root .hnotif-seg:not(.row) {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  row-gap: var(--s-4);
  column-gap: 0;
}

:root .ev-rsvp > button:not(.ev-cancel),
:root .ev-toggle > button,
:root .hstatus-seg > button,
:root .hnotif-seg:not(.row) > button {
  position: relative;
  /* basis auto, not 0: "Do not disturb" needs more room than "Away", and equal
     thirds would clip it. The cells still grow to fill the whole track. */
  flex: 1 1 auto;
  min-width: 0;
  min-height: 34px;
  margin-left: -1px;           /* collapse the hairline shared by two cells */
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--c-border);
  border-radius: 0;
  background: var(--c-surface-2);
  color: var(--c-text-2);
  font-size: var(--t-sm);
  font-weight: var(--t-medium);
  line-height: var(--t-tight);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: background var(--m-fast) var(--m-ease),
              color var(--m-fast) var(--m-ease),
              border-color var(--m-fast) var(--m-ease);
}

:root .ev-rsvp > button:not(.ev-cancel):first-child,
:root .ev-toggle > button:first-child,
:root .hstatus-seg > button:first-child,
:root .hnotif-seg:not(.row) > button:first-child {
  margin-left: 0;
  border-start-start-radius: var(--r-md);
  border-end-start-radius: var(--r-md);
}

:root .ev-rsvp > button:not(.ev-cancel):last-child,
:root .ev-toggle > button:last-child,
:root .hstatus-seg > button:last-child,
:root .hnotif-seg:not(.row) > button:last-child {
  border-start-end-radius: var(--r-md);
  border-end-end-radius: var(--r-md);
}

:root .ev-rsvp > button:not(.ev-cancel):hover,
:root .ev-toggle > button:hover,
:root .hstatus-seg > button:hover,
:root .hnotif-seg:not(.row) > button:hover {
  z-index: 1;
  background: var(--c-surface-3);
  border-color: var(--c-border-strong);
  color: var(--c-text);
}

:root .ev-rsvp > button:not(.ev-cancel):active,
:root .ev-toggle > button:active,
:root .hstatus-seg > button:active,
:root .hnotif-seg:not(.row) > button:active {
  background: var(--c-selected);
}

/* The chosen cell is lifted out of the recessed track: the page background,
   a doubled accent edge and full-strength text. Colour lives in the ring, not
   in the label - accent-coloured 12px text fails AA on a tinted surface. */
:root .ev-rsvp > button.on:not(.ev-cancel),
:root .ev-toggle > button.on,
:root .hstatus-seg > button.on,
:root .hnotif-seg:not(.row) > button.on {
  z-index: 2;
  background: var(--c-bg);
  border-color: var(--c-accent);
  color: var(--c-text);
  font-weight: var(--t-semibold);
  box-shadow: inset 0 0 0 1px var(--c-accent), var(--e-1);
}

:root .ev-rsvp > button:not(.ev-cancel):disabled,
:root .ev-toggle > button:disabled,
:root .hstatus-seg > button:disabled,
:root .hnotif-seg:not(.row) > button:disabled {
  background: var(--c-surface-2);
  color: var(--c-text-3);
  box-shadow: none;
  cursor: default;
}

/* The focus ring has to clear the neighbouring cells' borders. */
:root .ev-rsvp > button:focus-visible,
:root .ev-toggle > button:focus-visible,
:root .hstatus-seg > button:focus-visible,
:root .hnotif-seg:not(.row) > button:focus-visible { z-index: 3; }

/* ============================================================================
   POLLS - an in-message card. Every option is a bar whose fill is its share.
   ========================================================================= */
:root .poll-card {
  max-width: 520px;
  margin: var(--s-3) 0 var(--s-2);
  padding: var(--s-5) var(--s-6);
}

:root .poll-head {
  display: flex;
  align-items: flex-start;
  gap: var(--s-4);
}

:root .poll-q {
  flex: 1;
  min-width: 0;
  color: var(--c-text);
  font-size: var(--t-md);
  font-weight: var(--t-semibold);
  line-height: var(--t-snug);
  overflow-wrap: break-word;
}

:root .poll-tag {
  flex: none;
  margin-top: 1px;             /* optical: sit the cap height on the question */
  padding: var(--s-1) var(--s-3);
  border: 1px solid var(--c-accent);
  border-radius: var(--r-xs);
  background: var(--c-accent-quiet);
  color: var(--c-text);
  font-size: var(--t-2xs);
  font-weight: var(--t-bold);
  letter-spacing: 0.06em;
  line-height: 1.4;
}
:root .poll-closed .poll-tag {
  border-color: var(--c-border-strong);
  background: var(--c-surface-3);
  color: var(--c-text-2);
}

:root .poll-opts {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  margin: var(--s-5) 0 var(--s-4);
}

:root .poll-opt {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-start;   /* components.css centres every button */
  white-space: normal;           /* ...and stops every button from wrapping */
  gap: var(--s-4);
  width: 100%;
  min-height: 38px;
  padding: var(--s-4) var(--s-5);
  overflow: hidden;
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  background: var(--c-bg);
  color: var(--c-text);
  font-family: inherit;
  font-size: var(--t-base);
  font-weight: var(--t-medium);
  text-align: left;
  transition: border-color var(--m-fast) var(--m-ease),
              background var(--m-fast) var(--m-ease);
}
:root .poll-opt:hover:not(:disabled) {
  border-color: var(--c-accent);
  background: var(--c-hover);
}
:root .poll-opt:active:not(:disabled) { background: var(--c-surface-2); }
:root .poll-opt:disabled { cursor: default; opacity: 1; }

/* Your own choice: a doubled accent edge, so it survives a glance at a phone
   held in daylight rather than relying on the tick alone. */
:root .poll-opt.mine {
  border-color: var(--c-accent);
  box-shadow: inset 0 0 0 1px var(--c-accent);
}

:root .poll-fill {
  position: absolute;
  inset: 0 auto 0 0;
  background: var(--fx-accent-fill);
  transition: width var(--m-slow) var(--m-out);
  pointer-events: none;
}
:root .poll-opt.mine .poll-fill { background: var(--fx-accent-fill-strong); }

:root .poll-tick {
  position: relative;
  flex: none;
  width: 13px;
  color: var(--c-accent);
  font-size: var(--t-sm);
  line-height: 1;
}
:root .poll-txt {
  position: relative;
  flex: 1;
  min-width: 0;
  overflow-wrap: break-word;
}
:root .poll-num {
  position: relative;
  flex: none;
  color: var(--c-text-2);
  font-size: var(--t-sm);
  font-weight: var(--t-normal);
  font-variant-numeric: tabular-nums;
}
:root .poll-opt.mine .poll-num { color: var(--c-text); }

:root .poll-foot {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  font-size: var(--t-sm);
}
:root .poll-count { color: var(--c-text-2); }
/* An error inside a card is an inline alert, not red text: red text at 12.5px
   drops under AA on the panel surface in the light theme. */
:root .poll-err,
:root .ev-err {
  padding: var(--s-3) var(--s-5);
  border-left: 3px solid var(--c-danger);
  border-radius: var(--r-xs);
  background: var(--c-danger-quiet);
  color: var(--c-text);
  font-size: var(--t-sm);
}

/* the compact rows in the Polls panel */
:root .poll-row-meta {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-top: var(--s-2);
  font-size: var(--t-sm);
}
:root .poll-pill {
  flex: none;
  padding: var(--s-1) var(--s-3);
  border-radius: var(--r-xs);
  background: var(--c-surface-3);
  color: var(--c-text-2);
  font-size: var(--t-2xs);
  font-weight: var(--t-bold);
  letter-spacing: 0.06em;
}
:root .poll-pill.open {
  border: 1px solid var(--fx-success-edge);
  background: var(--c-success-quiet);
  color: var(--c-text);
}

/* ============================================================================
   EVENTS - a date block, the detail, RSVP as a segmented control.
   ========================================================================= */
:root .ev-card {
  max-width: 520px;
  margin: var(--s-3) 0 var(--s-2);
  padding: var(--s-5) var(--s-6);
}
:root .ev-in-panel {
  max-width: none;
  margin: 0 0 var(--s-4);
}

:root .ev-head {
  display: flex;
  align-items: flex-start;
  gap: var(--s-5);
}

/* The date block is a tile rather than a line of text, so a column of events
   scans by date the way a calendar does. */
/* A fixed width, not `flex: none` on auto: the time string is long enough that
   max-content sizing would eat the whole row and squeeze the title to nothing. */
:root .ev-when {
  flex: none;
  width: 114px;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  background: var(--c-bg);
  text-align: center;
}
:root .ev-day {
  color: var(--c-text);
  font-size: var(--t-xs);
  font-weight: var(--t-bold);
  letter-spacing: 0.05em;
  line-height: var(--t-tight);
  text-transform: uppercase;
}
:root .ev-time {
  margin-top: var(--s-1);
  color: var(--c-text-2);
  font-size: var(--t-xs);
  line-height: var(--t-snug);
  font-variant-numeric: tabular-nums;
  /* "6:44 PM - 7:51 PM" is one character too wide for the tile: balance splits
     it at the dash instead of orphaning the trailing "PM". */
  text-wrap: balance;
}

:root .ev-main { flex: 1; min-width: 0; }
:root .ev-title {
  color: var(--c-text);
  font-size: var(--t-md);
  font-weight: var(--t-semibold);
  line-height: var(--t-snug);
  overflow-wrap: break-word;
}
:root .ev-loc {
  margin-top: var(--s-1);
  color: var(--c-text-2);
  font-size: var(--t-sm);
  line-height: var(--t-snug);
  overflow-wrap: break-word;
}

/* Solid, not tinted: CANCELLED has to be the loudest thing on the card. */
:root .ev-tag {
  flex: none;
  padding: var(--s-1) var(--s-3);
  border-radius: var(--r-xs);
  background: var(--c-danger);
  color: var(--c-text-inverse);
  font-size: var(--t-2xs);
  font-weight: var(--t-bold);
  letter-spacing: 0.06em;
  line-height: 1.5;
}

/* A cancelled event is muted with colour, not opacity - opacity would drag
   every child under the contrast floor at once. */
:root .ev-canceled .ev-title {
  color: var(--c-text-2);
  text-decoration: line-through;
}
:root .ev-canceled .ev-when { background: var(--c-surface-3); border-color: transparent; }
:root .ev-canceled .ev-day { color: var(--c-text-2); }

:root .ev-desc {
  margin-top: var(--s-4);
  color: var(--c-text-2);
  font-size: var(--t-base);
  line-height: var(--t-body);
  white-space: pre-wrap;
  overflow-wrap: break-word;
}
:root .ev-counts {
  margin: var(--s-5) 0 var(--s-4);
  color: var(--c-text-2);
  font-size: var(--t-sm);
}

/* On a wide card the three cells stay at their natural width so the cancel
   button still fits on the same line. */
:root .ev-rsvp > button:not(.ev-cancel) { flex: 0 1 auto; min-width: 82px; }

/* Quiet until you reach for it, then unmistakably destructive. */
:root .ev-cancel {
  flex: none;
  margin-left: auto;
  min-height: 34px;
  padding: var(--s-3) var(--s-5);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--c-text-2);
  font-size: var(--t-sm);
  font-weight: var(--t-medium);
  transition: background var(--m-fast) var(--m-ease),
              color var(--m-fast) var(--m-ease),
              border-color var(--m-fast) var(--m-ease);
}
:root .ev-cancel:hover:not(:disabled) {
  background: var(--c-danger-quiet);
  border-color: var(--fx-danger-edge);
  color: var(--c-danger);
}
:root .ev-cancel:active:not(:disabled) { background: var(--c-surface-3); }
:root .ev-cancel:disabled { color: var(--c-text-3); cursor: default; }

:root .ev-toggle { max-width: 260px; margin-bottom: var(--s-5); }

/* ============================================================================
   CANVASES - the shared document. Blocks get room to breathe and reveal their
   controls on hover; on touch the controls are simply always there.
   ========================================================================= */
:root .cv-modal .modal { max-width: min(900px, 94vw); }

:root .cv-doc { padding-bottom: var(--s-2); }

:root .cv-title {
  width: 100%;
  padding: var(--s-3) var(--s-4);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--c-text);
  font-family: inherit;
  font-size: var(--t-lg);
  font-weight: var(--t-semibold);
  transition: background var(--m-fast) var(--m-ease),
              border-color var(--m-fast) var(--m-ease);
}
:root .cv-title:hover { border-color: var(--c-border); }
:root .cv-title:focus {
  border-color: var(--c-accent);
  background: var(--c-surface-2);
}
:root .cv-title::placeholder { color: var(--c-text-3); }

:root .cv-blocks {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
}

:root .cv-block {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-1) var(--s-2) var(--s-1) var(--s-3);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  transition: background var(--m-fast) var(--m-ease),
              border-color var(--m-fast) var(--m-ease);
}
:root .cv-block:hover { border-color: var(--c-border); background: var(--c-hover); }
:root .cv-block:focus-within { border-color: var(--c-border-strong); }

:root .cv-main { flex: 1; min-width: 0; }

:root .cv-view {
  min-height: 30px;
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-sm);
  color: var(--c-text);
  line-height: var(--t-loose);
  cursor: text;
  overflow-wrap: break-word;
  transition: background var(--m-fast) var(--m-ease);
}
:root .cv-view:hover { background: var(--c-surface-2); }
:root .cv-ph { color: var(--c-text-2); }

:root .cv-edit {
  width: 100%;
  min-height: 36px;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--c-accent);
  border-radius: var(--r-sm);
  background: var(--c-bg);
  color: var(--c-text);
  font-family: inherit;
  font-size: inherit;
  line-height: var(--t-loose);
  resize: none;
  overflow: hidden;
}

:root .cv-heading .cv-view,
:root .cv-heading .cv-edit {
  font-size: var(--t-xl);
  font-weight: var(--t-semibold);
  line-height: var(--t-snug);
}

:root .cv-code .cv-edit {
  font-family: var(--t-mono);
  font-size: var(--t-sm);
}

:root .cv-pre {
  margin: 0;
  padding: var(--s-5) var(--s-6);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  background: var(--c-code-bg);
  color: var(--c-text);
  font-family: var(--t-mono);
  font-size: var(--t-sm);
  line-height: var(--t-body);
  overflow-x: auto;              /* code scrolls in place, never widens the page */
  overscroll-behavior-x: contain;
  tab-size: 2;
}
/* A canvas is a document, not a chat log, so its code blocks get a monochrome
   treatment of their own: structure by weight and dimming rather than hue.
   The reset first, so the message-list syntax palette does not leak in here. */
:root .cv-pre [class^="hljs-"],
:root .cv-pre [class*=" hljs-"] { color: var(--c-text); font-style: normal; }
:root .cv-pre .hljs-keyword,
:root .cv-pre .hljs-built_in,
:root .cv-pre .hljs-literal,
:root .cv-pre .hljs-title,
:root .cv-pre .hljs-name,
:root .cv-pre .hljs-section { color: var(--c-text); font-weight: var(--t-semibold); }
:root .cv-pre .hljs-comment,
:root .cv-pre .hljs-meta { color: var(--c-text-2); font-style: italic; }

/* The language field labels the block below it, so it starts where that block
   starts - .cv-view carries the horizontal padding, and without this the input
   sat 8px to the left of the code it belongs to. */
:root .cv-lang {
  width: 130px;
  max-width: 100%;
  margin: 0 0 var(--s-3) var(--s-4);
  padding: var(--s-2) var(--s-4);
  font-size: var(--t-sm);
}

:root .cv-check {
  flex: none;
  width: 17px;
  height: 17px;
  margin: 10px 0 0;              /* optical: line the box up with the first line */
  accent-color: var(--c-accent);
  cursor: pointer;
}
:root .cv-done .cv-view {
  color: var(--c-text-2);
  text-decoration: line-through;
}

/* Inset to the same edge as .cv-view's text, so a divider reads as a break in
   the document rather than a rule that overshoots every paragraph. */
:root .cv-hr {
  width: auto;
  margin: var(--s-5) var(--s-4);
  border: none;
  border-top: 1px solid var(--c-border);
}

:root .cv-tools {
  display: flex;
  flex: none;
  gap: var(--s-1);
  opacity: 0;
  transition: opacity var(--m-fast) var(--m-ease);
}
:root .cv-block:hover .cv-tools,
:root .cv-block:focus-within .cv-tools { opacity: 1; }
:root .cv-tools button { min-width: 26px; color: var(--c-text-2); }
:root .cv-tools button:hover { background: var(--c-surface-3); color: var(--c-text); }

:root .cv-add {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  flex-wrap: wrap;
  margin-top: var(--s-6);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-border);
}
:root .cv-add .muted { font-size: var(--t-sm); }
:root .cv-type { width: auto; }

:root .cv-status {
  margin-top: var(--s-5);
  color: var(--c-text-2);
  font-size: var(--t-xs);
  line-height: var(--t-snug);
}
:root .cv-status.send-error { color: var(--c-danger); }

:root .cv-new { width: 100%; margin: 0 0 var(--s-5); }
:root .cv-row b { display: block; margin-bottom: var(--s-1); }

/* ============================================================================
   TOPICS - a nav section in the sidebar plus a reading panel.
   The first two rules are the only place in this file that reaches for
   --c-nav-*, because they are the only markup that lands inside #sidebar.
   ========================================================================= */
:root .topics-count {
  flex: none;
  margin-left: auto;
  color: var(--c-nav-text);
  font-size: var(--t-xs);
  font-variant-numeric: tabular-nums;
}
:root .topics-msg {
  padding: var(--s-1) var(--s-4) var(--s-3);
  color: var(--c-nav-text);
  font-size: var(--t-sm);
  line-height: var(--t-snug);
}

:root .topics-head {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  flex-wrap: wrap;
  padding: var(--s-1) var(--s-2) var(--s-5);
  margin-bottom: var(--s-4);
  border-bottom: 1px solid var(--c-border);
  font-size: var(--t-sm);
}
:root .topics-head .topics-tools { margin-left: auto; }

:root .topics-msgs {
  --gutter: 34px;                /* a panel is narrower than the channel */
  display: flex;
  flex-direction: column;
}
:root .topics-msgs .topics-row {
  border-radius: var(--r-md);
  cursor: pointer;
  transition: background var(--m-fast) var(--m-ease);
}
:root .topics-msgs .topics-row:hover { background: var(--c-hover); }

/* ============================================================================
   FORUM - a card board that replaces the message list in a forum channel.
   ========================================================================= */
:root .forum-board {
  max-width: 860px;
  margin: 0 auto;
  padding: var(--s-5) var(--s-5) var(--s-9);
}

:root .forum-bar {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  flex-wrap: wrap;
  padding-bottom: var(--s-5);
  margin-bottom: var(--s-6);
  border-bottom: 1px solid var(--c-border);
}
:root .forum-tags {
  display: flex;
  gap: var(--s-3);
  flex-wrap: wrap;
  min-width: 0;
}
:root .forum-tools { flex: none; margin-left: auto; }
:root .forum-notags { color: var(--c-text-2); font-size: var(--t-sm); }

:root .forum-chip {
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  padding: var(--s-2) var(--s-5);
  border: 1px solid var(--c-border);
  border-radius: var(--r-full);
  background: var(--c-surface-2);
  color: var(--c-text-2);
  font-size: var(--t-sm);
  font-weight: var(--t-semibold);
  line-height: var(--t-tight);
  cursor: pointer;
  transition: background var(--m-fast) var(--m-ease),
              color var(--m-fast) var(--m-ease),
              border-color var(--m-fast) var(--m-ease);
}
:root .forum-chip:hover {
  border-color: var(--c-border-strong);
  background: var(--c-hover);
  color: var(--c-text);
}
:root .forum-chip:active { background: var(--c-surface-3); }
:root .forum-chip.on {
  border-color: var(--c-accent);
  background: var(--c-selected);
  color: var(--c-text);
}
:root .forum-chip-static { cursor: default; font-weight: var(--t-medium); }
:root .forum-chip-static:hover {
  border-color: var(--c-border);
  background: var(--c-surface-2);
  color: var(--c-text-2);
}

:root .forum-card {
  margin-bottom: var(--s-5);
  padding: var(--s-5) var(--s-6);
  background: var(--c-surface);
  cursor: pointer;
  transition: background var(--m-fast) var(--m-ease),
              border-color var(--m-fast) var(--m-ease),
              box-shadow var(--m-base) var(--m-ease),
              transform var(--m-base) var(--m-out);
}
:root .forum-card:hover {
  border-color: var(--c-border-strong);
  background: var(--c-surface-2);
  box-shadow: var(--e-2);
  transform: translateY(-1px);
}
:root .forum-card:active { transform: translateY(0); box-shadow: var(--e-1); }

:root .fc-title {
  margin-bottom: var(--s-2);
  color: var(--c-text);
  font-size: var(--t-md);
  font-weight: var(--t-semibold);
  line-height: var(--t-snug);
  overflow-wrap: break-word;
}
:root .fc-meta {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
  color: var(--c-text-2);
  font-size: var(--t-sm);
}
:root .fc-meta b { color: var(--c-text); font-weight: var(--t-semibold); }
:root .fc-tags {
  display: flex;
  gap: var(--s-2);
  flex-wrap: wrap;
  margin-top: var(--s-4);
}
:root .fc-foot {
  margin-top: var(--s-4);
  color: var(--c-text-2);
  font-size: var(--t-sm);
}

:root .forum-retry { margin-top: var(--s-5); }

:root .forum-posthead {
  padding: var(--s-1) var(--s-2) var(--s-5);
  margin-bottom: var(--s-4);
  border-bottom: 1px solid var(--c-border);
}
:root .fp-title {
  margin-bottom: var(--s-1);
  color: var(--c-text);
  font-size: var(--t-lg);
  font-weight: var(--t-semibold);
  line-height: var(--t-snug);
  overflow-wrap: break-word;
}
:root .forum-postmsgs { --gutter: 34px; }

:root .forum-tagpick {
  display: flex;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin-bottom: var(--s-5);
}

/* ============================================================================
   LATER - the work queue: three states, the reminders, and a jump back.
   ========================================================================= */
:root .later-sec {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  cursor: pointer;
  user-select: none;
}
:root .later-sec:hover { color: var(--c-text); }
:root .later-n {
  margin-left: auto;
  padding: 0 var(--s-3);
  border-radius: var(--r-full);
  background: var(--c-surface-3);
  color: var(--c-text-2);
  font-size: var(--t-2xs);
  font-weight: var(--t-semibold);
  letter-spacing: 0;
  line-height: 1.7;
  font-variant-numeric: tabular-nums;
}

:root .later-item { border-bottom: 1px solid var(--c-border-subtle); }
:root .later-item .body {
  max-height: 96px;
  overflow: hidden;
  color: var(--c-text);
  font-size: var(--t-base);
  line-height: var(--t-body);
}
:root .later-meta {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
  color: var(--c-text-2);
  font-size: var(--t-sm);
}
:root .later-meta b { color: var(--c-text); font-weight: var(--t-semibold); }

:root .later-bar {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin-top: var(--s-4);
}
:root .later-bar button { font-size: var(--t-sm); }
/* The three state buttons are a choice, so the chosen one gets the same
   treatment as every other segmented control here: an opaque background and an
   accent ring rather than accent-coloured text, which fails AA at 12.5px on
   the panel surface. */
:root .later-bar button.on {
  background: var(--c-bg);
  border-color: var(--c-accent);
  box-shadow: inset 0 0 0 1px var(--c-accent);
  color: var(--c-text);
}

/* A due time is a chip: the tint carries the urgency, --c-text carries the
   reading. Amber and red text at 12.5px fail AA on the panel surface. */
:root .later-when,
:root .later-over,
:root .mx-sched-when {
  padding: var(--s-1) var(--s-3);
  border-radius: var(--r-xs);
  background: var(--c-warn-quiet);
  box-shadow: inset 0 0 0 1px var(--fx-warn-edge);
  color: var(--c-text);
  font-weight: var(--t-medium);
}
:root .later-over {
  background: var(--c-danger-quiet);
  box-shadow: inset 0 0 0 1px var(--fx-danger-edge);
  font-weight: var(--t-semibold);
}
:root .later-badge { margin-left: var(--s-1); vertical-align: top; }
:root .later-done .body {
  color: var(--c-text-2);
  text-decoration: line-through;
}

/* ============================================================================
   STATUS - the chip in the top bar and the popover behind it.
   ========================================================================= */
/* This chip is injected INTO #userMenu, which shell.css sizes to the top bar's
   right column and cannot grow. So the chip has to be the thing that gives:
   without min-width:0 its nowrap content set a min-content floor, the user menu
   overflowed by 20px and the chip's right edge ran off the window. */
:root .hstatus-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  flex: 0 1 auto;
  min-width: 0;
  max-width: 190px;
  min-height: 24px;
  overflow: hidden;
  padding: var(--s-1) var(--s-4);
  /* --c-nav-*, not the content palette: this chip sits in the global bar, which
     is aubergine in the colorful theme. A --c-surface-2 pill there reads as a
     piece of the message list that fell into the chrome. The fill is a tint of
     the nav text so it works on any of the three nav backgrounds. */
  border: 1px solid var(--c-nav-border);
  border-radius: var(--r-full);
  background: color-mix(in srgb, var(--c-nav-text) 12%, transparent);
  color: var(--c-nav-text);
  font-size: var(--t-sm);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--m-fast) var(--m-ease),
              color var(--m-fast) var(--m-ease),
              border-color var(--m-fast) var(--m-ease);
}
/* Both states go to --c-nav-text-active: --c-nav-active is a saturated blue in
   two of the three themes, and the resting text colour only reaches 3.7 on it. */
:root .hstatus-chip:hover,
:root .hstatus-chip:active {
  border-color: var(--c-nav-text-2);
  color: var(--c-nav-text-active);
}
:root .hstatus-chip:hover { background: var(--c-nav-hover); }
:root .hstatus-chip:active { background: var(--c-nav-active); }
:root .hstatus-chip-t {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 130px;
  overflow: hidden;
  text-overflow: ellipsis;
}

:root .hstatus-msg { font-size: var(--t-sm); cursor: default; }
:root .hstatus-badge { margin-left: var(--s-2); font-size: var(--t-xs); }

:root .hstatus-pop {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  width: min(300px, calc(100vw - var(--s-8)));
  padding: var(--s-4) var(--s-5) var(--s-6);
}
:root .hstatus-pop h4.sec { margin: var(--s-2) var(--s-1) 0; }

:root .hstatus-inputs { display: flex; gap: var(--s-3); }
:root .hstatus-inputs .hstatus-emoji {
  flex: none;
  width: 58px;
  padding: var(--s-4) var(--s-2);
  font-family: var(--t-emoji);
  text-align: center;
}
:root .hstatus-inputs .hstatus-text { flex: 1; min-width: 0; }

:root .hstatus-presets { display: flex; flex-direction: column; gap: var(--s-2); }
:root .hstatus-preset {
  display: flex;
  align-items: center;
  justify-content: flex-start;   /* components.css centres every button */
  gap: var(--s-4);
  width: 100%;
  min-height: 36px;
  padding: var(--s-3) var(--s-4);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--c-text);
  font-size: var(--t-base);
  font-weight: var(--t-normal);
  text-align: left;
  transition: background var(--m-fast) var(--m-ease),
              border-color var(--m-fast) var(--m-ease);
}
:root .hstatus-preset:hover {
  background: var(--c-hover);
  border-color: var(--c-border);
}
:root .hstatus-preset:active { background: var(--c-surface-2); }
:root .hstatus-preset .muted {
  margin-left: auto;
  color: var(--c-text-2);
  font-size: var(--t-xs);
}

:root .hstatus-actions { align-items: center; gap: var(--s-4); }
:root .hstatus-exp {
  margin-left: auto;
  color: var(--c-text-2);
  font-size: var(--t-xs);
  text-align: right;
}
:root .hstatus-note {
  color: var(--c-text-2);
  font-size: var(--t-xs);
  line-height: var(--t-snug);
}

/* The pause buttons are independent actions, not a choice - a plain row. */
:root .hstatus-pop [data-slot="dnd"] {
  display: flex;
  gap: var(--s-3);
  flex-wrap: wrap;
}

/* ============================================================================
   NOTIFICATIONS - quiet hours, pauses, and a level per channel.
   ========================================================================= */
:root .hnotif-block {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  padding: var(--s-1) var(--s-2) var(--s-5);
}
:root .hnotif-hours {
  display: flex;
  align-items: flex-end;
  gap: var(--s-4);
}
:root .hnotif-hours .field { flex: 1; min-width: 0; margin: 0; }
:root .hnotif-hours button { flex: none; }

:root .hnotif-hint {
  color: var(--c-text-2);
  font-size: var(--t-sm);
  line-height: var(--t-body);
}

/* The pause row borrows the class name but is a row of separate buttons. */
:root .hnotif-seg.row {
  display: flex;
  gap: var(--s-3);
  flex-wrap: wrap;
}

/* The row wraps rather than truncating. Four cells - Default, All, Mentions,
   Nothing - want 250px, and the panel only offers ~350, so on one line
   "#introductions" became "#introduct...". A preference you cannot read the
   subject of is useless, so when the two do not fit the control takes its own
   full-width line under the name. */
:root .hnotif-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-5);
  padding: var(--s-4);
  border-radius: var(--r-md);
  border-bottom: 1px solid var(--c-border-subtle);
  transition: background var(--m-fast) var(--m-ease);
}
:root .hnotif-row:hover { background: var(--c-hover); }
:root .hnotif-row .hnotif-seg { flex: 1 1 250px; }
:root .hnotif-name {
  flex: 1 1 140px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--c-text);
  font-size: var(--t-base);
  font-weight: var(--t-medium);
}
:root .hnotif-name .ch-ico { color: var(--c-text-2); }

/* ============================================================================
   INTEGRATIONS - webhooks, bots, remote commands, custom emoji.
   Every section mints or spends a credential, so the copyable block and the
   shown-once warning carry most of the weight here.
   ========================================================================= */
:root .intg-lead {
  margin: var(--s-1) var(--s-2) var(--s-5);
  color: var(--c-text-2);
  font-size: var(--t-sm);
  line-height: var(--t-body);
}
:root .intg-mini {
  margin: 0 var(--s-2) var(--s-4);
  color: var(--c-text-2);
  font-size: var(--t-sm);
  line-height: var(--t-body);
}

/* The only sighting of a secret, so it has to read as a warning at a glance:
   warm tint, a solid left edge, and a sign. */
:root .intg-warn {
  position: relative;
  margin: 0 0 var(--s-5);
  padding: var(--s-5) var(--s-6) var(--s-5) var(--s-10);
  border: 1px solid var(--fx-warn-edge);
  border-left: 3px solid var(--c-warn);
  border-radius: var(--r-md);
  background: var(--c-warn-quiet);
  color: var(--c-text);
  font-size: var(--t-sm);
  line-height: var(--t-body);
}
:root .intg-warn::before {
  content: "⚠";
  position: absolute;
  top: var(--s-5);
  left: var(--s-5);
  color: var(--c-warn);
  font-size: var(--t-md);
  line-height: var(--t-body);
}

/* A token or a curl line: monospace, selectable in one gesture, scrolling
   sideways rather than wrapping - a wrapped curl cannot be read or pasted. */
:root .intg-code {
  margin: var(--s-3) 0 var(--s-1);
  padding: var(--s-4) var(--s-5);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  background: var(--c-code-bg);
  color: var(--c-text);
  font-family: var(--t-mono);
  font-size: var(--t-xs);
  line-height: var(--t-body);
  white-space: pre;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  user-select: all;
  cursor: text;
}

:root .intg-caplabel {
  margin-top: var(--s-5);
  color: var(--c-text-2);
  font-size: var(--t-2xs);
  font-weight: var(--t-semibold);
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

:root .intg-row {
  display: flex;
  align-items: center;
  gap: var(--s-4);
}
/* The label and its Copy button share a line, so the air above them belongs to
   the ROW. A top margin on one flex item only drops that item, which left the
   label sitting half a line below the button it labels. */
:root .intg-row > .intg-caplabel { margin-top: 0; }
:root .intg-row:has(> .intg-caplabel) { margin-top: var(--s-5); }
:root .intg-grow { flex: 1; min-width: 0; }
:root .intg-title {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  overflow: hidden;
  color: var(--c-text);
  font-size: var(--t-base);
  font-weight: var(--t-semibold);
  text-overflow: ellipsis;
}
:root .intg-mono {
  color: var(--c-text-2);
  font-family: var(--t-mono);
  font-size: var(--t-xs);
  overflow-wrap: anywhere;
}

:root .intg-emoji {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  padding: var(--s-2) 0;
}
:root .intg-emoji-cell {
  width: 84px;
  padding: var(--s-3) var(--s-2);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  color: var(--c-text-2);
  font-size: var(--t-xs);
  line-height: var(--t-snug);
  text-align: center;
  overflow-wrap: anywhere;
  cursor: pointer;
  transition: background var(--m-fast) var(--m-ease),
              color var(--m-fast) var(--m-ease),
              border-color var(--m-fast) var(--m-ease);
}
:root .intg-emoji-cell:hover {
  border-color: var(--c-border);
  background: var(--c-hover);
  color: var(--c-text);
}
:root .intg-emoji-cell img,
:root .intg-emoji-ph {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin: 0 auto var(--s-2);
  border-radius: var(--r-sm);
  background: var(--c-surface-2);
  object-fit: contain;
}

/* ============================================================================
   MESSAGE EXTRAS - acknowledgements, read receipts, link cards, pins and the
   unread divider.
   ========================================================================= */
:root .mx-ack {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  flex-wrap: wrap;
  max-width: 520px;
  margin: var(--s-4) 0 var(--s-1);
  padding: var(--s-4) var(--s-5);
  border: 1px solid var(--fx-warn-edge);
  border-left: 3px solid var(--c-warn);
  border-radius: var(--r-md);
  background: var(--c-warn-quiet);
  color: var(--c-text);
  font-size: var(--t-sm);
}
:root .mx-ack button {
  padding: var(--s-3) var(--s-5);
  border-radius: var(--r-sm);
  font-size: var(--t-sm);
}
:root .mx-ack-count {
  border-bottom: 1px dotted var(--c-border-strong);
  color: var(--c-text-2);
  cursor: pointer;
  transition: color var(--m-fast) var(--m-ease);
}
:root .mx-ack-count:hover { color: var(--c-text); border-bottom-color: var(--c-text-2); }
:root .mx-done {
  padding: var(--s-1) var(--s-3);
  border-radius: var(--r-xs);
  background: var(--c-success-quiet);
  box-shadow: inset 0 0 0 1px var(--fx-success-edge);
  color: var(--c-text);
  font-weight: var(--t-semibold);
}

:root .mx-list {
  min-width: 200px;
  max-height: 260px;
  overflow: auto;
  padding: var(--s-2);
}
:root .mx-list-row {
  display: flex;
  justify-content: space-between;
  gap: var(--s-6);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-sm);
  font-size: var(--t-base);
}
:root .mx-list-row:hover { background: var(--c-hover); }
:root .mx-list-row span { color: var(--c-text-2); font-size: var(--t-xs); }

:root .mx-seen {
  margin-top: var(--s-2);
  color: var(--c-text-2);
  font-size: var(--t-xs);
  cursor: default;
}

/* Link preview: a card, not a blue string of characters. */
:root .mx-link {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  max-width: min(430px, 100%);
  margin: var(--s-4) 0 var(--s-1);
  padding: var(--s-4) var(--s-5);
  color: var(--c-text);
  text-decoration: none;
  transition: background var(--m-fast) var(--m-ease),
              border-color var(--m-fast) var(--m-ease),
              box-shadow var(--m-base) var(--m-ease);
}
:root .mx-link:hover {
  border-color: var(--c-border-strong);
  background: var(--c-surface-3);
  box-shadow: var(--e-2);
  text-decoration: none;
}
:root .mx-link:active { box-shadow: var(--e-1); }
/* Longhands, not the shorthand: the favicon arrives as an inline background-image. */
:root .mx-fav {
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: var(--r-sm);
  background-color: var(--c-surface-3);
  background-size: 18px;
  background-position: center;
  background-repeat: no-repeat;
}
:root .mx-link-txt { display: flex; flex-direction: column; min-width: 0; }
:root .mx-link-host {
  color: var(--c-text);
  font-size: var(--t-base);
  font-weight: var(--t-semibold);
}
:root .mx-link-url {
  color: var(--c-text-2);
  font-size: var(--t-xs);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
:root .mx-link-out { flex: none; margin-left: auto; color: var(--c-text-2); }

/* A pinned message keeps a warm rule down its left edge. */
:root .mx-pinned { box-shadow: inset 3px 0 0 var(--c-warn); }

/* The unread rule: a coloured line with a label, the way Slack marks the spot
   you left off at.

   The inset is PADDING, not margin. reading.css puts this element on the
   reading column with `width: 100%`, and a horizontal margin on top of that
   pushes it past the list: on a 390px phone the rule ran to 398px and the right
   end was clipped by #messages' overflow. Padding stays inside the 100%, and
   the value matches .msg so the rule ends where the messages do.
   margin-inline is restated as auto because the legacy injected <style> still
   sets 4px there and lands after every stylesheet. */
:root .mx-newdiv {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  flex-wrap: wrap;
  margin-block: var(--s-6);
  margin-inline: auto;
  padding-inline: var(--s-5);
}
:root .mx-newdiv-line {
  flex: 1 1 40px;
  height: 1px;
  background: var(--fx-danger-edge);
}
:root .mx-newdiv-label {
  flex: none;
  color: var(--c-danger);
  font-size: var(--t-2xs);
  font-weight: var(--t-bold);
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
:root .mx-newdiv button {
  flex: none;
  padding: var(--s-2) var(--s-4);
  font-size: var(--t-xs);
}

/* ============================================================================
   SHORTCUTS AND DRAFTS - the help sheet, the drafts inbox, the unread nudge.
   ========================================================================= */
:root .sc-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-2) var(--s-9);
}
:root .sc-col h4 { margin: var(--s-5) 0 var(--s-2); }

:root .sc-row {
  display: flex;
  align-items: baseline;
  gap: var(--s-5);
  padding: var(--s-2) 0;
  font-size: var(--t-base);
}
/* Keys last, the way every shortcut sheet prints them: the descriptions then
   share one left edge instead of stepping in and out with the key count.
   Command rows keep their natural order - there the /name IS the subject. */
:root .sc-row:not(.sc-cmd) { flex-direction: row-reverse; }
:root .sc-row .sc-what { flex: 1; min-width: 0; color: var(--c-text-2); }
/* On a key row the ACTION is the content and the keycap is the reference, so
   the description carries full-strength text. On a /command row it is the other
   way round - the command is the subject - and the description stays quiet. */
:root .sc-row:not(.sc-cmd) .sc-what { color: var(--c-text); }

:root .sc-keys { display: flex; flex: none; gap: var(--s-1); }

/* Keycaps, matching the <kbd> treatment base.css already defines. */
:root .sc-key,
:root .sc-cmd code {
  display: inline-block;
  min-width: 1.6em;
  padding: 1px 5px;
  border: 1px solid var(--c-border-strong);
  border-bottom-width: 2px;
  border-radius: var(--r-xs);
  background: var(--c-surface-2);
  color: var(--c-text-2);
  font-family: var(--t-font);
  font-size: var(--t-xs);
  font-weight: var(--t-semibold);
  line-height: 1.5;
  text-align: center;
  white-space: nowrap;
}
:root .sc-cmd code {
  flex: none;
  min-width: 5.5em;              /* one left edge for the descriptions beside them */
  padding-inline: var(--s-3);
  color: var(--c-text);
  font-family: var(--t-mono);
  text-align: left;
}
:root .sc-cmd { font-size: var(--t-sm); }

/* Floats over the message list, so it needs real elevation to read as floating. */
:root .sc-jump {
  position: absolute;
  top: var(--s-5);
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 32px;
  border-radius: var(--r-full);
  box-shadow: var(--e-3);
}

:root .sc-draft-head {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  margin-bottom: var(--s-2);
  color: var(--c-text-2);
  font-size: var(--t-sm);
}
:root .sc-draft-head .sc-when { margin-left: auto; white-space: nowrap; }
:root .sc-draft-row {
  display: flex;
  justify-content: flex-end;
  gap: var(--s-3);
  margin-top: var(--s-3);
}

/* ============================================================================
   BOOKMARKS - the pinned-link strip at the top of a channel. It scrolls
   sideways; wrapping would push the conversation off a phone screen.
   ========================================================================= */
:root .bmk-bar {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: nowrap;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  /* auto, not 0: reading.css puts this strip on the same centred column as the
     conversation, and a zero inline margin would left-align it on a wide pane
     while every message under it stayed centred. */
  margin: 0 auto var(--s-5);
  padding: var(--s-3) var(--s-5);
  background: var(--c-bg);
  border-bottom: 1px solid var(--c-border);
  scrollbar-width: none;
}
:root .bmk-bar::-webkit-scrollbar { height: 0; }

:root .bmk-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  flex: none;
  max-width: 230px;
  min-height: 28px;
  padding: var(--s-2) var(--s-5);
  border: 1px solid var(--c-border);
  border-radius: var(--r-full);
  background: var(--c-surface-2);
  color: var(--c-text);
  font-size: var(--t-sm);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--m-fast) var(--m-ease),
              color var(--m-fast) var(--m-ease),
              border-color var(--m-fast) var(--m-ease);
}
:root .bmk-pill:hover {
  border-color: var(--c-accent);
  background: var(--c-selected);
  color: var(--c-text);
  text-decoration: none;
}
:root .bmk-pill:active { background: var(--c-surface-3); }
:root .bmk-pill.bmk-dead { color: var(--c-text-2); cursor: default; }
:root .bmk-pill.bmk-dead:hover {
  border-color: var(--c-border);
  background: var(--c-surface-2);
  color: var(--c-text-2);
}
:root .bmk-add {
  border-style: dashed;
  background: transparent;
  color: var(--c-text-2);
  font-weight: var(--t-semibold);
}
:root .bmk-add:hover {
  border-style: dashed;
  border-color: var(--c-accent);
  color: var(--c-text);
}

/* The strip scrolls sideways and does not wrap, which is right for PILLS: a
   wrapping row of bookmarks would push the conversation down the screen, and
   that is what the note at the top of this section says.

   A note is not a pill. It is a whole sentence, and `flex: none` plus
   `white-space: nowrap` made it a rigid 457px item inside a 330px strip on a
   390px phone - 184px of it off the side of the screen, in a scroller whose
   scrollbar is deliberately hidden, so it read as text that had simply been
   chopped off. That is the "Pin the links this channel keeps reaching for - a
   doc" that runs off the edge.

   So the note wraps, and the strip is allowed to wrap only when it contains
   one. A strip of pure pills keeps the sideways scroll it was designed for. */
:root .bmk-bar:has(.bmk-note) { flex-wrap: wrap; }
:root .bmk-note {
  flex: 1 1 12ch;
  min-width: 0;
  color: var(--c-text-2);
  font-size: var(--t-xs);
  line-height: var(--t-loose);
  white-space: normal;
  overflow-wrap: anywhere;
}
:root .bmk-note.bmk-err { color: var(--c-danger); }

:root .bmk-row { display: flex; align-items: center; gap: var(--s-4); }
:root .bmk-row .bmk-url {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--c-text-2);
  font-size: var(--t-sm);
}

/* ============================================================================
   SNIPPETS - saved code, previewed in the panel, dropped into a message.
   ========================================================================= */
:root .snip-head {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  font-size: var(--t-sm);
}
:root .snip-head b { color: var(--c-text); font-size: var(--t-base); }
:root .snip-lang {
  flex: none;
  padding: var(--s-1) var(--s-4);
  border-radius: var(--r-full);
  background: var(--c-surface-3);
  color: var(--c-text-2);
  font-size: var(--t-xs);
  font-weight: var(--t-medium);
}
:root .snip-pre {
  margin: var(--s-3) 0 0;
  padding: var(--s-4) var(--s-5);
  max-height: 150px;
  overflow: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  background: var(--c-code-bg);
  color: var(--c-text);
  font-family: var(--t-mono);
  font-size: var(--t-sm);
  line-height: var(--t-body);
  white-space: pre;
  tab-size: 2;
}
:root .snip-pre.snip-full { max-height: 52vh; }
:root .snip-bar {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin-top: var(--s-5);
}
:root .snip-bar button { font-size: var(--t-sm); }
:root .snip-open { margin-left: var(--s-3); font-size: var(--t-sm); }

/* ============================================================================
   PHONE - the primary target. Cards go full width, dense rows become stacks,
   and anything that ends a scrolling pane clears the home indicator.
   ========================================================================= */
@media (max-width: 860px) {
  :root .poll-card,
  :root .ev-card,
  :root .mx-ack { max-width: none; }

  :root .mx-link { max-width: 100%; }

  /* messages.css floats a 128x44 notch into the top-right of every message
     body on a phone so the hover action bar never sits on a word. Text flows
     around it, but a card whose head is a flex row establishes its own
     formatting context and gets shrunk to ~109px instead of flowing. Clearing
     the notch puts the card back on the full column, under the action bar. */
  :root .poll-card,
  :root .ev-card,
  :root .mx-ack,
  :root .mx-link { clear: right; }

  :root .ev-head { gap: var(--s-4); }
  :root .ev-when { width: 96px; }
  /* At 360px the three cells share the row and the cancel button drops below. */
  :root .ev-rsvp > button:not(.ev-cancel) { flex: 1 1 0; min-width: 0; }
  :root .ev-cancel { margin-left: auto; }
  :root .ev-toggle { max-width: none; }

  :root .forum-board {
    padding: var(--s-4) var(--s-4) calc(var(--s-9) + env(safe-area-inset-bottom));
  }
  :root .forum-tools { width: 100%; margin-left: 0; }

  :root .hnotif-row { padding: var(--s-4) var(--s-4) var(--s-5); }
  :root .hnotif-hours { flex-wrap: wrap; }
  :root .hnotif-hours button { width: 100%; }

  /* "Jump to newest" will not fit beside the rule and its label at 360px, and a
     clipped button is worse than a wrapped one. Give it a line of its own. */
  :root .mx-newdiv { row-gap: var(--s-3); padding-inline: var(--s-4); }
  :root .mx-newdiv > button { flex: 1 0 100%; }

  /* The three block tools are 40px squares once the input is touch, and beside
     the content they took 124px of a 335px column - code blocks were crushed to
     177px and a sentence wrapped every four words. Under 860px they drop to a
     row of their own, right-aligned, and the block gets the whole width.

     Which means the block needs an edge. Desktop only paints one on hover; on a
     phone the tools are always visible, and without a boundary a tool row reads
     as belonging to the block BELOW it. A hairline and real space between
     blocks says which three arrows act on which paragraph. */
  :root .cv-blocks { gap: var(--s-5); }
  :root .cv-block {
    flex-wrap: wrap;
    row-gap: 0;
    padding: var(--s-2) var(--s-3);
    border-color: var(--c-border-subtle);
  }
  :root .cv-tools { flex: 1 0 100%; justify-content: flex-end; }

  :root .sc-grid { grid-template-columns: 1fr; gap: 0; }

  :root .hstatus-chip { max-width: 110px; }
  :root .hstatus-chip-t { display: none; }

  :root .intg-emoji-cell { width: 76px; }

  :root .cv-add { padding-bottom: env(safe-area-inset-bottom); }
}

/* ============================================================================
   TOUCH - a hover-revealed control is invisible on a phone, and a 28px pill is
   not a tap target. Both are fixed by input type, not by viewport width.
   ========================================================================= */
@media (hover: none) {
  /* A hover-revealed tool bar does not exist on a phone. The buttons themselves
     are button.icon, and components.css already grows those to 40px and hangs a
     44px target off them, so nothing more is needed here than making them
     visible - and, above, taking them off the content's line. */
  :root .cv-tools { opacity: 1; }

  /* Tapping a block is how you open its editor, so the block IS the target. */
  :root .cv-view { min-height: 44px; }
  /* A native checkbox is a replaced element: it cannot carry a pseudo-element,
     so the only honest way to make it tappable is to draw it bigger. */
  :root .cv-check { width: 24px; height: 24px; margin-top: 8px; }

  :root .bmk-pill,
  :root .forum-chip:not(.forum-chip-static),
  :root .hstatus-preset,
  :root .poll-opt,
  :root .ev-cancel,
  :root .sc-jump,
  :root .later-sec,
  :root .ev-rsvp > button:not(.ev-cancel),
  :root .ev-toggle > button,
  :root .hstatus-seg > button,
  :root .hnotif-seg:not(.row) > button { min-height: 44px; }

  /* Nothing lights up on hover here, so the pressed state does the whole job. */
  :root .forum-card:hover { transform: none; box-shadow: var(--e-1); }
  :root .forum-card:active { background: var(--c-surface-2); }
}


/* ============================================================================
   THE ORGANISATION LAYER (0064)

   The rail used to be a flat list of Spaces because there was nothing to group
   by: every Space owned its own hidden organisation, so 150 Spaces meant 150
   orgs and "which of these belong together" had no answer. Now an org holds many
   team servers, and the rail says so - a small label above each org's run of
   servers, and a "…" tile at the end of the run that opens the directory of the
   ones this person has not joined.
   ========================================================================= */
:root .sorg-label {
  flex: none;
  width: 44px;
  margin: var(--s-4) auto var(--s-1);
  color: var(--c-nav-text-2);
  font-size: var(--t-2xs);
  font-weight: var(--t-bold);
  letter-spacing: 0.08em;
  text-align: center;
  text-transform: uppercase;
}
:root .sorg-sep {
  flex: none;
  width: 24px;
  height: 1px;
  margin: var(--s-4) auto 0;
  background: var(--c-nav-border);
}
/* Quieter than a real server: it is a door, not a place. */
:root .sicon.sorg-more {
  background: transparent;
  border: 1px dashed var(--c-nav-border);
  color: var(--c-nav-text-2);
  font-size: var(--t-lg);
  line-height: 1;
}
:root .sicon.sorg-more:hover { border-color: var(--c-nav-text-2); color: var(--c-nav-text); }

/* ---------------------------------------------------------------- directory */
:root .orgdir-head {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  margin-bottom: var(--s-5);
}
:root .orgdir-head .muted { flex: 1 1 auto; min-width: 0; font-size: var(--t-sm); }
:root .orgdir-list { display: flex; flex-direction: column; gap: var(--s-2); }
:root .orgdir-row {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  background: var(--c-surface);
}
:root .orgdir-row:hover { border-color: var(--c-accent); }
:root .orgdir-ico {
  flex: none;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--c-surface-2) 100%, transparent);
  filter: hue-rotate(calc(var(--h, 0) * 1deg));
  font-size: var(--t-xs);
  font-weight: var(--t-bold);
}
:root .orgdir-main { flex: 1 1 auto; min-width: 0; }
:root .orgdir-sub { font-size: var(--t-xs); }
:root .orgdir-locked { flex: none; font-size: var(--t-xs); }
:root .orgdir-foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: var(--s-6);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-border);
}

/* ---------------------------------------------------------------- people */
:root .orgppl-row {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--c-border-subtle, var(--c-border));
}
:root .orgppl-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
:root .orgppl-row select { flex: none; }

@media (max-width: 860px) {
  :root .orgdir-head { flex-wrap: wrap; }
  :root .orgdir-row { flex-wrap: wrap; }
}
