/* Leftover from the original ASP.NET Core MVC scaffold (`dotnet new mvc`'s default
   site.css): it set the root font-size to 14px on mobile / 16px from 768px up, which
   directly conflicts with NSW's own `html{font-size:100%}` reset (designsystem.nsw.gov.au)
   — since EVERY NSW font-size/spacing value is expressed in rem, this silently shrank the
   entire Design System's type/spacing scale by 12.5% (14/16) on any viewport under 768px
   (real mobile devices, or a narrow desktop window), while only "accidentally" matching
   the NSW spec at wider widths, and only for users whose browser default is exactly 16px.
   Removed outright so NSW's own 100% (i.e. "respect the browser/user font-size setting")
   rule applies everywhere, uncontested. */

/* Also leftover scaffold cruft: targeted Bootstrap's own .btn/.form-control/.form-check-input
   classes, none of which remain anywhere in this app after the full NSW component re-skin —
   this rule has been fully dead code since then. Removed rather than left to bit-rot further. */

html {
  position: relative;
  min-height: 100%;
}

body {
  margin-bottom: 60px;
}

/* Bootstrap's reboot re-declares `body{font-family:var(--bs-body-font-family)}` (its own
   system-font stack, NOT Public Sans) and `button,input,select,textarea{font-family:inherit}`
   at the SAME specificity as NSW's equivalent rules — and since Bootstrap's stylesheet is
   loaded AFTER NSW's in _Layout.cshtml, Bootstrap wins the cascade tie, silently overriding
   Public Sans with the browser's default system font on <body> (and therefore on every
   plain heading/paragraph/label that just inherits font-family) and on every form control.
   site.css loads last of all, so reasserting NSW's font-family here wins outright and
   restores Public Sans site-wide, matching the actual NSW Digital Design System. */
body,
button,
input,
select,
textarea {
  font-family: var(--nsw-font-family);
}

/* Header account area (right side of the NSW masthead) — not a stock NSW DDS
   component; matches the account-widget pattern used by other NSW Gov services. */
.nsw-header__account {
  margin-left: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 0.2rem;
  text-align: right;
}

.nsw-header__account-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.nsw-header__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background-color: #002664;
  color: #fff;
  font-weight: 700;
  font-size: 0.75rem;
  flex-shrink: 0;
}

.nsw-header__account-org {
  font-size: 0.75rem;
  text-transform: uppercase;
  color: #55565b;
}

/* NSW's .nsw-form__helper--error/--valid always paint a padded background box,
   even with no message text (asp-validation-for renders an empty span until
   there's an actual error) — hide the box entirely when it has no content. */
.nsw-form__helper--error:empty,
.nsw-form__helper--valid:empty {
  display: none;
}

/* The NSW form template's error/valid helper text is normally preceded by a
   material-icons child span (see designsystem.nsw.gov.au/components/form) — but that
   markup can't be injected inside asp-validation-for's own span (the tag helper
   overwrites its content with the validation message) without breaking the :empty rule
   above. Render the icon via a ::before ligature instead: it's not a real child node, so
   :empty still correctly detects "no error" and hides the box. */
.nsw-form__helper--error:not(:empty)::before,
.nsw-form__helper--valid:not(:empty)::before {
  font-family: "Material Icons";
  margin-right: 0.25rem;
  vertical-align: text-bottom;
}

.nsw-form__helper--error:not(:empty)::before {
  content: "cancel";
}

.nsw-form__helper--valid:not(:empty)::before {
  content: "check_circle";
}

/* Port of legacy's .msg-attention/.center/.larger (Themes/theme01/css/site.css) — the
   "Next System Test Date Based on X Year(s) Time Interval" banner on the Test Result form,
   computed from Test Conducted Date + Retest Interval. Colors match legacy exactly. */
.next-test-date-banner {
  background-color: #faeeaa;
  border: 1px solid #ffd800;
  padding: 20px 10px;
  margin: 10px 0;
  text-align: center;
  color: #000;
}

.next-test-date-banner .larger {
  font-size: 30px;
}

/* NSW's .nsw-card is designed as a clickable teaser link (its :hover state darkens the
   whole card as click affordance) but throughout this app it's reused as a plain static
   panel — a <div>, never an <a> — for grouping content like forms or summaries. Cancel
   the hover-darkening only for that div usage (restoring .nsw-card__content's own resting
   values exactly — border-color must stay var(--nsw-grey-03), matching its non-hover
   value, not var(--nsw-brand-dark) which still visibly changed the border on hover); a
   real future `<a class="nsw-card">` link card would still get NSW's intended hover
   feedback. */
div.nsw-card:hover .nsw-card__content {
  background-color: var(--nsw-white);
  border-color: var(--nsw-grey-03);
}

div.nsw-card:hover,
div.nsw-card:hover .nsw-material-icons,
div.nsw-card:hover a {
  color: inherit;
}

div.nsw-card,
div.nsw-card .nsw-card__content {
  transition: none;
}

/* Legacy's ContentHeader (Template/global.Master) is one <h1> holding the page heading, the
   Help link and the "Change Systems Display List" dropdown on a single line, the latter two
   floated right (.help { float: right }). Reproduced as flex rather than floats, inside the
   nsw-masthead--light banner this app already uses for page titles. Not a stock DDS
   component — hence the cps- prefix rather than a fake nsw- one. */
.cps-page-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
}

.cps-page-heading__title {
  margin: 0;
}

.cps-page-heading__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  /* justify-content: space-between only right-aligns these while they share the row with the
     title. A long title (OrgInvite's runs the full width) pushes them onto their own line, where
     space-between leaves them at flex-start; margin-left keeps them right-aligned either way. */
  margin-left: auto;
}

/* The scope <select> sizes to its content (legacy CssClass="width-auto") instead of
   stretching, so it sits beside the heading rather than below it. */
.cps-page-heading__scope {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.cps-page-heading__scope .nsw-form__select {
  width: auto;
  max-width: 100%;
}

/* Port of legacy's .msg-box-gray (Themes/theme01/css/site.css) — the grey strip carrying the
   "Export the CP Systems list below to Excel" label and its button. Legacy's #EEE/#BBB are
   swapped for the nearest DDS tokens so it stays on-palette. */
.cps-panel-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  background-color: var(--nsw-off-white);
  border: 1px solid var(--nsw-grey-03);
  padding: 1rem;
  margin-bottom: 1rem;
}

/* ---- DeviceManager Add/Edit form (Views/DeviceManager/Edit.cshtml, shared by both) ---- */

/* NSW gives `.nsw-form` a 3rem top margin and `h2` another 3rem of its own. Stacked, that left
   ~6rem of empty space between the page heading and the first section heading. Collapsed to a
   single small gap; the per-section spacing is handled by .cps-form-section below. */
.cps-device-form {
  margin-top: 1rem;
}

/* ---- Site-wide maintenance banner (OutageBanner view component) ---- */

/* NSW's in-page alert is built for flowing page content: 2rem top margin, 1.5rem padding and
   a left-aligned icon+text row. Sitting at the very top of every page that reads as a tall
   band of empty space, so the layout is replaced here — centred and compact — while the
   palette, left accent bar and warning icon colour still come from the component. */
.cps-outage-banner {
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin: 0;
  /* Symmetrical side padding leaves room for the close button without pulling the centred
     message off-centre. */
  padding: 0.5rem 3rem;
}

.cps-outage-banner__icon {
  margin-right: 0;
}

.cps-outage-banner__text {
  margin: 0;
  text-align: center;
}

/* Taken out of the flex flow (.nsw-in-page-alert is already position:relative) so the message
   centres on the banner rather than on whatever space is left beside the button. */
.cps-outage-banner__close {
  position: absolute;
  top: 50%;
  right: 0.75rem;
  transform: translateY(-50%);
  display: flex;
  padding: 0.25rem;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}

.cps-outage-banner__close:hover {
  color: var(--nsw-brand-dark);
}

.cps-outage-banner__close:focus-visible {
  outline: 3px solid var(--nsw-focus);
  outline-offset: 2px;
}

/* NSW gives every .nsw-in-page-alert a 2rem top margin, which is right for an alert dropped
   into flowing prose but too much for a stack of them sitting directly under a page's action
   bar — there it just reads as a hole. Used on DeviceManager/Details, where up to three of
   these can appear in a row between the button bar and the first form section. */
.cps-alert--tight {
  margin-top: 1rem;
}

.cps-form-section {
  margin-top: 1rem;
  /* .nsw-masthead's own 0.5rem top padding would otherwise show as a pale strip above the
     heading bar; zeroed so the bar sits flush at the top of its section. */
  padding-top: 0;

  /* These content panels are built on .nsw-masthead purely for its off-white band, but that
     component also sets font-size to --nsw-font-size-xxs (0.75rem) because its real job is the
     tiny "A NSW Government website" strip. Everything inside therefore inherited text 25%
     smaller than the body. It went unnoticed for a while because .nsw-form__input re-asserts
     1rem on itself, so readonly FIELD VALUES looked right while their labels, and any plain
     text or table put in the same panel, did not. Reset to the body size (sm is 1rem/1.5 at
     both breakpoints, so one declaration covers mobile and desktop). */
  font-size: var(--nsw-font-size-sm-desktop);
  line-height: var(--nsw-line-height-sm-desktop);
}

.cps-device-form > .cps-form-section:first-child {
  margin-top: 0;
}

/* Legacy styles every section subheading on this page as a solid black bar —
   `h2 { background-color:#000; color:#fff; padding:10px; margin-bottom:1px }`
   (Themes/theme01/css/theme-1.0.css). Reproduced with --nsw-black/--nsw-text-light. The bar
   aligns with the fields below it rather than bleeding to the section edge, since both sit
   inside the same .nsw-container. */
.cps-form-heading {
  margin: 0 0 1rem;
  padding: 0.5rem 1rem;
  background-color: var(--nsw-black);
  color: var(--nsw-text-light);
  font-size: 1.5rem;
  line-height: 1.4;
}

/* Several of these headings carry a qualifier span ("Available only to Admin", "(This will be
   available to the general public)") built from .nsw-form__helper, whose grey is unreadable on
   black. */
.cps-form-heading .nsw-form__helper {
  color: var(--nsw-text-light);
  font-weight: normal;
}

/* Horizontal radio group. NSW stacks radios by design — `.nsw-form__radio-label` is
   `display:block; margin:1rem 0 0` — and ships no inline variant, so a plain Yes/No pair takes
   two rows plus a gap. This lays the pair out on one line.

   Only the LABELS become flex items: `.nsw-form__radio-input` is `position:absolute; opacity:0`
   (NSW hides the native control and paints the dot with the label's ::before/::after), and an
   absolutely-positioned child is out of flow. The label keeps its 3rem left padding, which is
   the space that circle occupies. */
.cps-radio-inline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 1.5rem;
}

.cps-radio-inline .nsw-form__radio-label {
  margin-top: 0;
}

/* A row of label-above-select filters sitting side by side (AdminEmailListByCPS's "CPS List" and
   "Sort by"). Needed because `.nsw-form__select` is width:100% by default, so two of them in a
   plain flex row each claim a whole line and wrap. */
.cps-filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem 1.5rem;
  margin-bottom: 1rem;
}

.cps-filter-row__field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.cps-filter-row__field .nsw-form__select {
  width: auto;
  min-width: 16rem;
  max-width: 100%;
}

/* AdminEmailListByCPS's "Get List of Email For" strip — legacy's msg-attention box with a
   horizontal CheckBoxList (RepeatDirection="Horizontal") and the button floated right. */
.cps-email-type {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.5rem;
}

.cps-email-type__options {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 1.5rem;
}

/* NSW checkbox labels carry a 1rem top margin meant for stacked lists. */
.cps-email-type .nsw-form__checkbox-label {
  margin-top: 0;
}

/* Push the button to the right edge of the strip (legacy CssClass="float-right"). */
.cps-email-type .nsw-button {
  margin-left: auto;
}

/* txtEmailList — legacy renders it green (msg-box-green) and read-only-ish for copying. */
.cps-email-output {
  background-color: #eaf6ea;
  font-family: inherit;
}

/* Bulk agent assignment's CPS picker — legacy's
   `<div class="cps-list" style="overflow-y:auto; height:500px">` around its CheckBoxList. */
.cps-checkbox-list {
  overflow-y: auto;
  height: 500px;
  border: 1px solid var(--nsw-grey-03);
  padding: 0.5rem 1rem;
}

/* NSW checkbox labels carry their own top margin; one row per system without it doubling up. */
.cps-checkbox-list__item + .cps-checkbox-list__item {
  margin-top: 0.25rem;
}

/* A read-only grid used as a preview alongside a form (Replace Agent's list of the systems
   about to move) — capped so it never pushes the form off screen. */
.cps-scroll-table {
  max-height: 300px;
  overflow: auto;
}

/* Legacy renders the second line of a two-line grid cell smaller than the first — the branch
   under the organisation, the timestamp under the downloader's name
   (`<span style="font-size:smaller">` in gvCPSYearlyCertificateReportsSubmission). */
.cps-cell-secondary {
  font-size: smaller;
}

/* Home page's suburb / post-code search — input and button on one line, sized to content.
   Deliberately not nsw-grid/nsw-col: those add `padding: 2rem 0` per column plus negative row
   margins, which is right for a page-width layout grid but leaves a large dead gap under the
   heading band when all it holds is two adjacent controls. */
.cps-inline-search {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

/* .nsw-form__input is width:100% by default, which would push the button onto its own line. */
.cps-inline-search .nsw-form__input {
  width: auto;
  min-width: 18rem;
  max-width: 100%;
}

/* --wide: the pair spans the full row, box stretching and button pinned to the right edge, for
   list pages where the search sits above a full-width table (Admin/Organisations). The plain
   variant keeps its controls shrink-wrapped, which suits a short standalone form. */
.cps-inline-search--wide {
  flex-wrap: nowrap;
}

.cps-inline-search--wide .nsw-form__input {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
}

.cps-inline-search--wide .nsw-button {
  flex: 0 0 auto;
}

/* Column widths for the organisations list. Without these the browser sizes columns to content,
   so the fixed-width action buttons win and the Name column is squeezed into wrapping over
   several lines while space sits unused to its right. */
.cps-table-orgs table {
  table-layout: fixed;
  width: 100%;
}

.cps-table-orgs__name { width: 28%; }
.cps-table-orgs__abn { width: 14%; }
.cps-table-orgs__flag { width: 11%; }
.cps-table-orgs__actions { width: 36%; }

/* Keep Edit / View / Deactivate on a single line. The column above is sized to hold all three;
   nowrap stops the last one dropping to its own row when a browser would otherwise break there.
   Targeted by position because table-layout:fixed takes its widths from the header row, so only
   the <th> carries the width class. */
.cps-table-orgs tbody td:last-child {
  white-space: nowrap;
}

/* Contacts (List of All Registered Users). Seven columns, one of them full email addresses:
   left to size themselves the table grows past the container and .nsw-table's overflow-x
   turns into a horizontal scrollbar that hides the Login button. Fixed layout with explicit
   shares keeps everything inside the page width. */
.cps-table-contacts table {
  table-layout: fixed;
  width: 100%;
  /* .nsw-table table sets min-width:37.5rem for narrow viewports; that is well under the
     content area here, so it never fights the widths below. */
}

.cps-table-contacts__name { width: 13%; }
.cps-table-contacts__position { width: 15%; }
.cps-table-contacts__org { width: 19%; }
.cps-table-contacts__phone { width: 10%; }
.cps-table-contacts__mobile { width: 10%; }
.cps-table-contacts__email { width: 22%; }
.cps-table-contacts__actions { width: 11%; }

/* Email addresses carry no spaces to break at, so a long one overflows its fixed-width cell
   and spills into the next column. Targeted by position because table-layout:fixed takes its
   widths from the header row, so only the <th> carries the width class. */
.cps-table-contacts tbody td:nth-child(6) {
  overflow-wrap: anywhere;
}

/* Keep the Login button on one line in its column. */
.cps-table-contacts tbody td:last-child {
  white-space: nowrap;
}

/* ---- Certificate upload page (port of Cps/UploadCPScertificate.aspx + FileUpload.ascx) ---- */

/* Legacy `<h3>` — `background-color:#006699; color:#fff; padding:10px` — one step down from the
   black `<h2>` bar. The distinction is legacy's, so it is kept: h2 -> --nsw-black,
   h3 -> --nsw-brand-dark. */
.cps-subsection-heading {
  /* Flex so the bar can carry its own right-aligned actions, as legacy's
     `<h3 class="main-heading">… <a class="button float-right">` does on the Interested Parties
     list. Harmless where the bar is just text. */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  margin: 1rem 0;
  padding: 0.5rem 1rem;
  background-color: var(--nsw-brand-dark);
  color: var(--nsw-text-light);
  font-size: 1.25rem;
  line-height: 1.5;
}

.cps-subsection-heading__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

/* Legacy renders each interested party as a full-width `td.heading` band — branch name on the
   left, "RelationShip Status" and the action floated right — inside a GridView with
   ShowHeader="false". So it is a stack of ROWS, not a striped table with a "Branch" column,
   which is what this page had before; that structure is kept.
   The band's blue fill was dropped on request (2026-08-07) — a deliberate departure from
   legacy's #006699 — so the rows now sit on the section's own off-white and are separated by a
   rule instead of by colour. */
.cps-party-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--nsw-grey-03);
}

.cps-party-row:last-of-type {
  border-bottom: 0;
}

.cps-party-row__name {
  font-weight: var(--nsw-font-bold);
}

.cps-party-row__actions,
.cps-party-row__form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

/* The reason box sizes to content rather than stretching the band. */
.cps-party-row__form .nsw-form__input {
  width: auto;
  max-width: 100%;
}

/* `<table class="view">` with a `<td class="heading">` label cell: a fixed-width #006699 label
   beside a #e0e0e0 value cell. Expressed as a flex row rather than a layout table, since it is
   one label/control pair and not tabular data. */
.cps-field-row {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  margin-bottom: 1rem;
}

.cps-field-row__label {
  display: flex;
  align-items: center;
  /* Legacy is `td.heading { width: 200px }` — a real table column, so every label cell is
     identical and long text WRAPS inside it. `min-width` let a long label widen its own row
     instead, which is why the label column came out ragged. 12.5rem == legacy's 200px. */
  flex: 0 0 12.5rem;
  max-width: 100%;
  padding: 0.75rem 1rem;
  background-color: var(--nsw-brand-dark);
  color: var(--nsw-text-light);
  font-weight: var(--nsw-font-bold);
}

/* For the one genuinely long label ("Request Approval For Interval More Than 7 Years") — the
   wording is legacy's, so it is the type that gives rather than the text. */
.cps-field-row__label--sm {
  font-size: 0.875rem;
  line-height: 1.4;
}

.cps-field-row__value {
  display: flex;
  flex: 1 1 20rem;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1rem;
  background-color: var(--nsw-off-white);
}

.cps-field-row__value .nsw-form__select {
  width: auto;
  max-width: 100%;
}

/* A run of these rows is legacy's `<table class="view">` — collapsed table rows, not separated
   cards — so inside a row list they stack tight. A standalone row (the Certificates picker)
   keeps its own bottom margin. */
.cps-field-rows > .cps-field-row {
  margin-bottom: 1px;
}

/* The banners legacy renders as full-width `colspan="2"` rows sit in the same run. */
.cps-field-rows > .next-test-date-banner {
  margin: 1px 0;
}

/* Legacy's `h2 { margin-bottom: 1px }` puts the heading bar directly on top of whatever follows
   it. --flush restores that where the bar introduces its own content block (the Certificates
   page's Attached Files table); the DeviceManager form uses the same bar without it, because
   there the heading does need space before the first field. NSW's own
   `.nsw-table { margin-top: 2rem }` has to be cancelled as well, or it reopens the gap. */
.cps-form-heading--flush {
  margin-bottom: 0;
}

.cps-form-heading--flush + .nsw-table,
.cps-form-heading--flush + .cps-subsection-heading,
.cps-form-heading--flush + .cps-attention-msg {
  margin-top: 0;
}

/* lblMsg / lmsg — legacy's #faeeaa highlight, already ported once as .next-test-date-banner. */
.cps-attention-msg {
  background-color: #faeeaa;
  border: 1px solid #ffd800;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  color: #000;
}

/* lmsg sits inside divExistingFiles, tucked under the heading bar, so it takes the bar's own
   flush treatment rather than floating between the two. */
.cps-attention-msg--under-heading {
  margin-bottom: 0;
}

.cps-attention-msg--under-heading + .nsw-table,
.cps-attention-msg--under-heading + .cps-subsection-heading {
  margin-top: 0;
}

/* `.Delete-file { color:red; text-decoration:none; font-weight:bold; font-size:smaller }`. It is
   a POST here rather than legacy's GET link (deleting on GET is not something to reproduce), so
   the button is stripped back to look like the original text link. */
.cps-delete-file {
  background: none;
  border: 0;
  padding: 0;
  color: #d7153a;
  font-weight: var(--nsw-font-bold);
  font-size: smaller;
  cursor: pointer;
}

.cps-delete-file:hover {
  text-decoration: underline;
}

.cps-file-row__action {
  text-align: right;
  white-space: nowrap;
}

/* Legacy renders each nav alert count as `<span class="text-red"><strong>N</strong></span>`
   inside the item's own label — "Overdue Testing (35 CPS)" with just the 35 in red. Same idea
   here, using the DDS accent so it stays on-palette. */
.cps-nav-count {
  color: var(--nsw-brand-accent);
  font-weight: var(--nsw-font-bold);
}

/* Devices/Search's search panel. Legacy's pSearch is a single `<h3>` — `background-color:#006699;
   color:#fff; padding:10px` — holding the literal word "Search" plus the button, the search-by
   dropdown and the text box, the three controls pushed to the right by
   `h3 input, h3 select { float: right; margin-left: 7px }` (Themes/theme01/css/site.css). Same
   arrangement here as flexbox, and the same --nsw-brand-dark the grid headers use, since legacy
   gives both that identical #006699. Control order left-to-right is text box, dropdown, button —
   which is what those right floats actually produce, the first floated element landing furthest
   right. */
.cps-search-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  background-color: var(--nsw-brand-dark);
  color: var(--nsw-text-light);
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
}

/* Sized down from NSW's default heading scale: this is a bar label sitting beside form
   controls, not a section heading in the page's visual hierarchy. */
.cps-search-bar__label {
  margin: 0;
  font-size: 1.25rem;
  line-height: 1.5;
}

.cps-search-bar__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

/* Legacy's inputs size to their content rather than filling the row (txtSearch is
   CssClass="medium-font", ddlSearchBy is "width-auto"). */
.cps-search-bar__controls .nsw-form__input,
.cps-search-bar__controls .nsw-form__select {
  width: auto;
  max-width: 100%;
}

/* Legacy renders grid headers as a solid dark band with white text — `th, th a
   { background-color:#006699 !important; color:#fff !important; text-align:left }`
   (Themes/theme01/css/site.css). That rule is unscoped in legacy, i.e. EVERY grid in the Web
   Forms app looks this way, so this is applied to `.nsw-table` rather than to one page: all 21
   tables in this app are already inside an `.nsw-table` wrapper and every one of them has a
   `<thead>`, so no view markup needs to change and no table can be missed.

   NSW's own table has no dark-header variant (only --striped/--bordered/--valign-*), so this
   adds one. #006699 isn't in the NSW palette, so the treatment is reproduced with
   --nsw-brand-dark rather than the raw legacy hex; the DDS has a documented token set for
   content on dark surfaces (--nsw-text-light / --nsw-link-light / --nsw-focus-light), which is
   what makes the sort links and their focus ring legible here. */
.nsw-table thead {
  border-bottom: 0;
}

.nsw-table thead th {
  background-color: var(--nsw-brand-dark);
  color: var(--nsw-text-light);
  border-bottom: 0;
  vertical-align: middle;
}

/* Sortable column headings (the GridViews' AllowSorting links). NSW's default link colour is
   --nsw-link (#002664), i.e. the band's own background — invisible without this. */
.nsw-table thead th a {
  color: var(--nsw-link-light);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

.nsw-table thead th a:hover {
  text-decoration: underline;
}

/* NSW's standard focus ring (--nsw-focus, #0086b3) is too close to the dark band to read;
   --nsw-focus-light is the palette's answer for exactly this case. */
.nsw-table thead th a:focus {
  outline-color: var(--nsw-focus-light);
}

/* The sort-direction arrow is a Material Icons ligature, which carries its own colour. */
.nsw-table thead th .nsw-material-icons {
  color: inherit;
}

/* --bordered would otherwise draw a near-black grey-01 grid over the dark band. No view uses it
   today; this keeps the two composable if one ever does. */
.nsw-table--bordered thead th {
  border-color: var(--nsw-brand-dark);
}

/* Read-only detail views (e.g. DeviceManager/Details) reuse nsw-form__group/label to
   stack a bold label above its value, matching the NSW form template's field layout —
   but browsers indent <dd> by default, which only makes sense for the classic
   side-by-side dt/dd layout, not this stacked one. */
.nsw-form__group dd {
  margin-left: 0;
}