/* Roboto throughout, as ScafellWeb uses it. Self-hosted from libman (@fontsource-variable/roboto): one variable font
   per style covers every weight, so bold is real rather than synthesised, and the Latin Extended file loads only when
   a page has a character from its range. Scafell also loads it from Google Fonts; nothing here needs to. */
@font-face {
  font-family: "Roboto";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../lib/roboto/files/roboto-latin-wght-normal.woff2") format("woff2-variations");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

@font-face {
  font-family: "Roboto";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("../lib/roboto/files/roboto-latin-wght-italic.woff2") format("woff2-variations");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

@font-face {
  font-family: "Roboto";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../lib/roboto/files/roboto-latin-ext-wght-normal.woff2") format("woff2-variations");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

@font-face {
  font-family: "Roboto";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("../lib/roboto/files/roboto-latin-ext-wght-italic.woff2") format("woff2-variations");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

:root {
  --gc-font-family: Roboto, system-ui, -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  /* Bootstrap's body text, and every form control and button, which inherit it. */
  --bs-font-sans-serif: var(--gc-font-family);
  --bs-body-font-family: var(--gc-font-family);
}

/* DevExtreme's widgets, which name their own font (the theme's "segoe ui" stack) on these selectors. One element
   more specific than the theme's own rules, because each page links the theme after this stylesheet. */
html .dx-widget,
html .dx-widget input,
html .dx-widget textarea,
html .dx-overlay-wrapper,
html .dx-overlay-wrapper input,
html .dx-overlay-wrapper textarea,
html .dx-field,
html .dx-field input,
html .dx-field textarea,
html .dx-theme-generic-typography,
html .dx-theme-generic-typography input,
html .dx-theme-generic-typography textarea {
  font-family: var(--gc-font-family);
}

/* DevExtreme's charts are SVG, and set their font on the chart's own elements; !important because some labels
   carry it inline. Leaflet's map controls and attribution. */
svg.dxc text,
svg.dxc tspan,
.leaflet-container {
  font-family: var(--gc-font-family) !important;
}

/* Grids in Roboto 16px with the font shorthand, as ScafellWeb's site.css has it (".dx-datagrid { font: 16px Roboto }"):
   the shorthand also sets line-height back to normal, which is what spaces TradeCube's rows (34px: 7px of padding round
   a normal line), where the cells otherwise inherit Bootstrap's 1.5 from <body>. The size is then scaled by the Text
   size preference (textSize.css). "html" to outrank the theme, linked after this stylesheet. */
html .dx-datagrid {
  font: 16px var(--gc-font-family);
}

/* A Bootstrap badge in a grid cell (the event grids' Severity), kept within the cell's line: at Bootstrap's own padding
   it stands 1px taller than the text, and sat on the text's baseline its smaller font's descent drops below the line,
   each of which made those grids' rows taller than every other grid's. */
.dx-datagrid .badge {
  padding-top: 0.25em;
  padding-bottom: 0.25em;
  vertical-align: top;
}

/* A grid's command buttons centred on the line rather than sat on its baseline, as ScafellWeb's site.css has them: on
   the baseline DevExtreme's own icons (edit, delete) drop below the line by their font's descent and make the rows 1px
   taller than a Font Awesome icon's. Centred, every grid's rows are the same height whatever its buttons. */
.dx-datagrid .dx-command-edit .dx-link {
  vertical-align: middle;
}

/* Every grid's column headings bold in the primary colour, as ScafellWeb's site.css has them (#007bff there;
   Bootstrap's own primary here, so they follow the dark mode). */
.dx-header-row > td[role="columnheader"] > div.dx-datagrid-text-content {
  font-weight: bold;
  color: var(--bs-primary);
}

/* A column's header filter icon red while it filters and faded while it does not, as ScafellWeb's site.css has it, so
   a filtered column shows from across the grid. */
.dx-datagrid .dx-header-filter {
  color: var(--bs-danger);
}

.dx-datagrid .dx-header-filter-empty {
  color: rgba(149, 149, 149, 0.5);
}

/* The grids' View eye, coloured as ScafellWeb's site.css colours .fa-eye. */
.fa-eye {
  color: deepskyblue !important;
}

/* A focused editor's border in the primary colour, as ScafellWeb's site.css has it over the same generic theme
   (#007bff there; Bootstrap's own primary here, so it follows the dark mode). The theme draws it all round, and the
   rest — tight grid rows, labels beside values, dashed read-only borders — is the theme's own. */
html .dx-texteditor.dx-state-focused.dx-editor-filled,
html .dx-texteditor.dx-state-focused.dx-editor-underlined,
html .dx-texteditor.dx-state-focused.dx-editor-outlined {
  border-color: var(--bs-primary);
}

/* The same page text on every screen. DevExtreme puts its theme's typography class (.dx-theme-generic-typography) on
   <body> of any page with a DevExtreme widget (it falls back to <body> without a .dx-viewport), and that class restyles
   the whole PAGE, not just its widgets: body text at 14px, headings in fixed pixels (h1 34px at weight 200), small at
   12px, links in its blue. Pages without a widget (Alerts, Subscriptions, Market Analysis…) keep Bootstrap's, so text
   would change from screen to screen and only Bootstrap's would follow the Text size preference. Bootstrap's own values
   again, below; DevExtreme's widgets keep their own sizes (.dx-widget, textSize.css). "html body" to outrank the
   theme's rules, which each page links after this stylesheet. */
html body.dx-theme-generic-typography {
  background-color: var(--bs-body-bg);
  color: var(--bs-body-color);
  font-size: var(--bs-body-font-size);
  font-weight: var(--bs-body-font-weight);
  line-height: var(--bs-body-line-height);
}

html body.dx-theme-generic-typography :is(h1, h2, h3, h4, h5, h6) {
  font-weight: 500;
}

html body.dx-theme-generic-typography h1 { font-size: calc(1.375rem + 1.5vw); }
html body.dx-theme-generic-typography h2 { font-size: calc(1.325rem + 0.9vw); }
html body.dx-theme-generic-typography h3 { font-size: calc(1.3rem + 0.6vw); }
html body.dx-theme-generic-typography h4 { font-size: calc(1.275rem + 0.3vw); }
html body.dx-theme-generic-typography h5 { font-size: 1.25rem; }
html body.dx-theme-generic-typography h6 { font-size: 1rem; }

@media (min-width: 1200px) {
  html body.dx-theme-generic-typography h1 { font-size: 2.5rem; }
  html body.dx-theme-generic-typography h2 { font-size: 2rem; }
  html body.dx-theme-generic-typography h3 { font-size: 1.75rem; }
  html body.dx-theme-generic-typography h4 { font-size: 1.5rem; }
}

html body.dx-theme-generic-typography small {
  font-size: 0.875em;
}

/* Plain links only: a link with a class of its own (the nav bar's, buttons, BM Unit links) styles itself. */
html body.dx-theme-generic-typography a:not([class]) {
  color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
}

/* 16px at every width, as ScafellWeb's text is (Bootstrap's default, which it leaves alone), scaled by the
   Preferences screen's Text size (--gc-text-scale on <html>, wwwroot/js/site/preferenceService.js), and with it everything
   Bootstrap sizes in rem. Narrow screens were 14px, from the ASP.NET template. */
html {
  font-size: calc(16px * var(--gc-text-scale, 1));
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

/* scrollbar-gutter: the scrollbar's width is reserved on every page, whether it scrolls or not. Otherwise a page
   that scrolls is a scrollbar narrower than one that fits the window (BM Units, whose grid is sized to the space left),
   and everything right-aligned in the nav bar — the bell, the user menu — moves sideways between them. A no-op where
   scrollbars overlay the page (macOS, phones), which never had the problem. */
html {
  position: relative;
  min-height: 100%;
  scrollbar-gutter: stable;
}

/* Reserves the space the fixed .footer covers (below), so the end of a page can be scrolled clear of it. Kept in
   step with the footer's own height by hand (the logo's 52px, the padding's 16px and the 1px border) — the two are
   a pair, and a body margin larger than the footer is
   dead space at the bottom of every page, while a smaller one leaves the last of the page under it. */
body {
  margin-bottom: 69px;
}

/* The stock template shipped line-height: 60px here, which put a single line of ~16px text inside a
   60px line box — nearly 40px of pure white space across the bottom of every page, and a matching
   60px body margin reserving it. In Development it was worse: the footer renders a second paragraph
   (the culture name), so it stood ~120px tall while the body still reserved 60, and the overflow ran
   up under the page content.

   Here rather than in _Layout.cshtml.css, where it used to be: that file is CSS isolation, whose rules only
   match elements carrying the build's scope attribute (b-…), and Development's runtime Razor compilation
   recompiles an edited _Layout WITHOUT it. So the first edit to the layout dropped the footer into the page
   flow until the next build. An unscoped rule cannot be lost that way.

   Now sized by its own content: normal line height plus real padding. Anything measuring the space
   left above it — see fitHeights() in bidOfferCashflow.js and fitGridHeight() in bmUnits.js —
   reads the rendered height at runtime, so both adapt to this automatically. */
/* Fixed to the bottom of the window, as the header is held at the top, so it is always in view. It covers
   what scrolls beneath it, hence its own background and border, and it sits under the header's dropdowns. */
.footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1020;
  background-color: var(--bs-body-bg);
  border-top: 1px solid var(--bs-border-color);
  white-space: nowrap;
  line-height: 1.5;
  padding: 0.5rem 0;
  font-size: 0.875rem;
}

/* The footer's one row (_Layout): its text on the left and the CTRM Cubed logo on the right, level with each other, as
   ScafellWeb's .footerWithLogo has them, the logo 70px in from the right as its .logoPartial is. The dark logo on a
   light theme, the light one on a dark theme, as TradeCube's theme.js chooses. */
.gc-footer-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* 52px whichever version shows (the light one is 47px tall, the dark 52px), so the theme does not change the footer's
   height. */
.gc-ctrm-logo {
  margin-right: 70px;
  height: 52px;
  display: flex;
  align-items: center;
}

.gc-ctrm-logo-light,
[data-bs-theme="dark"] .gc-ctrm-logo-dark {
  display: none;
}

[data-bs-theme="dark"] .gc-ctrm-logo-light {
  display: inline;
}

/* Bootstrap gives a <p> a 1rem bottom margin, which in the footer is space below the last line and
   nothing else. */
.footer p {
  margin-bottom: 0;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
  color: var(--bs-secondary-color);
  text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
  text-align: start;
}

a {
  color: #0077cc;
}

.btn-primary {
  color: #fff;
  background-color: #1b6ec2;
  border-color: #1861ac;
}

/* GridCube navigation */

:root {
  /* The home page hero's ground, which its SVG is drawn on. Named for the navbar, whose colour it was; the bar
     itself is now ScafellWeb's (--gc-nav-*, below), and the hero keeps this so its image still sits seamlessly. */
  --gc-navbar-bg: #0b1220;
  --gc-navbar-border: #1e293b;
  /* ScafellWeb's navigation bar (its .scafellWebNavBar, .dropdown-menu and .dropdown-item): the bar, its menus,
     and a menu item under the pointer. */
  --gc-nav-bg: #030227;
  --gc-nav-menu-bg: #080561;
  --gc-nav-menu-hover-bg: #100ac2;
  --gc-accent: #22d3ee;
  --gc-text: #cbd5e1;
}

/* The navigation stays at the top of the window as the page scrolls. Sticky on the HEADER, not on the nav
   inside it: a sticky element only sticks within its parent, and the header is exactly as tall as the nav, so a
   sticky nav scrolled away with it. Sticky rather than fixed, so the page needs no padding kept in step with the
   bar's height, which changes when the menu wraps or opens on a narrow screen. */
.gc-header {
  position: sticky;
  top: 0;
  z-index: 1030;
}

/* ScafellWeb's colour and height: its bar is 84px tall, set by its 58px logo in Bootstrap's brand and navbar
   padding, with no border or shadow. A minimum rather than a height, so the bar still grows when the menu wraps
   or opens on a narrow screen. */
.gc-navbar {
  background-color: var(--gc-nav-bg);
  min-height: 84px;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
}

.gc-navbar .gc-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: #f8fafc;
  font-weight: 600;
  font-size: 1.15rem;
  letter-spacing: -0.01em;
  text-decoration: none;
}

.gc-navbar .gc-brand:hover {
  color: #f8fafc;
}

/* The navbar's logo image (wwwroot/images), at its own 160 x 60. Never squashed: on a bar too narrow for it, it scales
   down whole. Space after it, or the first menu item's highlight meets the "e" of "cube". */
.gc-brand-logo {
  display: block;
  height: 60px;
  width: auto;
  max-width: 100%;
  margin-right: 1rem;
}

.gc-toggler {
  border-color: var(--gc-navbar-border);
}

.gc-toggler .navbar-toggler-icon {
  filter: invert(1) grayscale(1) brightness(1.4);
}

.gc-nav {
  gap: 0.25rem;
}

/* ScafellWeb's menu text: Roboto (site-wide, above), 1rem (16px at the standard text size), regular weight,
   white. Scoped to .gc-navbar, here and on the brand, so DevExtreme's typography (its link colour, above) cannot
   outrank it on a page with a DevExtreme widget. */
.gc-navbar .gc-nav-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.9rem;
  border-radius: 8px;
  color: #fff;
  font-weight: 400;
  font-size: 1rem;
  text-decoration: none;
  position: relative;
  transition: color 0.15s ease, background-color 0.15s ease;
}

.gc-nav-icon {
  width: 17px;
  height: 17px;
  flex: none;
}

.gc-navbar .gc-nav-link:hover {
  color: #f8fafc;
  background-color: rgba(148, 163, 184, 0.08);
}

.gc-navbar .gc-nav-link.active {
  color: #f8fafc;
  background-color: rgba(34, 211, 238, 0.1);
}

.gc-nav-link.active::after {
  content: "";
  position: absolute;
  left: 0.9rem;
  right: 0.9rem;
  bottom: -0.25rem;
  height: 2px;
  background: var(--gc-accent);
  border-radius: 2px;
}

@media (max-width: 767.98px) {
  .gc-nav-link.active::after {
    display: none;
  }
}

.gc-user-nav {
  gap: 0.25rem;
}

/* The Alerts bell, as ScafellWeb's (its .scafellwebAlert and .fa-stack[data-count]:after): Font Awesome's bell in a
   2x stack, and the New count as a red circle over its top right, from data-count. The stack is 2em tall, so its
   margins give some of that back, which keeps the bar at ScafellWeb's height. */
.gc-navbar .gc-alerts-link {
  padding-top: 0;
  padding-bottom: 0;
}

.gc-alerts-bell {
  margin-top: -0.75rem;
  margin-bottom: -0.75rem;
  color: #fff;
}

/* Only for a count: no attribute, an empty one or "0" draws no circle, as ScafellWeb's has none at zero. */
.gc-alerts-bell[data-count]:not([data-count=""]):not([data-count="0"])::after {
  position: absolute;
  right: 15%;
  top: 20%;
  content: attr(data-count);
  font-family: var(--gc-font-family);
  font-size: 40%;
  padding: 0.6em;
  border-radius: 999px;
  line-height: 0.75em;
  color: #fff;
  text-align: center;
  min-width: 2em;
  font-weight: bold;
  background: rgba(255, 0, 0, 0.85);
}

.gc-user-toggle {
  align-items: center;
}

.gc-user-label {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
  text-align: left;
}

.gc-user-name {
  font-size: 1rem;
}

.gc-user-company {
  font-size: 0.72rem;
  color: #94a3b8;
}

/* The menus as ScafellWeb's: white text on its menu blue, a brighter blue under the pointer, 1rem. */
.gc-dropdown-menu {
  background-color: var(--gc-nav-menu-bg);
  border: 0;
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.35);
  margin-top: 0.5rem;
}

.gc-dropdown-menu .dropdown-item {
  color: #fff;
  background-color: var(--gc-nav-menu-bg);
  font-size: 1rem;
  padding: 0.55rem 1rem;
}

.gc-dropdown-menu .dropdown-item:hover,
.gc-dropdown-menu .dropdown-item:focus {
  background-color: var(--gc-nav-menu-hover-bg);
  color: #fff;
}

/* The page being shown: the hover blue, as there is no other blue in the menu to mark it with. */
.gc-dropdown-menu .dropdown-item.active {
  background-color: var(--gc-nav-menu-hover-bg);
  color: #fff;
}

.gc-dropdown-menu .dropdown-item.disabled {
  color: rgba(255, 255, 255, 0.5);
  pointer-events: none;
}

.gc-premium-badge {
  font-size: 0.62rem;
  font-weight: 600;
  vertical-align: middle;
}

/* GridCube home page

   The one screen with nothing to read from Elexon, and so the one screen that can sit on the
   navbar's own ground rather than the white a chart or a grid needs. Panel colour is the hero SVG's
   own ground exactly (#0b1220 both sides, via the same custom property the navbar uses), which is
   what lets the image be a plain rectangle with no rounding of its own and still sit seamlessly
   inside the rounded panel. */

.gc-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  padding: clamp(1.75rem, 4vw, 3.25rem);
  border: 1px solid var(--gc-navbar-border);
  border-radius: 14px;
  background: var(--gc-navbar-bg);
}

.gc-hero-title {
  margin: 0;
  line-height: 1;
}

/* The logo in place of the wordmark text, at the size that text was (4rem lettering is a 144px logo, the lettering
   being about a third of the image's height), shrinking with the screen as the text did. Never squashed.

   Pulled left by the glow's transparent margin, so the coastline lines up with the text under it: the artwork starts
   6.9% of the way across (52px of 768 in gridcube-logo-hero@2x.png), which is 18.4% of the height, the image being
   2.67 times as wide as it is tall. */
.gc-hero-logo {
  --gc-hero-logo-height: clamp(5.5rem, 13vw, 9rem);
  display: block;
  height: var(--gc-hero-logo-height);
  width: auto;
  max-width: 100%;
  margin-left: calc(var(--gc-hero-logo-height) * -0.184);
}

/* Wide enough to hold the line in one piece on a desktop, and balanced rather than ragged when it
   does wrap: at 36ch it broke as "half hour by half / hour.", orphaning the last word. */
.gc-hero-lead {
  margin: 1.4rem 0 0;
  max-width: 52ch;
  text-wrap: balance;
  color: #e2e8f0;
  font-size: clamp(1.1rem, 2.2vw, 1.45rem);
  line-height: 1.35;
  letter-spacing: -0.01em;
}

.gc-hero-body {
  margin: 1.4rem 0 0;
  max-width: 48ch;
  color: #94a3b8;
  font-size: 1rem;
  line-height: 1.65;
}

/* Sized rather than left to fill its column: the map is a tall portrait, and at column width it
   would set the height of the whole panel. */
.gc-hero-art {
  display: block;
  width: clamp(11rem, 26vw, 19rem);
  height: auto;
}

/* Stacked below the copy on a narrow screen, and capped: at full width the cube reads as a poster
   rather than as the illustration to a sentence. */
@media (max-width: 767.98px) {
  .gc-hero {
    grid-template-columns: minmax(0, 1fr);
  }

  .gc-hero-art {
    width: min(13rem, 60vw);
    margin: 0 auto;
  }
}

/* Every grid screen's header line, as System Prices first had it: the title, the live feed's connection badge, the
   screen's filters, each label beside its box, and anything for the right hand end (System Prices' chart export, the
   archive readers' Clear and Save filter buttons). A grid of tracks (title | badge | filters | end), so the badge
   changing state moves nothing: its track is as wide as its longest state. A screen with no live feed has no badge
   and drops its track (gc-page-header-static). Below 1200px, a wrapping row instead, the badge's cell still fixed. */
.gc-page-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1rem;
    margin-bottom: 1rem;
}

/* "reconnecting…", the longest state, in a badge's 0.75em type and padding (about 6.4rem), with a little to spare;
   rem, so it grows with the text-size preference as the badge does. On a cell, not the badge: IrisCommon.connect
   replaces the badge's whole class attribute. */
.gc-page-status {
    flex: 0 0 6.75rem;
    width: 6.75rem;
}

.gc-page-header-end {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

@media (min-width: 1200px) {
    .gc-page-header {
        display: grid;
        grid-template-columns: auto 6.75rem minmax(0, 1fr) auto;
    }

    .gc-page-header-static {
        grid-template-columns: auto minmax(0, 1fr) auto;
    }

    .gc-page-header-end {
        grid-column: -2;
        margin-left: 0;
    }
}

/* The filters, IN COLUMNS: equal tracks as many as fit, so filters that run out of room wrap into the same columns
   as the row above rather than wherever each happens to end. Sized by its own width (a container), which is what lets
   a wide filter take two columns only where two exist. */
.gc-page-selectors {
    container-type: inline-size;
    flex: 1 1 24rem;
    min-width: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr));
    align-items: center;
    gap: 0.5rem 1.5rem;
}

/* One filter: its label in a fixed column beside the box (right-aligned, below), so boxes line up down a column. DevExtreme editors have no
   label-left mode, so the label is the page's own and the box takes it as its accessible name. */
.gc-page-filter {
    display: grid;
    grid-template-columns: 8.5rem minmax(0, 1fr);
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

/* After a connection badge, the filters run on from it at their own widths, each just after the last, rather than in
   columns: those screens have a few filters, and the columns left wide gaps between them. Each label fits its text. A
   wide filter (the BM Unit pickers) takes the room left over. */
.gc-page-status ~ .gc-page-selectors {
    display: flex;
    flex-wrap: wrap;
}

/* Half the header's 1rem gap, where the filters always sit beside the badge: they belong with it. Not in the narrower
   wrapping row, where they can start a line of their own and would then hang off the page's edge. */
@media (min-width: 1200px) {
    .gc-page-status ~ .gc-page-selectors {
        margin-left: -0.5rem;
    }
}

.gc-page-status ~ .gc-page-selectors > .gc-page-filter {
    flex: 0 1 auto;
    grid-template-columns: max-content minmax(0, auto);
}

.gc-page-status ~ .gc-page-selectors > .gc-page-filter-wide {
    flex: 1 1 30rem;
    grid-template-columns: max-content minmax(0, 1fr);
}

/* A date picker is as wide as dd/MM/yyyy, its calendar and its clear button need, not the column's width. rem, so it
   grows with the text-size preference. */
.gc-page-filter > .dx-datebox {
    justify-self: start;
    width: 11rem;
}

/* A filter with no label of its own (a checkbox carries its text) takes the whole cell. */
.gc-page-filter > :only-child {
    grid-column: 1 / -1;
}

/* The BM Unit tag boxes: two columns where there are two, since their tags need the room. */
@container (min-width: 40rem) {
    .gc-page-filter-wide {
        grid-column: span 2;
    }
}

/* Right-aligned against its box, so a short label ("Timeframe") sits beside the box rather than across the column's
   width from it, and the boxes still line up down a column. */
.gc-page-selector-label {
    line-height: 1.2;
    text-align: right;
}

/* The close button in the top right corner of every grid's read-only form (BowfellGrids.viewFormButtons,
   dataGridDefaults.js), the same plain-text button as the form's own at its foot. The form row's cell (the row itself is a
   <tr>) is its positioning context, with room at the top so the first row of fields is clear of it. */
.dx-datagrid-rowsview .dx-row.dx-datagrid-edit-form > td {
    position: relative;
    padding-top: 3rem;
}

.gc-view-form-close {
    position: absolute;
    top: 0.5rem;
    right: 1.25rem;
    z-index: 2;
}

/* A little space between the words and the cross after them, on both close buttons, which DevExtreme's right-hand
   icon leaves touching. */
.dx-datagrid-edit-form .dx-button-has-text .dx-button-content .dx-icon:last-child {
    margin-inline-start: 0.5rem;
}

/* GridCube error page

   Views/Shared/Error.cshtml, which every failure in the site lands on — an unhandled exception via
   UseExceptionHandler and any bare 4xx/5xx via UseStatusCodePagesWithReExecute (see Program.cs).

   Quiet on purpose. Nothing here is red: a 404 is a mistyped address far more often than a fault, and
   a page that shouts is a page that makes a stale bookmark look like an outage. The accent is the
   navbar's own cyan on the status code and nowhere else. */

.gc-error {
  max-width: 44rem;
  margin: clamp(2rem, 8vh, 5rem) auto;
  text-align: center;
}

/* Large, but in the muted slate the footer and the hero body use rather than in the accent — it is a
   label, not a headline, and the heading below it is what the eye should land on. Tabular figures so
   404 and 500 occupy the same width and the block does not shift between them. */
.gc-error-code {
  margin: 0;
  color: #cbd5e1;
  font-size: clamp(3.5rem, 12vw, 6rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
}

.gc-error-heading {
  margin: 0.5rem 0 0;
  font-size: clamp(1.6rem, 4vw, 2.1rem);
  font-weight: 600;
  letter-spacing: -0.02em;
}

/* Balanced rather than ragged, and capped well short of the section width: the detail runs to two
   lines at most, and a centred paragraph reads badly once it is wider than that. */
.gc-error-detail {
  margin: 1rem auto 0;
  max-width: 44ch;
  color: #475569;
  font-size: 1.05rem;
  line-height: 1.6;
  text-wrap: balance;
}

/* The requested path, on a 404 only. break-all because it is user-supplied and can be arbitrarily
   long with no space in it — without this a pasted URL widens the page and brings a horizontal
   scrollbar with it. */
.gc-error-path {
  margin: 1rem auto 0;
  max-width: 100%;
  overflow-wrap: anywhere;
  word-break: break-all;
  color: #64748b;
  font-size: 0.95rem;
}

.gc-error-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 2rem;
}

/* Last and smallest. It is addressed to the one reader in many who is about to raise a ticket; for
   everyone else it should be legible and otherwise out of the way. */
.gc-error-reference {
  margin: 2.5rem auto 0;
  max-width: 40ch;
  color: #94a3b8;
  font-size: 0.85rem;
  line-height: 1.6;
}

.gc-error-reference code,
.gc-error-path code {
  color: inherit;
  overflow-wrap: anywhere;
}

/* NESO system warning toasts (site-notices.js): fixed just below the nav bar, top right, stacking. The
   top offset is set by the script, which follows the header as the page scrolls. */
.gc-notice-toasts {
  position: fixed;
  top: 4rem;
  right: 1rem;
  z-index: 1090;
  width: min(30rem, calc(100vw - 2rem));
}

.gc-notice {
  width: 100%;
  border-left-width: 0.35rem;
}

.gc-notice .toast-header {
  text-transform: none;
}

/* NESO's text arrives with its own line breaks and runs to ~2,000 characters for a margin notice, so
   the breaks are kept and the body scrolls rather than covering the page. */
.gc-notice-body {
  white-space: pre-line;
  max-height: 14rem;
  overflow-y: auto;
  font-size: 0.875rem;
}

.gc-notice-critical {
  border-left-color: var(--bs-danger);
}

.gc-notice-critical .toast-header {
  background-color: var(--bs-danger);
  color: #fff;
}

/* The toast's close X (a dxButton) white on the red header, and no taller than the header's text. */
.gc-notice-critical .gc-notice-close .dx-icon {
  color: #fff;
}

.gc-notice .gc-notice-close.dx-button {
  min-height: 0;
}

.gc-notice .gc-notice-close .dx-button-content {
  padding: 0;
}

/* The Alerts screen's error notice's close X (a dxButton), where Bootstrap's dismissible alert puts its own. */
.alert-dismissible .gc-alert-dismiss {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
}

/* The Subscriptions screen: a readable column of switches. */
.gc-subscriptions,
.gc-subscriptions-intro,
.gc-subscriptions-saved {
  max-width: 60ch;
}

/* The Preferences screen: the same readable column. */
.gc-preferences {
  max-width: 60ch;
}

/* The Text size slider's tooltip is always shown, above the handle and outside the slider's own height, so the row
   makes room for it rather than letting it cover the Theme box; the label moves down with the track. In rem, so the
   room grows with the text size. */
.gc-preferences-text-size .dx-field-item-content,
.gc-preferences-text-size .dx-field-item-label {
  padding-top: 2.25rem;
}

/* The dark theme (Preferences; wwwroot/js/site/preferenceService.js sets data-bs-theme on <html>). Bootstrap 5.3 and
   DevExtreme's dark stylesheet theme almost everything; these are the rules that named light colours outright.
   The navigation bar is dark in both themes. */
[data-bs-theme="dark"] a:not(.btn):not(.gc-nav-link):not(.dropdown-item):not(.navbar-brand) {
  color: #6cb6ff;
}

[data-bs-theme="dark"] .btn:focus,
[data-bs-theme="dark"] .btn:active:focus,
[data-bs-theme="dark"] .form-control:focus,
[data-bs-theme="dark"] .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem var(--bs-body-bg), 0 0 0 0.25rem #258cfb;
}

[data-bs-theme="dark"] .boalf-panel,
[data-bs-theme="dark"] .bod-panel,
[data-bs-theme="dark"] .boav-panel,
[data-bs-theme="dark"] .boc-panel,
[data-bs-theme="dark"] .pn-panel {
  background: var(--bs-body-bg);
  border-color: var(--bs-border-color);
}

[data-bs-theme="dark"] .gc-bmud-placeholder {
  color: var(--bs-secondary-color);
  background-color: var(--bs-tertiary-bg);
}

/* A BM Unit id linked to its BM Unit Detail screen (site.js BowfellLinks), on every screen that shows one: the look
   of a unit named in an alert or a report, so a linked unit reads the same everywhere. */
a.gc-bmunit {
  color: inherit;
  text-decoration: underline dashed;
  text-underline-offset: 0.2em;
  cursor: pointer;
}

/* Its tooltip (site.js BowfellLinks, alerts.js, ReportRenderer): one line per fact, so newlines are kept and the
   text left-aligned. */
.gc-bmunit-tooltip .tooltip-inner {
  white-space: pre-line;
  text-align: left;
  max-width: 22rem;
}

/* A feature disabled for a signed-out visitor. The wrapper carries the tooltip; the disabled control inside
   passes the pointer through to it, since a disabled element receives no mouse events itself. */
.gc-login-required > :disabled {
  pointer-events: none;
}

/* A grid's first cell opens the row's form, as the eye does (BowfellGrids.openFromFirstColumn): it reads as a link. */
.gc-open-cell {
    cursor: pointer;
    color: var(--bs-link-color, #0d6efd);
}

.gc-open-cell:hover {
    text-decoration: underline;
}
