/*
 * Control classes: the look a control has whether an Angular component draws it or plain
 * markup does. Ported from minutes/frontend/src/styles/base.css (.btn, inputs, .check,
 * .option, .table, .notice, .badge-stub), with the skeleton sweep from
 * grand-total/frontend/src/styles.css (@keyframes skeleton-sweep) and the badge tones from
 * grand-total/frontend/src/app/core/status.ts. Every class is prefixed `cp-`.
 *
 * Only semantic tokens are used, so dark mode follows tokens.css with no theme selectors here.
 *
 *   buttons   .cp-btn  --ghost --quiet --signal --plain --danger  --sm --lg --block  --icon
 *             (a toggle button is .cp-btn[aria-pressed])
 *   fields    .cp-field (label wrapper)  .cp-input  .cp-check  .cp-option (__label, __hint)
 *             .cp-switch
 *   table     .cp-table (--stack, .cp-num, .cp-actions)  .cp-table-scroll
 *   notice    .cp-notice  --signal --danger
 *   badge     .cp-badge  --neutral --signal --danger --interactive --surface
 *   loading   .cp-spinner  .cp-skeleton  .cp-progress (__bar)
 *   floating  .cp-tooltip  .cp-popover  (panels only; the components position them)
 *   text      .cp-kbd  .cp-error
 *
 * Accessibility, kept in this file so a product that loads controls.css without base.css
 * still gets it:
 *   - every control class has its own :focus-visible rule (--focus-ring, --focus-offset)
 *   - a control whose only boundary is a border draws it in --field-border (3:1), never in
 *     --hairline, which is for decorative dividers
 *   - state is never colour alone (a pressed button gets an inset rule, a switch a thumb
 *     position), and there is a @media (forced-colors: active) block at the end for every
 *     class that shows state with a background
 */

/* Controls start with no margin, at zero specificity, so a layout class (.cp-stack, .cp-row)
   still spaces them: a reset inside each rule would tie with it and, coming later, win. */
:where(.cp-btn, .cp-input, .cp-switch, .cp-notice, .cp-progress) {
  margin: 0;
}

/* One focus ring for every control. Selector lists are repeated per class below on purpose:
   the rule must not depend on base.css's global :focus-visible. */

/* --- Buttons --- */

.cp-btn {
  /* Tracking leaves trailing space after the last letter; adding it to the left padding
     centres the label optically. Variants change the variables, not the padding. */
  --btn-pad: var(--space-4);
  --btn-track: var(--tracking-label);
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-height);
  padding: 0 var(--btn-pad) 0 calc(var(--btn-pad) + var(--btn-track));
  background: var(--fg);
  color: var(--bg);
  border: 1px solid var(--fg);
  border-radius: 0;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: var(--btn-track);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
@media (prefers-reduced-motion: no-preference) {
  .cp-btn {
    transition:
      background-color 150ms ease-out,
      border-color 150ms ease-out,
      color 150ms ease-out,
      translate 150ms ease-out;
  }
}
.cp-btn:hover:not(:disabled, [aria-disabled='true']) {
  background: var(--interactive);
  border-color: var(--interactive);
  color: var(--on-interactive);
}
.cp-btn:active:not(:disabled, [aria-disabled='true']) {
  translate: 0 1px;
}
.cp-btn:disabled,
.cp-btn[aria-disabled='true'] {
  opacity: var(--disabled-opacity);
  cursor: not-allowed;
}
.cp-btn[aria-busy='true'] {
  cursor: progress;
}
.cp-btn:focus-visible {
  outline: var(--focus-ring) solid var(--interactive);
  outline-offset: var(--focus-offset);
}

/* Outlined: the second action beside a primary one. */
.cp-btn--ghost {
  background: transparent;
  color: var(--fg);
  border-color: var(--fg);
}
.cp-btn--ghost:hover:not(:disabled, [aria-disabled='true']) {
  background: var(--fg);
  border-color: var(--fg);
  color: var(--bg);
}
/* Underlined text: an action that should not compete with the page. */
.cp-btn--quiet {
  --btn-pad: var(--space-2);
  background: transparent;
  color: var(--fg);
  border-color: transparent;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}
.cp-btn--quiet:hover:not(:disabled, [aria-disabled='true']) {
  background: transparent;
  border-color: transparent;
  color: var(--interactive);
}
/* The one action that needs a decision. */
.cp-btn--signal {
  background: transparent;
  color: var(--signal);
  border-color: var(--signal);
}
.cp-btn--signal:hover:not(:disabled, [aria-disabled='true']) {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--on-signal);
}
/* Destructive: delete, discard, revoke. */
.cp-btn--danger {
  background: transparent;
  color: var(--danger-ink);
  border-color: var(--danger);
}
.cp-btn--danger:hover:not(:disabled, [aria-disabled='true']) {
  /* --danger-ink, not --danger: white on --danger is 3.8:1, on --danger-ink 5.6:1. */
  background: var(--danger-ink);
  border-color: var(--danger-ink);
  color: var(--on-danger);
}
.cp-btn--sm {
  --btn-pad: var(--space-3);
  min-height: var(--control-height-sm);
  font-size: var(--text-xs);
}
.cp-btn--lg {
  min-height: var(--control-height-lg);
  font-size: var(--text-md);
}
.cp-btn--block {
  display: flex;
  width: 100%;
}
/* Chrome-level actions (a header): secondary ink, underlined only on hover. After the size
   modifiers so it keeps its zero padding when combined with them. */
.cp-btn--plain {
  --btn-pad: 0px;
  background: transparent;
  color: var(--fg-secondary);
  border-color: transparent;
}
.cp-btn--plain:hover:not(:disabled, [aria-disabled='true']) {
  background: transparent;
  border-color: transparent;
  color: var(--fg);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}

/* A square icon-only button: at least --control-height on both sides, the glyph centred.
   Always give it an accessible name (aria-label). Combine with --sm for a 28px square. */
.cp-btn--icon {
  --btn-pad: 0px;
  width: var(--control-height);
  min-width: var(--control-height);
  padding: 0;
  gap: 0;
}
.cp-btn--icon.cp-btn--sm {
  width: var(--control-height-sm);
  min-width: var(--control-height-sm);
}
.cp-btn--icon.cp-btn--lg {
  width: var(--control-height-lg);
  min-width: var(--control-height-lg);
}
.cp-btn--icon > svg,
.cp-btn--icon > * {
  flex: none;
}

/* A toggle button that is on. Fill AND an inset rule, so it reads without colour; the
   forced-colors block gives it Highlight and an inner outline. Works on every variant. */
.cp-btn[aria-pressed='true'] {
  background: var(--interactive);
  border-color: var(--interactive);
  color: var(--on-interactive);
  box-shadow: inset 0 -3px 0 currentColor;
}

/* --- Fields --- */

/* A label around its caption and its control: <label class="cp-field"><span class="cp-eyebrow">… */
.cp-field {
  display: block;
}
.cp-field > .cp-eyebrow {
  display: block;
  margin-bottom: var(--space-1);
}

/* Text-like inputs, select and textarea. */
/* Forms align at their labels; helper text only grows the space below a control.
   Actions have their own row so a label or hint can never displace a button. */
.cp-form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
  gap: var(--space-3);
}
.cp-form-grid > * {
  min-width: 0;
}
.cp-form-grid--wide {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.cp-form-grid > button,
.cp-form-actions {
  grid-column: 1 / -1;
  justify-self: start;
}
.cp-form-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
}
@media (max-width: 1100px) {
  .cp-form-grid--wide {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 600px) {
  .cp-form-grid {
    grid-template-columns: 1fr;
  }
}

.cp-input {
  appearance: none;
  display: block;
  width: 100%;
  min-height: var(--control-height);
  padding: var(--space-1) var(--space-2);
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--field-border);
  border-radius: 0;
  font-family: var(--font-body);
  font-size: var(--text-md);
  line-height: 1.5;
}
select.cp-input {
  appearance: auto;
}
textarea.cp-input {
  resize: vertical;
  min-height: calc(var(--control-height) * 2.5);
}
.cp-input::placeholder {
  color: var(--fg-secondary);
  opacity: 1;
}
.cp-input:focus,
.cp-input:focus-visible {
  outline: var(--focus-ring) solid var(--interactive);
  outline-offset: -1px;
  border-color: var(--interactive);
}
.cp-input[aria-invalid='true'] {
  border-color: var(--signal);
}
.cp-input:disabled {
  opacity: var(--disabled-opacity);
  cursor: not-allowed;
}

/* A checkbox or radio with its label: <label class="cp-check"><input type="checkbox"> Text</label> */
.cp-check,
.cp-option {
  gap: var(--space-2);
  cursor: pointer;
}
.cp-check {
  display: inline-flex;
  align-items: center;
}
.cp-check,
.cp-option {
  min-height: var(--target-min); /* the label is the target, not the 16px box */
}
/* The box is drawn here (not by the browser) so its edge is --field-border: 3.7:1. */
.cp-check input,
.cp-option input {
  appearance: none;
  position: relative;
  flex: none;
  width: 16px;
  height: 16px;
  margin: 0;
  background: var(--bg);
  border: 1px solid var(--field-border);
  border-radius: 0;
  cursor: inherit;
}
.cp-check input[type='radio'],
.cp-option input[type='radio'] {
  border-radius: 50%;
}
.cp-check input:checked,
.cp-option input:checked,
.cp-check input:indeterminate,
.cp-option input:indeterminate {
  background: var(--fg);
  border-color: var(--fg);
}
/* Checkbox: a tick (or a dash when indeterminate) cut out in the page colour. */
.cp-check input[type='checkbox']::before,
.cp-option input[type='checkbox']::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--bg);
  clip-path: polygon(20% 52%, 30% 42%, 43% 55%, 72% 24%, 82% 34%, 43% 75%);
  visibility: hidden;
}
.cp-check input[type='checkbox']:checked::before,
.cp-option input[type='checkbox']:checked::before {
  visibility: visible;
}
.cp-check input[type='checkbox']:indeterminate::before,
.cp-option input[type='checkbox']:indeterminate::before {
  clip-path: polygon(22% 44%, 78% 44%, 78% 58%, 22% 58%);
  visibility: visible;
}
/* Radio: a ring and a dot, in the page colour on the filled circle. */
.cp-check input[type='radio']:checked,
.cp-option input[type='radio']:checked {
  box-shadow: inset 0 0 0 3px var(--bg);
}
.cp-check input:focus-visible,
.cp-option input:focus-visible {
  outline: var(--focus-ring) solid var(--interactive);
  outline-offset: var(--focus-offset);
}
.cp-check:has(input:disabled),
.cp-option:has(input:disabled) {
  opacity: var(--disabled-opacity);
  cursor: not-allowed;
}
/* A radio (or checkbox) with a label and a line of help under it. */
.cp-option {
  display: flex;
  align-items: flex-start;
}
.cp-option input {
  margin-top: 4px;
}
.cp-option__label,
.cp-option__hint {
  display: block;
}
.cp-option__hint {
  font-size: var(--text-sm);
  color: var(--fg-secondary);
}

/* A switch: a square track with a thumb that slides. Put it on a <button role="switch"
   aria-checked> or an <input type="checkbox" role="switch">. The thumb's position says
   on/off, so colour is never the only signal. 40x24 meets --target-min. */
.cp-switch {
  appearance: none;
  position: relative;
  display: inline-block;
  flex: none;
  width: 40px;
  height: var(--target-min);
  padding: 0;
  background: var(--bg);
  border: 1px solid var(--field-border);
  border-radius: 0;
  cursor: pointer;
  vertical-align: middle;
}
.cp-switch::before {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  background: var(--field-border);
}
@media (prefers-reduced-motion: no-preference) {
  .cp-switch,
  .cp-switch::before {
    transition:
      background-color var(--duration-fast) var(--ease),
      translate var(--duration-fast) var(--ease);
  }
}
.cp-switch[aria-checked='true'],
.cp-switch:checked {
  background: var(--fg);
  border-color: var(--fg);
}
.cp-switch[aria-checked='true']::before,
.cp-switch:checked::before {
  background: var(--bg);
  translate: 16px 0;
}
.cp-switch:focus-visible {
  outline: var(--focus-ring) solid var(--interactive);
  outline-offset: var(--focus-offset);
}
.cp-switch:disabled,
.cp-switch[aria-disabled='true'] {
  opacity: var(--disabled-opacity);
  cursor: not-allowed;
}

/* --- Table --- */

.cp-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-md);
}
.cp-table th {
  background: var(--surface);
  text-align: left;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  color: var(--fg);
  padding: var(--space-2) var(--space-3) var(--space-2) 0;
  border-bottom: 1px solid var(--fg);
  white-space: nowrap;
  vertical-align: bottom;
}
.cp-table td {
  padding: var(--space-3) var(--space-3) var(--space-3) 0;
  border-bottom: 1px solid var(--hairline);
  vertical-align: top;
}
.cp-table tr:last-child td {
  border-bottom-color: var(--fg);
}
.cp-table th:last-child,
.cp-table td:last-child {
  padding-right: 0;
}
/* A figure: right-aligned, tabular, kept on one line. */
.cp-table .cp-num {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* A row's own actions: as narrow as its buttons, at the end, centred on the row. */
.cp-table .cp-actions {
  width: 1%;
  text-align: end;
  white-space: nowrap;
  vertical-align: middle;
}
.cp-table th button,
.cp-table th [role='button'] {
  min-height: var(--target-min);
}
.cp-table th button:focus-visible,
.cp-table th [role='button']:focus-visible,
.cp-table td button:focus-visible,
.cp-table input:focus-visible {
  outline: var(--focus-ring) solid var(--interactive);
  outline-offset: -2px; /* inside the cell: the scroller would clip a ring drawn outside */
}
/* A horizontally scrolling wrapper. The padding (cancelled by the negative margin, so the
   layout does not move) leaves room for a focus ring on the first and last cell. Make it
   keyboard-scrollable with tabindex="0", role="region" and an accessible name. */
.cp-table-scroll {
  position: relative;
  min-width: 0;
  --cp-scroll-pad: calc(var(--focus-ring) + var(--focus-offset));
  overflow-x: auto;
  padding: var(--cp-scroll-pad);
  margin: calc(-1 * var(--cp-scroll-pad));
}
.cp-table-scroll:focus-visible {
  outline: var(--focus-ring) solid var(--interactive);
  outline-offset: calc(-1 * var(--focus-ring));
}

/* A table that becomes a list of stacked rows on a handset. Cells carry data-label. */
@media (max-width: 600px) {
  .cp-table--stack,
  .cp-table--stack tbody,
  .cp-table--stack tr,
  .cp-table--stack td {
    display: block;
    width: 100%;
  }
  /* The header row is visually hidden, not display:none, so its sort and select-all
     controls stay in the accessibility tree and the tab order. A focused one is shown again.
     The data-table component also offers a visible sort control above the table; plain
     markup that stacks must provide its own. */
  .cp-table--stack thead {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
  .cp-table--stack thead:focus-within {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip: auto;
    white-space: normal;
  }
  .cp-table--stack tr {
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--hairline);
  }
  .cp-table--stack tr:first-child {
    border-top: 1px solid var(--fg);
  }
  .cp-table--stack td,
  .cp-table--stack .cp-num,
  .cp-table--stack .cp-actions {
    padding: 2px 0;
    border: 0;
    text-align: left;
  }
  .cp-table--stack td[data-label]::before {
    content: attr(data-label);
    display: inline-block;
    min-width: 84px;
    margin-inline-end: var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-label);
    color: var(--fg-secondary);
  }
}

/* --- Notice ---
 *
 * Status lines, the same everywhere:
 *   a request that failed           <p class="cp-notice cp-notice--danger" role="alert">
 *   something that went through     <p class="cp-notice" role="status">
 *   something to look at, not wrong <p class="cp-notice cp-notice--signal" role="status">
 * A field that is not right is a `.cp-error` line the field names with
 * aria-describedby, not a notice.
 */
.cp-notice {
  padding: var(--space-3) 0;
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  font-size: var(--text-sm);
}
.cp-notice--signal {
  border-color: var(--signal);
  color: var(--signal);
}
.cp-notice--danger {
  border-color: var(--danger);
  color: var(--danger-ink);
}

/* --- Badge: a state or a fact in mono caps. Neutral is the default look. --- */

.cp-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 1px var(--space-2) 1px calc(var(--space-2) + var(--tracking-label));
  border: 1px solid var(--hairline);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: 1.6;
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  white-space: nowrap;
  color: var(--fg-secondary);
  vertical-align: middle;
}
.cp-badge--neutral {
  color: var(--fg-secondary);
  border-color: var(--hairline);
}
.cp-badge--signal {
  color: var(--signal);
  border-color: var(--signal);
}
.cp-badge--danger {
  color: var(--danger-ink);
  border-color: var(--danger);
}
.cp-badge--interactive {
  color: var(--interactive);
  border-color: var(--interactive);
}
/* The site's filled tag: a --surface fill, with the hairline edge kept. */
.cp-badge--surface {
  background: var(--surface);
  color: var(--fg-secondary);
  border-color: var(--hairline);
}

/* --- Loading --- */

/* A hairline bar with a segment travelling along it, in the current text colour. */
.cp-spinner {
  position: relative;
  display: inline-block;
  flex: none;
  width: 16px;
  height: 1px;
  overflow: hidden;
  vertical-align: middle;
}
.cp-spinner::before,
.cp-spinner::after {
  content: '';
  position: absolute;
  inset: 0;
  background: currentColor;
}
.cp-spinner::before {
  opacity: 0.25;
}
.cp-spinner::after {
  width: 40%;
}
@media (prefers-reduced-motion: no-preference) {
  .cp-spinner::after {
    animation: cp-spinner-travel 900ms var(--ease) infinite;
  }
}
@keyframes cp-spinner-travel {
  from {
    translate: -100% 0;
  }
  to {
    translate: 250% 0;
  }
}

/* A placeholder where content is coming. The sweep runs only when motion is welcome;
   otherwise it is a still surface block. */
.cp-skeleton {
  display: block;
  width: 100%;
  height: 1em;
  background: var(--surface);
}
@media (prefers-reduced-motion: no-preference) {
  .cp-skeleton {
    background: linear-gradient(90deg, var(--surface) 40%, var(--hairline) 50%, var(--surface) 60%);
    background-size: 300% 100%;
    animation: cp-skeleton-sweep 1.4s linear infinite;
  }
}
@keyframes cp-skeleton-sweep {
  from {
    background-position: 100% 50%;
  }
  to {
    background-position: 0 50%;
  }
}

/* --- Error text --- */

/* The line under a field, or anywhere, that says what is wrong. --danger-ink, not --danger:
   the fill colour is too light to read as small text. */
.cp-error {
  color: var(--danger-ink);
  font-size: var(--text-sm);
}

/* --- Progress ---
 * A bar for a known (or unknown) amount of work. Two ways to write it:
 *   <progress class="cp-progress" value="40" max="100" aria-label="Uploading">
 *   <div class="cp-progress" role="progressbar" aria-label="Uploading" aria-valuenow="40"
 *        aria-valuemin="0" aria-valuemax="100"><span class="cp-progress__bar" style="width:40%"></span></div>
 * Indeterminate: a <progress> without value, or .cp-progress--indeterminate on the div. The
 * label is required; the percentage (or "working") belongs in text beside it. */
.cp-progress {
  appearance: none;
  display: block;
  position: relative;
  width: 100%;
  height: 4px;
  padding: 0;
  overflow: hidden;
  background: var(--hairline);
  border: 0;
  border-radius: 0;
  color: var(--fg);
}
.cp-progress__bar {
  display: block;
  height: 100%;
  background: var(--fg);
}
progress.cp-progress::-webkit-progress-bar {
  background: var(--hairline);
}
progress.cp-progress::-webkit-progress-value {
  background: var(--fg);
}
progress.cp-progress::-moz-progress-bar {
  background: var(--fg);
}
.cp-progress--indeterminate .cp-progress__bar {
  width: 40%;
}
@media (prefers-reduced-motion: no-preference) {
  .cp-progress--indeterminate .cp-progress__bar {
    animation: cp-progress-travel 1.2s var(--ease) infinite;
  }
  progress.cp-progress:indeterminate::-moz-progress-bar {
    animation: cp-progress-travel 1.2s var(--ease) infinite;
  }
}
@keyframes cp-progress-travel {
  from {
    translate: -100% 0;
  }
  to {
    translate: 250% 0;
  }
}

/* --- Floating panels ---
 * Panel looks only. The component places them in the top layer (openOverlay /
 * positionOverlay); `inset: auto` hands the position to it. */

/* A tooltip: ink on --fg, 21:1. At most 32 characters wide, square, no shadow. */
.cp-tooltip {
  white-space: pre-line; /* the text keeps its line breaks */
  position: fixed;
  inset: auto;
  max-width: 32ch;
  margin: 0;
  padding: var(--space-1) var(--space-2);
  overflow: visible;
  background: var(--fg);
  color: var(--bg);
  border: 0;
  border-radius: 0;
  box-shadow: none;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: 1.4;
  overflow-wrap: anywhere;
}

/* A popover: a bordered panel. The edge is --field-border (a control boundary). Floating
   overlays are the only thing with a shadow (--shadow-md); cards and the tooltip are flat. */
.cp-popover {
  position: fixed;
  inset: auto;
  max-width: calc(100vw - 16px);
  margin: 0;
  padding: var(--space-3);
  overflow: auto;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--field-border);
  border-radius: 0;
  box-shadow: var(--shadow-md);
  font-size: var(--text-sm);
}
.cp-popover:focus-visible {
  outline: var(--focus-ring) solid var(--interactive);
  outline-offset: calc(-1 * var(--focus-ring));
}

/* --- Kbd: a key, in mono, in a bordered cap. --- */
.cp-kbd {
  display: inline-block;
  padding: 0 var(--space-1);
  border: 1px solid var(--field-border);
  border-bottom-width: 2px;
  border-radius: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: 1.6;
  white-space: nowrap;
  color: var(--fg);
  background: var(--bg);
}

/* --- Forced colours (Windows High Contrast) ---
 * The browser replaces author colours with system ones and drops backgrounds and shadows, so
 * anything that shows state with a background needs a border, an outline or a system colour
 * keyword (those are kept). Highlight/HighlightText mark the on state, GrayText the off. */
@media (forced-colors: active) {
  .cp-btn {
    border-color: ButtonText;
  }
  .cp-btn:hover:not(:disabled, [aria-disabled='true']) {
    background: Highlight;
    border-color: Highlight;
    color: HighlightText;
  }
  .cp-btn:disabled,
  .cp-btn[aria-disabled='true'] {
    opacity: 1;
    color: GrayText;
    border-color: GrayText;
  }
  /* Pressed: Highlight fill plus a rule drawn inside it (box-shadow does not survive). */
  .cp-btn[aria-pressed='true'] {
    background: Highlight;
    border-color: Highlight;
    color: HighlightText;
    box-shadow: none;
    outline: 1px solid HighlightText;
    outline-offset: -4px;
  }
  .cp-btn[aria-pressed='true']:focus-visible {
    outline: var(--focus-ring) solid CanvasText;
    outline-offset: var(--focus-offset);
  }
  .cp-btn--quiet {
    border-color: transparent;
  }

  .cp-input,
  .cp-popover,
  .cp-kbd {
    border-color: CanvasText;
  }
  .cp-input[aria-invalid='true'] {
    border-width: 2px;
    padding: calc(var(--space-1) - 1px) calc(var(--space-2) - 1px);
  }
  .cp-input:disabled {
    opacity: 1;
    color: GrayText;
    border-color: GrayText;
  }
  .cp-check:has(input:disabled),
  .cp-option:has(input:disabled) {
    opacity: 1;
    color: GrayText;
  }
  .cp-check input,
  .cp-option input {
    background: Canvas;
    border-color: CanvasText;
  }
  .cp-check input:checked,
  .cp-option input:checked,
  .cp-check input:indeterminate,
  .cp-option input:indeterminate {
    background: Highlight;
    border-color: Highlight;
  }
  .cp-check input[type='checkbox']::before,
  .cp-option input[type='checkbox']::before {
    background: HighlightText;
  }
  .cp-check input[type='radio']:checked,
  .cp-option input[type='radio']:checked {
    box-shadow: none;
    background: radial-gradient(circle, HighlightText 0 28%, Highlight 32%);
  }

  .cp-switch {
    background: Canvas;
    border-color: CanvasText;
  }
  .cp-switch::before {
    background: CanvasText;
  }
  .cp-switch[aria-checked='true'],
  .cp-switch:checked {
    background: Highlight;
    border-color: Highlight;
  }
  .cp-switch[aria-checked='true']::before,
  .cp-switch:checked::before {
    background: HighlightText;
  }
  .cp-switch:disabled,
  .cp-switch[aria-disabled='true'] {
    opacity: 1;
    border-color: GrayText;
  }
  .cp-switch:disabled::before,
  .cp-switch[aria-disabled='true']::before {
    background: GrayText;
  }

  .cp-table-scroll:focus-visible,
  .cp-popover:focus-visible {
    outline-color: CanvasText;
  }

  /* Notices carry their kind in the rule's weight too, since colour is gone. */
  .cp-notice {
    border-color: CanvasText;
  }
  .cp-notice--signal {
    border-top-width: 2px;
    border-bottom-width: 2px;
  }
  .cp-notice--danger {
    border-top: 3px double CanvasText;
    border-bottom: 3px double CanvasText;
  }

  .cp-badge,
  .cp-badge--neutral,
  .cp-badge--signal,
  .cp-badge--danger,
  .cp-badge--interactive,
  .cp-badge--surface {
    border-color: CanvasText;
  }
  .cp-badge--signal {
    border-style: dashed;
  }
  .cp-badge--danger {
    border-width: 2px;
  }

  .cp-skeleton {
    background: none;
    border: 1px solid GrayText;
    animation: none;
  }
  .cp-spinner {
    height: 3px;
  }
  .cp-spinner::before {
    background: GrayText;
    opacity: 1;
  }
  .cp-spinner::after {
    background: CanvasText;
  }

  .cp-progress,
  progress.cp-progress {
    background: Canvas;
    border: 1px solid CanvasText;
    height: 8px;
    forced-color-adjust: none;
    color: CanvasText;
  }
  .cp-progress__bar,
  progress.cp-progress::-webkit-progress-value,
  progress.cp-progress::-moz-progress-bar {
    background: Highlight;
  }
  progress.cp-progress::-webkit-progress-bar {
    background: Canvas;
  }

  .cp-tooltip {
    background: Canvas;
    color: CanvasText;
    border: 1px solid CanvasText;
  }
}

/* Keep a row visible while reading across its cells or using its controls. */
.cp-table tbody tr:hover,
.cp-table tbody tr:focus-within {
  background: var(--surface);
}
.cp-table .cp-badge--neutral {
  color: var(--fg);
}

/* Native dialog hierarchy, consolidated from Knowledge Hub / Brain source-browser dialogs.
   showModal()/close(), accessible names, initial focus and saving remain host-owned.
   Angular Dialog applies these same classes. Never display:flex on a closed dialog. */
.cp-dialog {
  --cp-dialog-inset: max(var(--space-3), env(safe-area-inset-top), env(safe-area-inset-bottom), env(safe-area-inset-left), env(safe-area-inset-right));
  width: min(560px, calc(100% - 2 * var(--cp-dialog-inset)));
  max-width: none;
  max-height: calc(100dvh - 2 * var(--cp-dialog-inset));
  overscroll-behavior: contain;
  scroll-padding-block: var(--space-3);
  overflow-wrap: anywhere;
  padding: 0;
  margin: auto;
  overflow: auto;
  border: 1px solid var(--field-border);
  border-radius: 0;
  background: var(--bg);
  color: var(--fg);
}
.cp-dialog--sm { width: min(400px, calc(100% - 2 * var(--cp-dialog-inset))); }
.cp-dialog--lg { width: min(800px, calc(100% - 2 * var(--cp-dialog-inset))); }
/* Edge-aligned native modal for evidence/detail views; lifecycle stays host-owned. */
.cp-dialog--drawer {
  width: min(640px, 100%);
  height: 100dvh;
  max-height: 100dvh;
  margin: 0 0 0 auto;
  border-width: 0 0 0 1px;
  padding: var(--space-4);
  padding-block-start: max(var(--space-4), env(safe-area-inset-top));
  padding-block-end: max(var(--space-4), env(safe-area-inset-bottom));
  padding-inline-end: max(var(--space-4), env(safe-area-inset-right));
  padding-inline-start: max(var(--space-4), env(safe-area-inset-left));
}
.cp-dialog--drawer[open] { display: flex; flex-direction: column; }
.cp-dialog::backdrop { background: var(--overlay); }
.cp-dialog__panel { padding: var(--space-4); }
.cp-dialog__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}
.cp-dialog__header > :first-child { min-width: 0; }
.cp-dialog__header > button { flex: none; }
.cp-dialog__title {
  margin: 0;
  font: 400 var(--text-lg)/1.4 var(--font-mono);
  overflow-wrap: anywhere;
}
.cp-dialog__header .cp-eyebrow { margin: 0 0 var(--space-2); }
.cp-dialog__description {
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--fg-secondary);
}
.cp-dialog__body:not(:empty) { margin-top: var(--space-4); }
.cp-dialog__body, .cp-dialog__section {
  display: grid;
  gap: var(--space-3);
  min-width: 0;
}
.cp-dialog__body > *, .cp-dialog__section > * { min-width: 0; }
.cp-dialog__section { margin-top: var(--space-3); }
.cp-dialog__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.cp-dialog__actions:not(:empty) {
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--hairline);
}
.cp-dialog__actions .cp-btn { min-width: 0; max-width: 100%; overflow-wrap: anywhere; white-space: normal; line-height: 1.4; padding-block: var(--space-2); }
/* Native disclosure for optional form sections and secondary page context. */
.cp-disclosure { border-top: 1px solid var(--hairline); padding-block: var(--space-3); }
.cp-disclosure > summary {
  width: fit-content;
  min-height: var(--target-min);
  font: 500 var(--text-sm)/1.6 var(--font-mono);
  color: var(--fg);
  cursor: pointer;
  overflow-wrap: anywhere;
}
.cp-disclosure > summary:hover { text-decoration: underline; text-underline-offset: var(--space-1); }
.cp-disclosure > summary:focus-visible, .cp-dialog:focus-visible {
  outline: var(--focus-ring) solid var(--interactive);
  outline-offset: var(--focus-offset);
}
@media (max-width: 600px) {
  .cp-dialog__panel { padding: var(--space-3); }
  .cp-dialog__actions .cp-btn { flex: 1 1 auto; }
  /* Keep fields readable without focus zoom and touch actions easy to acquire. */
  .cp-input { font-size: var(--text-md); min-width: 0; max-width: 100%; }
  .cp-btn, .cp-disclosure > summary { min-height: 44px; }
}
@media (forced-colors: active) {
  .cp-dialog, .cp-dialog__actions, .cp-disclosure { border-color: CanvasText; }
  .cp-dialog:focus-visible, .cp-disclosure > summary:focus-visible { outline-color: Highlight; }
  .cp-dialog::backdrop { background: Canvas; opacity: 0.7; }
}

/* Framework-free icons and validation share the existing Angular registry/error pattern. */
.cp-icon { display: inline-block; flex: none; vertical-align: middle; fill: none; stroke: currentColor; stroke-width: 1.5px; stroke-linecap: square; stroke-linejoin: miter; }
.cp-icon[data-family='general'], .cp-icon[data-family='systems'] { stroke-linecap: butt; }
.cp-icon path { vector-effect: non-scaling-stroke; }
.cp-error-summary { border: 2px solid var(--signal); padding: var(--space-3); color: var(--fg); background: var(--bg); }
.cp-error-summary > [role='heading'] { font: 500 var(--text-md)/1.5 var(--font-mono); }
.cp-error-summary ul { padding-left: var(--space-4); margin-block: var(--space-2) 0; }
.cp-error-summary a { display: inline-block; min-height: var(--target-min); text-decoration: underline; }
.cp-error-summary:focus-visible { outline: var(--focus-ring) solid var(--interactive); outline-offset: var(--focus-offset); }
.cp-field > .cp-error { display: block; margin-top: var(--space-1); }
@media (forced-colors: active) { .cp-error-summary { border-color: CanvasText; } .cp-error-summary:focus-visible { outline-color: Highlight; } }

.cp-field + .cp-error { display: block; margin-top: calc(-1 * var(--space-2)); }

.cp-field-feedback { min-width: 0; }
.cp-field-feedback > .cp-error { display: block; margin-top: var(--space-1); }

/* Inline explanation for a chrome icon action: available on hover and keyboard focus.
   Kept in flow so it cannot be clipped or require another floating-panel implementation. */
.cp-icon-action { display: inline-flex; align-items: center; gap: var(--space-2); }
.cp-icon-action__label { display: none; font-size: var(--text-sm); }
.cp-icon-action:hover > .cp-icon-action__label,
.cp-icon-action:focus-within > .cp-icon-action__label { display: inline; }
