/* ================= THE RICH-TEXT TOOLBAR =================
   Clothes for JS/features/rich-text-toolbar.js — the Notes editor, the team-task editor, and
   any future adopter. Nothing here hangs off `.alt-app` or any page's class — that was written
   for `classic_tasks.html?embed=task`, the one host with neither, and stayed defensive after
   that page retired: its replacement, `tasks.html?embed=task`, carries both `.alt-app` and the
   `--a-*` scale (tasks.html loads CSS/alt/alt-tokens.css same as every other Suite page), so
   today's hosts all have them, but a future adopter is not guaranteed to. Nothing here decides
   where the bar sits — that is the host's answer (see `.a-fmt-host` in alt-notes.css). Not named
   `.a-rte` — that class is alt-tasks.css's task-drawer textarea, and sharing it once rendered a
   26px bar at 120px tall. */

/* The box the bar mounts into — richTextToolbarMount() appends it to whatever element the host
   hands it, so this host element may not impose a width of its own. */
.a-fmt-host{ min-width:0; }

/* ================= EVERY TOKEN CARRIES ITS CLASSIC FALLBACK =================
   Written when one live host had no `--a-*` scale at all (unframed `classic_tasks.html`, since
   retired) — so each colour is `var(--a-raised, var(--panel-2))`: the Suite role, then the
   CLASSIC alias that means the same thing (CSS/alt/alt-tokens.css declares the pairs), so the
   fallback matches in both themes rather than approximating one. Every current host loads the
   `--a-*` scale, so the fallback does not fire today; it is kept for the same future-adopter
   case the section above guards against. */

/* ---------- the row ----------
   One row, enforced not hoped for — `flex-wrap:wrap` let this bar reach 146px (three rows) on a
   330px editor. rtFit() folds the least-used groups into "More formatting" until the row fits,
   so nothing is hidden behind a scrollbar nobody looks for. */
.a-fmt{
  display:flex; align-items:center; gap:var(--a-2, 8px); flex-wrap:nowrap; overflow:hidden;
  /* No margin — where the bar sits is the host's answer (rule 2, above). */
  padding:var(--a-2, 8px); border-radius:var(--a-r, 9px);
  background:var(--a-raised, var(--panel-2)); border:1px solid var(--a-line-soft, var(--border-soft));
}
/* ---------- THE TWO WAYS ONE ROW IS NOT ENOUGH ----------
   `.nofold`: no menu to fold into (a page without JS/alt/alt-layers.js, e.g. team_board.html) —
   rtFit() declines to fold and says so. `.wrapped`: folding was exhausted and it still doesn't
   fit — measured on team_board.html at 320px, the More button itself clipped, putting seven
   controls out of reach. Both let the row wrap instead of clipping a control invisibly. */
.a-fmt.nofold,
.a-fmt.wrapped{ flex-wrap:wrap; overflow:visible; row-gap:var(--a-1, 4px); }
.a-fmt-g{ display:flex; align-items:center; gap:2px; }
.a-fmt-g + .a-fmt-g{
  padding-left:var(--a-2, 8px); border-left:1px solid var(--a-line, var(--border));
}
.a-fmt-b{
  display:inline-flex; align-items:center; justify-content:center; gap:5px;
  min-width:28px; height:26px; padding:0 6px; border-radius:var(--a-r-sm, 6px);
  border:1px solid transparent; background:transparent; color:var(--a-dim, var(--text-dim));
  font:500 12px/1 var(--a-body, var(--app-font, system-ui, -apple-system, sans-serif)); cursor:pointer;
}
.a-fmt-b.wide{ padding:0 8px; }
.a-fmt-b:hover{ background:var(--a-panel, var(--panel)); color:var(--a-text, var(--text)); border-color:var(--a-line, var(--border)); }
.a-fmt-b:focus-visible{ outline:2px solid var(--a-ring, var(--focus-ring)); outline-offset:1px; }
.a-fmt-b.on{ background:var(--a-blue-soft, var(--accent-soft)); border-color:var(--a-blue, var(--accent)); color:var(--a-blue-text, var(--accent-text)); }
.a-fmt-b svg{ width:15px; height:15px; }
.a-fmt-b .cv{ font-size:9px; opacity:.7; }
.a-fmt-b sub{ font-size:9px; }
/* The swatch says what the caret is sitting in — the only part of colour that fits on a button.
   Borrows the shared rt-* tokens, so it is the same colour the text will be, in both themes. */
.a-fmt-sw{
  width:11px; height:11px; border-radius:3px; border:1px solid var(--a-line-strong, var(--border-strong));
  background:currentColor; display:inline-block;
}
.a-fmt-sw.hi{ background:transparent; }
.a-fmt-folded{ font-size:12px; color:var(--a-faint, var(--text-faint)); padding-left:4px; }
/* The three selects (paragraph style, font, size) sit on the same row at the same 26px as the
   buttons — `.a-field.inline` exists to stop a 32px control beside a 26px one. Native selects,
   not menus: the reader sees what's in force without opening anything. */

/* ================= AND A HOST MAY NOT RESIZE THEM =================
   Two hosts override selects by id — alt-team.css's `#taskModal select` (1,1,1) and
   alt-embed-task.css's `:root.embed-task … select` (0,2,1) — both correct for their own job,
   both beating this component's `.a-fmt-s` at (0,1,0): selects rendered 36px on a 26px row.
   No host-agnostic selector can outrank an id without naming one (which would break rule 1,
   above), so the component defends its own geometry with `!important`, per sys_design-system
   §2 ("qualify by type first, `!important` only if that isn't enough, and say why"). The
   background is written as longhands — a host's shorthand `background:` would otherwise reset
   the caret image along with the colour it was trying to override. */
.a-fmt-s{
  flex:0 0 auto; min-width:0; cursor:pointer;
  height:26px !important;                       /* 26px clears the 24px pointer floor */
  padding:0 20px 0 7px !important;              /* 20px on the right is the caret's room */
  font:500 12px/1 var(--a-body, var(--app-font, system-ui, -apple-system, sans-serif)) !important;
  border-radius:var(--a-r-sm, 6px) !important;
  border:1px solid var(--a-line, var(--border)) !important;
  color:var(--a-dim, var(--text-dim)) !important;
  /* The caret is the bar's own, not two of them — `:root.embed-task select{appearance:auto}`
     (alt-embed-task.css) reaches these selects too; without resetting it, a native arrow would
     draw beside the bar's own gradient one in the same padding. */
  -webkit-appearance:none !important; appearance:none !important;
  background-color:var(--a-panel, var(--panel)) !important;
  background-image:linear-gradient(45deg, transparent 50%, currentColor 50%),
                   linear-gradient(135deg, currentColor 50%, transparent 50%) !important;
  background-position:calc(100% - 11px) 11px, calc(100% - 7px) 11px !important;
  background-size:4px 4px, 4px 4px !important;
  background-repeat:no-repeat !important;
}
/* Hover must repeat `!important` too — an `!important` base outranks a plain state rule. */
.a-fmt-s:hover{
  color:var(--a-text, var(--text)) !important;
  border-color:var(--a-line-strong, var(--border-strong)) !important;
}
.a-fmt-s:focus-visible{ outline:2px solid var(--a-ring, var(--focus-ring)); outline-offset:1px; }
.a-fmt-s.style{ width:94px; }
.a-fmt-s.family{ width:80px; }
.a-fmt-s.size{ width:74px; }
/* A native option list is drawn by the platform and does not inherit the panel's colours —
   named here to keep the popup legible in dark mode, where the UA default is white on white. */
.a-fmt-s option{ background:var(--a-panel, var(--panel)); color:var(--a-text, var(--text)); }

/* ================= THE COMMENT COMPOSER, AND WHAT IT WRITES =================
   The other half of the same component: the editable box under the bar. One stylesheet, one
   <link> — a second file for "the thing under the bar" is one more thing every adopting page
   must remember to load. Tokens still carry their classic fallback for the same reason as
   above. */

/* ---------- the column ----------
   Bar and box read as one control: squared edges, one shared border. Descendant, not child —
   richTextToolbarMount() lets a host nest the bar at any depth, typically inside its own
   `.a-fmt-host`, so `>` here would make the join square-cornered on one page and rounded on
   the next. */
.rt-composer{ display:flex; flex-direction:column; min-width:0; }
.rt-composer .a-fmt.composer{ border-bottom-left-radius:0; border-bottom-right-radius:0; }
/* `:has(.a-fmt)`, not unconditional on the wrapper's presence — a read-only note composer omits
   the bar entirely (nothing to format with if nothing may be typed), and a rule keyed only on
   `.rt-composer .rt-input` zeroed the box's top border/radius regardless, leaving it bordered
   on three sides and open on the fourth. `.rt-input` now closes its own box whenever it has no
   bar above it, rather than trusting every caller to keep the two in lockstep. */
.rt-composer:has(.a-fmt) .rt-input{ border-top-left-radius:0; border-top-right-radius:0; border-top:0; }

/* ---------- the bar over a comment box ----------
   Tighter than the document bar it is the same bar as — a reply box is one of many in a
   scrolling thread, and the preset has already taken five groups off. */
.a-fmt.composer{ padding:4px var(--a-2, 8px); gap:var(--a-1, 4px); }
.a-fmt.composer .a-fmt-g + .a-fmt-g{ padding-left:var(--a-1, 4px); }

/* ---------- the editable box ----------
   A contenteditable dressed to look exactly like the <textarea> it replaces. `min-height`, not
   `rows` — it has none, and grows with its content the same way a handful of plain `<textarea>`
   fields already fake it elsewhere by setting `style.height` from `scrollHeight` on input (no
   shared helper — JS/alt/alt-notes.js, JS/alt/alt-team-task.js and
   JS/features/task-editor-checklist.js each do it with their own local closure). The placeholder
   needs two selectors, not one: an emptied contenteditable holds
   `<br>` (or `<p><br></p>`), so `:empty` alone would lose the hint the first time a reader
   clears the box. */
.rt-input{
  min-height:64px; max-height:40vh; overflow:auto; min-width:0;
  padding:var(--a-2, 8px) var(--a-3, 12px);
  border:1px solid var(--a-line, var(--border)); border-radius:var(--a-r, 9px);
  background:var(--a-panel, var(--panel)); color:var(--a-text, var(--text));
  font:14px/1.55 var(--a-body, var(--app-font, system-ui, -apple-system, sans-serif));
  cursor:text; word-break:break-word; overflow-wrap:anywhere;
}
.rt-input:focus{ outline:none; border-color:var(--a-blue, var(--accent)); }
/* An edit box fits what it holds — the composer's 40vh ceiling above is not its rule.
   PRODUCT OWNER: "when editing a comment, make room to see the whole edit window instead of a
   vertical scroll bar."
   `.comment-item-body`/`.a-comment-b` reach only an OPEN EDIT (known content, grow to fit) —
   never a brand-new comment box (`.comment-add-row .rt-input`, which keeps its 40vh floor).
   `overflow:auto` never shows a scrollbar on an unbounded height, so whatever actually bounds
   the box (`.comments-list`, or `.a-comments` on the Suite drawer) decides the scroll. */
.comment-item-body .rt-input,
.a-comment-b .rt-input{ max-height:none; }
/* A locked rich-text input looks locked, wherever it is — product rule: an authorized assigner
   who can READ a comment thread but not post in it must never see an enabled composer.
   Unscoped on purpose: `.rt-input` is the shared primitive, and four composer surfaces gain
   this state at once — scoping to one would leave the other three looking editable while
   refusing input. Precedent/matched values: alt-team.css:715-716's `.rich-text-field` rule for
   the classic dialogs. */
.rt-input[contenteditable="false"]{ opacity:.65; cursor:default; }

/* The read-only notice beside a locked composer. Values match `.a-hint` (alt-shell.css:887)
   deliberately — the established shape for a quiet status line beside a control.
   NO `display` DECLARATION HERE — LOAD-BEARING. Shown/hidden via the `hidden` attribute
   (`[hidden]{display:none!important}`); an author `display` here would tie with it and win on
   load order, per the defect CSS/base.css:26 documents. */
.comment-readonly-notice{ font-size:12px; color:var(--a-dim, var(--text-dim)); line-height:1.45; }

.rt-input:focus-visible{ outline:2px solid var(--a-ring, var(--focus-ring)); outline-offset:-1px; }
.rt-composer:focus-within .a-fmt.composer{ border-color:var(--a-blue, var(--accent)); }
.rt-input:empty::before,
.rt-input:has(> br:only-child)::before,
.rt-input:has(> p:only-child > br:only-child)::before{
  content:attr(data-placeholder);
  color:var(--a-faint, var(--text-faint));
  pointer-events:none;               /* the hint must never eat the click that focuses the box */
}
/* A browser without :has() shows the placeholder only while the box is genuinely empty — one
   state is plainer, nothing is broken. */

/* ---------- what a formatted comment looks like once it is posted ----------
   `.rt-body` is the marker commentBodyIsRich() reads. A comment is a paragraph in a list, so no
   opening margin its neighbours lack, and a pasted table or long code line scrolls in its own
   box. The formatting classes themselves (`rt-lg`, `rt-c-blue`, etc.) live in CSS/components.css,
   which every renderer already loads — one vocabulary, not a second definition here. */
/* White space is the host's answer for plain text and the wrong one for markup — a legacy body
   needs `white-space:pre-wrap` for its own newlines; a rich body's source newlines between tags
   are not paragraphs. Declared on the marker so it lands wherever the host's body element is. */
.rt-body{ white-space:normal; }
.rt-body > :first-child{ margin-top:0; }
.rt-body > :last-child{ margin-bottom:0; }
.rt-body p{ margin:0 0 .5em; }
.rt-body ul, .rt-body ol{ margin:0 0 .5em; padding-left:1.4em; }
.rt-body blockquote{
  margin:0 0 .5em; padding:2px 0 2px var(--a-3, 12px);
  border-left:2px solid var(--a-line-strong, var(--border-strong));
  color:var(--a-dim, var(--text-dim));
}
.rt-body pre{
  margin:0 0 .5em; padding:var(--a-2, 8px); overflow-x:auto;
  background:var(--a-raised, var(--panel-2)); border-radius:var(--a-r-sm, 6px);
}
.rt-body table{ display:block; max-width:100%; overflow-x:auto; border-collapse:collapse; }
.rt-body td, .rt-body th{ border:1px solid var(--a-line, var(--border)); padding:2px 6px; }
/* Headings in a comment are a size cue, not a document outline — a browser default h1 in a
   thread is three times the size of the sentence next to it. */
.rt-body h1{ font-size:1.35em; margin:0 0 .4em; }
.rt-body h2{ font-size:1.2em;  margin:0 0 .4em; }
.rt-body h3{ font-size:1.08em; margin:0 0 .4em; }

/* ---------- the inline editor's own actions row ----------
   `.rt-edit-actions` is UNSCOPED ON PURPOSE. commentEditStart() (JS/components/comment-list.js)
   is the one editor for every surface that edits a comment — `.a-comment-b` in the drawer,
   `.comment-item-body` in the task panel and the board — so scoping this rule to one host's
   wrapper leaves the editor unstyled on the others. Buttons are `.a-btn`
   (CSS/alt/alt-components.css, which tasks.html loads) per sys_design-system §3 —
   `.btn`/`.btn.small` are declared per-page, and this page declares neither. */
.rt-edit-actions{
  display:flex; flex-direction:row; align-items:center; gap:8px; margin-top:8px;
}

/* A label is a label: it never wraps mid-word. `.a-comment-b` (alt-conversation.css) sets
   `white-space:pre-wrap`/`overflow-wrap:anywhere` for posted comment PROSE; when the editor
   replaces that body element, the formatting bar inherited them too — reset here so the bar
   wraps as a bar, not as text. */
.a-comment-b .a-fmt-host,
.a-comment-b .a-fmt-host *{ white-space:nowrap; overflow-wrap:normal; word-break:normal; }
