/*!
 * GOV UI
 * Lightweight UI for government software.
 *
 * Framework-independent stylesheet. Link it directly; no build step
 * is required. Theme it by overriding the --gov-* custom properties.
 *
 * MIT licensed. Not affiliated with or endorsed by any government.
 */

/*
 * GOV UI — design tokens
 *
 * Tokens are the contract between the visual system and the components.
 * Components consume these variables; they never repeat raw values.
 *
 * A department themes GOV UI by overriding variables here, not by editing
 * component CSS. See docs/design-principles.md.
 */

:root {
  /* ---------------------------------------------------------------
   * Color — primary
   * ------------------------------------------------------------- */

  --gov-primary: #0b2a55;
  --gov-primary-hover: #071d3d;
  --gov-primary-contrast: #ffffff;

  /* ---------------------------------------------------------------
   * Color — surfaces and text
   * ------------------------------------------------------------- */

  --gov-background: #ffffff;
  --gov-surface: #f8fafc;
  --gov-surface-sunken: #eef2f7;

  --gov-text: #111827;
  --gov-text-muted: #56616f;
  --gov-text-inverse: #ffffff;

  /* Two border tokens, because they have different jobs.
   *
   * --gov-border is decoration: table rules, dividers, card edges. It may
   * be light, because nothing depends on seeing it precisely.
   *
   * --gov-border-strong is the edge of an interactive control — an input,
   * a secondary button. WCAG 2.2 requires 3:1 against the adjacent
   * background for those (1.4.11 Non-text Contrast), and the decorative
   * value does not come close. Using one token for both is the most
   * common way a design system quietly fails this criterion. */
  --gov-border: #d7dee8;
  --gov-border-strong: #6b7785;

  /* ---------------------------------------------------------------
   * Color — focus
   *
   * Deliberately NOT derived from --gov-primary: a navy ring on a navy
   * button is invisible.
   *
   * Yellow alone is not enough either — #ffdd00 on white is about 1.1:1,
   * so a plain yellow ring fails against light backgrounds. The ring is
   * therefore two-tone: a yellow band sandwiched in a dark one, so
   * whatever the ring sits on, an adjacent edge carries the contrast.
   * See the :focus-visible rule in base.css.
   * ------------------------------------------------------------- */

  --gov-focus: #ffdd00;
  --gov-focus-contrast: #0b0c0c;
  --gov-focus-width: 3px;
  --gov-focus-offset: 2px;

  /* ---------------------------------------------------------------
   * Color — status
   *
   * Each status is a tinted surface with dark text, not a saturated fill
   * with white text. The reference screens use solid amber with white
   * text, which does not reach 4.5:1.
   *
   * Status must never be carried by color alone (WCAG 1.4.1) — the
   * component pairs these with a text label.
   * ------------------------------------------------------------- */

  --gov-success: #15803d;
  --gov-success-surface: #e3f2e7;
  --gov-success-text: #14532d;

  --gov-warning: #b45309;
  --gov-warning-surface: #fbeedb;
  --gov-warning-text: #703c04;

  --gov-danger: #b91c1c;
  --gov-danger-hover: #911616;
  --gov-danger-surface: #fbe6e6;
  --gov-danger-text: #8f1414;

  --gov-info: #0369a1;
  --gov-info-surface: #e2eff7;
  --gov-info-text: #0b4a6f;

  --gov-neutral-surface: #eef1f5;
  --gov-neutral-text: #33404f;

  /* ---------------------------------------------------------------
   * Typography
   *
   * System stack first, so nothing is downloaded. Government networks are
   * frequently locked down or offline, and the target device is a low-end
   * phone on a slow connection — not a laptop. Indic faces follow as
   * local fallbacks rather than as a webfont.
   * ------------------------------------------------------------- */

  --gov-font-sans:
    system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif,
    "Noto Sans", "Noto Sans Devanagari", "Noto Sans Bengali",
    "Noto Sans Tamil";

  /* Tabular figures for IDs, dates and amounts, so digits align down a
   * column. Applied by the table and any numeric cell — not globally,
   * because proportional figures read better in prose. */
  --gov-font-tabular: "Menlo", "Consolas", ui-monospace, monospace;

  --gov-font-size-1: 12px;
  --gov-font-size-2: 14px;
  --gov-font-size-3: 16px;
  --gov-font-size-4: 18px;
  --gov-font-size-5: 20px;
  --gov-font-size-6: 24px;
  --gov-font-size-7: 28px;
  --gov-font-size-8: 32px;
  --gov-font-size-9: 40px;
  --gov-font-size-10: 48px;

  --gov-font-weight-normal: 400;
  --gov-font-weight-medium: 500;
  --gov-font-weight-bold: 600;

  /* A floor, not a preference. Devanagari matras sit above and below the
   * baseline and clip at the ~1.2 heading line-height most design systems
   * use. Bengali, Tamil and Gurmukhi behave the same way. Costs nothing
   * now; breaks every heading if retrofitted later. */
  --gov-line-height-tight: 1.4;
  --gov-line-height-body: 1.6;

  /* ---------------------------------------------------------------
   * Spacing — numeric steps, not t-shirt sizes
   * ------------------------------------------------------------- */

  --gov-space-1: 4px;
  --gov-space-2: 8px;
  --gov-space-3: 12px;
  --gov-space-4: 16px;
  --gov-space-5: 20px;
  --gov-space-6: 24px;
  --gov-space-7: 32px;
  --gov-space-8: 40px;
  --gov-space-9: 48px;

  /* ---------------------------------------------------------------
   * Shape — small radii. GOV UI is border-driven, not card-driven.
   * ------------------------------------------------------------- */

  --gov-radius-sm: 3px;
  --gov-radius-md: 5px;
  --gov-border-width: 1px;

  /* ---------------------------------------------------------------
   * Density
   *
   * Administrative software is read all day. Density is a mode set once
   * on a container, never a prop on a component.
   * ------------------------------------------------------------- */

  --gov-control-height: 40px;
  --gov-table-row-padding-block: var(--gov-space-3);

  /* ---------------------------------------------------------------
   * Layout
   * ------------------------------------------------------------- */

  --gov-content-width: 1280px;

  /* ---------------------------------------------------------------
   * Motion — only where it communicates state. Overridden to 0 under
   * prefers-reduced-motion in base.css.
   * ------------------------------------------------------------- */

  --gov-duration: 120ms;
  --gov-easing: ease-out;
}

/*
 * Compact density.
 *
 * The reference screens spend ~90px of row height on a single line of
 * text. A caseworker working a long queue wants closer to 40.
 */
[data-gov-density="compact"] {
  --gov-control-height: 32px;
  --gov-table-row-padding-block: var(--gov-space-2);
}

/*
 * GOV UI — base styles
 *
 * A deliberately small reset plus the global behaviors every component
 * depends on: focus, high contrast, reduced motion.
 *
 * Everything here is opt-in at the document level. GOV UI does not
 * restyle arbitrary elements beyond what a reset needs, because it is
 * frequently dropped into an existing application that already has
 * styles of its own.
 */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--gov-background);
  color: var(--gov-text);
  font-family: var(--gov-font-sans);
  font-size: var(--gov-font-size-3);
  line-height: var(--gov-line-height-body);
}

/*
 * Headings use the tight line-height, which is floored at 1.4 so that
 * Devanagari, Bengali, Tamil and Gurmukhi matras are not clipped.
 */
h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 0;
  line-height: var(--gov-line-height-tight);
  font-weight: var(--gov-font-weight-bold);
}

/*
 * Focus.
 *
 * Two-tone by necessity. A single yellow ring is about 1.1:1 against a
 * white page, so on its own it fails SC 1.4.11 on light backgrounds; a
 * single dark ring disappears on dark backgrounds. Painting a yellow
 * band inside a dark one means whichever surface the ring lands on,
 * one of its two edges carries the contrast.
 *
 * The outline is drawn on top of the box-shadow, so the layers read
 * outward as: dark, yellow, dark.
 */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--gov-focus-width) solid var(--gov-focus);
  outline-offset: var(--gov-focus-offset);
  box-shadow: 0 0 0
    calc(var(--gov-focus-offset) + var(--gov-focus-width) * 2)
    var(--gov-focus-contrast);
}

/*
 * Windows High Contrast / forced-colors.
 *
 * A meaningful number of government users browse with forced colors on.
 * Authored colors are discarded there, so the ring is re-expressed with
 * a system color; box-shadow is not rendered at all in this mode, which
 * is why the outline has to stand on its own.
 */
@media (forced-colors: active) {
  :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: var(--gov-focus-width) solid Highlight;
    outline-offset: var(--gov-focus-offset);
    box-shadow: none;
  }

  /* Borders drawn with background-color vanish under forced colors.
   * Anything structural must use a real border so it survives. */
  .gov-table,
  .gov-table th,
  .gov-table td {
    border-color: CanvasText;
  }
}

/*
 * Motion.
 *
 * Zeroing the duration token is enough, because components read the
 * token rather than hard-coding durations.
 */
@media (prefers-reduced-motion: reduce) {
  :root {
    --gov-duration: 0ms;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/*
 * Visually hidden, but available to assistive technology.
 *
 * Used for skip-link targets, table caption text and status
 * announcements. Not `display: none`, which removes it from the
 * accessibility tree entirely.
 */
.gov-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/*
 * Numeric columns. Tabular figures make digits align down a column,
 * which is the difference between a scannable ID column and a ragged
 * one. Applied deliberately, not globally — proportional figures read
 * better in prose.
 */
.gov-tabular {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/*
 * Button
 *
 * Three variants and two sizes. Not fifteen: every additional variant is
 * a decision pushed onto the application author, and the point of a
 * design system is to make that decision once.
 */

.gov-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--gov-space-2);

  border: var(--gov-border-width) solid transparent;
  border-radius: var(--gov-radius-sm);

  font: inherit;
  font-weight: var(--gov-font-weight-bold);
  line-height: var(--gov-line-height-tight);
  text-align: center;
  text-decoration: none;

  cursor: pointer;
}

/*
 * Size lives entirely in the size modifiers, so both classes carry
 * meaning. Putting the medium values on the base and only overriding for
 * small leaves `gov-button--md` in every piece of markup while styling
 * nothing — a class that looks load-bearing and is not.
 *
 * Buttons sit next to inputs constantly, so medium tracks the shared
 * control height and a toolbar lines up.
 */
.gov-button--md {
  min-height: var(--gov-control-height);
  padding-inline: var(--gov-space-4);
  font-size: var(--gov-font-size-2);
}

.gov-button--sm {
  min-height: calc(var(--gov-control-height) - 8px);
  padding-inline: var(--gov-space-3);
  font-size: var(--gov-font-size-1);
}

.gov-button--primary {
  background: var(--gov-primary);
  color: var(--gov-primary-contrast);
}

.gov-button--primary:hover {
  background: var(--gov-primary-hover);
}

/*
 * Secondary carries a strong border, not the decorative one. It is the
 * edge of an interactive control, so it needs 3:1 against the page
 * (WCAG 2.2 SC 1.4.11).
 */
.gov-button--secondary {
  background: var(--gov-background);
  color: var(--gov-text);
  border-color: var(--gov-border-strong);
}

.gov-button--secondary:hover {
  background: var(--gov-surface-sunken);
}

.gov-button--danger {
  background: var(--gov-danger);
  color: var(--gov-text-inverse);
}

.gov-button--danger:hover {
  background: var(--gov-danger-hover);
}

/*
 * Disabled is deliberately dimmed rather than greyed to illegibility.
 * A control the user cannot operate still has to be readable, because
 * they need to know what they are being denied.
 */
.gov-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/*
 * Under forced colors, authored backgrounds are discarded and every
 * variant collapses to the same appearance. A border keeps the button
 * looking like a button.
 */
@media (forced-colors: active) {
  .gov-button {
    border-color: ButtonBorder;
  }
}

/*
 * Field: label, hint, error and control.
 *
 * Input and Select share this, because the wiring is the part that
 * matters and it is identical for both.
 */

.gov-field {
  display: flex;
  flex-direction: column;
  gap: var(--gov-space-1);
  margin-block-end: var(--gov-space-4);
}

.gov-field__label {
  font-size: var(--gov-font-size-2);
  font-weight: var(--gov-font-weight-bold);
  line-height: var(--gov-line-height-tight);
  color: var(--gov-text);
}

.gov-field__hint {
  margin: 0;
  font-size: var(--gov-font-size-2);
  line-height: var(--gov-line-height-tight);
  color: var(--gov-text-muted);
}

.gov-field__error {
  margin: 0;
  font-size: var(--gov-font-size-2);
  font-weight: var(--gov-font-weight-bold);
  line-height: var(--gov-line-height-tight);
  color: var(--gov-danger-text);
}

/*
 * A red bar on the inline-start edge of the whole field.
 *
 * Logical property, so it moves to the right edge under RTL without a
 * second rule. It also means the error is visible when scanning a long
 * form, rather than only at the moment of reading the message.
 */
.gov-field--error {
  padding-inline-start: var(--gov-space-3);
  border-inline-start: 4px solid var(--gov-danger);
}

.gov-input,
.gov-select {
  min-height: var(--gov-control-height);
  padding: var(--gov-space-2) var(--gov-space-3);

  /* The strong border: this is a control edge, which needs 3:1 against
   * the page. The decorative --gov-border would fail SC 1.4.11 here. */
  border: var(--gov-border-width) solid var(--gov-border-strong);
  border-radius: var(--gov-radius-sm);

  background: var(--gov-background);
  color: var(--gov-text);

  font: inherit;
  font-size: var(--gov-font-size-3);
  line-height: var(--gov-line-height-tight);

  /* Without this, a long input overflows its grid or flex parent
   * instead of shrinking. */
  min-width: 0;
  max-width: 100%;
}

/*
 * The error state thickens the border rather than only recoloring it,
 * so the state survives forced-colors mode and is not carried by color
 * alone.
 */
.gov-input--error,
.gov-select--error {
  border-width: 2px;
  border-color: var(--gov-danger);
}

.gov-input:disabled,
.gov-select:disabled {
  background: var(--gov-surface-sunken);
  color: var(--gov-text-muted);
  cursor: not-allowed;
}

.gov-input[readonly] {
  background: var(--gov-surface);
}

/*
 * Keep the native select arrow. Replacing it with a background image
 * means maintaining an icon that ignores the user's color scheme and
 * disappears under forced colors — for no functional gain.
 */
.gov-select {
  padding-inline-end: var(--gov-space-2);
}

/*
 * Layout: Page, PageHeader, Toolbar.
 *
 * Three containers, no grid system. A utility framework is explicitly
 * out of scope (CLAUDE.md section 27) — applications use ordinary CSS
 * for their own layout.
 */

/* ---------------------------------------------------------------
 * Page
 * ------------------------------------------------------------- */

.gov-page {
  max-width: var(--gov-content-width);
  margin-inline: auto;

  /* padding-block and padding-inline rather than the shorthand, so a
   * side gutter is always present at small widths. */
  padding-block: var(--gov-space-7);
  padding-inline: var(--gov-space-6);
}

@media (max-width: 40em) {
  .gov-page {
    padding-block: var(--gov-space-5);
    padding-inline: var(--gov-space-4);
  }
}

/* ---------------------------------------------------------------
 * PageHeader
 * ------------------------------------------------------------- */

.gov-page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--gov-space-6);
  margin-block-end: var(--gov-space-6);
}

.gov-page-header__content {
  /* Lets the title wrap instead of forcing the actions off the row. */
  min-width: 0;
  flex: 1 1 20rem;
}

.gov-page-header__title {
  font-size: var(--gov-font-size-8);
  line-height: var(--gov-line-height-tight);
  color: var(--gov-text);
}

.gov-page-header__description {
  margin-block: var(--gov-space-2) 0;
  font-size: var(--gov-font-size-3);
  color: var(--gov-text-muted);
}

.gov-page-header__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gov-space-3);
}

@media (max-width: 40em) {
  .gov-page-header__title {
    font-size: var(--gov-font-size-6);
  }
}

/* ---------------------------------------------------------------
 * Toolbar
 * ------------------------------------------------------------- */

.gov-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--gov-space-3);

  margin-block-end: var(--gov-space-4);
  padding: var(--gov-space-4);

  border: var(--gov-border-width) solid var(--gov-border);
  border-radius: var(--gov-radius-md);
  background: var(--gov-background);
}

/*
 * Fields inside a toolbar drop the bottom margin they carry in a form:
 * the toolbar's own gap handles spacing, and `align-items: flex-end`
 * lines the controls up along their baseline regardless of whether each
 * one has a hint.
 */
.gov-toolbar .gov-field {
  margin-block-end: 0;
}

/*
 * Breadcrumb and Pagination.
 *
 * Both are lists of links; both use logical properties throughout so
 * they mirror correctly under RTL without a second set of rules.
 */

/* ---------------------------------------------------------------
 * Breadcrumb
 * ------------------------------------------------------------- */

.gov-breadcrumb {
  margin-block-end: var(--gov-space-4);
  font-size: var(--gov-font-size-2);
}

.gov-breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gov-space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.gov-breadcrumb__item {
  display: flex;
  align-items: center;
  gap: var(--gov-space-2);
}

/*
 * The separator is generated content on the item, not a character in the
 * markup, so it is never read aloud as "slash" between every level.
 *
 * `/` in the content string and a logical margin mean the chevron does
 * not need reversing under RTL.
 */
.gov-breadcrumb__item + .gov-breadcrumb__item::before {
  content: "/";
  color: var(--gov-text-muted);
}

.gov-breadcrumb__link {
  color: var(--gov-primary);
  text-decoration: underline;
}

.gov-breadcrumb__link:hover {
  text-decoration: none;
}

.gov-breadcrumb__current {
  color: var(--gov-text-muted);
}

/* ---------------------------------------------------------------
 * Pagination
 * ------------------------------------------------------------- */

.gov-pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gov-space-2);
  margin-block-start: var(--gov-space-4);
  font-size: var(--gov-font-size-2);
}

.gov-pagination__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gov-space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

/*
 * A 40px minimum on both axes. Pagination links are among the smallest
 * targets in an admin interface and among the most-tapped on a phone;
 * WCAG 2.2 SC 2.5.8 asks for 24px, and this is comfortably past it.
 */
.gov-pagination__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;

  min-width: var(--gov-control-height);
  min-height: var(--gov-control-height);
  padding-inline: var(--gov-space-3);

  border: var(--gov-border-width) solid transparent;
  border-radius: var(--gov-radius-sm);

  color: var(--gov-primary);
  text-decoration: underline;
}

.gov-pagination__link:hover {
  background: var(--gov-surface-sunken);
  text-decoration: none;
}

/*
 * The current page is filled, and it is also the only item carrying
 * aria-current, so the state is available whether or not color is
 * perceived.
 */
.gov-pagination__link--current {
  background: var(--gov-primary);
  color: var(--gov-primary-contrast);
  font-weight: var(--gov-font-weight-bold);
  text-decoration: none;
}

.gov-pagination__link--current:hover {
  background: var(--gov-primary-hover);
  color: var(--gov-primary-contrast);
}

.gov-pagination__link--previous,
.gov-pagination__link--next {
  font-weight: var(--gov-font-weight-bold);
}

@media (forced-colors: active) {
  .gov-pagination__link--current {
    border-color: CanvasText;
  }
}

/*
 * StatusBadge
 *
 * Tinted surface, dark text, always with a written label.
 *
 * The reference screens use a saturated fill with white text. Amber that
 * way measures about 2.1:1 and fails SC 1.4.3 — and a user who cannot
 * distinguish the fills has nothing else to read. The label is the
 * status; the color reinforces it.
 */

.gov-status {
  display: inline-flex;
  align-items: center;

  padding-block: var(--gov-space-1);
  padding-inline: var(--gov-space-2);

  border: var(--gov-border-width) solid transparent;
  border-radius: var(--gov-radius-sm);

  font-size: var(--gov-font-size-1);
  font-weight: var(--gov-font-weight-bold);
  line-height: var(--gov-line-height-tight);
  white-space: nowrap;
}

.gov-status--success {
  background: var(--gov-success-surface);
  color: var(--gov-success-text);
}

.gov-status--warning {
  background: var(--gov-warning-surface);
  color: var(--gov-warning-text);
}

.gov-status--danger {
  background: var(--gov-danger-surface);
  color: var(--gov-danger-text);
}

.gov-status--info {
  background: var(--gov-info-surface);
  color: var(--gov-info-text);
}

.gov-status--neutral {
  background: var(--gov-neutral-surface);
  color: var(--gov-neutral-text);
}

/*
 * Under forced colors the tints are discarded and every status looks
 * alike. A border keeps the badge distinguishable from the surrounding
 * cell text; the label continues to carry the meaning.
 */
@media (forced-colors: active) {
  .gov-status {
    border-color: CanvasText;
  }
}

/*
 * Table
 *
 * Border-driven and dense. The flagship pattern for administrative
 * software, so it earns more CSS than anything else here.
 */

/*
 * The scroll container.
 *
 * Focusable in the markup, which is what makes an overflowing table
 * reachable by keyboard. The focus ring from base.css applies, so a
 * keyboard user can see where they are before scrolling.
 */
.gov-table-wrapper {
  overflow-x: auto;
  border: var(--gov-border-width) solid var(--gov-border);
  border-radius: var(--gov-radius-md);
  background: var(--gov-background);
}

.gov-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--gov-font-size-2);
}

.gov-table__caption {
  padding: var(--gov-space-3) var(--gov-space-4);
  text-align: start;
  font-weight: var(--gov-font-weight-bold);
  color: var(--gov-text);
}

.gov-table__head {
  background: var(--gov-surface);
}

.gov-table__header {
  padding: var(--gov-space-3) var(--gov-space-4);
  text-align: start;
  font-weight: var(--gov-font-weight-bold);
  color: var(--gov-text);
  border-block-end: var(--gov-border-width) solid var(--gov-border);
  white-space: nowrap;
}

.gov-table__cell {
  padding-block: var(--gov-table-row-padding-block);
  padding-inline: var(--gov-space-4);
  border-block-end: var(--gov-border-width) solid var(--gov-border);
  color: var(--gov-text);
  vertical-align: middle;
}

/* No trailing rule above the wrapper's own border. */
.gov-table__row:last-child .gov-table__cell {
  border-block-end: 0;
}

.gov-table__row:hover {
  background: var(--gov-surface);
}

/*
 * Numeric columns align to the end and use tabular figures, so digits
 * line up down the column. The difference between a scannable ID column
 * and a ragged one.
 */
.gov-table__header--numeric,
.gov-table__cell--numeric {
  text-align: end;
  font-variant-numeric: tabular-nums;
}

/*
 * The sort control is a real link, so sorting works with no JavaScript.
 * It fills the header cell to give a comfortable target.
 */
.gov-table__sort {
  display: inline-flex;
  align-items: center;
  gap: var(--gov-space-1);
  color: inherit;
  text-decoration: none;
}

.gov-table__sort:hover {
  text-decoration: underline;
}

/*
 * Sort direction shown with a character, not an icon font or an image.
 * It survives forced-colors, needs no extra request, and is announced
 * correctly because aria-sort on the header is what actually conveys
 * the state — this is decoration.
 */
.gov-table__header[aria-sort="ascending"] .gov-table__sort::after {
  content: "\2191";
}

.gov-table__header[aria-sort="descending"] .gov-table__sort::after {
  content: "\2193";
}

/*
 * Print.
 *
 * Caseworkers print records constantly, and a table that prints badly
 * gets screenshotted instead. Repeating the header on each page is the
 * single highest-value print rule there is.
 */
@media print {
  .gov-table-wrapper {
    overflow: visible;
    border: 0;
  }

  .gov-table__head {
    display: table-header-group;
  }

  .gov-table__row {
    break-inside: avoid;
  }
}
