/* Homer's parts as plain CSS classes. Load design/tokens.css and
   design/palette.css first: every value here is a token from them.
   /style-guide shows every part.

   Every rule here names a class (or a state attribute), so it changes
   nothing that wears none of its classes. The element rules are in
   design/base.css, which every page layout loads before this file
   (test/lint/design_system_stylesheets_test.rb). A part reads
   the accent three ways: --accent-on for words on it, --accent-text for
   links, text actions and chosen words, --accent-frame for a chosen frame
   and focus. The accent itself only fills.

   Class names say what a thing is, never how it looks. A state is an
   attribute where the page already has one (aria-pressed, aria-expanded,
   aria-checked, disabled, data-step), so the look follows the state. */

/* ---------- Small helpers ---------- */
.muted { color: var(--grey); }
.mono { font-family: var(--font-mono); }
.nb { white-space: nowrap; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
/* The class the shared controllers (reveal, toggle, visibility, list_filter,
   clipboard, note box, comparison) add and take away to hide a thing. It
   wins over every part's own display, so no area keeps a copy of it. */
.hidden { display: none !important; }

/* Glyphs: a 12 by 12 grid of squares in the color of the words around it */
.glyph { flex: 0 0 auto; display: inline-block; vertical-align: -0.125em; }
.glyph-ink { color: var(--ink); }
.glyph-grey { color: var(--grey); }
.glyph-edge { color: var(--edge); }
.glyph-accent { color: var(--accent-text); }
.glyph-white { color: var(--white); }
.glyph-red { color: var(--red); }
.glyph-amber { color: var(--amber); }
.glyph-green { color: var(--green); }
.glyph-orange { color: var(--orange); }

/* ---------- The page ---------- */
.desk { min-height: 100vh; padding-block: var(--space-28); padding-inline: max(var(--space-28), env(safe-area-inset-left, 0px)) max(var(--space-28), env(safe-area-inset-right, 0px)); }
.page { max-width: var(--shell-width); margin: 0 auto; background: var(--paper); border: 2px solid var(--ink); border-radius: var(--radius-panel); padding: var(--space-44) var(--space-48) var(--space-52); display: flex; flex-direction: column; gap: var(--space-36); min-width: 0; }
.titlebar { display: flex; flex-direction: column; gap: var(--space-10); max-width: var(--measure-text); }
.title { font-size: var(--text-title); font-weight: 700; line-height: 1.1; text-wrap: balance; }
.lead { font-size: var(--text-lead); color: var(--grey); text-wrap: balance; }
.heading { font-size: var(--text-heading); font-weight: 700; line-height: 1.2; text-wrap: balance; }
.subheading { font-size: var(--text-small); font-weight: 700; }
/* A section's heading with a quiet meta line or an action at its right
   (Ui::Core::SectionHeading). The caller may set the space under it; by
   default it keeps the section's own gap (.spaced). */
.section-heading { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-4) var(--space-20); }
.section-heading.spaced { margin-bottom: var(--space-12); }
.section-heading-meta { font-size: var(--text-meta); color: var(--grey); }
.section-heading-action { flex: none; }
.section { display: flex; flex-direction: column; gap: var(--space-14); min-width: 0; }
.fine { font-size: var(--text-meta); color: var(--grey); text-wrap: pretty; max-width: var(--measure-text); }
.back { display: inline-flex; align-items: center; gap: var(--space-6); font-size: var(--text-small); font-weight: 700; text-decoration: none; color: var(--accent-text); align-self: flex-start; }
.tabs { display: flex; flex-wrap: wrap; gap: var(--space-6) 22px; font-size: var(--text-small); }
.tabs a { text-decoration: none; padding-bottom: var(--space-4); border-bottom: 2px solid transparent; color: var(--grey); }
.tabs a:hover { color: var(--ink); }
.tabs a[aria-current="page"] { border-color: var(--ink); color: var(--ink); font-weight: 700; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-12) var(--space-20); }
@media (max-width: 760px) {
  .desk { padding: var(--space-10); }
  .page { padding: var(--space-24) 18px var(--space-36); gap: var(--space-28); }
  .title { font-size: 30px; }
}

/* ---------- Buttons ---------- */
/* Main (the accent, one for each screen), plain (white), danger (red).
   Every button sits on a 3px ink edge and sinks onto it when pressed. */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-8); font: inherit; font-weight: 700; line-height: 1.5; padding: 9px 20px; border: 2px solid var(--ink); border-radius: var(--radius-button); background: var(--white); color: var(--ink); box-shadow: var(--edge-button); cursor: pointer; text-decoration: none; white-space: nowrap; }
.btn:hover { background: var(--desk); color: var(--ink); }
.btn:active { transform: translateY(3px); box-shadow: none; }
.btn[hidden] { display: none; }
.btn.main { background: var(--accent); color: var(--accent-on); }
.btn.main:hover { background: var(--accent-deep); }
.btn.danger { background: var(--red); color: var(--white); }
.btn.danger:hover { background: var(--red-deep); }
.btn.danger-words { color: var(--red); }
.btn.small { padding: 5px 14px; font-size: var(--text-small); }
.btn.large { padding: 14px 28px; font-size: var(--text-lead); }
.btn.square { padding: 0; width: 36px; height: 36px; }
.btn.square.small { width: 28px; height: 28px; }
/* On: a toggle that is on, or a button whose panel is open, stays pressed in */
.btn[aria-pressed="true"], .btn[aria-expanded="true"], .btn[aria-current="page"] { background: var(--accent-light); color: var(--accent-text); transform: translateY(3px); box-shadow: none; }
/* Not ready: no edge, a line-grey frame, grey words */
.btn:disabled, .btn[aria-disabled="true"] { background: transparent; border-color: var(--line); color: var(--grey); box-shadow: none; transform: none; cursor: not-allowed; }
.btn[aria-busy="true"] { cursor: progress; }
/* A toggle's glyph and its count (Ui::Core::ToggleButton) */
.btn .toggle-icon { display: inline-flex; flex: none; }
.btn .toggle-count { font-weight: 400; color: var(--grey); }
.text-action { display: inline-flex; align-items: center; gap: var(--space-6); font: inherit; font-weight: 700; color: var(--accent-text); text-decoration: none; background: none; border: 0; padding: 0; cursor: pointer; }
.text-action:hover { text-decoration: underline; text-underline-offset: 3px; }
.text-action.danger { color: var(--red); }
.text-action.small { font-size: var(--text-small); }
.text-action.meta-size { font-size: var(--text-meta); }
.text-action.tag-size { font-size: var(--text-tag); }
/* A quiet text action stands beside the one accent action without
   competing with it: grey, the accent under the pointer */
.text-action.quiet { color: var(--grey); font-weight: 600; }
.text-action.quiet:hover { color: var(--accent-text); }
/* A text action inside a row that is itself the link follows the row */
a:hover > .text-action, a:hover .text-action { text-decoration: underline; text-underline-offset: 3px; }
/* A text action that works after a press. Turbo turns its button off while
   it works: the words give way to the working words and the dots, in the
   same place, so the action keeps its width. */
.text-action.works { display: inline-grid; text-align: left; }
.text-action.works > * { grid-area: 1 / 1; }
.text-action.works > .working { visibility: hidden; font-weight: 400; }
.text-action.works:disabled { cursor: progress; text-decoration: none; }
.text-action.works:disabled > .ready { visibility: hidden; }
.text-action.works:disabled > .working { visibility: visible; }

/* Reading dots: something is working */
.dots { display: inline-flex; gap: 3px; margin-left: var(--space-4); }
.dots i { width: 4px; height: 4px; background: currentColor; animation: dots 1.2s infinite; }
.dots i:nth-child(2) { animation-delay: .2s; }
.dots i:nth-child(3) { animation-delay: .4s; }
@keyframes dots { 0%, 60%, 100% { opacity: .25; } 30% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .dots i { animation: none; opacity: 1; } }
.working { color: var(--grey); }
/* The dots alone, where a spinner stood (Ui::Core::Spinner): three sizes,
   in grey, white or the accent */
.dots.spinner { margin-left: 0; vertical-align: middle; }
.dots.small i { width: 3px; height: 3px; }
.dots.large i { width: 5px; height: 5px; }
.dots.grey { color: var(--grey); }
.dots.white { color: var(--white); }
.dots.accent { color: var(--accent-text); }

/* ---------- Choosing and switching ---------- */
/* A switch between views: one frame, one edge, the chosen part in the tint */
/* A row of joined toggles (Ui::Core::ViewToggleButton, joined: true) is a
   switcher too: the group that holds them takes the frame, and each joined
   toggle is one of its parts. A switcher of real radios (ToggleGroup) tints
   the part whose radio is checked. */
.switcher, [role="group"]:has(> .joined) { display: inline-flex; border: 2px solid var(--ink); border-radius: var(--radius-button); box-shadow: var(--edge-button); overflow: hidden; background: var(--white); }
.switcher > *, .joined { display: inline-flex; align-items: center; gap: var(--space-6); font: inherit; font-size: var(--text-small); font-weight: 600; border: 0; background: transparent; color: var(--ink); padding: 7px 14px; cursor: pointer; text-decoration: none; }
.switcher > * + *, .joined + .joined { border-left: 2px solid var(--ink); }
.switcher > *:hover, .joined:hover { background: var(--desk); }
.switcher > [aria-pressed="true"], .switcher > [aria-current="page"], .switcher > label:has(input:checked), .joined[aria-pressed="true"], .joined[aria-current="page"] { background: var(--accent-light); color: var(--accent-text); font-weight: 700; }
.switcher > label { position: relative; }
.switcher > label > input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.switcher > label:has(input:focus-visible) { outline: 2px solid var(--accent-frame); outline-offset: -4px; }

/* Chips are round tokens (.toks .tok), the house's own names. A chip row
   asks one question: its answers are .tok.choice. A saved thing in a list is
   a plain .tok with an x; a pick waiting in a form is .tok.picked. A token
   stands alone too, outside a .toks row. A control's only frame is edge
   grey, never line grey. */
.toks { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-8); }
.toks-label { font-size: var(--text-meta); color: var(--grey); margin-right: var(--space-4); }
.tok { display: inline-flex; align-items: center; gap: var(--space-6); max-width: 100%; padding: 4px 4px 4px 12px; background: var(--shade); border-radius: var(--radius-token); font-size: var(--text-small); font-weight: 700; color: var(--ink); }
.tok[hidden] { display: none; }
.tok:not(:has(.x)) { padding-right: 12px; }
.tok-label { flex: none; font-weight: 400; color: var(--grey); }
.tok-words { min-width: 0; overflow-wrap: anywhere; }
.tok-x-form { display: inline-flex; margin: 0; }
.tok.choice { padding: 4px 12px; border: 2px solid var(--edge); background: var(--white); font: inherit; font-size: var(--text-small); font-weight: 700; cursor: pointer; text-decoration: none; }
.tok.choice:hover { border-color: var(--ink); }
.tok.choice[aria-pressed="true"], .tok.choice[aria-current="page"], .tok.choice.on { border-color: var(--accent-frame); background: var(--accent-light); color: var(--accent-text); }
/* A chip row's second level asks about the first row's answer: its chips
   are smaller and unfilled. A muted chip is the quietest at its level. */
.tok.choice.small { padding: 2px 10px; font-size: var(--text-tag); background: transparent; }
.tok.choice.small[aria-pressed="true"], .tok.choice.small[aria-current="page"], .tok.choice.small.on { background: var(--accent-light); }
.tok.muted { color: var(--grey); font-weight: 400; }
/* A chip row (Ui::Core::ChipRow): a question and its answers. Below 640 px
   the label stands above the answers, so a phone gives the answers its whole
   width; from 640 px it stands in its own 96 px column beside them. */
.chip-row { display: flex; flex-direction: column; gap: var(--space-6); min-width: 0; }
.chip-row > .toks-label { margin: 0; }
@media (min-width: 640px) {
  .chip-row { flex-direction: row; align-items: flex-start; gap: var(--space-8); }
  .chip-row > .toks-label { flex: none; width: 96px; padding-top: 6px; }
  .chip-row > .toks { flex: 1 1 0; min-width: 0; }
}
.tok.picked { background: var(--accent-light); color: var(--accent-text); white-space: nowrap; }
.tok.picked .tok-label { color: inherit; opacity: 0.75; }
.tok .x { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: var(--radius-round); color: inherit; border: 0; background: none; padding: 0; cursor: pointer; }
.tok .x:hover { background: var(--line); }

/* On and off */
.toggle { display: inline-flex; align-items: center; gap: var(--space-10); }
.switch { position: relative; flex: none; width: 44px; height: 26px; padding: 0; background: var(--shade); border: 2px solid var(--ink); border-radius: 13px; cursor: pointer; }
.switch::after { content: ""; position: absolute; top: 2px; left: 2px; box-sizing: border-box; width: 18px; height: 18px; background: var(--white); border: 2px solid var(--ink); border-radius: var(--radius-round); }
.switch[aria-checked="true"] { background: var(--accent); }
.switch[aria-checked="true"]::after { left: 20px; }

/* Boxes */
.check { display: inline-flex; align-items: center; gap: var(--space-8); cursor: pointer; }
.check input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.box { width: 20px; height: 20px; flex: 0 0 20px; border: 2px solid var(--ink); border-radius: var(--radius-check); background: var(--white); display: inline-flex; align-items: center; justify-content: center; color: var(--white); }
.box.round { border-radius: var(--radius-round); }
.check input:checked + .box { background: var(--accent); border-color: var(--accent-frame); color: var(--accent-on); }
.check input:checked + .box.round { background: var(--white); border-color: var(--ink); box-shadow: inset 0 0 0 3px var(--white), inset 0 0 0 10px var(--accent); }
.check input:not(:checked) + .box .glyph { visibility: hidden; }
.check input:focus-visible + .box { outline: 2px solid var(--accent-frame); outline-offset: 2px; }

/* Option cards (.levels, the house's name): one choice from a few, each
   with a sub-line. The chosen card is a 2px accent frame on the tint. */
.levels { display: flex; flex-wrap: wrap; gap: var(--space-8); }
.levels > * { display: flex; flex-direction: column; flex: 0 1 220px; padding: 10px 14px; border: 2px solid var(--edge); border-radius: var(--radius-button); background: var(--white); color: var(--ink); font-weight: 700; text-decoration: none; cursor: pointer; }
.levels > *:hover { border-color: var(--ink); color: var(--ink); }
.levels > .on, .levels > [aria-checked="true"] { border-color: var(--accent-frame); background: var(--accent-light); color: var(--accent-text); }
.levels .sub { font-size: var(--text-meta); font-weight: 400; color: var(--grey); }

/* Fields */
.field { display: flex; flex-direction: column; gap: var(--space-6); font-weight: 600; max-width: 420px; }
.input { font: inherit; font-weight: 400; color: var(--ink); background: var(--white); border: 2px solid var(--edge); border-radius: var(--radius-button); padding: 9px 12px; width: 100%; }
.input:focus { border-color: var(--accent-frame); outline: 2px solid var(--accent-frame); outline-offset: 1px; }
.input[aria-invalid="true"] { border-color: var(--red); }
textarea.input { min-height: 96px; resize: vertical; }
/* The height of a rich text field, small, medium or large (RichTextArea) */
.input.rows-small { min-height: 128px; }
.input.rows-medium { min-height: 192px; }
.input.rows-large { min-height: 256px; }
.hint { font-weight: 400; font-size: var(--text-small); color: var(--grey); text-wrap: pretty; }
.field-error { font-weight: 400; font-size: var(--text-small); color: var(--red); text-wrap: pretty; }
.field-optional { font-weight: 400; color: var(--grey); }
.field-label { font-weight: 600; }
/* A form (Ui::Core::Forms::*): its fields on a grid of six columns from
   640 px, its fields stacked down the page below that, and its actions
   under them. A field in the grid takes the width of its columns, so the
   grid lifts the field's own measure. A field says how many columns it
   takes with the caller's sm:col-span-* class. */
.form { display: flex; flex-direction: column; gap: var(--space-24); min-width: 0; }
.form > form { display: flex; flex-direction: column; gap: var(--space-24); margin: 0; }
.form-head { display: flex; flex-direction: column; gap: var(--space-4); padding-bottom: var(--space-14); border-bottom: 1px solid var(--line); }
.form-head p { color: var(--grey); text-wrap: pretty; max-width: var(--measure-text); }
.form-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-20) var(--space-24); }
.form-grid > .field { max-width: none; }
@media (min-width: 640px) { .form-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
/* A field's share of a six-column grid from 640 px (ColSpannable): two,
   three or all six columns. Below 640 px it takes the whole row. */
@media (min-width: 640px) {
  .span-2 { grid-column: span 2 / span 2; }
  .span-3 { grid-column: span 3 / span 3; }
  .span-6 { grid-column: span 6 / span 6; }
}
.form-body { display: flex; flex-direction: column; gap: var(--space-20); }
.form-body.ruled { padding-bottom: var(--space-24); border-bottom: 1px solid var(--line); }
.form-sections { display: flex; flex-direction: column; gap: var(--space-36); }
.form-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-12) var(--space-20); }
.form-actions.end { justify-content: flex-end; }
.form-actions.ruled { padding-top: var(--space-20); border-top: 1px solid var(--line); }
/* A form's save button: Turbo turns it off while the form sends, and it
   keeps its own look, its words giving way to the working words and dots */
.btn.main.works:disabled { background: var(--accent); border-color: var(--ink); color: var(--accent-on); box-shadow: var(--edge-button); cursor: progress; }
/* A select: a field with the caret at its right edge */
.select { position: relative; display: block; }
.select > select.input { appearance: none; -webkit-appearance: none; padding-right: 38px; background-image: none; cursor: pointer; }
.select > .glyph { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); pointer-events: none; color: var(--grey); }
/* A field with a sign before its words, such as a currency, and a search box
   with the search glyph there */
.prefixed { position: relative; display: block; }
.prefixed > .prefix { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); display: inline-flex; color: var(--grey); pointer-events: none; }
.prefixed > .input { padding-left: 30px; }
.prefixed > .prefix:has(.glyph) + .input { padding-left: 38px; }
/* A file field: the picker's button is the small plain button */
.file-input { font: inherit; font-size: var(--text-small); color: var(--grey); max-width: 100%; }
.file-input::file-selector-button { font: inherit; font-weight: 700; margin-right: var(--space-12); padding: 5px 14px; border: 2px solid var(--ink); border-radius: var(--radius-button); background: var(--white); color: var(--ink); cursor: pointer; }
.file-input::file-selector-button:hover { background: var(--desk); }
.file-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-12); }
.file-row > img { width: 48px; height: 48px; object-fit: cover; border-radius: var(--radius-small-tile); }
/* A group of boxes or round boxes under one question */
.choices { margin: 0; padding: 0; border: 0; min-width: 0; display: flex; flex-direction: column; gap: var(--space-8); }
.choices > legend, .choices > .field-label { padding: 0; margin-bottom: var(--space-4); font-weight: 600; }
.check input:indeterminate + .box { background: var(--accent); border-color: var(--accent-frame); color: var(--accent-on); }
.check input:indeterminate + .box .glyph { visibility: hidden; }
.check input:disabled + .box { border-color: var(--line); background: var(--desk); }
/* Option cards that hold a real round box: the chosen card follows its
   checked box, and the box itself hides under the card */
.levels > label { position: relative; }
.levels > label > input[type="radio"] { position: absolute; opacity: 0; width: 1px; height: 1px; }
.levels > label:has(input:checked) { border-color: var(--accent-frame); background: var(--accent-light); color: var(--accent-text); }
.levels > label:has(input:focus-visible) { outline: 2px solid var(--accent-frame); outline-offset: 2px; }
/* A switch that is a real checkbox (Ui::Core::Forms::ToggleSwitch): the
   box hides, and the switch beside it follows its state */
.switch-input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.switch-input:checked + .switch { background: var(--accent); }
.switch-input:checked + .switch::after { left: 20px; }
.switch-input:focus-visible + .switch { outline: 2px solid var(--accent-frame); outline-offset: 2px; }
label.toggle { cursor: pointer; }
/* A select worn as a chip, for a filter inside a dense row: the chip shows
   the choice, and the real select lies unseen over it */
.inline-select { position: relative; display: inline-flex; align-self: center; }
.inline-select > select { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; appearance: none; }
.inline-select > .tok.choice { gap: var(--space-4); padding-right: 8px; }
.inline-select:hover > .tok.choice { border-color: var(--ink); }
.inline-select:focus-within > .tok.choice { outline: 2px solid var(--accent-frame); outline-offset: 2px; }
/* A chart with the select that picks its metric above it (ChartMetricPicker) */
.metric-picker { display: grid; gap: var(--space-12); min-width: 0; }
/* A list to pick one from, under a search box (SearchSelect,
   SearchableSelect): it drops from a field that looks like a select */
.picker { position: relative; }
.picker-button { display: flex; align-items: center; justify-content: space-between; gap: var(--space-8); text-align: left; cursor: pointer; }
.picker-button > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picker-menu { position: absolute; left: 0; right: 0; z-index: 50; margin-top: var(--space-4); display: flex; flex-direction: column; gap: var(--space-6); min-width: 0; }
.picker-menu[hidden] { display: none; }
.listbox { list-style: none; margin: 0; padding: 0; max-height: 256px; overflow-y: auto; overflow-x: hidden; }
.listbox > li { display: flex; align-items: center; justify-content: space-between; gap: var(--space-8); padding: 8px 12px; border-radius: var(--radius-pill); color: var(--ink); cursor: pointer; overflow-wrap: anywhere; user-select: none; }
.listbox > li:hover, .listbox > li[data-highlighted] { background: var(--desk); }
.listbox > li[aria-selected="true"] { background: var(--accent-light); color: var(--accent-text); font-weight: 700; }
.listbox > li[aria-disabled="true"] { color: var(--grey); cursor: default; background: none; }
.listbox > li[hidden] { display: none; }
.listbox-note { padding: 8px 12px; font-size: var(--text-small); color: var(--grey); }
/* A filter in use: its button keeps the tint, so the filters that narrow
   the page show at a glance */
.btn.in-use { background: var(--accent-light); color: var(--accent-text); border-color: var(--accent-frame); }
/* A menu whose links each choose one answer; the chosen one is tinted */
.menu > [aria-current="true"], .menu > li > [aria-current="true"] { background: var(--accent-light); color: var(--accent-text); font-weight: 700; justify-content: space-between; }
.menu.wide { width: 320px; max-height: 320px; overflow-y: auto; }
@media (max-width: 639px) { .menu.wide { position: fixed; left: 16px; right: 16px; width: auto; } }
.menu.dropdown.start { right: auto; left: 0; }
/* The short menu of a pick in a form (Ui::Core::ChoiceChip): its script
   fixes it to the window under its button, so a box that clips cannot cut
   it. Each choice has its detail at the right. */
.menu.chip-menu { z-index: 50; min-width: 224px; }
.menu.chip-menu > button { justify-content: space-between; }
.menu.checks { min-width: 224px; }
.menu.checks > label { display: flex; align-items: center; gap: var(--space-10); padding: 6px 12px; border-radius: var(--radius-pill); cursor: pointer; }
.menu.checks > label:hover { background: var(--desk); }
/* A search box at the top of a menu, and the menu's list under it, which
   scrolls when it is long */
.menu-search { padding: var(--space-2) 0 var(--space-6); }
.menu-scroll { display: flex; flex-direction: column; max-height: 192px; overflow-y: auto; }
.menu-scroll > button, .menu-scroll > a { display: block; width: 100%; padding: 8px 12px; border: 0; background: none; font: inherit; color: var(--ink); text-align: left; text-decoration: none; border-radius: var(--radius-pill); cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu-scroll > button:hover, .menu-scroll > a:hover { background: var(--desk); }

/* The browser check before a form sends (Ui::Core::Forms::BotProtection).
   Holding a field: a line on top says what the check does, its two sets of
   words in one place so the line keeps its height; the widget's place
   keeps the widget's 65 px, and the amber panel lies over it when the
   check is stuck. Holding the button: the widget, then grey lines. */
.check-line { display: grid; margin-bottom: var(--space-12); font-size: var(--text-small); color: var(--grey); text-wrap: balance; }
.check-line > * { grid-area: 1 / 1; }
.check-line > .check-ready { color: var(--green); }
.check-line > .invisible { visibility: hidden; }
.widget-place { position: relative; height: 65px; margin-bottom: var(--space-28); }
.widget-stuck { position: absolute; inset: 0; }
.widget-stuck > .problem { height: 100%; align-items: center; flex-wrap: nowrap; padding: 0 var(--space-12); }
.widget-stuck > .problem > p { flex: 1 1 auto; min-width: 0; margin: 0; font-size: var(--text-small); text-wrap: balance; }
.held-field { min-width: 0; margin: 0; padding: 0; border: 0; }
.held-field-place { padding-top: var(--space-24); }
.bot-check { display: flex; flex-direction: column; gap: var(--space-6); margin-top: var(--space-12); }
.bot-check > .hint[hidden] { display: none; }

/* A tile that opens one page */
.link-tile { display: flex; flex-direction: column; gap: var(--space-2); max-width: 260px; padding: 14px 16px; border: 2px solid var(--ink); border-radius: var(--radius-button); background: var(--white); box-shadow: var(--edge-button); color: var(--ink); text-decoration: none; }
.link-tile:hover { background: var(--desk); }
.link-tile:active { transform: translateY(3px); box-shadow: none; }
.link-tile b, .link-tile .sub { text-wrap: balance; }
.link-tile .sub { font-size: var(--text-small); color: var(--grey); }

/* ---------- Menus ---------- */
.menu { list-style: none; margin: 0; padding: var(--space-6); background: var(--white); border: 2px solid var(--ink); border-radius: var(--radius-button); box-shadow: var(--edge-dialog); min-width: 240px; }
.menu > li > *, .menu > a, .menu > button, .menu > form > button, .menu > .menu-item > form > button { display: flex; align-items: center; gap: var(--space-10); width: 100%; padding: 8px 12px; border: 0; background: none; font: inherit; color: var(--ink); text-align: left; text-decoration: none; border-radius: var(--radius-pill); cursor: pointer; }
.menu > li > *:hover, .menu > a:hover, .menu > button:hover, .menu > form > button:hover, .menu > .menu-item > form > button:hover { background: var(--desk); }
.menu > li.danger { margin-top: var(--space-6); padding-top: var(--space-6); border-top: 1px solid var(--line); }
.menu > li.danger > *, .menu > .danger, .menu > form > .danger { color: var(--red); font-weight: 700; }
/* A menu that drops from its button (Ui::Core::OptionsMenu), its holder, a
   short menu, one floated in the top layer, and the rule between groups. A
   caller's plain links, buttons and forms are the items as they stand. */
.menu-holder { position: relative; flex: none; }
.menu.dropdown { position: absolute; right: 0; z-index: 50; margin-top: var(--space-4); }
.menu.narrow { min-width: 160px; }
.menu[popover] { inset: auto; margin: 0; }
.menu > form, .menu > .menu-item > form { margin: 0; }
.menu > .menu-rule { margin: var(--space-6) 0; border-top: 1px solid var(--line); }

/* A small i that opens a key to every number on a page (Ui::Core::InfoKey):
   a grey glyph that turns to the accent while its key is open. The key is
   a menu panel in the top layer, one column on a phone, two from 640 px
   and three from 1024 px, never wider than the window. */
.info-key { position: relative; display: inline-flex; }
.info-key-button { display: inline-flex; align-items: center; justify-content: center; padding: 6px; margin: -6px; border: 0; background: none; color: var(--grey); cursor: pointer; }
.info-key-button:hover, .info-key-button[aria-expanded="true"] { color: var(--accent-text); }
.info-key-panel { inset: auto; margin: 0; padding: var(--space-20); width: 704px; max-width: calc(100vw - 16px); overflow-y: auto; background: var(--white); border: 2px solid var(--ink); border-radius: var(--radius-button); box-shadow: var(--edge-dialog); color: var(--ink); text-align: left; font-family: var(--font-sans); font-size: var(--text-body); font-weight: 400; text-transform: none; letter-spacing: normal; white-space: normal; }
.info-key-section { margin-top: var(--space-8); }
.info-key-section.ruled { margin-top: var(--space-12); padding-top: var(--space-12); border-top: 1px solid var(--line); }
.info-key-heading { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2) var(--space-8); font-size: var(--text-meta); font-weight: 700; }
.info-key-heading .muted { font-weight: 400; }
.info-key-entries { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-12) var(--space-24); margin: var(--space-8) 0 0; }
@media (min-width: 640px) { .info-key-entries { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .info-key-entries { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.info-key-entries > * { min-width: 0; }
.info-key-entries > .wide { grid-column: 1 / -1; }
.info-key-entries dt { font-size: var(--text-key); font-weight: 600; color: var(--grey); }
.info-key-entries dd { margin: var(--space-2) 0 0; font-size: var(--text-meta); text-wrap: pretty; }
.info-key-formula { display: block; margin-top: var(--space-2); font-family: var(--font-mono); font-size: var(--text-key); color: var(--grey); }
.info-key-foot { margin-top: var(--space-12); padding-top: var(--space-12); border-top: 1px solid var(--line); font-size: var(--text-meta); color: var(--grey); text-wrap: pretty; }
/* A panel that opens above its trigger (Ui::Core::Popover) */
.popover { position: absolute; left: 0; bottom: 100%; z-index: 40; width: 288px; max-width: calc(100vw - 16px); margin-bottom: var(--space-8); padding: var(--space-14) var(--space-20); background: var(--white); border: 2px solid var(--ink); border-radius: var(--radius-button); box-shadow: var(--edge-dialog); }
.popover-title { font-weight: 700; margin-bottom: var(--space-6); }
.popover-body { font-size: var(--text-small); color: var(--grey); text-wrap: pretty; }
/* A word that shows on hover (Ui::Core::Tooltip, data-tip): ink words on
   white in an ink frame, the menu's own look */
.tooltip[data-tip]::before { background: var(--white); color: var(--ink); border: 2px solid var(--ink); border-radius: var(--radius-pill); box-shadow: var(--edge-button); font-family: var(--font-sans); font-size: var(--text-meta); font-weight: 600; padding: 4px 10px; }
.tooltip[data-tip]::after { background: var(--ink); }
/* Where the word stands and when it shows: hidden until the pointer rests
   on the thing, then above it (the default), below it, or beside it. */
.tooltip { position: relative; display: inline-block; }
.tooltip::before, .tooltip::after { position: absolute; z-index: 50; opacity: 0; transition: opacity 200ms; pointer-events: none; }
.tooltip::before { content: attr(data-tip); white-space: nowrap; }
.tooltip::after { content: ""; width: 8px; height: 8px; }
.tooltip:hover::before, .tooltip:hover::after { opacity: 1; }
.tooltip::before, .tooltip-top::before { bottom: 100%; left: 50%; transform: translateX(-50%); margin-bottom: 12px; }
.tooltip::after, .tooltip-top::after { bottom: 100%; left: 50%; transform: translateX(-50%) rotate(45deg); margin-bottom: 8px; }
.tooltip-bottom::before { top: 100%; bottom: auto; left: 50%; transform: translateX(-50%); margin: 4px 0 0; }
.tooltip-bottom::after { top: 100%; bottom: auto; left: 50%; transform: translateX(-50%) rotate(45deg); margin: -4px 0 0; }
.tooltip-left::before { right: 100%; top: 50%; bottom: auto; left: auto; transform: translateY(-50%); margin: 0 4px 0 0; }
.tooltip-left::after { right: 100%; top: 50%; bottom: auto; left: auto; transform: translateY(-50%) rotate(45deg); margin: 0 -4px 0 0; }
.tooltip-right::before { left: 100%; top: 50%; bottom: auto; transform: translateY(-50%); margin: 0 0 0 4px; }
.tooltip-right::after { left: 100%; top: 50%; bottom: auto; transform: translateY(-50%) rotate(45deg); margin: 0 0 0 -4px; }
@media (prefers-reduced-motion: reduce) { .tooltip::before, .tooltip::after { transition: none; } }
/* The settings list (Ui::Core::SettingsMenu): a row per page, ruled. Its
   inset is on the list, so a row's hover and the rules share one width. */
.settings-menu { list-style: none; margin: 0 -12px; padding: 0; }
.settings-menu > li + li { border-top: 1px solid var(--line); }
.settings-menu-row { display: flex; align-items: center; gap: var(--space-12); padding: 12px; color: var(--ink); text-decoration: none; }
a.settings-menu-row:hover { background: var(--desk); }
.settings-menu-glyph, .settings-menu-arrow { display: inline-flex; flex: none; color: var(--grey); }
a.settings-menu-row:hover .settings-menu-glyph, a.settings-menu-row:hover .settings-menu-arrow { color: var(--accent-text); }
.settings-menu-text { flex: 1 1 auto; min-width: 0; }
.settings-menu-label { display: flex; align-items: baseline; gap: var(--space-8); min-width: 0; }
.settings-menu-name { font-weight: 600; }
.settings-menu-label > .muted, .settings-menu-text > .sub { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.settings-menu-text > .sub { display: block; font-size: var(--text-small); color: var(--grey); }

/* ---------- Messages ---------- */
/* Good news is one quiet grey line under the title. It never gets a fill. */
.flash { font-size: var(--text-meta); color: var(--grey); text-wrap: balance; max-width: var(--measure-text); }
.saved { display: inline-flex; align-items: center; gap: var(--space-6); font-size: var(--text-meta); color: var(--grey); transition: opacity 0.5s; }
.saved[data-faded] { opacity: 0; }
/* A card's cited sources, loaded into their frame on the first open
   (Ui::Core::Insights::CitedSourcesFrame); a long card's words are cut to
   144 px while they say data-clamped */
.cited-sources { display: flex; flex-direction: column; gap: var(--space-8); padding: 0 var(--space-14) var(--space-14); }
.cited-sources[hidden] { display: none; }
[data-insight-expand-target="content"][data-clamped] { max-height: 144px; overflow: hidden; }
/* A problem: red when something is broken, amber when it waits on a person */
.problem { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-12) var(--space-20); padding: 14px 16px; background: var(--red-light); border-radius: var(--radius-button); color: var(--red); }
.problem.wait { background: var(--amber-light); color: var(--amber); }
.problem > div { flex: 1 1 260px; min-width: 0; }
.problem b { display: block; font-weight: 700; text-wrap: balance; }
.problem p { margin-top: var(--space-2); text-wrap: pretty; max-width: var(--measure-text); }
.problem > div > p:only-child { margin-top: 0; }
.problem .btn { flex: none; }
/* The messages at the top of a page, with the page's gap under them */
.messages { margin-bottom: var(--space-24); }
/* A message the reader can close (Ui::Core::Flash): the close stays at the
   right edge beside the words at every width, and the words wrap */
.closable { flex-wrap: nowrap; }
.closable > p { flex: 1 1 auto; min-width: 0; margin-top: 0; }
.closable > .btn { flex: none; margin-left: auto; }
/* A standing note: a fact a person must keep seeing, with nothing wrong.
   Not .note: the marketing home page's pile of notifications owns it. */
.standing-note { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-12) var(--space-20); padding: 14px 16px; background: var(--desk); border-radius: var(--radius-button); color: var(--ink); }
.standing-note > div { flex: 1 1 260px; min-width: 0; }
.standing-note b { display: block; font-weight: 700; }
.standing-note p { margin-top: var(--space-2); color: var(--grey); text-wrap: pretty; }
.form-errors { padding: 14px 16px; background: var(--red-light); border-radius: var(--radius-button); color: var(--red); }
.form-errors ul { margin: var(--space-6) 0 0; padding-left: 20px; }
/* An empty place */
.empty { display: flex; flex-direction: column; gap: var(--space-12); align-items: flex-start; padding: 28px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.empty b { font-weight: 600; }
/* A panel that asks for a step, such as a plan upgrade */
.ask { display: flex; flex-direction: column; gap: var(--space-12); align-items: flex-start; padding: 20px 22px; background: var(--white); border: 2px solid var(--ink); border-radius: var(--radius-button); max-width: var(--measure-text); }
.ask p { color: var(--grey); text-wrap: pretty; }
/* The way to delete a thing, at the foot of its page */
.danger-zone { display: flex; flex-direction: column; gap: var(--space-12); align-items: flex-start; padding-top: var(--space-20); border-top: 1px solid var(--line); }
.danger-zone p { color: var(--grey); max-width: var(--measure-text); text-wrap: pretty; }
/* The one shared delete confirm */
.dialog { background: var(--paper); border: 2px solid var(--ink); border-radius: var(--radius-panel); box-shadow: var(--edge-dialog); padding: var(--space-28); display: flex; flex-direction: column; gap: var(--space-14); max-width: 460px; }
.dialog p { color: var(--grey); text-wrap: pretty; }
/* Progress */
.progress { display: block; box-sizing: border-box; height: 14px; border: 2px solid var(--ink); border-radius: 7px; background: var(--white); overflow: hidden; max-width: 420px; }
.progress > span { display: block; height: 100%; background: var(--accent); }
.progress.done > span { background: var(--green); }
.progress.failed > span { background: var(--red); }

/* ---------- Pills, badges and score words ---------- */
/* Pills are for problems. In a column of statuses, the good state may be a
   green pill, so it reads as a state beside the others. */
.status { display: inline-flex; align-items: center; gap: var(--space-6); padding: 1px 8px; border-radius: var(--radius-pill); font-size: var(--text-meta); font-weight: 700; white-space: nowrap; }
.status.warning { background: var(--amber-light); color: var(--amber); }
.status.danger { background: var(--red-light); color: var(--red); }
.status.good { background: var(--green-light); color: var(--green); }
.status.quiet { background: transparent; color: var(--grey); padding-left: 0; font-weight: 400; }
/* A pill that is still an action (Reconnect, Update key): a link or a form's
   button around the pill, whose words underline under the pointer. */
.status-action { display: inline-flex; margin: 0; padding: 0; border: 0; background: none; font: inherit; color: inherit; text-decoration: none; cursor: pointer; }
.status-action:hover .status { text-decoration: underline; text-underline-offset: 3px; }
.status .status-time { font-weight: 400; }
.badge { display: inline-flex; align-items: center; background: var(--accent); color: var(--accent-on); border-radius: var(--radius-pill); padding: 0 7px; font-size: var(--text-tag); font-weight: 700; }
/* A step of the score scale: its words on its fill. data-step is -5 to 5. */
.score { display: inline-flex; align-items: center; padding: 1px 7px; border-radius: var(--radius-pill); font-size: var(--text-meta); font-weight: 700; white-space: nowrap; }
.score-words { font-weight: 700; }
/* A score in a column of scores (Ui::Core::ScoreBadge): one width, so the
   column lines up */
.score.score-badge { min-width: 40px; justify-content: center; }
[data-step="5"] { --step-text: var(--green-deep); --step-fill: var(--score-fill-good5); --step-bar: var(--score-bar-good5); }
[data-step="4"] { --step-text: var(--green-deep); --step-fill: var(--score-fill-good4); --step-bar: var(--score-bar-good4); }
[data-step="3"] { --step-text: var(--green); --step-fill: var(--score-fill-good3); --step-bar: var(--score-bar-good3); }
[data-step="2"] { --step-text: var(--green); --step-fill: var(--score-fill-good2); --step-bar: var(--score-bar-good2); }
[data-step="1"] { --step-text: var(--green); --step-fill: var(--score-fill-good1); --step-bar: var(--score-bar-good1); }
[data-step="0"] { --step-text: var(--grey); --step-fill: var(--score-fill-even); --step-bar: var(--score-bar-even); }
[data-step="-1"] { --step-text: var(--amber); --step-fill: var(--score-fill-bad1); --step-bar: var(--score-bar-bad1); }
[data-step="-2"] { --step-text: var(--amber); --step-fill: var(--score-fill-bad2); --step-bar: var(--score-bar-bad2); }
[data-step="-3"] { --step-text: var(--orange); --step-fill: var(--score-fill-bad3); --step-bar: var(--score-bar-bad3); }
[data-step="-4"] { --step-text: var(--red); --step-fill: var(--score-fill-bad4); --step-bar: var(--score-bar-bad4); }
[data-step="-5"] { --step-text: var(--red-deep); --step-fill: var(--score-fill-bad5); --step-bar: var(--score-bar-bad5); }
.score[data-step] { color: var(--step-text); background: var(--step-fill); }
.score-words[data-step] { color: var(--step-text); }
.status[data-step] { color: var(--step-text); background: var(--step-fill); }

/* ---------- Layout (Ui::Core::Layout::*) ---------- */
/* A white panel that holds a block of the page, in a line-grey frame. Flush
   panels carry no padding of their own; open ones have no frame or fill. */
.panel { display: block; width: 100%; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-button); padding: var(--space-14) var(--space-14); min-width: 0; }
@media (min-width: 640px) { .panel { padding: var(--space-24); } }
.panel.flush { padding: 0; }
.panel.open { background: none; border: 0; border-radius: 0; }
/* A stack of blocks with the page's gap between them */
.stack { display: flex; flex-direction: column; gap: var(--space-24); min-width: 0; }
@media (min-width: 768px) { .stack { gap: var(--space-36); } }
/* The page's side inset, for a block that sits flush in a panel */
.inset-x { display: block; width: 100%; padding-inline: var(--space-14); }
@media (min-width: 640px) { .inset-x { padding-inline: var(--space-24); } }
/* A heading over a panel's block, with a quiet meta line at its right */
.panel-heading { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-4) var(--space-20); }
.panel-heading.centered { justify-content: center; text-align: center; }
.panel-heading.spaced { margin-bottom: var(--space-14); }
.panel-heading > .heading { font-size: var(--text-lead); }
.panel-heading-meta { font-size: var(--text-meta); color: var(--grey); }
/* A titled block of the page, and a form's section: its title and words at
   the left, its fields at the right from 768 px */
.titled-section { display: flex; flex-direction: column; min-width: 0; }
.titled-section > .heading { margin-bottom: var(--space-14); }
.titled-section > .heading:has(+ .fine) { margin-bottom: var(--space-4); }
.titled-section > .fine { margin-bottom: var(--space-14); }
.form-section { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-28); }
.form-section.ruled { border-top: 1px solid var(--line); padding-top: var(--space-28); }
.form-section-title { font-size: var(--text-row); font-weight: 600; }
.form-section-words { margin-top: var(--space-4); font-size: var(--text-small); color: var(--grey); text-wrap: pretty; }
@media (min-width: 768px) {
  .form-section { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .form-section > .form-section-fields { grid-column: span 2 / span 2; }
}
/* The trail of pages above a page's title */
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4) var(--space-6); margin-bottom: var(--space-24); font-size: var(--text-small); }
.crumbs a { color: var(--grey); text-decoration: none; white-space: nowrap; }
.crumbs a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.crumbs-sep { color: var(--line); }
.crumbs-here { font-weight: 600; color: var(--ink); }
/* A page's header: the reserved eyebrow line, the title with its badge, the
   lead, and the page's own actions at the right from 640 px */
.page-header { display: flex; flex-direction: column; gap: var(--space-14); padding-bottom: var(--space-14); margin-bottom: var(--space-24); border-bottom: 1px solid var(--line); }
.page-header-row { display: flex; flex-direction: column; gap: var(--space-14); }
.page-header-main { min-width: 0; }
.eyebrow { display: block; min-height: 20px; margin-bottom: var(--space-4); font-size: var(--text-meta); font-weight: 600; color: var(--grey); }
.page-header-title { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-8); }
.page-header .lead { margin-top: var(--space-8); max-width: var(--measure-text); }
.page-header-actions { display: flex; flex: none; flex-wrap: wrap; align-items: center; gap: var(--space-8); }
@media (min-width: 640px) {
  .page-header-row { flex-direction: row; align-items: flex-end; justify-content: space-between; }
  .page-header-title { flex-direction: row; align-items: baseline; gap: var(--space-12); }
}
/* A page's one slim line: its name, a few words, a note and its actions */
.page-line { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-8) var(--space-14); margin-bottom: var(--space-14); }
@media (min-width: 640px) { .page-line { min-height: 32px; } }
.page-line-title { margin: 0; font-size: var(--text-small); font-weight: 700; color: var(--ink); text-wrap: balance; }
.page-line-words { margin: 0; font-size: var(--text-meta); color: var(--grey); text-wrap: balance; }
.page-line-note { margin: 0 0 0 auto; font-size: var(--text-meta); color: var(--grey); white-space: nowrap; }
.page-line-actions { display: flex; align-items: stretch; gap: var(--space-8); width: 100%; }
.page-line-action { flex: 1 1 auto; min-width: 0; }
@media (min-width: 640px) {
  .page-line-actions { width: auto; gap: var(--space-12); }
  .page-line-actions.end { margin-left: auto; }
  .page-line-action { flex: none; }
}
/* A tab strip: the page's tabs over a panel, or over a ruled line when bare */
.tab-strip { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-14); padding: var(--space-10) var(--space-14) 0; background: var(--white); border: 1px solid var(--line); border-bottom: 0; border-radius: var(--radius-button) var(--radius-button) 0 0; }
.tab-strip.bare { background: none; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; }
@media (min-width: 640px) { .tab-strip { padding-inline: var(--space-24); } }
.tabs .tab-count { margin-left: var(--space-4); font-weight: 400; color: var(--grey); }
.tabs > button { font: inherit; padding: 0 0 var(--space-4); border: 0; border-bottom: 2px solid transparent; background: none; color: var(--grey); cursor: pointer; white-space: nowrap; }
.tabs > button:hover { color: var(--ink); }
.tabs > button[aria-selected="true"] { border-color: var(--ink); color: var(--ink); font-weight: 700; }
.tabs.ruled { border-bottom: 1px solid var(--line); }
/* A small quiet line of facts */
.meta-line { font-size: var(--text-meta); color: var(--grey); }
/* A row of filters, ruled above when it follows a block */
.filter-bar { min-width: 0; }
.filter-bar.ruled { border-top: 1px solid var(--line); padding-top: var(--space-14); margin-top: var(--space-14); }
.filter-bar > .toks { gap: var(--space-8); }
/* A block that folds open from its one header button (Ui::Core::Layout::FoldBlock) */
.fold-block { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-button); overflow: hidden; }
.fold-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4) var(--space-12); width: 100%; padding: var(--space-12) var(--space-14); border: 0; background: none; font: inherit; color: var(--ink); text-align: left; cursor: pointer; }
.fold-head:hover { background: var(--desk); }
@media (min-width: 640px) { .fold-head { flex-wrap: nowrap; } }
.fold-title { display: flex; flex: 1 1 0; align-items: center; gap: var(--space-12); min-width: 0; }
.fold-logo { flex: none; display: inline-flex; color: var(--grey); }
.fold-words { display: block; flex: 1 1 0; min-width: 0; }
.fold-name { display: block; font-weight: 600; }
.fold-details { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2) var(--space-12); margin-top: var(--space-2); font-size: var(--text-meta); color: var(--grey); }
.fold-status { order: 99; flex-basis: 100%; padding-left: 32px; }
@media (min-width: 640px) { .fold-status { order: 0; flex-basis: auto; flex-shrink: 0; padding-left: 0; max-width: 45%; text-align: right; } }
.fold-control { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 24px; height: 24px; border: 2px solid var(--edge); border-radius: var(--radius-pill); background: var(--white); color: var(--grey); }
.fold-head:hover .fold-control { border-color: var(--ink); color: var(--ink); }
.fold-control > [hidden] { display: none; }
.fold-body { padding-left: 32px; border-top: 1px solid var(--line); }
.fold-body > * + * { border-top: 1px solid var(--line); }
/* Pictures of a person or an account, square in whole sizes. The initials
   of one with no picture take one of the chart colors' tints, by the
   person, so two people tell apart. */
.pic { display: inline-flex; flex: none; align-items: center; justify-content: center; object-fit: contain; overflow: hidden; }
.pic.photo { object-fit: cover; }
.pic.logo { border-radius: var(--radius-small-tile); background: var(--shade); }
.pic.gap { margin-right: var(--space-12); }
.pic-16 { width: 16px; height: 16px; }
.pic-24 { width: 24px; height: 24px; }
.pic-32 { width: 32px; height: 32px; }
.pic-40 { width: 40px; height: 40px; }
.pic-48 { width: 48px; height: 48px; }
.pic-64 { width: 64px; height: 64px; }
.pic-96 { width: 96px; height: 96px; }
.pic-heading { width: 32px; height: 32px; }
@media (min-width: 640px) { .pic-heading { width: 40px; height: 40px; } }
.initials { background: color-mix(in srgb, var(--series, var(--accent)) 18%, var(--white)); color: var(--ink); font-size: var(--text-key); font-weight: 700; line-height: 1; }
.initials.pic-16 { font-size: 8px; }
.initials.account { background: var(--accent-light); color: var(--accent-text); border-radius: var(--radius-small-tile); }
.account-name { font-size: var(--text-small); color: var(--grey); }
.account-name.name-gap { margin-right: var(--space-12); }
/* Homer's mark in a header */
.site-logo { display: flex; align-items: center; }
.site-logo-image { height: 16px; transform: translateY(2px); }
/* A count on the accent, beside a word or on a corner */
.badge.count { min-width: 18px; height: 18px; justify-content: center; padding: 0 4px; font-size: var(--text-key); line-height: 1; white-space: nowrap; }
.badge.corner { position: absolute; top: -4px; right: -4px; transform: translateX(50%); box-shadow: 0 0 0 2px var(--white); }
/* A card of words, with a quiet foot */
.content-card { padding: var(--space-20); background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-button); }
.content-card-title { font-weight: 600; }
.content-card-body { margin-top: var(--space-6); font-size: var(--text-small); color: var(--grey); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: var(--lines, 2); overflow: hidden; }
.content-card-foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4) var(--space-8); margin-top: var(--space-12); font-size: var(--text-meta); color: var(--grey); }
.content-card-foot > .sep { color: var(--line); }
/* A message with its glyph before its words (Ui::Core::Layout::Alert) */
.has-glyph { flex-wrap: nowrap; column-gap: var(--space-12); }
.has-glyph > .glyph { margin-top: 3px; }
.has-glyph > div { flex: 1 1 auto; }
.has-glyph > .readable { max-width: 60ch; }
/* An aside beside the page's words, marked by its kind in a bar at its left
   (Ui::Core::Layout::Callout) */
.callout { padding: var(--space-14) var(--space-14) var(--space-14) var(--space-14); background: var(--desk); border-left: 4px solid var(--edge); border-radius: 0 var(--radius-pill) var(--radius-pill) 0; }
.callout.accent { border-left-color: var(--accent-frame); }
.callout.wait { border-left-color: var(--amber); }
.callout.broken { border-left-color: var(--red); }
.callout-title { margin-bottom: var(--space-4); font-size: var(--text-meta); font-weight: 700; color: var(--grey); }
.callout.accent .callout-title { color: var(--accent-text); }
.callout.wait .callout-title { color: var(--amber); }
.callout.broken .callout-title { color: var(--red); }
.callout-body { font-size: var(--text-small); color: var(--ink); text-wrap: pretty; }
/* An empty place in a panel, with its glyph beside its words, or above them
   when centered */
.empty.in-panel { flex-direction: row; align-items: center; gap: var(--space-14); padding: var(--space-36) var(--space-14); border: 0; }
@media (min-width: 640px) { .empty.in-panel { padding-inline: var(--space-24); } }
.empty.in-panel.centered { flex-direction: column; text-align: center; padding-block: var(--space-44); }
.empty-mark { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: var(--radius-button); background: var(--desk); color: var(--grey); }
.empty-words { display: flex; flex-direction: column; gap: var(--space-4); }
.empty.in-panel.centered .empty-words { align-items: center; }
.empty-words > p { color: var(--grey); text-wrap: balance; }
.empty-words > b { text-wrap: balance; }
.empty-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-12); margin-top: var(--space-8); }
.empty.in-panel.centered .empty-actions { justify-content: center; }
/* The quiet way to remove a thing, on the page it was opened from */
.danger-line { margin-top: var(--space-28); padding-top: var(--space-14); border-top: 1px solid var(--line); font-size: var(--text-meta); color: var(--grey); }
.danger-line form { display: inline; margin: 0; }
/* A progress bar with its name and its share above it */
.progress-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-12); margin-bottom: var(--space-4); }
.progress-name { font-size: var(--text-small); font-weight: 600; }
.progress-share { font-size: var(--text-meta); color: var(--grey); }
.progress-share.failed { color: var(--red); }
.progress-share.done { color: var(--green); }
.progress.wide { max-width: none; }
.progress.thin { height: 8px; border-width: 0; background: var(--shade); border-radius: var(--radius-small-tile); }
.progress.thin > span { border-radius: var(--radius-small-tile); transition: width 0.3s; }
/* A placeholder that holds a block's shape while it loads */
.skeleton { animation: skeleton 1.6s ease-in-out infinite; }
@keyframes skeleton { 0%, 100% { opacity: 1; } 50% { opacity: .5; } }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }
.skeleton .bone { display: block; max-width: 100%; height: 8px; background: var(--shade); border-radius: var(--radius-small-tile); }
.skeleton .bone.faint { background: var(--desk); }
.skeleton-box { padding: var(--space-14); background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-button); }
.skeleton-box.desk { background: var(--paper); }
@media (min-width: 640px) { .skeleton-box { padding: var(--space-24); } }
.skeleton-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-28); }
.skeleton-stack { display: flex; flex-direction: column; gap: var(--space-8); }
.skeleton-grid { display: grid; grid-template-columns: repeat(var(--columns, 4), minmax(0, 1fr)); gap: var(--space-14); }
.skeleton-bars { display: flex; align-items: flex-end; gap: var(--space-6); height: 192px; }
.skeleton-bars > .bone { flex: 1 1 0; }
.skeleton-table { border: 1px solid var(--line); border-radius: var(--radius-button); overflow: hidden; }
.skeleton-table > .skeleton-row { padding: var(--space-14); }
@media (min-width: 640px) { .skeleton-table > .skeleton-row { padding-inline: var(--space-24); } }
.skeleton-head { background: var(--paper); }
.skeleton-line { border-top: 1px solid var(--line); }
.skeleton-box > .skeleton-line:first-of-type, .skeleton-stack > .skeleton-line { padding-block: var(--space-8); }
/* A carousel's slides and the dots that pick one */
.carousel-slide { display: none; }
.carousel-slide.active { display: block; }
.carousel-slide[hidden] { display: none; }
.carousel-dots { display: flex; align-items: center; gap: var(--space-6); margin-top: var(--space-8); }
.carousel-dot { width: 6px; height: 6px; padding: 0; border: 0; background: var(--line); cursor: pointer; transition: background-color 0.2s; }
.carousel-dot[aria-current="true"] { background: var(--accent); }
/* One notice in the Inbox or a panel (Ui::Core::Layout::NotificationCard):
   the mark's slot, the words, then the time. A notice drawn on its own has
   the page's side inset and a rule under it, and an unread one is white. */
.notice { display: flex; align-items: flex-start; gap: var(--space-12); padding-block: var(--space-12); color: var(--ink); text-decoration: none; }
.notice.edged { padding-inline: var(--space-14); border-bottom: 1px solid var(--line); }
@media (min-width: 640px) { .notice.edged { padding-inline: var(--space-24); } }
.notice.linked { cursor: pointer; }
.notice.linked:hover { background: var(--desk); }
.notice.unread { background: var(--white); }
.notice.with-action { flex-wrap: wrap; }
@media (min-width: 640px) { .notice.with-action { flex-wrap: nowrap; } }
.notice-words { display: flex; flex: 1 1 0; align-items: flex-start; gap: var(--space-12); min-width: 0; color: inherit; text-decoration: none; }
.notice-mark-slot { display: block; flex: none; width: 8px; height: 8px; margin-top: 7px; }
.notice-mark { display: block; width: 8px; height: 8px; background: var(--accent); border-radius: 2px; }
.notice-text { flex: 1 1 0; min-width: 0; }
.notice-headline { font-weight: 600; text-wrap: balance; }
.notice-line { margin-top: var(--space-2); font-size: var(--text-meta); color: var(--grey); text-wrap: balance; }
.notice-line.above-card { margin: 0 0 var(--space-8); text-wrap: pretty; }
.notice-time { flex: none; margin-top: var(--space-2); font-size: var(--text-key); color: var(--grey); white-space: nowrap; }
.notice-foot { display: flex; flex: none; flex-basis: 100%; align-items: center; justify-content: space-between; gap: var(--space-12); padding-left: 20px; }
@media (min-width: 640px) { .notice-foot { flex-basis: auto; padding-left: 0; } }
.notice-action { flex: none; }
.not-available { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-12); }
.not-available > .paragraph { max-width: var(--measure-text); }

/* ---------- Type (Ui::Core::Type::*) ---------- */
/* A heading in one of the type scale's sizes. The old sizes map onto the
   nearest step: xs is key, small meta, medium body, large lead, xl heading,
   xxl thing, and jumbo, giant and billboard the title. */
.headline { margin: 0; font-weight: 700; line-height: 1.3; color: var(--ink); text-wrap: balance; text-align: left; }
.headline.xs { font-size: var(--text-key); font-weight: 600; }
.headline.small { font-size: var(--text-meta); font-weight: 600; }
.headline.medium { font-size: var(--text-body); font-weight: 600; }
.headline.large { font-size: var(--text-lead); font-weight: 600; }
.headline.xl { font-size: var(--text-heading); line-height: 1.2; }
.headline.xxl { font-size: var(--text-thing); line-height: 1.1; }
.headline.jumbo, .headline.giant, .headline.billboard { font-size: var(--text-title); line-height: 1.1; }
@media (max-width: 760px) { .headline.xxl, .headline.jumbo, .headline.giant, .headline.billboard { font-size: 30px; } }
.headline.quiet { color: var(--grey); font-weight: 600; }
.headline.accent { color: var(--accent-text); }
.headline.tight { line-height: 1; }
.headline.right { text-align: right; }
@media (min-width: 768px) { .headline.centered { text-align: center; } }
.headline.spaced.xs { margin-bottom: var(--space-4); }
.headline.spaced.small, .headline.spaced.medium, .headline.spaced.large { margin-bottom: var(--space-8); }
.headline.spaced.xl, .headline.spaced.xxl { margin-bottom: var(--space-14); }
.headline.spaced.jumbo { margin-bottom: var(--space-24); }
.headline.spaced.giant { margin-bottom: var(--space-28); }
/* A paragraph of a panel's words */
.paragraph { margin: 0 0 var(--space-14); font-size: var(--text-small); line-height: 1.5; color: var(--grey); text-wrap: pretty; }
.paragraph.tight { line-height: 1; }
.paragraph.flush { margin-bottom: 0; }
/* A link inside words, in the accent; a quiet one is grey and underlined */
.inline-link { color: var(--accent-text); text-decoration: none; }
.inline-link:hover { text-decoration: underline; text-underline-offset: 3px; }
.inline-link.quiet { color: var(--grey); text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 2px; }
.inline-link.quiet:hover { color: var(--ink); text-decoration: none; }
/* Words in the accent (the old gradient text) */
.accent-words { color: var(--accent-text); }

/* ---------- Tables and rows ---------- */
.table-wrap { overflow-x: auto; max-width: 100%; }
.table { width: 100%; border-collapse: collapse; }
.table th { text-align: left; font-size: var(--text-meta); font-weight: 600; color: var(--grey); padding: 0 var(--space-12) var(--space-8) 0; white-space: nowrap; }
.table td { padding: 11px var(--space-12) 11px 0; border-top: 1px solid var(--line); vertical-align: baseline; }
.table tbody tr:last-child td { border-bottom: 1px solid var(--line); }
.table .number { text-align: right; }
.table .sub { display: block; font-size: var(--text-meta); color: var(--grey); }
.rows { list-style: none; margin: 0; padding: 0; border-bottom: 1px solid var(--line); }
.rows > li { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4) var(--space-14); padding: 11px 0; border-top: 1px solid var(--line); }
.rows .main { flex: 1 1 280px; min-width: 0; text-wrap: balance; }
.rows .sub { display: block; font-size: var(--text-meta); color: var(--grey); }
.rows .when { font-size: var(--text-meta); color: var(--grey); white-space: nowrap; }

/* ---------- Charts ---------- */
.chart { display: block; width: 100%; max-width: 640px; height: auto; }
.chart .grid { stroke: var(--desk); stroke-width: 1; }
.chart .axis { stroke: var(--line); stroke-width: 1; }
.chart .tick { fill: var(--grey); font-size: 12px; font-family: var(--font-sans); }
.chart .one { fill: none; stroke: var(--ink); stroke-width: 2; stroke-linejoin: round; }
.chart .before { fill: none; stroke: var(--edge); stroke-width: 2; stroke-dasharray: 4 4; }
.chart .marker { stroke: var(--edge); stroke-width: 1; stroke-dasharray: 3 3; }
.chart .marker-words { fill: var(--grey); font-size: 12px; font-family: var(--font-sans); }
.chart .gap { stroke: var(--paper); stroke-width: 2; }
.series-1 { --series: var(--chart-1); }
.series-2 { --series: var(--chart-2); }
.series-3 { --series: var(--chart-3); }
.series-4 { --series: var(--chart-4); }
.series-5 { --series: var(--chart-5); }
.series-6 { --series: var(--chart-6); }
.series-7 { --series: var(--chart-7); }
.series-other { --series: var(--edge); }
.series-brand { --series: var(--ink); }
.chart [class*="series-"] { fill: var(--series); }
.chart .line[class*="series-"] { fill: none; stroke: var(--series); stroke-width: 2; }
/* A chart that a script draws: its empty note, and the tip under the
   pointer, a small menu panel (line, multi-line and stacked bar charts) */
.chart-box { width: 100%; height: 100%; }
.chart-box.square { height: auto; aspect-ratio: 1 / 1; }
.chart-wide { width: 100%; }
/* Bars and dots drawn in rows (BarChart, DotPlot). A bar or a dot takes its
   series color (.series-1 to .series-7), and the caller's own color class
   wins over it: the fill sits in :where(), so it weighs nothing. */
.bar-chart { display: flex; flex-direction: column; gap: var(--space-14); }
.bar-row, .dot-row { display: flex; align-items: center; gap: var(--space-12); }
.dot-row { padding-block: var(--space-8); }
.bar-label { flex: none; width: 112px; text-align: right; font-size: var(--text-small); color: var(--ink); }
.dot-label { flex: none; width: 112px; font-size: var(--text-small); font-weight: 600; }
.bar-track { position: relative; flex: 1 1 0; height: 24px; background: var(--desk); }
.bar-fill { height: 24px; }
:where(.bar-fill, .dot) { background: var(--series, var(--ink)); }
.bar-value { flex: none; min-width: 40px; font-size: var(--text-meta); color: var(--grey); white-space: nowrap; text-align: right; }
.dot-track { position: relative; flex: 1 1 0; height: 24px; }
.dot-line { position: absolute; top: 50%; left: 0; right: 0; height: 1px; background: var(--desk); }
.dot-range { position: absolute; top: 50%; height: 2px; transform: translateY(-50%); background: var(--line); }
.dot { position: absolute; top: 50%; width: 12px; height: 12px; border-radius: var(--radius-round); transform: translate(-50%, -50%); }
/* A sparkline with its axis fills its column; a stretched one too, and its
   marks may reach past its edge */
.spark-chart { display: block; width: 100%; }
.spark-chart.stretched { height: auto; overflow: visible; }
.chart-empty { display: flex; align-items: center; justify-content: center; height: 100%; font-size: var(--text-small); color: var(--grey); }
.chart-empty[hidden], .chart-box[hidden] { display: none; }
.chart-tip { padding: var(--space-8) var(--space-12); background: var(--white); border: 2px solid var(--ink); border-radius: var(--radius-pill); box-shadow: var(--edge-button); font-size: var(--text-small); color: var(--ink); }
.chart-tip-date { margin-bottom: var(--space-4); font-size: var(--text-meta); color: var(--grey); }
.chart-tip-value { font-weight: 700; }
.chart-tip-rows { display: flex; flex-direction: column; gap: var(--space-4); }
.chart-tip-row { display: flex; align-items: center; gap: var(--space-8); }
.chart-tip-row > .chart-tip-value { margin-left: auto; }
.chart-tip-key { display: inline-block; flex: none; width: 8px; height: 8px; border-radius: 2px; }
.chart-tip-name { color: var(--grey); }
.legend { display: flex; flex-wrap: wrap; gap: var(--space-6) var(--space-14); font-size: var(--text-meta); color: var(--grey); list-style: none; margin: 0; padding: 0; }
.legend li { display: inline-flex; align-items: center; gap: var(--space-6); }
.legend .key { width: 12px; height: 12px; border-radius: 3px; background: var(--series, var(--ink)); }
.legend .key.dashed { width: 16px; height: 0; border-top: 2px dashed var(--edge); border-radius: 0; background: none; }
/* A bar of spend against the target, and the score's bar */
.meter { position: relative; display: block; width: 120px; height: 8px; border-radius: var(--radius-small-tile); background: var(--shade); }
.meter > span { display: block; height: 100%; border-radius: var(--radius-small-tile); background: var(--step-bar, var(--accent)); }
.meter > i { position: absolute; top: -3px; width: 2px; height: 14px; background: var(--ink); border-radius: 1px; }
/* Heat squares: how many things a day holds */
.heat { display: inline-block; width: 14px; height: 14px; border-radius: 3px; background: var(--desk); }
.heat[data-level="1"] { background: var(--shade); }
.heat[data-level="2"] { background: var(--edge); }
.heat[data-level="3"] { background: var(--grey); }
.heat[data-level="4"] { background: var(--ink); }
.heat.notes[data-level="1"] { background: var(--note-heat-1); }
.heat.notes[data-level="2"] { background: var(--note-heat-2); }
.heat.notes[data-level="3"] { background: var(--note-heat-3); }
/* The pacing line's band and its 100% line */
.spark .band { fill: var(--green-light); }
.spark .mid { stroke: var(--score-bar-good2); stroke-width: 0.75; }
.spark .path { fill: none; stroke: var(--grey); stroke-width: 1.5; stroke-linejoin: round; }
.spark .last { fill: var(--step-bar, var(--ink)); }

/* ---------- Placing a button ---------- */
/* A button that fills its row (BasicButton, full_width: true) */
.btn.full { width: 100%; }
/* A button pushed to the end of its row (DeleteButton), and one pushed
   there only from 1024 px (EditButton) */
.push-end { display: inline-flex; margin-left: auto; }
.push-end.from-wide { margin-left: 0; }
@media (min-width: 1024px) { .push-end.from-wide { margin-left: auto; } }

/* ---------- A drawer (Ui::Core::BottomDrawer) ---------- */
/* A drawer rises from the bottom of its column and falls back again,
   leaving the reader where they were. Its visibility flips at the end of
   the fall and at the start of the rise, so the drawer is never a ghost you
   can tab into while it is down. On the page it is fixed to the window,
   and its script places it under its anchor; in the style guide it stands
   in place. Its sheet is paper in an ink frame with no bottom edge. */
.drawer { display: flex; flex-direction: column; transform: translateY(100%); visibility: hidden; transition: transform 300ms cubic-bezier(0.32, 0.72, 0, 1), visibility 0s linear 300ms; }
.drawer.is-open { transform: translateY(0); visibility: visible; transition: transform 300ms cubic-bezier(0.32, 0.72, 0, 1), visibility 0s linear 0s; }
@media (prefers-reduced-motion: reduce) { .drawer, .drawer.is-open { transition: none; } }
.drawer.on-window { position: fixed; left: 0; right: 0; bottom: 0; top: 33.333%; z-index: 30; }
.drawer.in-place { position: relative; height: 384px; }
.drawer-sheet { display: flex; flex: 1 1 0; flex-direction: column; min-height: 0; background: var(--paper); border: 2px solid var(--ink); border-bottom: 0; border-radius: var(--radius-panel) var(--radius-panel) 0 0; }
.drawer-top { position: relative; flex: none; height: 44px; padding: var(--space-12) var(--space-14) 0; }
.drawer-handle { display: block; width: 40px; height: 4px; margin: 0 auto; background: var(--line); border-radius: 2px; }
.drawer-top > .btn { position: absolute; top: var(--space-8); right: var(--space-10); }
.drawer-body { flex: 1 1 0; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0 var(--space-14) var(--space-24); }
@media (min-width: 640px) { .drawer-top, .drawer-body { padding-inline: var(--space-20); } }
.drawer-frame { display: block; transition: opacity 150ms; }
.drawer-frame[aria-busy="true"] { opacity: 0.6; }

/* ---------- A flag's card in the knowledge base and in chat ---------- */
/* Ui::Core::Insights::Card: its pill and date, the headline, the words,
   the recommendation in an accent callout, then its sources */
.insight-card { display: flex; flex-direction: column; gap: var(--space-8); min-width: 0; padding: var(--space-20); background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-button); }
.insight-card-top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-12); }
.insight-card-meta { font-size: var(--text-meta); color: var(--grey); white-space: nowrap; }
.insight-card-headline { margin: var(--space-4) 0 0; font-size: var(--text-row); font-weight: 700; line-height: 1.3; color: var(--ink); text-wrap: balance; }
.insight-card-body { margin: 0; font-size: var(--text-small); color: var(--grey); white-space: pre-line; text-wrap: pretty; }
.insight-card-foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4) var(--space-14); }
.insight-card > .cited-sources { padding: 0; }

/* ---------- A change in words, and the list's loading line ---------- */
/* A signed change (Ui::Core::ScoreTrend): green up, red down, grey held */
.change-words { font-size: var(--text-small); font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.change-words.small { font-size: var(--text-meta); }
.change-words.large { font-size: var(--text-lead); }
.change-words.up { color: var(--green); }
.change-words.down { color: var(--red); }
.change-words.held { color: var(--grey); }
/* The end of a list that loads more as it comes into view
   (Ui::Core::LazyPaginationFrame): the dots and their words */
.loading-more { display: flex; align-items: center; justify-content: center; gap: var(--space-8); padding: var(--space-24) 0; font-size: var(--text-meta); color: var(--grey); }

/* ---------- A brand's week of urgency scores (Ui::Core::ScoreSparkline) ---------- */
/* One grey line over a faint middle line, the newest day's point in its
   step's words color, and one popover per day. The chart is one button; a
   phone draws the smaller of its two drawings. The popover fades in and out
   in 100 ms (none for a person who asks for less motion); "fading" is its
   fade, and "hidden" hides a popover, a mark or the definition. */
.score-spark { display: inline-flex; align-items: center; }
.score-spark-button { position: relative; display: inline-flex; flex: none; align-items: center; padding: 0; border: 0; background: none; font: inherit; color: inherit; cursor: pointer; }
.score-spark-button:focus-visible { outline: 2px solid var(--accent-frame); outline-offset: 2px; }
.score-spark-drawing { flex: none; overflow: visible; }
.score-spark-drawing.wide { display: none; }
@media (min-width: 640px) {
  .score-spark-drawing.wide { display: inline-flex; }
  .score-spark-drawing.phone { display: none; }
}
.score-spark-line { stroke: var(--edge); }
.score-spark-middle { stroke: var(--desk); }
.score-spark-point { color: var(--step-text, var(--grey)); }
.score-spark-days { position: absolute; inset: 0; display: flex; }
.score-spark-days > span { display: block; flex: 1 1 0; }
.score-tip { position: fixed; z-index: 50; max-width: 248px; padding: var(--space-10) var(--space-12); background: var(--white); border: 2px solid var(--ink); border-radius: var(--radius-pill); box-shadow: var(--edge-button); color: var(--ink); text-align: left; transition: opacity 100ms ease-out; }
@media (prefers-reduced-motion: reduce) { .score-tip { transition: none; } }
.score-tip.fading { opacity: 0; pointer-events: none; }
.score-tip-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-12); margin-bottom: var(--space-6); }
.score-tip-caption { margin: 0; font-size: var(--text-key); color: var(--grey); }
.score-tip-date { margin: 0; font-size: var(--text-meta); font-weight: 600; white-space: nowrap; }
.score-tip-row { display: flex; align-items: center; gap: var(--space-8); }
.score-tip-row > .score-words { font-size: var(--text-small); }
.score-tip-help { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 22px; height: 22px; margin-left: auto; padding: 0; border: 2px solid var(--edge); border-radius: var(--radius-pill); background: var(--white); font: inherit; font-size: var(--text-key); font-weight: 700; line-height: 1; color: var(--grey); cursor: pointer; }
.score-tip-help:hover, .score-tip-help[aria-expanded="true"] { border-color: var(--ink); color: var(--ink); }
/* The definition wraps inside the popover's width and never widens it */
.score-tip-definition { width: 0; min-width: 100%; margin: var(--space-8) 0 0; font-size: var(--text-meta); line-height: 1.4; color: var(--grey); text-wrap: pretty; }

/* A radar chart (Ui::Core::Charts::RadarChart) draws at its size, and
   shrinks with its column when the column is narrower */
.radar-chart { display: block; max-width: 100%; height: auto; }

/* ---------- Page helpers: the dot grid, progress, uploads, rich text and motion ---------- */
/* The dot grid: the guest pages' ground, and the ground of Ask Homer's
   thinking line. */
.dot-grid { background-color: var(--paper); background-image: radial-gradient(circle, var(--shade) 0.5px, transparent 0.5px); background-size: 16px 16px; }

/* Turbo's progress bar along the top of the page, in the accent */
.turbo-progress-bar { background: var(--accent); }

/* A button's words while it can be pressed, and its words while it works
   (BasicButton show_processing, SubmitButton, DefaultForm). Turbo disables
   a button while its form submits; a link takes .processing. */
button .show-when-enabled, a.enabled .show-when-enabled { display: initial; }
button .show-when-disabled, a .show-when-disabled { display: none; }
button[disabled] .show-when-enabled, a.processing .show-when-enabled { display: none; }
button[disabled] .show-when-disabled, a.processing .show-when-disabled { display: initial; }

/* A file on its way up (app/javascript/custom/direct_uploads.js): its name,
   on a bar that fills as it goes */
.direct-upload { display: inline-block; position: relative; padding: 2px 4px; margin: 0 3px 3px 0; border: 1px solid var(--line); border-radius: 3px; font-size: var(--text-key); line-height: 13px; }
.direct-upload--pending { opacity: 0.6; }
.direct-upload__progress { position: absolute; top: 0; left: 0; bottom: 0; opacity: 0.2; background: var(--accent); transition: width 120ms ease-out, opacity 60ms 60ms ease-in; transform: translate3d(0, 0, 0); }
.direct-upload--complete .direct-upload__progress { opacity: 0.4; }
.direct-upload--error { border-color: var(--red); }
input[type=file][data-direct-upload-url][disabled] { display: none; }

/* Rich text (Ui::Core::Forms::RichTextArea, and Action Text's content
   partial): headings at one size, links in the accent, lists with their
   marks, code and tables on paper. */
.rich-text { font-size: var(--text-body); color: var(--ink); }
.rich-text h1, .rich-text h2, .rich-text h3, .rich-text h4, .rich-text h5, .rich-text h6 { margin: var(--space-24) 0 var(--space-8); font-size: var(--text-lead); font-weight: 600; line-height: 1.5; }
.rich-text h1:first-child, .rich-text h2:first-child, .rich-text h3:first-child, .rich-text h4:first-child, .rich-text h5:first-child, .rich-text h6:first-child { margin-top: 0; }
.rich-text p { margin-bottom: var(--space-8); }
.rich-text p:last-child { margin-bottom: 0; }
.rich-text a { color: var(--accent-text); text-decoration: underline; }
.rich-text strong { font-weight: 600; }
.rich-text em { font-style: italic; }
.rich-text del { text-decoration: line-through; }
.rich-text code { padding: 2px 4px; background: var(--desk); border-radius: 4px; font-family: var(--font-mono); font-size: var(--text-small); }
.rich-text pre { margin-bottom: var(--space-14); padding: var(--space-14); background: var(--desk); border-radius: 4px; overflow-x: auto; }
.rich-text pre code { padding: 0; background: none; }
.rich-text blockquote { margin-bottom: var(--space-14); padding-left: var(--space-14); border-left: 4px solid var(--line); font-style: italic; color: var(--grey); }
.rich-text ul { margin-bottom: var(--space-14); padding-left: var(--space-24); list-style: disc outside; }
.rich-text ol { margin-bottom: var(--space-14); padding-left: var(--space-24); list-style: decimal outside; }
.rich-text li { margin-bottom: var(--space-4); }
.rich-text ul ul, .rich-text ol ul { margin: 0 0 0 var(--space-14); list-style-type: circle; }
.rich-text ul ol, .rich-text ol ol { margin: 0 0 0 var(--space-14); }
.rich-text table { width: 100%; margin-bottom: var(--space-14); border-collapse: collapse; }
.rich-text th { padding: var(--space-8) var(--space-12); background: var(--paper); border-bottom: 1px solid var(--line); text-align: left; font-size: var(--text-meta); font-weight: 600; }
.rich-text td { padding: var(--space-8) var(--space-12); border-bottom: 1px solid var(--shade); font-size: var(--text-meta); color: var(--grey); }
.rich-text tr:last-child td { border-bottom: 0; }

/* The dot grid spinner (Ui::Core::Spinners::DotGrid): its dot sizes and its
   four motions, named for the variant */
.dot-grid-dot-sm { width: 6px; height: 6px; }
.dot-grid-dot-md { width: 8px; height: 8px; }
.dot-grid-dot-lg { width: 12px; height: 12px; }
@keyframes dot-grid-scan { 0%, 100% { background-color: var(--line); } 50% { background-color: var(--accent); } }
@keyframes dot-grid-breathe { 0%, 100% { opacity: 0.1; } 50% { opacity: 1; } }
@keyframes dot-grid-wave_rows { 0%, 100% { opacity: 0.08; transform: scale(0.6); } 50% { opacity: 1; transform: scale(1); } }
@keyframes dot-grid-cascade { 0%, 100% { opacity: 0.08; } 50% { opacity: 1; } }

/* A field shakes when its form is sent empty (empty_submit_controller) */
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  10%, 30%, 50%, 70%, 90% { transform: translateX(-4px); }
  20%, 40%, 60%, 80% { transform: translateX(4px); }
}
.shake { animation: shake 0.5s ease-in-out; }

/* A chip that just arrived (Ui::Core::Chip): a short grey flash that ends on
   the chip's own color (Lee, 2026-11-06). */
@keyframes chip-added { from { background-color: var(--line); } }
.chip-added { animation: chip-added 3.5s ease-out; }

@media (prefers-reduced-motion: reduce) {
  .shake, .chip-added { animation: none; }
}
