/* Onest, self-hosted.

   The design system's one family (docs/products/jobs/design-system/design-tokens.md). Served from
   this app rather than from Google Fonts, as the sibling products do, because the privacy decision
   that lets this product run without a DPIA rests on it sending nothing to a third party
   (docs/products/jobs/compliance/privacy/privacy-data-inventory-and-dpia-decision.md, 7.1), and a
   font request carries every visitor's address to whoever serves it. The variable font covers
   400 to 700 in one file per subset; Latin carries the pound sign, dashes and curly quotes the copy
   uses, and Latin Extended the rest of the names a UK page meets. SIL Open Font Licence 1.1, in
   fonts/onest/OFL.txt beside the files. */
@font-face {
  font-family: "Onest";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/onest/onest-latin-ext.woff2") format("woff2");
  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: "Onest";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/onest/onest-latin.woff2") format("woff2");
  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;
}

/* THE DESIGN TOKENS. Every value below that the redesign draws is the one recorded in
   docs/products/jobs/design-system/design-tokens.md, which was read from the design canvas; change a
   value there and here together. The design fixes two widths, 390px and 1280px. A size that differs
   between them is interpolated linearly between the two with clamp(), which is this app's decision
   for the widths the design does not draw, and never goes past either drawn value. */
:root {
  /* Surfaces and text. */
  --job-canvas: #f7f5ef;
  --job-paper: #ffffff;
  --job-ink: #1a1f1d;
  --job-ink-soft: #5f6763;
  /* The accent: accent text, links, the current nav item, accent icons, a primary action's fill. */
  --job-brand: #2a5a4e;
  /* Hover and pressed. The design draws no hover state; this is the darker step its own stylesheet
     declared for link hover, kept so an action still answers the pointer. 10.16:1 on the canvas. */
  --job-brand-strong: #1f4239;
  --job-brand-soft: #e7efeb;
  --job-canvas-strong: #eae9e2;
  /* Hairline rules and borders. Raised on 28 September 2026 to 1.71:1 on the canvas: at the site's
     old value a 1px rule could not be seen. Every border in the app draws with it. */
  --job-line: #c0beb7;
  /* A border that has to read as stronger than a rule, such as on hover. The design leaves it open;
     this is the same warm grey stepped to 2.41:1. */
  --job-line-strong: #a0a09a;

  /* The inverse section: the one full-width coloured surface, and the plate of the mark. */
  --job-inverse: #244f46;
  --job-on-inverse: #ffffff;
  --job-on-inverse-soft: #d7e3dd;
  --job-on-inverse-accent: #a9e4c3;
  /* Text on a filled control: a primary action or a badge. */
  --job-on-fill: #ffffff;

  /* A quiet numeral, dark enough to be read.

     UXD-05. The step numbers and section numerals were set in --job-line-strong, which is a border
     colour: at 1.7:1 on the cream canvas the "1", "2" and "3" on Check a job advert were very
     nearly invisible. A border token carries no contrast obligation and text does, so borrowing one
     for text is a defect waiting on somebody to look. This is the same hue, dark enough to clear
     the 3:1 that large text needs, and still clearly subordinate to the heading beside it. */
  --job-ink-numeral: #7e8582;

  --job-focus: #145da0;

  /* The data marks: one series colour and one track tint, for every bar, line and meter.

     The marks drew in the brand green, which is a text and control colour: at OKLCH chroma 0.05 it
     reads as near-black in a 4px bar, and the track under it was the neutral hairline grey, so the
     one chart on the homepage carried no colour at all. This is the same green stepped into the
     lightness band the data-viz validator asks of a series colour, L 0.43 to 0.77, at 4.9:1 on the
     cream, and the track is the lighter step of the same hue, so the unfilled part of a meter reads
     as the rest of the same bar rather than as a rule. One series, one colour: the demand line, the
     salary range and the requirement bars all draw with it, and the text beside them stays in ink. */
  --job-mark: #35755f;
  --job-mark-track: #d9e6df;

  /* The count on My Career. A red, so the number of things somebody kept reads as a count at a
     glance rather than as part of the link's own colour; measured 5.35:1 under the white digit,
     which 12px bold text needs. Not the danger red: this is a tally, not a warning. */
  --job-badge: #c9301f;
  /* The dashed site-average line on a chart: the badge's red, so no new colour enters the set.
     4.91:1 on the canvas. */
  --job-chart-average: var(--job-badge);

  /* Type. One family; the monospace stack is the estate's principle line and nothing else. */
  --job-font: "Onest", "Helvetica Neue", Arial, sans-serif;
  --job-weight-regular: 400;
  --job-weight-medium: 500;
  --job-weight-semibold: 600;
  --job-weight-bold: 700;

  /* Text sizes, phone value to desktop value. */
  --job-text-display: clamp(2.625rem, 1.694rem + 3.82vw, 4.75rem);
  --job-text-headline: clamp(2.375rem, 1.772rem + 2.472vw, 3.75rem);
  --job-text-heading: clamp(2rem, 1.562rem + 1.798vw, 3rem);
  --job-text-figure: clamp(5rem, 4.124rem + 3.596vw, 7rem);
  --job-text-heading-module: clamp(1.5rem, 1.39rem + 0.4494vw, 1.75rem);
  --job-text-figure-glance: clamp(1.875rem, 1.601rem + 1.124vw, 2.5rem);
  --job-text-title: clamp(1.1875rem, 1.105rem + 0.3371vw, 1.375rem);
  --job-text-lede: clamp(1.0625rem, 0.9529rem + 0.4494vw, 1.3125rem);
  --job-text-intro: clamp(1rem, 0.9178rem + 0.3371vw, 1.1875rem);
  --job-text-lead: clamp(1rem, 0.9726rem + 0.1124vw, 1.0625rem);
  --job-text-label: clamp(0.9375rem, 0.8827rem + 0.2247vw, 1.0625rem);
  --job-text-body: clamp(0.9375rem, 0.9101rem + 0.1124vw, 1rem);
  --job-text-note: clamp(0.875rem, 0.8476rem + 0.1124vw, 0.9375rem);
  --job-text-link: clamp(0.9375rem, 0.9101rem + 0.1124vw, 1rem);
  --job-text-link-large: clamp(1rem, 0.9726rem + 0.1124vw, 1.0625rem);
  --job-text-small: 0.875rem;
  --job-text-caps-sm: 0.8125rem;

  /* Shape and elevation. */
  --job-radius-pill: 999px;
  --job-radius-card: 24px;
  --job-radius-bar: 0 999px 999px 0;
  --job-shadow-field: 0 1px 2px rgba(26, 31, 29, 0.04), 0 18px 48px -20px rgba(26, 31, 29, 0.28);

  /* Sizes. */
  --job-target: 44px;
  --job-link-height: 32px;
  --job-button-height: 48px;
  --job-button-large-height: 52px;
  --job-bar-height: 6px;

  /* Layout. The gutter is every page's side padding, header and footer included. */
  --job-gutter: clamp(1.25rem, -0.3933rem + 6.742vw, 5rem);
  --job-section-space: clamp(3.5rem, 2.404rem + 4.494vw, 6rem);
  --job-section-space-lg: clamp(4rem, 2.466rem + 6.292vw, 7.5rem);
  --job-module-space: clamp(3rem, 2.562rem + 1.798vw, 4rem);
  --job-module-gap: clamp(1.25rem, 1.14rem + 0.4494vw, 1.5rem);
  --job-heading-gap: 14px;
  --job-measure-display: 820px;
  --job-measure-heading: 760px;
  --job-measure-headline: 700px;
  --job-measure-lede: 620px;
  --job-measure-intro: 560px;
  --job-measure-intro-narrow: 520px;
  --job-measure-report: 720px;
  --job-measure-tagline: 384px;
  --job-width-search: 680px;
  --job-width-list: 720px;
  --job-width-pair: 760px;
  --job-width-cards: 920px;
  --job-width-report: 920px;

  /* The page title and section heading scale, owned here so a title is one size on every page.

     Interior titles were set at clamp(2.7rem, 6vw, 5.4rem) with -0.055em tracking, 77px at 1280px
     with the letters nearly touching, on pages whose job is a table or a form, while the occupation
     report and the methodology fell through to the browser's 32px. One scale for the title of a
     page, one for the heading of a section, and the true heroes on the homepage and the advert
     check keep their own larger display size. */
  --job-title-size: clamp(2.125rem, 1.5rem + 2.2vw, 3rem);
  --job-title-tracking: -0.025em;
  --job-heading-size: clamp(1.75rem, 1.25rem + 1.6vw, 2.5rem);
  --job-section-size: clamp(1.375rem, 1.125rem + 0.8vw, 1.75rem);

  /* THE SHARED TOKENS, POINTED AT THIS APP'S OWN PALETTE.

     Platform.Ui.Core's defaults are a cool slate grey and a saturated blue. Left alone they showed
     through wherever a shared component drew its own colour: the active link in the header and
     the cookie panel's one button were rgb(37, 99, 235) blue, and the footer's links, heading and
     wordmark were a slate that sat cold against this app's warm cream and green. Every other host
     in the estate maps these to its own tokens; this one did not, so the estate's defaults were
     this app's accent by accident.

     UXD-04 is kept. The muted text token used to be #55647c because Platform.Shell's default
     measured 4.32:1 on this cream. The app's own soft ink measures 5.97:1 on the same canvas, so
     it clears the same bar without introducing a second grey. */
  --pui-color-text-primary: var(--job-ink);
  --pui-color-text-strong: var(--job-ink);
  --pui-color-text-secondary: var(--job-ink-soft);
  --pui-color-text-muted: var(--job-ink-soft);
  --pui-color-surface-page: var(--job-canvas);
  --pui-color-surface-card: var(--job-paper);
  --pui-color-surface-raised: var(--job-paper);
  --pui-color-surface-control: var(--job-paper);
  --pui-color-surface-overlay: var(--job-paper);
  --pui-color-surface-muted: var(--job-canvas);
  --pui-color-surface-hover: var(--job-canvas-strong);
  --pui-color-surface-selected: var(--job-brand-soft);
  --pui-color-accent-soft: var(--job-brand-soft);
  --pui-color-border-subtle: var(--job-line);
  --pui-color-border-default: var(--job-line);
  --pui-color-border-hover: var(--job-line-strong);
  --pui-color-border-strong: var(--job-brand);
  --pui-color-border-focus: var(--job-focus);
  /* The design draws every link in the brand green, so the shared link colour is the brand and its
     hover the darker step. It was the other way round, which gave shared components' links a
     colour the design never uses. */
  --pui-color-link: var(--job-brand);
  --pui-color-link-hover: var(--job-brand-strong);
  --pui-color-action-primary: var(--job-brand);
  --pui-color-action-primary-hover: var(--job-brand-strong);
  --pui-color-action-secondary: var(--job-ink-soft);
  --pui-color-action-secondary-hover: var(--job-ink);
  --pui-color-nav-background: var(--job-paper);
  --pui-color-nav-border: var(--job-line);
  --pui-color-nav-text: var(--job-ink);
  --pui-color-nav-text-active: var(--job-brand);
  --pui-color-nav-hover-background: var(--job-canvas);
  --pui-color-form-background: var(--job-paper);
  --pui-color-card-background: var(--job-paper);
  --pui-color-card-border: var(--job-line);
  --pui-color-logo-text-primary: var(--job-ink);
  --pui-color-logo-text-secondary: var(--job-brand);
  /* The ring's colour is also consumed as a bare rgb triplet, so both forms are declared. */
  --pui-focus-color: var(--job-focus);
  --pui-focus-color-rgb: 20, 93, 160;
  --job-radius-sm: var(--pui-radius-sm, 0.5rem);
  --job-radius-md: var(--pui-radius-md, 0.875rem);
  --job-radius-lg: var(--pui-radius-lg, 1.5rem);
  --job-space-1: var(--pui-space-1, 0.25rem);
  --job-space-2: var(--pui-space-2, 0.5rem);
  --job-space-3: var(--pui-space-3, 0.75rem);
  --job-space-4: var(--pui-space-4, 1rem);
  --job-space-5: var(--pui-space-5, 1.5rem);
  --job-space-6: var(--pui-space-6, 2rem);
  --job-space-7: var(--pui-space-7, 3rem);
  --job-space-8: var(--pui-space-8, 4rem);
  /* The estate's soft elevation. --pui-shadow-md was never a token, so the fallback drew a large
     dark halo under the intake panel; the shared soft shadow is what the rest of the estate lifts
     a panel with. */
  --job-shadow: var(--pui-shadow-soft, 0 1px 3px rgba(23, 32, 29, 0.05), 0 8px 24px rgba(23, 32, 29, 0.06));
  /* The shell's column, set by the design's gutter: 1120px of content at 1280px, the phone width
     less 40px at 390px. Platform.Shell reads both for the header and the footer. */
  --site-shell-max-width: 70rem;
  --page-max-width: var(--site-shell-max-width);
  --page-gutter-x: var(--job-gutter);
  --font-body: var(--job-font);
  --font-label: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--job-canvas);
  color: var(--job-ink);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
}

button,
input,
select,
textarea {
  font: inherit;
}

button,
a,
input,
select,
textarea,
summary {
  outline-offset: 0.2rem;
}

/* Section 65, visible focus.
   MudBlazor ships `a:focus-visible{outline:none}` and `button:focus{outline:none}`. Those are
   element selectors, so they beat a bare `:focus-visible` on specificity no matter which
   stylesheet loads last, measured in Chromium, six focusable elements including this page's
   primary call to action had no focus indicator at all while the rule below appeared to define
   one. Naming the elements ties the specificity and site.css loads after MudBlazor, so this wins.

   `:focus-visible` and not `:focus`: a mouse user clicking a button should not get a keyboard
   focus ring, which is the reason MudBlazor suppresses the default in the first place. */
:focus-visible,
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 0.2rem solid var(--job-focus);
  outline-offset: 0.2rem;
}

h1[tabindex="-1"]:focus,
main[tabindex="-1"]:focus {
  outline: none;
}

/* Section 65, keyboard support. Off-screen until focused, then the first thing on the page.
   Translated rather than positioned at left: -9999px, which some browsers refuse to scroll back
   into view. No transition: appearing instantly is correct, and there is then nothing for
   prefers-reduced-motion to undo. */
.job-skip-link {
  position: absolute;
  z-index: 200;
  top: 0;
  left: var(--job-space-4);
  padding: var(--job-space-3) var(--job-space-5);
  border-radius: 0 0 var(--job-radius-sm) var(--job-radius-sm);
  background: var(--job-brand);
  color: var(--job-paper);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
}

.job-skip-link:focus {
  transform: translateY(0);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.job-shell-frame {
  min-height: calc(100vh - 4.5rem);
}

.job-shell-content {
  min-height: 62vh;
}

.job-page,
.job-page-shell {
  width: min(var(--site-shell-max-width), calc(100% - (2 * var(--page-gutter-x))));
  margin-inline: auto;
}

/* The page's vertical rhythm, owned here rather than left to whichever heading happens to sit at
   the top of each section. Measured across every page that uses this stack, the gap between one
   section and the next was zero: sections butted together and the only air came from a child's own
   margin, which is why the rhythm changed depending on what a section began with. */
.job-page-stack {
  display: grid;
  /* minmax(0, 1fr), not the implicit auto track. An auto track is sized by its widest child, so a
     table with a min-width pushed the whole page sideways at 390px instead of scrolling inside its
     own wrapper -- the wrapper had overflow-x: auto and never got the chance to use it. */
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  gap: var(--job-space-8);
  padding-block: var(--job-space-8);
}

.job-page-hero {
  max-width: 52rem;
}

/* The page and section kicker.

   UXD-16, closed. This was a colour and nothing else, so on every page but the homepage the
   eyebrow rendered as a line of body copy that happened to be capitalised in the markup, the
   same size and weight as the paragraph under the title. One treatment for every kicker: small,
   bold, letterspaced and quiet, so it reads as a label above the title rather than as a sentence
   competing with it. The homepage's own scoped rule is gone; this is the one it was waiting for. */
.job-eyebrow,
.job-step-label,
.job-section-kicker {
  margin: 0;
  color: var(--job-brand-strong);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.job-requirement-category,
/* The estate's footer line is Platform.Shell's now, so only its colour is set here, the face,
   size and letterspacing come from the shell and are the same on every app. */
.footer-principle {
  color: var(--job-brand);
}

/* The footer's rule, inset to the page column as the design draws it, with the footer's content
   20px below it rather than hard against it. Platform.Shell draws the rule across the column and
   both gutters; this app's column is the design's. */
.footer-shell__divider {
  max-width: var(--page-max-width);
  width: calc(100% - (2 * var(--page-gutter-x)));
  border-top-color: var(--job-line);
}

.footer-shell .footer-top {
  padding-top: 20px;
}

.job-home-hero {
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(28rem, 1.08fr);
  gap: clamp(2rem, 6vw, 5.5rem);
  /* Top-aligned, not centred. Centring measured the copy column against the taller intake panel and
     pushed the heading down by half the difference, 5px, so this page opened fractionally lower
     than every other one however the padding was set. The two columns are within 11px of each
     other, so centring was buying nothing and costing the alignment. */
  align-items: start;
  /* THE TOP GAP IS THE SHELL'S, NOT THE HERO'S. Every other page opens 40px below the header,
     because `.job-page-stack` owns that rhythm. Check a job advert is the one page that does not
     use the stack, this hero brought its own top padding instead, so it sat at 108px until the
     experiment callout was removed, then at 51px, and never at the 40px the rest of the site uses.
     Matching the stack's own token is what keeps it matching when that token changes.

     The bottom is the hero's own business: it separates the hero from the content below it, and it
     keeps the value it always had. */
  padding-block-start: var(--job-space-8);
  padding-block-end: clamp(3.5rem, 8vw, 7rem);
}

/* The advert check's hero is a true hero, so it takes the homepage's display scale exactly: one
   display size in the product, not two that drift. */
.job-home-hero-copy h1 {
  margin: var(--job-space-4) 0;
  font-size: clamp(2.75rem, 5.2vw, 4.5rem);
  line-height: 1.02;
  letter-spacing: -0.045em;
  font-weight: 800;
  text-wrap: balance;
}

/* Every other page title. Proportional to the page's job: a region table or a form of twelve
   fields does not need a 77px heading with the letters touching, it needs a title a reader can
   take in and move past. The occupation report and the methodology take the same token below, so
   a title is one size wherever it appears. */
.job-page-hero h1 {
  margin: var(--job-space-4) 0;
  font-size: var(--job-title-size);
  line-height: 1.08;
  letter-spacing: var(--job-title-tracking);
  text-wrap: balance;
}

/* The sentence under a title. Set as a lede, larger and quieter than body copy, so the page
   opens with a hierarchy of three, kicker, title, lede, rather than a title followed by a
   paragraph at the same weight as everything beneath it. Only the unclassed paragraphs: a note
   already has its own, smaller treatment. */
.job-page-hero > p:not([class]) {
  max-width: 40rem;
  margin: 0;
  color: var(--job-ink-soft);
  font-size: 1.125rem;
  line-height: 1.55;
  text-wrap: pretty;
}

/* What follows the lede keeps a breath from it. The lede's own margin is gone, so the space is
   declared here instead of being left to whichever element happens to come next. */
.job-page-hero > p + p:not([class]),
.job-page-hero > p + .job-account__note {
  margin-top: var(--job-space-3);
}

.job-page-hero > p + :not(p, h1) {
  margin-top: var(--job-space-4);
}

.job-page-hero > .job-button {
  margin-top: var(--job-space-5);
}

.job-explainer h2,
.job-report-hero h2 {
  margin: var(--job-space-4) 0;
  font-size: var(--job-heading-size);
  line-height: 1.1;
  letter-spacing: -0.03em;
}

.job-home-lede {
  max-width: 36rem;
  margin: 0;
  color: var(--job-ink-soft);
  font-size: clamp(1.05rem, 2vw, 1.28rem);
}

.job-trust-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2) var(--job-space-4);
  padding: 0;
  margin: var(--job-space-6) 0 0;
  list-style: none;
  color: var(--job-ink-soft);
  font-size: 0.92rem;
}

.job-trust-list li::before {
  content: "✓";
  margin-right: var(--job-space-2);
  color: var(--job-brand);
  font-weight: 700;
}

.job-intake-panel {
  padding: clamp(1.5rem, 4vw, 2.5rem);
  border: 1px solid var(--job-line);
  border-radius: var(--job-radius-lg);
  background: var(--job-paper);
  box-shadow: var(--job-shadow);
}

.job-intake-panel h2,
.job-section-heading h2,
.job-report-section h3,
.job-source-panel h3 {
  margin: var(--job-space-2) 0 var(--job-space-5);
  font-size: clamp(1.45rem, 3vw, 2.1rem);
  line-height: 1.15;
  letter-spacing: -0.03em;
}

.job-intake-panel label,
.job-form-field > label {
  display: block;
  margin-bottom: var(--job-space-2);
  font-weight: 700;
}

.job-intake-panel textarea,
.job-form-field input,
.job-requirement-row select {
  width: 100%;
  border: 1px solid var(--job-line-strong);
  border-radius: var(--job-radius-sm);
  background: var(--job-paper);
  color: var(--job-ink);
}

.job-intake-panel textarea {
  min-height: 15rem;
  padding: var(--job-space-4);
  resize: vertical;
}

.job-form-field input,
.job-requirement-row select {
  min-height: 3rem;
  padding: 0.65rem 0.8rem;
}

.job-input-meta {
  display: flex;
  justify-content: space-between;
  gap: var(--job-space-4);
  margin: var(--job-space-2) 0 var(--job-space-5);
  color: var(--job-ink-soft);
  font-size: 0.85rem;
}

.job-validation {
  padding: var(--job-space-3) var(--job-space-4);
  border-left: 0.25rem solid var(--job-ink);
  background: var(--job-canvas);
  font-weight: 700;
}

.job-button {
  display: inline-flex;
  min-height: 2.9rem;
  align-items: center;
  justify-content: center;
  padding: 0.7rem 1.25rem;
  border: 1px solid transparent;
  border-radius: 999px;
  cursor: pointer;
  font-weight: 700;
  text-decoration: none;
  /* Feedback on hover, brief and token-timed. Nothing moves; only the colour settles. */
  transition:
    background-color var(--pui-motion-fast, 160ms ease),
    border-color var(--pui-motion-fast, 160ms ease),
    color var(--pui-motion-fast, 160ms ease);
}

.job-button-primary {
  background: var(--job-brand);
  color: var(--job-paper);
}

.job-button-primary:hover {
  background: var(--job-brand-strong);
}

.job-button-secondary {
  border-color: var(--job-line-strong);
  background: transparent;
  /* The brand green rather than body ink. On a page that is almost entirely text, a control
     coloured like the paragraph beside it reads as a heading somebody has boxed; the green is the
     only thing on the page that means "this does something". */
  color: var(--job-brand);
}

.job-button-secondary:hover {
  border-color: var(--job-brand);
  background: var(--job-paper);
  color: var(--job-brand-strong);
}

.job-review-section,
.job-report {
  margin-bottom: var(--job-space-8);
}

.job-review-section {
  padding: clamp(1.5rem, 5vw, 3.5rem);
  border: 1px solid var(--job-line);
  border-radius: var(--job-radius-lg);
  background: var(--job-paper);
}

.job-section-heading {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(16rem, 0.7fr);
  gap: var(--job-space-6);
  align-items: end;
  padding-bottom: var(--job-space-6);
  border-bottom: 1px solid var(--job-line);
}

.job-section-heading p {
  margin: 0 0 var(--job-space-5);
  color: var(--job-ink-soft);
}

.job-review-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--job-space-5);
  padding-block: var(--job-space-6);
}

.job-form-field details {
  margin-top: var(--job-space-2);
  color: var(--job-ink-soft);
  font-size: 0.88rem;
}

.job-form-field summary {
  cursor: pointer;
  color: var(--job-focus);
}

.job-not-stated {
  display: block;
  margin-top: var(--job-space-2);
  color: var(--job-ink-soft);
  font-size: 0.88rem;
}

.job-caveat {
  color: var(--job-ink-soft);
}

.job-review-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-3);
}

.job-report {
  overflow: hidden;
  border: 1px solid var(--job-line);
  border-radius: var(--job-radius-lg);
  background: var(--job-paper);
}

.job-report-hero {
  padding: clamp(2rem, 6vw, 4.5rem);
  border-bottom: 1px solid var(--job-line);
  background: var(--job-ink);
  color: var(--job-paper);
}

.job-report-hero .job-eyebrow {
  color: #d6e7df;
}

.job-report-hero h2 {
  max-width: 56rem;
}

.job-report-hero h2 span {
  display: block;
  color: #c3cbc7;
  font-weight: 400;
}

.job-report-hero > p:not(.job-eyebrow) {
  max-width: 44rem;
  color: #d4dad7;
  font-size: 1.1rem;
}

.job-text-button {
  min-height: 2.75rem;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--job-paper);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 0.25rem;
}

.job-report-section {
  display: grid;
  grid-template-columns: 3rem minmax(0, 1fr);
  gap: var(--job-space-6);
  padding: clamp(1.5rem, 5vw, 3.5rem);
  border-bottom: 1px solid var(--job-line);
}

.job-section-number {
  color: var(--job-ink-numeral);
  font-family: var(--font-label);
  font-size: 1.15rem;
}

.job-fact-list {
  max-width: 48rem;
  margin: 0;
}

.job-fact-list > div {
  display: grid;
  grid-template-columns: minmax(10rem, 0.4fr) minmax(0, 0.6fr);
  gap: var(--job-space-5);
  padding-block: var(--job-space-3);
  border-bottom: 1px solid var(--job-line);
}

.job-fact-list dt {
  color: var(--job-ink-soft);
}

.job-fact-list dd {
  margin: 0;
  font-weight: 700;
}

.job-fact-origin {
  display: block;
  margin-top: var(--job-space-1);
  color: var(--job-brand);
  font-family: var(--font-label);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.job-question-list,
.job-source-panel ul {
  max-width: 52rem;
  padding: 0;
  margin: 0;
  list-style: none;
}

.job-question-list li,
.job-source-panel li {
  display: grid;
  gap: var(--job-space-1);
  padding: var(--job-space-4) 0;
  border-bottom: 1px solid var(--job-line);
}

.job-question-list span,
.job-source-panel li {
  color: var(--job-ink-soft);
}

.job-requirements-list {
  max-width: 58rem;
}

.job-requirement-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(14rem, 0.45fr);
  gap: var(--job-space-5);
  align-items: center;
  padding: var(--job-space-5) 0;
  border-bottom: 1px solid var(--job-line);
}

.job-requirement-row p {
  margin: var(--job-space-2) 0 0;
}

.job-next-action {
  background: var(--job-canvas);
}

.job-source-panel {
  padding: clamp(1.5rem, 5vw, 3.5rem);
  background: #f1f3f2;
}

.job-explainer {
  padding-block: clamp(3.5rem, 8vw, 7rem);
}

.job-explainer h2 {
  max-width: 42rem;
}

.job-explainer ol {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--job-space-6);
  padding: var(--job-space-7) 0 0;
  margin: 0;
  border-top: 1px solid var(--job-line-strong);
  list-style: none;
}

.job-explainer li > span {
  display: block;
  color: var(--job-ink-numeral);
  font-family: var(--font-label);
  font-size: 2rem;
}

.job-explainer li > strong {
  display: block;
  margin-top: var(--job-space-5);
  font-size: 1.3rem;
}

.job-explainer li p {
  color: var(--job-ink-soft);
}

/* In ink, not in the footer's muted grey: it is the product's name, and the one word set in the
   brand green needs a dark partner to read as a wordmark rather than as two colours of grey. */
.job-footer-brand {
  color: var(--job-ink);
  font-size: 1.15rem;
  font-weight: 700;
}

.job-footer-brand span {
  color: var(--job-brand);
}

.job-footer-tagline {
  max-width: 24rem;
  color: var(--job-ink-soft);
}

#blazor-error-ui {
  position: fixed;
  inset: auto 1rem 1rem 1rem;
  z-index: 1100;
  display: none;
  align-items: center;
  gap: var(--job-space-3);
  padding: var(--job-space-3) var(--job-space-4);
  border: 1px solid var(--job-line-strong);
  border-radius: var(--job-radius-sm);
  background: var(--job-paper);
  box-shadow: var(--job-shadow);
}

#blazor-error-ui .reload,
#blazor-error-ui .dismiss {
  color: var(--job-ink);
}

@media (max-width: 1024px) {
  .job-home-hero {
    grid-template-columns: 1fr;
  }

  .job-home-hero-copy {
    max-width: 48rem;
  }
}

@media (max-width: 768px) {
  .job-page,
  .job-page-shell {
    width: min(100% - 2rem, var(--site-shell-max-width));
  }

  .job-home-hero {
    /* The top keeps the shell's rhythm at every width, so this page opens level with every other
       one. Only the bottom tightens on a narrow screen. */
    padding-block-start: var(--job-space-8);
    padding-block-end: var(--job-space-7);
  }

  .job-home-hero-copy h1 {
    font-size: clamp(2.7rem, 15vw, 4rem);
  }

  .job-section-heading,
  .job-review-grid,
  .job-requirement-row,
  .job-explainer ol {
    grid-template-columns: 1fr;
  }

  .job-report-section {
    grid-template-columns: 1fr;
    gap: var(--job-space-3);
  }

  .job-fact-list > div {
    grid-template-columns: 1fr;
    gap: var(--job-space-1);
  }

  .job-input-meta {
    flex-direction: column;
    gap: var(--job-space-1);
  }
}

.job-candidate-list {
  max-width: 52rem;
  padding: 0;
  margin: var(--job-space-4) 0 0;
  list-style: none;
}

.job-candidate {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-4);
  align-items: center;
  justify-content: space-between;
  padding: var(--job-space-4) 0;
  border-bottom: 1px solid var(--job-line);
}

.job-candidate-detail {
  display: grid;
  gap: var(--job-space-1);
}

.job-candidate-detail span {
  color: var(--job-ink-soft);
  font-size: 0.92rem;
}

.job-optional-question {
  padding: var(--job-space-4);
  border: 1px solid var(--job-line);
  border-radius: var(--job-radius-md);
  background: var(--job-canvas);
}

.job-optional-question label {
  display: flex;
  gap: var(--job-space-3);
  align-items: baseline;
}

.job-optional-help {
  margin: var(--job-space-2) 0 0;
  color: var(--job-ink-soft);
  font-size: 0.88rem;
}

.job-source-list {
  display: grid;
  gap: var(--job-space-4);
  max-width: 52rem;
  margin: var(--job-space-4) 0 0;
}

.job-source-entry {
  padding-bottom: var(--job-space-4);
  border-bottom: 1px solid var(--job-line);
}

.job-source-entry dt {
  font-weight: 600;
}

.job-source-entry dd {
  display: grid;
  gap: var(--job-space-1);
  margin: var(--job-space-2) 0 0;
}

.job-source-line {
  color: var(--job-ink-soft);
  font-size: 0.92rem;
}

.job-source-state {
  justify-self: start;
  padding: var(--job-space-1) var(--job-space-3);
  border: 1px solid var(--job-line-strong);
  border-radius: var(--job-radius-sm);
  font-size: 0.82rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

/* Status is carried by the wording itself, so colour only reinforces it and is never the
   sole signal. Waiting on a source is ordinary, not an error, so nothing here turns red. */
.job-source-state[data-state="Current"] {
  border-color: var(--job-brand);
  background: var(--job-brand-soft);
  color: var(--job-brand-strong);
}

.job-attribution {
  max-width: 52rem;
  margin: var(--job-space-5) 0 0;
  color: var(--job-ink-soft);
  font-size: 0.88rem;
}

.job-provenance-list {
  max-width: 52rem;
  padding: 0;
  margin: var(--job-space-4) 0 0;
  list-style: none;
}

@media (max-width: 768px) {
  .job-candidate {
    align-items: flex-start;
    justify-content: flex-start;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

.job-analysing {
  display: grid;
  gap: var(--job-space-3);
  padding: var(--job-space-6);
  border: 1px solid var(--job-line);
  border-radius: var(--job-radius-lg);
  background: var(--job-paper);
}

.job-analysing h2 {
  margin: 0;
}

.job-analysing p {
  max-width: 46rem;
  margin: 0;
  color: var(--job-ink-soft);
}

.job-analysing-bar {
  overflow: hidden;
  width: 100%;
  max-width: 26rem;
  height: 0.25rem;
  border-radius: var(--job-radius-sm);
  background: var(--job-mark-track);
}

.job-analysing-bar span {
  display: block;
  width: 40%;
  height: 100%;
  border-radius: inherit;
  background: var(--job-mark);
  animation: job-analysing-slide 1.4s ease-in-out infinite;
}

@keyframes job-analysing-slide {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}

/* Motion is decorative here; the wording carries the meaning. */
@media (prefers-reduced-motion: reduce) {
  .job-analysing-bar span {
    animation: none;
    width: 100%;
  }
}

/* ---------------------------------------------------------------------------
   Role Market report

   Drawn to the redesign of 28 September 2026 (design-tokens.md, "Report page"). Every section runs
   full width with a hairline rule above it and puts one 920px reading column back inside itself.
   The page sits on the canvas; white appears only as the face of the glance card, the provenance
   panel and the chips, so no card sits on another. Every module's children are spaced by the
   column's gap alone, so the rhythm does not depend on what a module happens to start with.
   --------------------------------------------------------------------------- */

.role-market__column {
  width: min(var(--job-width-report), 100%);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--job-module-gap);
}

.role-market .role-market__column > * {
  margin-block: 0;
}

/* ── The opening ─────────────────────────────────────────────────────────────────────────────── */
.role-market__header {
  padding: 56px var(--page-gutter-x) 48px;
}

.role-market__eyebrow {
  margin: 0;
  color: var(--job-brand);
  font-size: 0.875rem;
  font-weight: var(--job-weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.role-market__header h1,
.role-market--empty h1 {
  margin: 0;
  max-width: var(--job-measure-display);
  font-size: var(--job-text-heading);
  font-weight: var(--job-weight-semibold);
  line-height: 1.05;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.role-market__identity {
  margin: 0;
  font-size: var(--job-text-label);
  color: var(--job-ink-soft);
}

.role-market__code {
  font-variant-numeric: tabular-nums;
}

/* A hairline between the code and the geography. Drawn, not typed: a "|" would be a character
   that reads as faint text rather than as the divider it is. */
.role-market__identity-rule {
  display: inline-block;
  width: 1px;
  height: 0.9em;
  margin-inline: 0.6em;
  vertical-align: -0.1em;
  background: var(--job-line);
}

/* Keep, and what keeping does, side by side. */
.role-market__save {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 20px;
  margin-top: 8px;
}

.role-market__save form {
  flex: none;
  margin: 0;
}

.role-market__save .job-button {
  min-height: var(--job-button-height);
  padding: 0 24px;
  border-radius: var(--job-radius-pill);
  font-size: 1rem;
  font-weight: var(--job-weight-medium);
}

.role-market__save-note {
  flex: 1 1 18rem;
  max-width: var(--job-measure-intro-narrow);
  margin: 0;
  font-size: var(--job-text-note);
  line-height: 1.5;
  color: var(--job-ink-soft);
}

/* The latest figures at a glance, on one white card. */
.role-market__glance {
  margin-top: 16px;
  padding: 32px;
  border-radius: var(--job-radius-card);
  background: var(--job-paper);
}

.role-market .role-market__column > .role-market__glance {
  margin-top: 16px;
}

.role-market__glance-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 24px;
}

.role-market__glance-list > li {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Held to one line so the four figures share a baseline. */
.role-market__glance-label {
  min-height: 1.3em;
  font-size: var(--job-text-small);
  font-weight: var(--job-weight-medium);
  line-height: 1.3;
  color: var(--job-ink-soft);
}

.role-market__glance-figure {
  font-size: var(--job-text-figure-glance);
  font-weight: var(--job-weight-semibold);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--job-ink);
}

.role-market__glance-period,
.role-market__glance-note {
  font-size: var(--job-text-small);
  color: var(--job-ink-soft);
}

.role-market__glance-note {
  margin: 0;
}

/* ── A module ────────────────────────────────────────────────────────────────────────────────── */
.role-market__module {
  padding: var(--job-module-space) var(--page-gutter-x);
  border-top: 1px solid var(--job-line);
}

.role-market__module--cannot {
  padding-bottom: clamp(4rem, 3.1rem + 3.6vw, 6rem);
}

/* The heading, and the period its evidence describes directly beneath it. */
.role-market__heading {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.role-market__heading h2 {
  margin: 0;
  font-size: var(--job-text-heading-module);
  font-weight: var(--job-weight-semibold);
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.role-market__evidence {
  margin: 0;
  color: var(--job-ink-soft);
  font-size: var(--job-text-caps-sm);
  font-weight: var(--job-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* The module's lead: what the figure is, in the site's own words, with its period. */
.role-market__headline {
  max-width: var(--job-measure-report);
  font-size: var(--job-text-lead);
  line-height: 1.5;
  color: var(--job-ink);
}

/* A secondary paragraph: a sample, a stale-period warning, a stated difference, a caveat. */
.role-market__sample,
.role-market__caveat,
.role-market__caveat--stale,
.role-market__difference,
.role-market__difference--withheld,
.role-market__comparison-verdict {
  max-width: var(--job-measure-report);
  font-size: var(--job-text-note);
  line-height: 1.5;
  color: var(--job-ink-soft);
}

.role-market__limitation {
  font-size: var(--job-text-note);
  color: var(--job-ink-soft);
}

.role-market__comparison {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.role-market__state {
  display: block;
  margin-top: 4px;
  font-size: var(--job-text-small);
}

.role-market__subheading {
  margin: 8px 0 0;
  font-size: clamp(1.125rem, 1.098rem + 0.1124vw, 1.1875rem);
  font-weight: var(--job-weight-semibold);
}

/* A text link with its arrow (see .job-link-arrow). The padding keeps the target at the link
   height. The report sets its links, its disclosures and the figures control at 15px on both
   widths, a step under the homepage's link size, because on the report they sit among notes rather
   than closing a section (design-tokens.md, "Report page exceptions"). */
.role-market__link {
  display: inline-block;
  align-self: flex-start;
  padding-block: 4px;
  color: var(--job-brand);
  font-size: 0.9375rem;
  font-weight: var(--job-weight-medium);
  line-height: 1.5;
  text-decoration: none;
}

.role-market__link:hover {
  color: var(--job-brand-strong);
}

/* ── Requirements, as bars ───────────────────────────────────────────────────────────────────── */
.role-market__bars {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 26px;
}

.role-market__bars > li {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.role-market__bar-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}

.role-market__bar-label {
  font-size: var(--job-text-label);
  font-weight: var(--job-weight-medium);
}

.role-market__bar-share {
  font-size: var(--job-text-label);
  font-weight: var(--job-weight-semibold);
  font-variant-numeric: tabular-nums;
}

.role-market__bar-track,
.role-market__region-track {
  display: block;
  height: var(--job-bar-height);
  border-radius: var(--job-radius-bar);
  background: var(--job-mark-track);
}

.role-market__bar-fill,
.role-market__region-fill {
  display: block;
  height: var(--job-bar-height);
  border-radius: var(--job-radius-bar);
  background: var(--job-mark);
}

/* ── Where the adverts were placed ───────────────────────────────────────────────────────────── */
.role-market__regions {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.role-market__region {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 10px 16px;
}

.role-market__region dt {
  font-size: var(--job-text-label);
  font-weight: var(--job-weight-medium);
}

.role-market__region dd {
  margin: 0;
  font-size: var(--job-text-label);
  font-weight: var(--job-weight-semibold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.role-market__region-track {
  grid-column: 1 / -1;
}

/* The year-earlier counts: two columns of rows, each divided by a rule. */
.role-market__regions--movement {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 48px;
}

.role-market__regions--movement .role-market__region {
  padding: 10px 0;
  border-top: 1px solid var(--job-line);
  gap: 16px;
}

.role-market__regions--movement .role-market__region dt,
.role-market__regions--movement .role-market__region dd {
  font-size: var(--job-text-note);
  font-weight: var(--job-weight-regular);
}

.role-market__regions--movement .role-market__region dd {
  color: var(--job-ink-soft);
  white-space: normal;
  text-align: right;
}

/* ── Chips: titles, related occupations, occupations that stated about the same ──────────────── */
.role-market__titles,
.role-market__related,
.role-market__peers {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.role-market__titles > li,
.role-market__related > li,
.role-market__peers > li {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  align-content: center;
  gap: 2px 8px;
  min-height: var(--job-target);
  padding: 0 18px;
  border-radius: var(--job-radius-pill);
  background: var(--job-paper);
  font-size: var(--job-text-note);
  font-weight: var(--job-weight-medium);
}

/* Every chip is a link, and the whole pill is its target: the name is stretched over the chip, as
   on the homepage's tool cards, so the figure or the "also in other occupations" beside it is part
   of what a reader taps. The white pill on the canvas is the affordance, the same as the homepage's
   chips, so no underline is drawn inside it. */
.role-market__titles > li,
.role-market__related > li,
.role-market__peers > li {
  position: relative;
}

.role-market__titles > li > a,
.role-market__related > li > a,
.role-market__peers > li > a {
  color: var(--job-ink);
  text-decoration: none;
}

.role-market__titles > li > a::after,
.role-market__related > li > a::after,
.role-market__peers > li > a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--job-radius-pill);
}

.role-market__titles > li > a:hover,
.role-market__related > li > a:hover,
.role-market__peers > li > a:hover {
  color: var(--job-brand-strong);
}

/* The ring goes round the chip the link stands for, not round the words of its name. */
.role-market__titles > li > a:focus-visible,
.role-market__related > li > a:focus-visible,
.role-market__peers > li > a:focus-visible {
  outline: none;
}

.role-market__titles > li > a:focus-visible::after,
.role-market__related > li > a:focus-visible::after,
.role-market__peers > li > a:focus-visible::after {
  outline: 0.2rem solid var(--job-focus);
  outline-offset: 0.2rem;
}

.role-market__peer-value,
.role-market__shared {
  color: var(--job-ink-soft);
  font-weight: var(--job-weight-regular);
  font-variant-numeric: tabular-nums;
}

.role-market__shared {
  font-size: 0.8125rem;
}

/* The band's own list is bounded and scrolls; the report's chip lists are not.

   Scoped to .salary-band deliberately. The same chips serve the occupation report, where they are
   a handful of neighbouring occupations and bounding them would add a scrollbar to something that
   already fits. Here the band can hold 144 occupations, which pushes everything below it off the
   page and turns a module into a directory. Only the chips move: the heading, the slider and the
   summary line stay put. Every chip is a link, so the list scrolls under the keyboard as well. */
.salary-band .role-market__peers {
  max-height: 26rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  align-content: flex-start;
}

/* ── Official occupation context ─────────────────────────────────────────────────────────────── */
.role-market__classification {
  margin: 0;
  padding: 0;
  list-style: none;
}

.role-market__classification > li {
  display: grid;
  grid-template-columns: 160px minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 16px;
  padding: 14px 0;
  border-top: 1px solid var(--job-line);
}

.role-market__level-name {
  color: var(--job-ink-soft);
  font-size: var(--job-text-caps-sm);
  font-weight: var(--job-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.role-market__level-label {
  font-size: var(--job-text-label);
}

.role-market__level-code {
  color: var(--job-ink-soft);
  font-size: var(--job-text-label);
  font-variant-numeric: tabular-nums;
}

.role-market__classification > li[aria-current] .role-market__level-label {
  color: var(--job-brand);
  font-weight: var(--job-weight-semibold);
}

/* ── Evidence periods ────────────────────────────────────────────────────────────────────────── */
.role-market__periods {
  max-width: var(--job-measure-report);
  margin: 0;
}

.role-market__period {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  padding: 12px 0;
  border-top: 1px solid var(--job-line);
  font-size: var(--job-text-body);
}

.role-market__period dd {
  margin: 0;
  text-align: right;
}

.role-market__period-value {
  white-space: nowrap;
}

.role-market__period-value,
.role-market__partial {
  font-weight: var(--job-weight-semibold);
}

.role-market__partial::before {
  content: ", ";
}

/* ── What this page cannot tell you ──────────────────────────────────────────────────────────── */
.role-market__list {
  max-width: 640px;
  margin: 0;
  padding-left: 20px;
  list-style: disc;
  font-size: var(--job-text-body);
  line-height: 1.5;
  color: var(--job-ink-soft);
}

.role-market__list > li + li {
  margin-top: 10px;
}

/* ── The monthly figures ─────────────────────────────────────────────────────────────────────────
   Closed, a text link with an arrow that says how many figures opening it gives. Open, the same
   words say what closing does, with a chevron turned down, and the table follows. */
.role-market__figures > summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--job-link-height);
  color: var(--job-brand);
  font-size: 0.9375rem;
  font-weight: var(--job-weight-medium);
  cursor: pointer;
  list-style: none;
}

.role-market__figures > summary::-webkit-details-marker {
  display: none;
}

.role-market__figures > summary:hover {
  color: var(--job-brand-strong);
}

.role-market__figures-open,
.role-market__figures[open] .role-market__figures-closed {
  display: none;
}

.role-market__figures[open] .role-market__figures-open {
  display: inline;
}

/* The arrow after the closed link, and the chevron before the open one, drawn in the link's own
   colour from the same shapes as Platform.Ui.Core's icons. */
.role-market__figures > summary::after,
.role-market__figures[open] > summary::before {
  content: "";
  flex: none;
  background: currentColor;
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: contain;
}

.role-market__figures > summary::after {
  width: 16px;
  height: 16px;
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 12h15M13.5 6l6 6-6 6'/%3E%3C/svg%3E");
}

.role-market__figures[open] > summary::after {
  content: none;
}

.role-market__figures[open] > summary::before {
  width: 12px;
  height: 12px;
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 9 7 7 7-7'/%3E%3C/svg%3E");
}

/* The published tables. Shared with the Region, Requirement and Compare pages, so this part says
   only what every one of them is: ruled rows, a quiet header, figures right-aligned under a
   right-aligned heading so a column of numbers reads as one. */
.role-market__history,
.role-market__table {
  width: 100%;
  margin: 0;
  border-collapse: collapse;
  font-size: var(--job-text-note);
  font-variant-numeric: tabular-nums;
}

.role-market__history caption,
.role-market__table caption {
  caption-side: top;
  padding-bottom: 12px;
  text-align: left;
  color: var(--job-ink-soft);
  font-size: var(--job-text-note);
  line-height: 1.5;
}

.role-market__history th,
.role-market__history td,
.role-market__table th,
.role-market__table td {
  padding: 10px 0;
  border-top: 1px solid var(--job-line);
  text-align: left;
  font-weight: var(--job-weight-regular);
}

.role-market__history td + td,
.role-market__table td + td {
  padding-left: 16px;
}

.role-market__history thead th,
.role-market__table thead th {
  padding-top: 0;
  border-top: 0;
  color: var(--job-ink-soft);
  font-size: var(--job-text-small);
}

.role-market__history td,
.role-market__table td,
.role-market__history thead th + th,
.role-market__table thead th + th {
  text-align: right;
}

/* On the report: the monthly figures under a chart. The figure is the evidence and carries the
   weight; the column after it says whether the publisher revised it, which qualifies the figure
   rather than being one, so it is set quieter. */
.role-market .role-market__history,
.role-market .role-market__table {
  max-width: var(--job-measure-report);
}

.role-market .role-market__figures .role-market__history {
  margin-top: 12px;
}

/* Set as a label, as the design draws it, because under a chart it names one measure in a few
   words. The shared pages keep a sentence, since their captions run to two lines. */
.role-market .role-market__history caption {
  font-size: var(--job-text-caps-sm);
  font-weight: var(--job-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.role-market .role-market__history td:first-of-type,
.role-market .role-market__table td:first-of-type {
  font-weight: var(--job-weight-semibold);
}

.role-market .role-market__history td + td {
  color: var(--job-ink-soft);
}

/* ── The short states: loading, unavailable, nothing published ───────────────────────────────── */
.role-market--empty {
  padding: 56px var(--page-gutter-x) clamp(4rem, 3.1rem + 3.6vw, 6rem);
}

.role-market__search {
  width: min(var(--job-width-search), 100%);
  margin-top: 8px;
}

.role-market__status {
  padding-block: var(--job-module-space);
  color: var(--job-ink-soft);
}

/* ── The salary range ────────────────────────────────────────────────────────────────────────────
   Restraint is the whole design here: a hairline track, one filled span, two plain handles, and
   the figures set as text rather than crammed into the control. The occupations underneath are
   the content and this is only how a reader asks for them. */
.salary-band__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px 24px;
}

.salary-band__value {
  margin: 0;
  font-size: var(--job-text-title);
  font-weight: var(--job-weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--job-ink);
}

.salary-range {
  position: relative;
  height: 2.5rem;
}

.salary-range__track,
.salary-range__fill {
  position: absolute;
  top: 50%;
  height: var(--job-bar-height);
  border-radius: 999px;
  transform: translateY(-50%);
  pointer-events: none;
}

.salary-range__track {
  left: 0;
  right: 0;
  background: var(--job-mark-track);
}

.salary-range__fill {
  background: var(--job-mark);
}

/* The inputs are invisible and inert; only their thumbs are drawn and only their thumbs take the
   pointer. That is what lets two native ranges sit on one track and still behave like ranges. */
.salary-range__input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  background: none;
  appearance: none;
  -webkit-appearance: none;
  pointer-events: none;
}

.salary-range__input::-webkit-slider-thumb {
  -webkit-appearance: none;
  pointer-events: auto;
  width: 1.375rem;
  height: 1.375rem;
  border-radius: 50%;
  border: 2px solid var(--job-mark);
  background: var(--job-paper);
  box-shadow: 0 1px 3px rgba(26, 31, 29, 0.18);
  cursor: grab;
}

.salary-range__input::-moz-range-thumb {
  pointer-events: auto;
  width: 1.375rem;
  height: 1.375rem;
  border-radius: 50%;
  border: 2px solid var(--job-mark);
  background: var(--job-paper);
  box-shadow: 0 1px 3px rgba(26, 31, 29, 0.18);
  cursor: grab;
}

.salary-range__input:focus-visible::-webkit-slider-thumb {
  outline: 0.2rem solid var(--job-focus);
  outline-offset: 2px;
}

.salary-range__input:focus-visible::-moz-range-thumb {
  outline: 0.2rem solid var(--job-focus);
  outline-offset: 2px;
}

/* The upper handle sits above so the two can be brought together without one becoming
   unreachable. */
.salary-range__input--ceiling {
  z-index: 1;
}

.salary-band__scale {
  display: flex;
  justify-content: space-between;
  color: var(--job-ink-soft);
  font-size: var(--job-text-small);
  font-variant-numeric: tabular-nums;
}

.role-market .role-market__column > .salary-band__scale {
  margin-top: -12px;
}

.salary-band__summary {
  font-size: var(--job-text-note);
  line-height: 1.5;
  color: var(--job-ink-soft);
}

.salary-band__note {
  max-width: var(--job-measure-report);
  font-size: var(--job-text-note);
  line-height: 1.5;
  color: var(--job-ink-soft);
}

/* ── The report on a phone ───────────────────────────────────────────────────────────────────── */
@media (max-width: 45rem) {
  .role-market__header,
  .role-market--empty {
    padding-block: 40px;
  }

  .role-market__save {
    flex-direction: column;
    align-items: stretch;
    gap: 20px;
  }

  .role-market__save .job-button {
    width: 100%;
    min-height: 56px;
    justify-content: center;
  }

  .role-market__save-note {
    flex-basis: auto;
    font-size: var(--job-text-small);
  }

  .role-market__glance {
    padding: 24px;
    border-radius: 20px;
  }

  .role-market .role-market__column > .role-market__glance {
    margin-top: 4px;
  }

  .role-market__glance-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .role-market__glance-label {
    min-height: 2.6em;
    font-size: 0.8125rem;
  }

  .role-market__glance-period,
  .role-market__glance-note {
    font-size: 0.8125rem;
  }

  .role-market__module--cannot {
    padding-bottom: 64px;
  }

  .role-market__regions {
    gap: 18px;
  }

  .role-market__regions--movement {
    grid-template-columns: minmax(0, 1fr);
  }

  .role-market__regions--movement .role-market__region {
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
  }

  .role-market__regions--movement .role-market__region dd {
    text-align: left;
  }

  .role-market__titles > li,
  .role-market__related > li,
  .role-market__peers > li {
    padding: 10px 18px;
    line-height: 1.3;
  }

  /* Shorter on a phone, where 26rem is most of the screen. */
  .salary-band .role-market__peers {
    max-height: 20rem;
  }

  .role-market__classification > li {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 4px 16px;
  }

  .role-market__level-name {
    grid-column: 1 / -1;
    font-size: 0.75rem;
  }
}

/* ---------------------------------------------------------------------------
   Job market homepage

   The entry point. One question, one input, one action, the search is the page's
   only job above the fold, so nothing else competes with it for attention.
   --------------------------------------------------------------------------- */

/* ── Homepage bands ────────────────────────────────────────────────────────────────────────────
   Specification section 8, drawn to the redesign of 28 September 2026. Every value is a token from
   the root block, which records the design (docs/products/jobs/design-system/design-tokens.md).

   ONE SURFACE, RULES BETWEEN. The page sits on the canvas throughout; three sections are divided
   from the one above by a hairline rule, and the demand band is the one full-width coloured
   surface. White appears only as the face of a card, a chip or the search field, so no card ever
   sits on another card. This is why `Index.razor` renders the component without a `.job-page`
   wrapper: each band owns its own full width and puts the page column back inside itself. */
.job-market-band {
  padding-block: var(--job-section-space);
}

.job-market-band__inner {
  width: min(var(--site-shell-max-width), calc(100% - (2 * var(--page-gutter-x))));
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.job-market-band--tools,
.job-market-band--scope,
.job-market-band--close {
  border-top: 1px solid var(--job-line);
}

.job-market-band--tools .job-market-band__inner {
  gap: 40px;
}

.job-market-band--requirements {
  padding-block: 112px;
}

.job-market-band--requirements .job-market-band__inner,
.job-market-band--scope .job-market-band__inner {
  gap: 48px;
}

/* The one inverse surface: the demand figures are the page's subject here, not its evidence. */
.job-market-band--evidence {
  padding-block: var(--job-section-space-lg);
  background: var(--job-inverse);
  color: var(--job-on-inverse);
}

.job-market-band--evidence .job-market-band__inner {
  gap: 36px;
}

.job-market-band--hero,
.job-market-band--tools,
.job-market-band--evidence,
.job-market-band--requirements,
.job-market-band--scope,
.job-market-band--close {
  text-align: center;
}

.job-market-band__intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--job-heading-gap);
}

.job-market-band__heading {
  margin: 0;
  max-width: var(--job-measure-heading);
  font-size: var(--job-text-heading);
  font-weight: var(--job-weight-semibold);
  line-height: 1.05;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.job-market-band__lede {
  margin: 0;
  max-width: var(--job-measure-intro-narrow);
  font-size: var(--job-text-intro);
  line-height: 1.5;
  color: var(--job-ink-soft);
  text-wrap: pretty;
}

.job-market-band--evidence .job-market-band__heading {
  color: var(--job-on-inverse);
}

.job-market-band--evidence .job-market-band__lede {
  max-width: var(--job-measure-intro);
  color: var(--job-on-inverse-soft);
}

/* On the inverse band the site's blue focus ring measures 1.36:1 and cannot be seen, so focus
   there is drawn in the band's own white. */
.job-market-band--evidence :focus-visible {
  outline-color: var(--job-on-inverse);
}

/* A link inside a sentence: ink at 500, underlined, the only underlined link on the page, as the
   design draws "Check a job advert". Scoped to the bands because MudBlazor's bare `a` rule
   otherwise wins and renders it identical to the sentence around it. */
.job-market-band p a:not([class*="job-button"]) {
  color: var(--job-ink);
  font-weight: var(--job-weight-medium);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

.job-market-band p a:not([class*="job-button"]):hover {
  color: var(--job-brand-strong);
  text-decoration-thickness: 2px;
}

/* A text link with an arrow after it, from Platform.Ui.Core's icon set, on the homepage and the report alike. The arrow sits in the
   text flow rather than in a flex row, so when the words wrap on a phone it stays after the last of
   them instead of standing at the far edge; the last words and the arrow are held together so the
   arrow is never left on a line of its own. */
.job-link-arrow {
  display: inline-block;
  flex: none;
  margin-left: 6px;
  vertical-align: -0.125em;
}

.job-link-tail {
  white-space: nowrap;
}

/* ── Homepage hero ─────────────────────────────────────────────────────────────────────────── */
.job-market-band--hero {
  padding-block: clamp(2.75rem, 1.107rem + 6.742vw, 6.5rem) clamp(2.5rem, 1.185rem + 5.393vw, 5.5rem);
}

.job-market-hero {
  gap: clamp(1.125rem, 0.8511rem + 1.124vw, 1.75rem);
}

/* The line that says what the site is, read at a glance before the headline, as BeforeYouMove's
   "Property research · England" is: in capitals like every eyebrow, a step larger and wider-set. */
.job-market-hero .job-eyebrow {
  font-size: 0.8125rem;
  letter-spacing: 0.18em;
}

.job-market-hero h1 {
  margin: 0;
  max-width: var(--job-measure-display);
  font-size: var(--job-text-display);
  font-weight: var(--job-weight-semibold);
  line-height: 1;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

/* A colour change on the second clause, not a second sentence. The heading's text content is
   still section 8's sentence, unbroken, which is what the specification fixed. */
.job-market-hero__accent {
  color: var(--job-brand);
}

.job-market-hero__lede {
  margin: 0;
  max-width: var(--job-measure-lede);
  font-size: var(--job-text-lede);
  line-height: 1.5;
  color: var(--job-ink-soft);
  text-wrap: pretty;
}

/* The search, then its small print. Left-aligned inside the centred hero once results appear,
   because the choices under it are a list to read down. */
.job-market-hero__search {
  width: min(var(--job-width-search), 100%);
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.job-market-hero__secondary {
  margin: 0;
  font-size: var(--job-text-note);
  color: var(--job-ink-soft);
}

/* ── Where other people started ────────────────────────────────────────────────────────────────
   Section 8 item 3, in the hero because that is the moment it answers: the reader has just been
   handed a blank box. A way in, not a leaderboard: no counts, no ranking marks, no emphasis that
   would make one name look more significant than another. The heading is a real heading, set as
   the first words of the note under the chips. */
.job-market-watched {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 28px;
  margin-top: 36px;
  max-width: 100%;
}

.job-market-watched__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.job-market-watched__list a {
  display: inline-flex;
  align-items: center;
  min-height: var(--job-target);
  padding: 0 18px;
  border-radius: var(--job-radius-pill);
  background: var(--job-paper);
  color: var(--job-ink);
  font-size: var(--job-text-note);
  font-weight: var(--job-weight-medium);
  text-decoration: none;
  white-space: nowrap;
}

.job-market-watched__list a:hover {
  color: var(--job-brand-strong);
}

.job-market-watched__lede {
  margin: 0;
  font-size: var(--job-text-small);
  color: var(--job-ink-soft);
}

.job-market-watched__heading {
  display: inline;
  margin: 0;
  font: inherit;
  color: inherit;
}

.occupation-search {
  display: grid;
  gap: var(--job-space-2);
}

.occupation-search label {
  font-weight: var(--job-weight-medium);
  font-size: var(--job-text-label);
}

/* The field and, in the hero, its magnifier. */
.occupation-search__field {
  display: flex;
  align-items: center;
  min-width: 0;
}

/* Stacks below 34rem so the input never shrinks to a width nobody can type into. */
.occupation-search__row {
  display: grid;
  gap: var(--job-space-2);
}

.occupation-search input {
  min-height: 3rem;
  padding: 0.7rem 1rem;
  border: 1px solid var(--job-line-strong);
  border-radius: var(--job-radius-md);
  background: var(--job-paper);
  color: var(--job-ink);
  font: inherit;
  width: 100%;
}

.occupation-search .job-button {
  background: var(--job-brand);
  color: var(--job-paper);
}

/* UXD-06. White on the border grey measured 1.87:1: the primary call to action could not be read
   in its resting state. WCAG exempts a genuinely disabled control from contrast and this one is
   truly `disabled`, so it was not a conformance failure -- it was worse in practice, because a
   reader could not tell what the button would do if they filled the field in. Now it reads as
   unavailable by having no fill rather than by being unreadable. */
.occupation-search .job-button:disabled {
  border: 1px solid var(--job-line-strong);
  background: transparent;
  color: var(--job-ink-soft);
  cursor: not-allowed;
}

.occupation-search__help,
.occupation-search__status {
  margin: 0;
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
}

/* A result is a module of its own on the canvas, not a card: its heading, the site's sentence, and
   for an ambiguous term the list of choices. */
.occupation-search__result {
  margin-top: 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  text-align: left;
}

.occupation-search__result h2 {
  margin: 0;
  font-size: var(--job-text-heading-module);
  font-weight: var(--job-weight-semibold);
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.occupation-search__result p {
  margin: 0;
  font-size: var(--job-text-lead);
  line-height: 1.5;
  color: var(--job-ink-soft);
}

.occupation-search__candidates {
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
}

.occupation-search__candidate {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px;
  align-items: center;
  padding: 16px 0;
  border-top: 1px solid var(--job-line);
  color: var(--job-ink);
  text-decoration: none;
}

.occupation-search__candidate-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.occupation-search__candidate-label {
  font-size: var(--job-text-label);
  font-weight: var(--job-weight-medium);
}

.occupation-search__candidate:hover .occupation-search__candidate-label {
  color: var(--job-brand-strong);
}

.occupation-search__candidate-arrow {
  color: var(--job-brand);
}

/* The evidence that made a title a candidate, so a user asked to choose can see
   what the choice rests on rather than being handed a bare list. */
.occupation-search__matched {
  display: block;
  color: var(--job-ink-soft);
  font-size: var(--job-text-small);
}


/* ── The hero pill ─────────────────────────────────────────────────────────────────────────────
   Presentation only: the same form, the same control, the same states, with the question above it
   and the magnifier, field and action on one white surface. Compare keeps the labelled panel,
   because there the same control sits beside another one. */
.occupation-search--hero {
  gap: 14px;
}

.occupation-search--hero > label {
  font-size: var(--job-text-label);
  font-weight: var(--job-weight-medium);
  text-align: center;
}

.occupation-search--hero .occupation-search__row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 8px 8px 22px;
  border-radius: var(--job-radius-pill);
  background: var(--job-paper);
  box-shadow: var(--job-shadow-field);
}

.occupation-search--hero .occupation-search__field {
  flex: 1;
  gap: 8px;
}

.occupation-search--hero .occupation-search__icon {
  flex: none;
  color: var(--job-ink-soft);
}

.occupation-search--hero input {
  flex: 1;
  min-width: 0;
  height: var(--job-button-height);
  min-height: 0;
  padding: 0 8px;
  border: 0;
  border-radius: 0;
  background: transparent;
  font-size: 1.125rem;
  color: var(--job-ink);
}

/* Focus is shown by the pill, not by the input inside it. The site's ring round the input drew a
   rectangle inside the rounded field, which read as a broken box rather than as focus. The pill
   takes the ring instead, following its own curve, in the brand colour so the field reads as the
   thing being typed in. Still an outline rather than a box-shadow, because forced-colours mode
   keeps an outline and drops a shadow. STA012 holds the two rules together, so the input's ring
   cannot be removed without the pill's taking its place. */
.occupation-search--hero input:focus-visible {
  outline: none;
}

.occupation-search--hero .occupation-search__row:has(input:focus-visible) {
  outline: 2px solid var(--job-brand);
  outline-offset: 3px;
}

/* The browser's clear control, drawn as the magnifier is: the same soft ink and the same stroke as
   Platform.Ui.Core's icons, rather than the browser's own blue cross. */
.occupation-search--hero input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  flex: none;
  width: 20px;
  height: 20px;
  background: var(--job-ink-soft);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6 6 18'/%3E%3C/svg%3E") center / 16px no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6 6 18'/%3E%3C/svg%3E") center / 16px no-repeat;
  cursor: pointer;
}

.occupation-search--hero input::-webkit-search-cancel-button:hover {
  background: var(--job-ink);
}

.occupation-search--hero .job-button {
  flex: none;
  height: var(--job-button-height);
  min-height: 0;
  padding: 0 24px;
  border-radius: var(--job-radius-pill);
  font-size: 1rem;
  font-weight: var(--job-weight-medium);
}

/* The help stays the field's description for anybody not looking at it; the design gives the hero
   one line of small print instead, under the field. */
.occupation-search--hero .occupation-search__help {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

.occupation-search--hero .occupation-search__status:empty {
  display: none;
}

/* ── Job essentials ────────────────────────────────────────────────────────────────────────────
   Section 8 item 7, as six cards. The icon, the name and the sentence all come from the menu's own
   list, so a tool added to the menu arrives here complete or fails `NAV002`. The name is the link,
   and its hit area is stretched over the card, so the whole card is the target while the link's
   name stays the four or five words of the tool. */
.job-market-essentials__list {
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr));
  gap: 20px;
  text-align: left;
}

.job-market-essentials__item {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 32px;
  border-radius: var(--job-radius-card);
  background: var(--job-paper);
}

.job-market-essentials__icon {
  width: 26px;
  height: 26px;
  font-size: 26px;
  color: var(--job-brand);
}

.job-market-essentials__name {
  margin: 26px 0 0;
  font-size: var(--job-text-title);
  font-weight: var(--job-weight-semibold);
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.job-market-essentials__link {
  color: var(--job-ink);
  text-decoration: none;
}

.job-market-essentials__link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--job-radius-card);
}

.job-market-essentials__link:hover {
  color: var(--job-brand-strong);
}

/* The ring goes round the card the link now stands for, not round the four words of its name. */
.job-market-essentials__link:focus-visible {
  outline: none;
}

.job-market-essentials__link:focus-visible::after {
  outline: 0.2rem solid var(--job-focus);
  outline-offset: 0.2rem;
}

.job-market-essentials__description {
  margin: 8px 0 0;
  font-size: var(--job-text-body);
  line-height: 1.5;
  color: var(--job-ink-soft);
}

/* ── How occupation demand is changing ─────────────────────────────────────────────────────────
   Section 8 item 2, on the inverse band. Each figure over the sentence that says what it is a
   share of; the first in the band's accent, the rest in white. */
.job-market-change__counts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  gap: 64px;
  width: min(var(--job-width-pair), 100%);
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
}

.job-market-change__counts li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  font-size: var(--job-text-label);
  line-height: 1.45;
  color: var(--job-on-inverse-soft);
}

.job-market-change__counts strong {
  color: var(--job-on-inverse);
  font-size: var(--job-text-figure);
  font-weight: var(--job-weight-semibold);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  letter-spacing: -0.04em;
}

.job-market-change__counts li:first-child strong {
  color: var(--job-on-inverse-accent);
}

/* The note under the figures and its disclosure, in the band's own colours. */
.job-market-change__limitation {
  margin: 8px 0 0;
  font-size: var(--job-text-note);
  color: var(--job-on-inverse-soft);
}

.job-market-band--evidence .job-limitation-detail > summary {
  color: var(--job-on-inverse);
}

.job-market-band--evidence .job-limitation-detail > p {
  color: var(--job-on-inverse-soft);
}

/* ── What job adverts ask for ──────────────────────────────────────────────────────────────── */
.job-market-requirements__list {
  width: min(var(--job-width-list), 100%);
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 26px;
  text-align: left;
}

.job-market-requirements__list li {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.job-market-requirements__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}

.job-market-requirements__label {
  font-size: var(--job-text-label);
  font-weight: var(--job-weight-medium);
}

.job-market-requirements__share {
  font-size: var(--job-text-label);
  font-weight: var(--job-weight-semibold);
  font-variant-numeric: tabular-nums;
}

/* The bar carries nothing the printed share does not: it is the same number drawn against 100 per
   cent of adverts, so two requirements can be compared without arithmetic. Square where it starts,
   round where it ends. */
.job-market-requirements__track {
  display: block;
  height: var(--job-bar-height);
  border-radius: var(--job-radius-bar);
  background: var(--job-mark-track);
}

.job-market-requirements__fill {
  display: block;
  height: var(--job-bar-height);
  border-radius: var(--job-radius-bar);
  background: var(--job-mark);
}

.job-market-requirements__limitation {
  margin: 0;
  font-size: var(--job-text-note);
  color: var(--job-ink-soft);
}

/* ── What the evidence covers ──────────────────────────────────────────────────────────────────
   Section 8 item 5: the statement, then what the evidence covers and what it does not on two cards,
   then the way to the methodology. */
.job-market-scope__heading {
  max-width: var(--job-measure-heading);
}

.job-market-scope__lede {
  max-width: var(--job-measure-intro);
}

.job-market-scope__lists {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: 24px;
  width: min(var(--job-width-cards), 100%);
  text-align: left;
}

.job-market-scope__list {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 36px;
  border-radius: var(--job-radius-card);
  background: var(--job-paper);
}

.job-market-scope__list-heading {
  margin: 0;
  font-size: var(--job-text-title);
  font-weight: var(--job-weight-semibold);
  color: var(--job-ink);
}

.job-market-scope__list ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: var(--job-text-body);
  line-height: 1.5;
  color: var(--job-ink-soft);
}

/* A text link with an arrow: no underline, the brand green, a 32px target. */
.job-market-scope__link,
.job-market-career__secondary {
  display: inline-block;
  padding-block: 4px;
  color: var(--job-brand);
  font-size: var(--job-text-link);
  font-weight: var(--job-weight-medium);
  line-height: 1.5;
  text-decoration: none;
}

.job-market-scope__link:hover,
.job-market-career__secondary:hover {
  color: var(--job-brand-strong);
}

/* ── My Career, closing the page ───────────────────────────────────────────────────────────────
   Section 8 item 6. It closes rather than sits mid-page because it is the one thing on the
   homepage worth doing after reading the rest of it. */
.job-market-band--close {
  padding-block: var(--job-section-space-lg) clamp(4rem, 2.2rem + 7.4vw, 8rem);
}

.job-market-band--close .job-market-band__inner {
  gap: 24px;
}

.job-market-career__heading {
  margin: 0;
  max-width: var(--job-measure-headline);
  font-size: var(--job-text-headline);
  font-weight: var(--job-weight-semibold);
  line-height: 1;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.job-market-career__lede {
  margin: 0;
  max-width: var(--job-measure-intro);
  font-size: var(--job-text-intro);
  line-height: 1.5;
  color: var(--job-ink-soft);
}

.job-market-career__actions {
  margin-top: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 28px;
}

.job-market-career__actions .job-button-primary {
  min-height: var(--job-button-large-height);
  padding: 0 28px;
  border-radius: var(--job-radius-pill);
  font-size: var(--job-text-link-large);
  font-weight: var(--job-weight-medium);
}

.job-market-career__secondary {
  font-size: var(--job-text-link-large);
}

/* ── Homepage on a phone ───────────────────────────────────────────────────────────────────────
   The design's phone board: the hero, the band and the close stay centred; the tools, the
   requirements and the evidence read left-aligned; the search's action moves under the field at
   full width; the closing action takes the full width. */
@media (max-width: 45rem) {
  .job-market-band--tools,
  .job-market-band--requirements,
  .job-market-band--scope {
    text-align: left;
  }

  .job-market-band--tools .job-market-band__inner,
  .job-market-band--requirements .job-market-band__inner,
  .job-market-band--scope .job-market-band__inner {
    align-items: stretch;
    gap: 20px;
  }

  .job-market-band--requirements {
    padding-block: var(--job-section-space);
  }

  .job-market-band--requirements .job-market-band__inner {
    gap: 24px;
  }

  .job-market-band--tools .job-market-band__intro,
  .job-market-band--requirements .job-market-band__intro,
  .job-market-band--scope .job-market-band__intro {
    align-items: flex-start;
  }

  .job-market-band--evidence .job-market-band__inner,
  .job-market-band--close .job-market-band__inner {
    gap: 20px;
  }

  .job-market-band--close .job-market-band__inner {
    gap: 18px;
  }

  .job-market-hero h1 {
    line-height: 1.02;
    letter-spacing: -0.03em;
  }

  .job-market-hero__search {
    margin-top: 8px;
    gap: 10px;
  }

  .occupation-search--hero {
    gap: 10px;
  }

  .occupation-search--hero > label {
    font-size: 1rem;
  }

  /* The field keeps the pill and its magnifier; the action leaves it for a full-width button. */
  .occupation-search--hero .occupation-search__row {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    padding: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
  }

  /* On a phone the pill is the field alone, so the focus ring moves with it. */
  .occupation-search--hero .occupation-search__row:has(input:focus-visible) {
    outline: none;
  }

  .occupation-search--hero .occupation-search__field:has(input:focus-visible) {
    outline: 2px solid var(--job-brand);
    outline-offset: 3px;
  }

  /* flex: none, because the row is a column here: the desktop rule's flex: 1 makes the field's
     base size zero along that axis, and the pill shrank to the 40px input inside it. */
  .occupation-search--hero .occupation-search__field {
    flex: none;
    height: 56px;
    gap: 10px;
    padding: 0 18px;
    border-radius: var(--job-radius-pill);
    background: var(--job-paper);
    box-shadow: 0 1px 2px rgba(26, 31, 29, 0.04), 0 16px 40px -20px rgba(26, 31, 29, 0.3);
  }

  .occupation-search--hero input {
    height: 40px;
    padding: 0;
    font-size: 1rem;
  }

  .occupation-search--hero .job-button {
    height: 56px;
  }

  .job-market-hero__secondary {
    margin-top: 4px;
  }

  .job-market-watched {
    margin-top: 12px;
    gap: 10px;
  }

  .job-market-watched__list {
    gap: 8px;
  }

  /* Occupation names run long; on a phone a chip wraps its words rather than run off the screen. */
  .job-market-watched__list a {
    padding: 10px 18px;
    line-height: 1.3;
    white-space: normal;
    text-align: left;
  }

  .job-market-watched__lede {
    font-size: 0.8125rem;
  }

  .job-market-essentials__list {
    gap: 12px;
  }

  .job-market-essentials__item {
    padding: 24px;
  }

  .job-market-change__counts {
    gap: 28px;
    margin-top: 8px;
  }

  .job-market-change__counts li {
    gap: 6px;
  }

  .job-market-change__limitation {
    margin-top: 0;
  }

  .job-market-requirements__limitation {
    text-align: left;
  }

  .job-market-scope__lists {
    gap: 20px;
  }

  .job-market-scope__list {
    gap: 14px;
    padding: 24px;
    border-radius: 20px;
  }

  .job-market-scope__list ul {
    gap: 10px;
  }

  .job-market-career__actions {
    flex-direction: column;
    gap: 18px;
    width: 100%;
  }

  .job-market-career__actions .job-button-primary {
    width: 100%;
    min-height: 56px;
    justify-content: center;
  }
}

@media (min-width: 34rem) {
  .occupation-search__row {
    grid-template-columns: minmax(0, 1fr) auto;
  }
}



/* ---------------------------------------------------------------------------
   Legal pages: the privacy policy, and the terms and conditions

   Laid out after BeforeYouMove's legal pages, the owner's layout concept of 29
   September 2026: a tinted hero panel, then a grid of cards, each a pill label,
   a heading and its text, closing on a full-width card. Drawn in this app's own
   surfaces: white only as the surface of a card, the 24px corners and soft
   shadow of the My Career cards, and the brand's soft green for the pills. The
   content is this site's own; only the shape is borrowed.
   --------------------------------------------------------------------------- */

.job-legal {
  display: grid;
  gap: var(--job-space-5);
  padding-block: var(--job-space-6) var(--job-space-8);
}

.job-legal__hero {
  position: relative;
  display: grid;
  gap: var(--job-space-3);
  padding: clamp(2rem, 1.4rem + 2.4vw, 3.5rem) clamp(1.5rem, 0.9rem + 2.6vw, 3.5rem);
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--job-ink) 9%, transparent);
  border-radius: var(--job-radius-card);
  background: color-mix(in srgb, var(--job-brand-soft) 60%, var(--job-canvas));
}

/* The one accent: a line across the top of the panel, fading out. */
.job-legal__hero::before,
.job-legal__card--lead::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 3px;
  background: linear-gradient(90deg, var(--job-brand), transparent 85%);
}

.job-legal__hero h1 {
  margin: 0;
  font-size: var(--job-text-headline);
  line-height: 1.04;
  letter-spacing: -0.03em;
}

.job-legal__lede {
  max-width: 42rem;
  margin: 0;
  color: var(--job-ink-soft);
  font-size: var(--job-text-lede);
  line-height: 1.55;
}

.job-legal__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--job-space-4);
}

.job-legal__card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--job-space-3);
  padding: var(--job-space-6);
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--job-ink) 7%, transparent);
  border-radius: var(--job-radius-card);
  background: var(--job-paper);
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--job-ink) 4%, transparent),
    0 16px 40px -28px color-mix(in srgb, var(--job-ink) 28%, transparent);
}

.job-legal__card--wide {
  grid-column: 1 / -1;
}

.job-legal__label {
  display: inline-flex;
  align-items: center;
  min-height: 1.625rem;
  margin: 0;
  padding: 0 0.75rem;
  border-radius: var(--job-radius-pill);
  background: var(--job-brand-soft);
  color: var(--job-brand-strong);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.job-legal__card h2 {
  margin: 0;
  font-size: clamp(1.125rem, 1.06rem + 0.28vw, 1.3125rem);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.job-legal__card p {
  margin: 0;
  color: var(--job-ink-soft);
  line-height: 1.6;
  text-wrap: pretty;
}

.job-legal__card a {
  color: var(--job-brand);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* A list of named things, one per line, divided by hairlines. */
.job-legal__list {
  align-self: stretch;
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--job-ink-soft);
  line-height: 1.55;
}

.job-legal__list li {
  padding: var(--job-space-2) 0;
  border-top: 1px solid var(--job-line);
}

.job-legal__list li:first-child {
  border-top: none;
  padding-top: 0;
}

.job-legal__list strong,
.job-legal__list code {
  color: var(--job-ink);
}

.job-legal__updated {
  margin: 0;
  color: var(--job-ink-soft);
  font-size: var(--job-text-note);
}

@media (max-width: 1024px) {
  .job-legal__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 640px) {
  .job-legal__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .job-legal__card {
    padding: var(--job-space-5);
    border-radius: 1.375rem;
  }
}

/* ---------------------------------------------------------------------------
   Methodology page

   Long-form reading, so it is set for reading: one narrow column, generous
   leading, and headings that separate seventeen topics without shouting.
   --------------------------------------------------------------------------- */

.methodology {
  max-width: 44rem;
  padding-block: var(--job-space-8);
  display: grid;
  gap: var(--job-space-7);
}

.methodology__header {
  display: grid;
  gap: var(--job-space-3);
}

.methodology__header h1 {
  margin: 0;
  font-size: var(--job-title-size);
  line-height: 1.08;
  letter-spacing: var(--job-title-tracking);
  text-wrap: balance;
}

.methodology__lede {
  margin: 0;
  font-size: clamp(1.0625rem, 2.2vw, 1.1875rem);
  line-height: 1.6;
  color: var(--job-ink-soft);
}

.methodology section {
  display: grid;
  gap: var(--job-space-3);
}

.methodology h2 {
  margin: 0;
  padding-top: var(--job-space-4);
  border-top: 1px solid var(--job-line);
  font-size: clamp(1.25rem, 2.6vw, 1.5rem);
  line-height: 1.25;
}

.methodology h3 {
  margin: var(--job-space-2) 0 0;
  font-size: 1.0625rem;
}

.methodology p {
  margin: 0;
  line-height: 1.65;
}

.methodology ul {
  margin: 0;
  padding-inline-start: 1.25rem;
  list-style: disc outside;
  display: grid;
  gap: var(--job-space-2);
  line-height: 1.6;
}

.methodology li {
  list-style: inherit;
}

.methodology__sources {
  margin: 0;
  display: grid;
  gap: var(--job-space-3);
}

.methodology__sources > div {
  padding-inline-start: var(--job-space-3);
  border-left: 2px solid var(--job-line);
}

.methodology__sources dt {
  font-weight: 600;
}

.methodology__sources dd {
  margin: 0;
  color: var(--job-ink-soft);
  line-height: 1.55;
}

.methodology__close {
  padding-top: var(--job-space-3);
  border-top: 1px solid var(--job-line);
}


/* ---------------------------------------------------------------------------
   Module provenance panel

   Closed by default and quiet when open. It carries the answers to "where did
   this come from", which most readers never ask and none should have to read
   before reaching the number. The limitation is deliberately not in here.

   Closed, it is a quiet link with the same chevron as the caveat disclosure, so
   every disclosure on the page opens the same way. Open, the facts sit on one
   white face in three columns, the only white on the page besides the glance
   card and the chips.
   --------------------------------------------------------------------------- */

.trust-panel > summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--job-link-height);
  color: var(--job-brand);
  font-size: 0.9375rem;
  font-weight: var(--job-weight-medium);
  cursor: pointer;
  list-style: none;
}

.trust-panel > summary::-webkit-details-marker {
  display: none;
}

.trust-panel > summary::before {
  content: "";
  flex: none;
  width: 0.375rem;
  height: 0.375rem;
  margin-inline: 0.125rem 0.1875rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--pui-motion-fast, 160ms ease);
}

.trust-panel[open] > summary::before {
  transform: rotate(45deg);
}

.trust-panel > summary:hover {
  color: var(--job-brand-strong);
}

.trust-panel__facts {
  margin: 12px 0 0;
  padding: 28px;
  border-radius: var(--job-radius-card);
  background: var(--job-paper);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px 32px;
}

.trust-panel__facts > div {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.trust-panel__facts dt {
  color: var(--job-ink-soft);
  font-size: var(--job-text-caps-sm);
  font-weight: var(--job-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.trust-panel__facts dd {
  margin: 0;
  font-size: var(--job-text-note);
  line-height: 1.5;
}

/* The edition is a checksum, so it keeps a fixed-width face and may break anywhere. */
.trust-panel__edition {
  font-family: var(--font-label);
  font-size: 0.8125rem;
  overflow-wrap: anywhere;
}

.trust-panel__note {
  display: block;
  margin-top: 4px;
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
}

@media (max-width: 45rem) {
  .trust-panel__facts {
    grid-template-columns: minmax(0, 1fr);
    padding: 24px;
    border-radius: 20px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .trust-panel > summary::before {
    transition: none;
  }
}

/* ── Sign in and account, specification sections 52 and 53 ─────────────────────────────────────
   Deliberately the same page furniture as everything else: the hero, the type scale and the
   buttons are the site's own. The estate's other magic-link hosts render a stand-alone document
   for this screen, and a sign-in page that does not look like the site is the exact page where
   that costs the most trust. */

.job-sign-in__scope {
  max-width: 34rem;
  margin: 0;
  padding: var(--job-space-4);
  border: 1px solid var(--job-line);
  border-radius: var(--job-radius-md);
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.job-sign-in__error {
  max-width: 34rem;
  margin: 0;
  color: var(--job-ink);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.job-sign-in__form {
  display: flex;
  flex-direction: column;
  gap: var(--job-space-2);
  max-width: 24rem;
  margin: 0;
}

.job-sign-in__label {
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
}

.job-sign-in__input {
  padding: var(--job-space-3);
  border: 1px solid var(--job-line-strong);
  border-radius: var(--job-radius-md);
  background: var(--job-paper);
  color: var(--job-ink);
  font: inherit;
  font-size: 1rem;
}

.job-sign-in__input:focus-visible {
  outline: 2px solid var(--job-ink);
  outline-offset: 1px;
}

.job-sign-in__form .job-button {
  align-self: flex-start;
}

.job-account {
  display: flex;
  flex-direction: column;
  gap: var(--job-space-3);
  max-width: 46rem;
}

/* An action in a section, not a banner across it. The section is a flex column, and a flex item
   stretches unless told otherwise, so "Search an occupation" on My Career and "Open your job
   search" on the questions page ran the full 46rem, a pill the width of a paragraph. */
.job-account > .job-button {
  align-self: flex-start;
}

/* The kept-occupations list is not an account panel of stored fields; it is the page. Its rows
   carry an occupation's full name, its measures and its controls on one line, and at the 46rem
   used for a settings panel the name wrapped while the controls crowded it. The prose inside keeps
   its own narrower measure, so widening the rows does not widen a paragraph. */
.job-account--roster {
  max-width: 60rem;
  gap: var(--job-space-4);
}

/* One row per stored field. The list is short on purpose and reads better as rows than as cards,
   which would make three facts look like three features. */
.job-account__facts {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin: 0;
  border-top: 1px solid var(--job-line);
}

.job-account__facts > div {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2) var(--job-space-4);
  padding: var(--job-space-3) 0;
  border-bottom: 1px solid var(--job-line);
}

.job-account__facts dt {
  min-width: 12rem;
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
}

.job-account__facts dd {
  margin: 0;
  color: var(--job-ink);
  overflow-wrap: anywhere;
}

.job-account__note {
  max-width: 42rem;
  margin: 0;
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
  line-height: 1.5;
}

/* Open sessions. One row per device, with its action beside it rather than under it, so the list
   scans as "here is a thing, here is what you can do about it". */
.job-account__sessions {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--job-line);
}

.job-account__sessions li {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-3);
  align-items: center;
  justify-content: space-between;
  padding: var(--job-space-4) 0;
  border-bottom: 1px solid var(--job-line);
}

.job-account__session-facts {
  display: flex;
  flex-direction: column;
  gap: var(--job-space-1);
  min-width: 16rem;
  flex: 1 1 20rem;
}

.job-account__session-title {
  margin: 0;
  color: var(--job-ink);
  font-weight: 600;
}

.job-account__session-detail {
  margin: 0;
  color: var(--job-ink-soft);
  font-size: 0.875rem;
  line-height: 1.5;
}

/* Deletion. Marked out rather than shouted: a red panel on a page about your own account reads as
   an alarm, and this is a legitimate thing to want to do. A left border and a restrained button
   are enough to say "this one is different". */
.job-account--danger {
  padding-left: var(--job-space-4);
  border-left: 3px solid var(--job-line-strong);
}

.job-button-danger {
  align-self: flex-start;
  padding: var(--job-space-3) var(--job-space-5);
  border: 1px solid #8c2f26;
  border-radius: var(--job-radius-md);
  background: var(--job-paper);
  color: #8c2f26;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.job-button-danger:hover {
  background: #8c2f26;
  color: var(--job-paper);
}

.job-button-danger:focus-visible {
  outline: 2px solid #8c2f26;
  outline-offset: 2px;
}

/* ── Header ────────────────────────────────────────────────────────────────────────────────────
   Overrides of Platform.Shell, kept here because they are this product's identity rather than
   shell behaviour. */

/* The wordmark is the platform's standard, which this product's two-line name set first: the name
   sets as two lines because it is more than two words. Its colours come from the logo tokens above. */

/* The header's one action, in the site's own hand.

   It is a MudButton, so it arrived in MudBlazor's dress: Roboto, which is not loaded here and fell
   through to Helvetica, uppercase, letterspaced, a 10px corner and a drop shadow. Beside a header
   set in the body face and pages whose every button is a plain pill, it was the one element on
   every page that looked borrowed. Anchored on the shell's action slot so it reaches only the
   header. */
.nav-actions .mud-button-root {
  border-radius: 999px;
  box-shadow: none;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
}

.nav-actions .mud-button-filled:hover,
.nav-actions .mud-button-filled:focus-visible {
  box-shadow: none;
}

/* The kept count, in red whatever state its link is in. Platform.Shell fills the badge with
   currentColor, so it was ink at rest and turned green on hover with the link; a count that
   changes colour with its label reads as decoration. The selector matches the shell's exactly and
   loads after it, which is what lets the host colour win. */
.nav-list a.nav-leading-link .nav-leading-link__badge {
  background: var(--job-badge);
}

/* Sections centred between the brand and the actions, rather than pushed against the logo. With
   four of the five sections still unbuilt, a left-packed list reads as a row of disabled words
   trailing off; centred, it reads as the product's shape. */
.nav-list {
  flex: 1;
  justify-content: center;
}

/* A narrow viewport opens the drawer, where the list is vertical and centring it would leave the
   labels floating away from their own hit areas. */
@media (max-width: 900px) {
  .nav-list {
    flex: initial;
    justify-content: flex-start;
  }
}

/* My Career's kept occupations. A row per occupation with its action beside it, the same shape as
   the account page's sessions list, because they are the same kind of thing: a thing you have, and
   what you can do about it. */
.job-career__roles {
  display: flex;
  flex-direction: column;
  gap: var(--job-space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* A card per occupation, redrawn on 29 September 2026 to the approved "My career occupations
   redesign" canvas: the rows had read as a plain ruled list. Each card sits straight on the cream
   canvas, and the section around the list has no surface of its own, so this is one surface, not a
   card inside a card. The name and its status lead, the controls stay top right where they were,
   and the measures and the movement run the card's full width beneath them. */
.job-career__roles li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--job-space-5) var(--job-space-6);
  padding: var(--job-space-6) var(--job-space-6) var(--job-space-5);
  border: 1px solid color-mix(in srgb, var(--job-ink) 7%, transparent);
  border-radius: var(--job-radius-card);
  background: var(--job-paper);
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--job-ink) 4%, transparent),
    0 16px 40px -28px color-mix(in srgb, var(--job-ink) 28%, transparent);
}

.job-career__role-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.625rem;
  min-width: 0;
}

/* The occupation is the largest thing on its card. It is what the reader is looking for when they
   scan their own list, and everything else is evidence about it. The arrow says it opens the
   occupation's own page. */
.job-career__role-link {
  color: var(--job-ink);
  font-size: clamp(1.3125rem, 1.2rem + 0.45vw, 1.625rem);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.015em;
  text-decoration: none;
}

.job-career__role-link:hover {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

/* The arrow is drawn the way the app draws its other icons, a stroke mask in the brand green, so
   the page holds no drawing of its own. */
.job-career__role-link::after {
  content: "";
  display: inline-block;
  width: 1.25rem;
  height: 1.25rem;
  margin-left: 0.5rem;
  vertical-align: -0.1875em;
  background: var(--job-brand);
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17 17 7M8 7h9v9'/%3E%3C/svg%3E");
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: contain;
}

.job-career__role-note {
  margin: var(--job-space-1) 0 0;
  color: var(--job-ink-soft);
  font-size: 0.875rem;
}

/* A set of notes about what the things above are.

   Below a rule and under their own heading rather than trailing the last row, so a reader who has
   decided to check what a figure means can find where that starts. Quieter than the measures and
   narrower than the page, because a caveat that is as loud as the number it qualifies is read as
   part of the number.

   Not named for My Career: the same block carries the standing notes on Where to search, and one
   authoritative copy of a shared element beats two that drift. */
.job-notes {
  display: grid;
  gap: var(--job-space-3);
  margin: var(--job-space-7) 0 0;
  padding: var(--job-space-6) 0 0;
  border-top: 1px solid var(--job-line);
}

.job-notes__heading {
  margin: 0;
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* What is said when there is no figure to set. The measures below carry the numbers; this line
   exists so an occupation with no readable evidence still says so rather than showing a gap. */
.job-career__role-evidence {
  grid-column: 1 / -1;
  margin: 0;
  font-size: 0.9375rem;
}

.job-career__role-evidence--none {
  color: var(--job-ink-soft);
}

/* ── Compare two offers ────────────────────────────────────────────────────────────────────────
   Specification section 28. Two columns of fields, then a table per group. A table because it is
   genuinely tabular data, two values against a field name, and forcing that into cards would make
   the one thing somebody came to do, reading across, the hard thing. */
.job-offers {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--job-space-7);
  max-width: 60rem;
  margin: var(--job-space-2) 0 0;
}

@media (max-width: 760px) {
  .job-offers {
    grid-template-columns: minmax(0, 1fr);
  }
}

.job-offer-fields {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.job-offer-fields__legend {
  padding: 0;
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.job-offer-fields__group {
  margin: var(--job-space-6) 0 var(--job-space-4);
  padding-block-start: var(--job-space-4);
  border-block-start: 1px solid var(--job-line);
  font-size: 1rem;
}

.job-offer-fields .job-form-field {
  margin-block-end: var(--job-space-4);
}

.job-offer-fields .job-form-field > label {
  font-size: 0.9375rem;
  font-weight: 500;
}

.job-input-note {
  margin: var(--job-space-2) 0 0;
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  line-height: 1.45;
}

.job-offer-group {
  min-width: 0;
  margin-block-start: var(--job-space-6);
}

.job-offer-group__title {
  margin: 0 0 var(--job-space-3);
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-align: left;
  text-transform: uppercase;
}

/* The table scrolls inside its own box rather than pushing the page sideways. */
.job-offer-table-wrap {
  position: relative;
  overflow-x: auto;
}

/* Fixed columns, so the three group tables line up as one page rather than as three tables that
   happen to be stacked. Sized independently, each one set its own column widths from its own
   longest field name and the values sat in a different place in every group. */
.job-offer-table {
  width: 100%;
  min-width: 34rem;
  border-collapse: collapse;
  table-layout: fixed;
  font-variant-numeric: tabular-nums;
}

.job-offer-table th:first-child {
  width: 34%;
}

.job-offer-table th:nth-child(2),
.job-offer-table th:nth-child(3) {
  width: 17%;
}

.job-offer-table th,
.job-offer-table td {
  padding: var(--job-space-3) var(--job-space-4) var(--job-space-3) 0;
  text-align: left;
  vertical-align: top;
  border-block-end: 1px solid var(--job-line);
}

.job-offer-table thead th {
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  font-weight: 600;
}

.job-offer-table tbody th {
  font-size: 0.9375rem;
  font-weight: 500;
}

/* The working behind a derived figure, under the field it belongs to. */
.job-offer-table__note {
  display: block;
  max-width: 20rem;
  margin-block-start: var(--job-space-1);
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  font-weight: 400;
  line-height: 1.4;
}

.job-cannot {
  display: grid;
  gap: var(--job-space-3);
  max-width: 42rem;
  margin: var(--job-space-2) 0 0;
  padding: 0;
  color: var(--job-ink-soft);
  line-height: 1.5;
  list-style: none;
}

.job-cannot li {
  padding-block-start: var(--job-space-3);
  border-block-start: 1px solid var(--job-line);
}

/* Links inside prose.

   Found by looking rather than by reading: on the readiness page the two links into this site's own
   evidence computed to rgb(23,32,29) with no underline and normal weight -- the same as the text
   around them, in every respect. They were unreachable in practice for anybody who does not hover
   over sentences to find out, and colour alone would not have been enough anyway.

   Scoped to paragraphs and note blocks so it never reaches the anchors that are buttons or
   navigation; those carry their own classes and say what they are by shape. */
.job-page-stack p a:not([class*="job-button"]),
.job-notes a:not([class*="job-button"]),
/* The methodology is not in the stack either, so "Search an occupation" at its close was the third
   page to render a link as a sentence. */
.methodology p a:not([class*="job-button"]),
.job-ready__evidence a,
.job-step__source a {
  color: var(--job-brand-strong, var(--job-brand));
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

.job-page-stack p a:not([class*="job-button"]):hover,
.job-notes a:not([class*="job-button"]):hover,
.methodology p a:not([class*="job-button"]):hover,
.job-ready__evidence a:hover,
.job-step__source a:hover {
  text-decoration-thickness: 2px;
}


/* ── If you have lost your job ─────────────────────────────────────────────────────────────────
   Specification section 33. Three groups in the order the clock puts them in, ruled rather than
   boxed: somebody reading this does not need eleven cards competing for attention. */
.job-steps {
  display: grid;
  gap: 0;
  max-width: 46rem;
  margin: var(--job-space-2) 0 0;
  padding: 0;
  list-style: none;
}

.job-step {
  padding: var(--job-space-5) 0;
  border-block-start: 1px solid var(--job-line);
}

.job-step__topic {
  margin: 0;
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
}

/* Why it sits where it sits, then what to do. The reason is quieter than the action, because the
   action is the part somebody has to carry away. */
.job-step__why {
  margin: var(--job-space-2) 0 0;
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.job-step__do {
  margin: var(--job-space-2) 0 0;
  line-height: 1.55;
}

.job-step__source {
  margin: var(--job-space-3) 0 0;
  font-size: 0.9375rem;
}

/* ── Advertised salary spread ──────────────────────────────────────────────────────────────────
   The published deciles, section 32. A band with the median marked on it, sitting under the
   headline figure it qualifies.

   Deliberately not a chart: there are seven points on one axis and a bar reads instantly, where
   axes and gridlines would dress seven numbers up as an analysis. The figures themselves are listed
   beneath, so nobody has to measure a rectangle to read one. */
.salary-spread {
  max-width: 34rem;
  margin: var(--job-space-4) 0 0;
}

.salary-spread__caption {
  margin: 0 0 var(--job-space-3);
  color: var(--job-ink);
  font-size: 0.9375rem;
  font-variant-numeric: tabular-nums;
}

.salary-spread__track {
  position: relative;
  height: 0.5rem;
}

.salary-spread__band {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  /* Lighter at the ends than the middle. The 10th and 80th percentiles are where the evidence
     thins, and a bar of one flat colour says the opposite -- that the market stops at each end. */
  background: linear-gradient(
    to right,
    color-mix(in srgb, var(--job-mark) 22%, transparent),
    color-mix(in srgb, var(--job-mark) 55%, transparent),
    color-mix(in srgb, var(--job-mark) 22%, transparent));
}

/* The median, marked rather than labelled on the track. A line, not a dot: a dot on a band reads
   as a data point among others, and this is the one figure the section is actually about. */
.salary-spread__median {
  position: absolute;
  inset-block: -0.25rem;
  width: 2px;
  border-radius: 1px;
  background: var(--job-ink);
  transform: translateX(-1px);
}

.salary-spread__ends {
  display: flex;
  justify-content: space-between;
  gap: var(--job-space-3);
  margin-block-start: var(--job-space-2);
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

/* The median's label, carried at the marker's own offset. translateX(-50%) centres it on the
   line; the clamped inset keeps it inside the figure when the median sits near an end. */
.salary-spread__marker-label {
  position: relative;
  height: 1.2rem;
  margin-block-start: var(--job-space-2);
}

.salary-spread__middle {
  position: absolute;
  transform: translateX(-50%);
  color: var(--job-ink);
  font-size: 0.8125rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The reader's own figure on the same scale. A different shape from the median's line as well as a
   different colour, because colour alone is not a distinction everybody can see -- and confusing
   your own salary with the published median is the one mistake this control must not cause. */
.salary-spread__yours {
  position: absolute;
  inset-block: -0.375rem;
  width: 0.75rem;
  height: 0.75rem;
  margin-block: auto;
  border: 2px solid var(--job-paper);
  border-radius: 999px;
  background: var(--job-brand-strong, #1f4d3d);
  transform: translateX(-50%);
}

/* The input sits under the band it reads against, not in a panel of its own: it is a way of reading
   those figures rather than a separate feature. */
.salary-yours {
  margin-block-start: var(--job-space-5);
  padding-block-start: var(--job-space-4);
  border-block-start: 1px solid var(--job-line);
}

.salary-yours label {
  display: block;
  margin-block-end: var(--job-space-2);
  font-size: 0.9375rem;
  font-weight: 500;
}

.salary-yours input {
  width: 100%;
  max-width: 12rem;
  padding: var(--job-space-2) var(--job-space-3);
  border: 1px solid var(--job-line-strong);
  border-radius: var(--job-radius-md);
  background: var(--job-paper);
  color: var(--job-ink);
  font: inherit;
  font-variant-numeric: tabular-nums;
}

.salary-yours__note {
  margin: var(--job-space-2) 0 0;
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  line-height: 1.5;
}

.salary-yours__reading {
  margin: var(--job-space-3) 0 0;
  color: var(--job-ink);
  font-size: 0.9375rem;
  font-variant-numeric: tabular-nums;
}

.salary-spread__figures {
  margin-block-start: var(--job-space-3);
}

.salary-spread__figures summary {
  color: var(--job-ink-soft);
  font-size: 0.875rem;
  cursor: pointer;
}

.salary-spread__figures summary:hover {
  color: var(--job-ink);
}

/* ── The personal evidence bank ────────────────────────────────────────────────────────────────
   Specification section 26. A place to write something down and find it again, no more, because
   section 26 permits organising and retrieving experience and nothing else. */
.job-evidence-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: var(--job-space-5) var(--job-space-6);
  margin: var(--job-space-2) 0 0;
}

.job-evidence-kinds {
  border: 0;
  padding: 0;
  margin: 0;
}

.job-evidence-kinds legend {
  padding: 0;
  color: var(--job-ink);
  font-weight: 500;
}

.job-evidence-kinds__options {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2);
  margin-block-start: var(--job-space-2);
}

.job-evidence-list {
  display: grid;
  gap: 0;
  margin: var(--job-space-2) 0 0;
  padding: 0;
  list-style: none;
}

.job-evidence-item {
  padding: var(--job-space-5) 0;
  border-block-start: 1px solid var(--job-line);
}

.job-evidence-item:first-child {
  border-block-start: 0;
}

.job-evidence-item__title {
  margin: 0;
  font-size: 1.0625rem;
}

.job-evidence-item__when {
  margin: var(--job-space-1) 0 0;
  color: var(--job-ink-soft);
  font-size: 0.875rem;
}

/* The reader's own words, set to be read rather than skimmed: full measure, generous leading, and
   line breaks kept as they typed them. */
.job-evidence-item__body {
  max-width: 42rem;
  margin: var(--job-space-3) 0 0;
  line-height: 1.6;
  white-space: pre-wrap;
}

/* Labels, not badges. They are how an example is found again, and styling them as achievements
   would make the labelling look like the point. */
.job-evidence-item__kinds {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2);
  margin: var(--job-space-3) 0 0;
  padding: 0;
  list-style: none;
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
}

.job-evidence-item__kinds li::after {
  content: "·";
  margin-inline-start: var(--job-space-2);
}

.job-evidence-item__kinds li:last-child::after {
  content: "";
}

.job-evidence-item__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2);
  margin-block-start: var(--job-space-3);
}

/* ── Preparing for one interview ───────────────────────────────────────────────────────────────
   Specification section 27. The reader's own material, laid out to be read the night before: the
   examples they chose are set at full measure like the bank itself, and the list they pick from is
   deliberately quieter than the ones they have already chosen. */

/* Which job this is for, directly under the heading. Without it the page is preparation for an
   interview in the abstract, which is nobody's situation. */
.job-interview-for {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2);
  align-items: baseline;
  margin: var(--job-space-3) 0 0;
}

.job-interview-for__title {
  font-size: 1.125rem;
  font-weight: 500;
  color: var(--job-ink);
}

.job-interview-for__employer {
  color: var(--job-ink-soft);
}

.job-interview-pick {
  margin-block-start: var(--job-space-6);
  padding-block-start: var(--job-space-5);
  border-block-start: 1px solid var(--job-line);
}

.job-interview-pick__heading {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--job-ink-soft);
}

.job-interview-pick__filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2);
  margin-block-start: var(--job-space-3);
}

.job-interview-pick__list {
  display: grid;
  gap: var(--job-space-2);
  margin: var(--job-space-3) 0 0;
  padding: 0;
  list-style: none;
}

/* The whole row is the target: a title and its labels are one thing to press, and a small tick box
   beside a long title fails 2.5.8 on the only pointer most people will use here. */
.job-interview-pick__button {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-1) var(--job-space-3);
  align-items: baseline;
  width: 100%;
  min-height: 2.75rem;
  padding: var(--job-space-3) var(--job-space-4);
  border: 1px solid var(--job-line);
  border-radius: var(--job-radius-md);
  background: var(--job-paper);
  color: var(--job-ink);
  font: inherit;
  text-align: start;
  cursor: pointer;
  transition: border-color 120ms ease, background-color 120ms ease;
}

.job-interview-pick__button:hover {
  border-color: var(--job-line-strong);
}

.job-interview-pick__button:disabled {
  cursor: default;
  opacity: 0.6;
}

.job-interview-pick__title {
  font-weight: 500;
}

.job-interview-pick__kinds {
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
}

/* ── Work attached to a saved job ──────────────────────────────────────────────────────────────
   Specification section 25. Quiet: it sits inside an application's row, and a to-do list that
   shouts competes with the job it belongs to. */
.job-tasks {
  margin-block-start: var(--job-space-4);
}

.job-tasks__list {
  display: grid;
  gap: var(--job-space-2);
  margin: 0 0 var(--job-space-3);
  padding: 0;
  list-style: none;
}

.job-tasks__item {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2) var(--job-space-3);
  align-items: baseline;
}

/* Done work stays visible rather than disappearing. Somebody scanning their own list needs to see
   what they have already dealt with, or they will wonder whether they did it. */
.job-tasks__item--done .job-tasks__title {
  color: var(--job-ink-soft);
  text-decoration: line-through;
}

.job-tasks__check {
  display: flex;
  gap: var(--job-space-2);
  align-items: baseline;
  cursor: pointer;
}

/* Without font: inherit the checkbox is measured by its own font rather than the label's and sits
   high against the text -- the same alignment defect fixed in the platform checklist. */
.job-tasks__check input[type="checkbox"] {
  font: inherit;
  width: 1em;
  height: 1em;
  margin: 0;
  margin-block-start: 0.25rem;
  accent-color: var(--job-brand);
}

.job-tasks__title {
  color: var(--job-ink);
  font-size: 0.9375rem;
}

.job-tasks__due {
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

/* Overdue is marked, and nothing else is. Colouring everything by proximity would invent urgency;
   the weight carries it as well as the colour, so it does not depend on seeing the difference. */
.job-tasks__due--overdue {
  color: #8c2f26;
  font-weight: 600;
}

.job-tasks__add {
  display: grid;
  gap: var(--job-space-2);
  max-width: 32rem;
  margin-block-start: var(--job-space-2);
}

.job-tasks__add-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2);
}

.job-tasks__add-row .job-search-input {
  flex: 1 1 12rem;
}

.job-tasks__add-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2);
}

/* ── Saving a vacancy ──────────────────────────────────────────────────────────────────────────
   Specification section 22. Two columns where there is room, because most of these answers are
   short and one long column makes a twelve-field form look longer than it is. */
.job-vacancy-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: var(--job-space-5) var(--job-space-6);
  margin: var(--job-space-2) 0 0;
}

.job-vacancy-field {
  display: grid;
  gap: var(--job-space-2);
  align-content: start;
}

/* Notes need the width; a four-line box in a half column is a box nobody writes in. */
.job-vacancy-field--wide {
  grid-column: 1 / -1;
}

.job-vacancy-field label {
  color: var(--job-ink);
  font-weight: 500;
}

.job-vacancy-date {
  max-width: 14rem;
}

.job-vacancy-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-3);
  align-items: center;
  margin-block-start: var(--job-space-6);
}

/* A failure the reader can act on. role="alert" so it is announced rather than only appearing. */
.job-vacancy-error {
  margin: var(--job-space-4) 0 0;
  padding: var(--job-space-3) var(--job-space-4);
  border-inline-start: 3px solid #8c2f26;
  color: var(--job-ink);
}

/* The controls under a saved job. Laid out as a label and a row of buttons so the group reads as
   one question with several answers rather than a scatter of unrelated controls. */
.job-workspace-job__controls {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2) var(--job-space-3);
  align-items: baseline;
  margin-block-start: var(--job-space-3);
}

.job-workspace-job__controls-label {
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.job-workspace-job__stages {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2);
}

.job-workspace-job__edit {
  margin: var(--job-space-3) 0 0;
  font-size: 0.9375rem;
}

/* ── The job search workspace ──────────────────────────────────────────────────────────────────
   Specification section 19. The organising question is "what requires my attention", so the work
   that is due leads and everything else is context beneath it. */
.job-workspace-calm {
  margin: 0;
  color: var(--job-ink);
  font-size: 1.0625rem;
}

.job-workspace-actions {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.job-workspace-actions li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0 var(--job-space-4);
  align-items: baseline;
  padding: var(--job-space-3) 0;
  border-block-start: 1px solid var(--job-line);
}

.job-workspace-actions li:first-child {
  border-block-start: 0;
}

.job-workspace-actions__task {
  color: var(--job-ink);
  font-weight: 500;
}

/* Which application the work belongs to. Without it a list of tasks is a list with no subjects. */
.job-workspace-actions__job {
  grid-column: 1;
  color: var(--job-ink-soft);
  font-size: 0.875rem;
}

.job-workspace-actions__when {
  grid-row: 1;
  grid-column: 2;
  color: var(--job-ink-soft);
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* A count beside a heading, not a score. It says how many are in this stage and nothing about how
   well anybody is doing. */
.job-workspace-count {
  margin-inline-start: var(--job-space-2);
  color: var(--job-ink-soft);
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
  font-weight: 400;
}

.job-workspace-targeting {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, max-content));
  gap: var(--job-space-3) var(--job-space-7);
  margin: var(--job-space-2) 0 0;
}

.job-workspace-targeting dt {
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.job-workspace-targeting dd {
  margin: var(--job-space-1) 0 0;
  color: var(--job-ink);
}

.job-workspace-jobs {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.job-workspace-job {
  padding: var(--job-space-5) 0;
  border-block-start: 1px solid var(--job-line);
}

.job-workspace-job:first-child {
  border-block-start: 0;
}

.job-workspace-job__head {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--job-space-3);
  align-items: baseline;
}

.job-workspace-job__title {
  color: var(--job-ink);
  font-size: 1.0625rem;
  font-weight: 600;
}

.job-workspace-job__employer {
  color: var(--job-ink-soft);
}

/* What the advert stated, in its own words. Set as measures so it never reads as a published
   statistic -- section 22 keeps the two apart and this is where a reader sees which is which. */
.job-workspace-job__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, max-content));
  gap: var(--job-space-2) var(--job-space-6);
  margin: var(--job-space-3) 0 0;
}

.job-workspace-job__facts dt {
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
}

.job-workspace-job__facts dd {
  margin: 0;
  color: var(--job-ink);
  font-size: 0.9375rem;
}

.job-workspace-job__waiting {
  margin: var(--job-space-3) 0 0;
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
}

.job-workspace-job__tasks {
  display: grid;
  gap: var(--job-space-1);
  margin: var(--job-space-3) 0 0;
  padding: 0 0 0 var(--job-space-4);
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
}

.job-workspace-job__due {
  margin-inline-start: var(--job-space-2);
  font-variant-numeric: tabular-nums;
}

.job-workspace-job__link {
  margin: var(--job-space-3) 0 0;
  font-size: 0.9375rem;
}

/* ── Start a job search ────────────────────────────────────────────────────────────────────────
   Specification section 18. Each question is a fieldset: the alternatives to answering belong to
   the question, not to the page, and a fieldset is what says so to a screen reader. */
.job-search-question {
  margin: 0 0 var(--job-space-6);
  padding: 0 0 var(--job-space-6);
  border: 0;
  border-block-end: 1px solid var(--job-line);
}

.job-search-question:last-of-type {
  border-block-end: 0;
}

.job-search-question__legend {
  padding: 0;
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--job-ink);
}

.job-search-question__body {
  margin-block-start: var(--job-space-3);
}

/* What the page says back once somebody has declined to answer. Set as their answer rather than
   as an empty field, because it is one. */
.job-search-question__standing {
  margin: 0;
  color: var(--job-ink);
  font-size: 0.9375rem;
}

/* The alternatives sit beside the answer rather than under a "skip" link. Skipping leaves a
   question open; saying you do not know closes it, and the two must not look like one control. */
.job-search-question__alternatives {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2);
  margin-block-start: var(--job-space-3);
}

.job-search-alt {
  padding: var(--job-space-2) var(--job-space-4);
  border: 1px solid var(--job-line);
  border-radius: 999px;
  background: var(--job-paper);
  color: var(--job-ink-soft);
  font: inherit;
  font-size: 0.875rem;
  cursor: pointer;
}

.job-search-alt:hover {
  border-color: var(--job-line-strong);
  color: var(--job-ink);
}

/* Carries aria-pressed as well, so the chosen alternative is not signalled by colour alone. */
.job-search-alt--current {
  border-color: var(--job-brand);
  background: var(--job-brand-soft);
  color: var(--job-brand-strong);
  font-weight: 600;
}

.job-search-input {
  width: 100%;
  max-width: 28rem;
  padding: var(--job-space-3) var(--job-space-4);
  border: 1px solid var(--job-line-strong);
  border-radius: var(--job-radius-md);
  background: var(--job-paper);
  color: var(--job-ink);
  font: inherit;
}

.job-search-textarea {
  min-height: 5rem;
  resize: vertical;
}

.job-search-money {
  display: flex;
  gap: var(--job-space-2);
  align-items: baseline;
  color: var(--job-ink-soft);
}

.job-search-input--money {
  width: 10rem;
  font-variant-numeric: tabular-nums;
}

.job-search-money__unit {
  font-size: 0.9375rem;
}

/* The note under a control, saying what the answer is and is not used for. */
.job-search-note {
  max-width: 34rem;
  margin: var(--job-space-2) 0 0;
  color: var(--job-ink-soft);
  font-size: 0.875rem;
  line-height: 1.5;
}

.job-search-option {
  display: flex;
  gap: var(--job-space-2);
  align-items: baseline;
  margin-block-end: var(--job-space-2);
  cursor: pointer;
}

/* Without this the radio is measured by its own font rather than the label's, and sits high. */
.job-search-option input[type="radio"] {
  font: inherit;
  width: 1em;
  height: 1em;
  margin: 0;
  margin-block-start: 0.2rem;
  accent-color: var(--job-brand);
}

.job-search-roles {
  display: grid;
  gap: var(--job-space-2);
  margin: var(--job-space-3) 0 0;
  padding: 0;
  list-style: none;
}

.job-search-roles__kind {
  margin-inline-start: var(--job-space-3);
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.job-search-pending__heading {
  margin: 0 0 var(--job-space-2);
  font-size: 0.9375rem;
  font-weight: 600;
}

/* ── Learn ─────────────────────────────────────────────────────────────────────────────────────
   The reading index, specification section 51. Cards rather than a ruled list, because each entry
   carries a summary that needs its own block; the ruled treatment used elsewhere is for rows whose
   whole content is one line. */
.job-learn-hero__top {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-3);
  align-items: baseline;
  justify-content: space-between;
}

/* The count and the latest date, derived from what is actually published. */
.job-learn-stamp {
  margin: 0;
  color: var(--job-ink-soft);
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
}

.job-learn-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-2);
  margin: 0 0 var(--job-space-5);
}

.job-learn-chip {
  display: inline-block;
  padding: var(--job-space-2) var(--job-space-4);
  border: 1px solid var(--job-line);
  border-radius: 999px;
  background: var(--job-paper);
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
  text-decoration: none;
}

.job-learn-chip:hover {
  border-color: var(--job-line-strong);
  color: var(--job-ink);
}

/* The selected topic. Carries aria-current as well, so the state is not colour alone. */
.job-learn-chip--current {
  border-color: var(--job-brand);
  background: var(--job-brand-soft);
  color: var(--job-brand-strong);
  font-weight: 600;
}

.job-learn-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
  gap: var(--job-space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.job-learn-card {
  display: grid;
  gap: var(--job-space-2);
  height: 100%;
  padding: var(--job-space-5);
  border: 1px solid var(--job-line);
  border-radius: var(--job-radius-lg);
  background: var(--job-paper);
  text-decoration: none;
}

.job-learn-card:hover {
  border-color: var(--job-line-strong);
}

.job-learn-card__top {
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-3);
  align-items: baseline;
  justify-content: space-between;
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
}

.job-learn-card__topic {
  color: var(--job-brand-strong);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.job-learn-card__title {
  color: var(--job-ink);
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.job-learn-card__summary {
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
  line-height: 1.5;
}

/* Said, not shown as an empty grid: "loading", "none published" and "the CMS could not be reached"
   are three different answers and an empty list looks like all of them. */
.job-learn-empty {
  margin: 0;
  color: var(--job-ink-soft);
}

.job-learn-article__summary {
  max-width: 42rem;
  color: var(--job-ink-soft);
  font-size: 1.0625rem;
  line-height: 1.55;
}

.job-learn-article__body {
  max-width: 44rem;
}

.job-learn-article__footer {
  margin-block-start: var(--job-space-6);
  padding-block-start: var(--job-space-5);
  border-block-start: 1px solid var(--job-line);
}

/* ── Occupation suggestions ────────────────────────────────────────────────────────────────────
   UXD-10. The list of occupations the index thinks the typed words might mean. It sits under the
   field in normal flow rather than floating over the page: the homepage has content directly below
   and an overlay would cover it, and a list that pushes the page down is easier to read on a phone
   than one that hovers over what it hides. */
.occupation-search__suggestions {
  display: grid;
  gap: 0;
  max-width: 46rem;
  margin: var(--job-space-2) 0 0;
  padding: 0;
  border: 1px solid var(--job-line);
  border-radius: var(--job-radius-md);
  background: var(--job-paper);
  list-style: none;
  overflow: hidden;
}

.occupation-search__suggestion {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--job-space-3);
  align-items: baseline;
  /* Comfortably past the 24px minimum, because this list is used with a thumb. */
  padding: var(--job-space-3) var(--job-space-4);
  border-block-start: 1px solid var(--job-line);
  cursor: pointer;
}

.occupation-search__suggestion:first-child {
  border-block-start: 0;
}

/* The keyboard highlight and the hover state are deliberately the same. Two different appearances
   for "this is the one you are about to choose" is a difference without a meaning. */
.occupation-search__suggestion:hover,
.occupation-search__suggestion--active {
  background: var(--job-brand-soft);
}

.occupation-search__suggestion-label {
  color: var(--job-ink);
  font-weight: 500;
}

.occupation-search__suggestion-matched {
  color: var(--job-ink-soft);
  font-size: 0.875rem;
}

/* ── Touch targets ─────────────────────────────────────────────────────────────────────────────
   UXD-07. WCAG 2.5.8 asks for 24x24 CSS pixels, and these lists were 17 to 22 pixels tall: a line
   of text with no room around it. They are not incidental links either, on Regions and
   Requirements they *are* the page, and the recognised-title list is how somebody confirms the
   occupation they landed on is the one they meant.

   Height is bought with padding rather than line-height, so the space belongs to the target and not
   to the gap between lines: a taller line box would push the rows apart without making any of them
   easier to hit. Inline links inside a sentence are left alone, which is what 2.5.8 exempts and
   what keeps prose from becoming double-spaced. */
.job-requirements__index li > a,
.job-destination__link,
.footer-links li > a,
/* Occupation links inside a table row. Missed on the first pass because that pass checked
   /regions and /requirements and not their detail pages, where the occupation list is a table
   rather than a list -- a reminder that "verified" means the sample, not the site. */
.role-market__history th > a,
.role-market__history td > a {
  display: inline-block;
  padding-block: 0.3rem;
}

/* Links that are the content.

   The occupations in a regional table: every one is a link, and every one rendered in body ink with
   no underline, indistinguishable from a sentence, because MudBlazor's bare `a` rule strips both
   and nothing here put them back. The prose rule above underlines a link in full because it has to
   stand out from the words around it; these stand in a column of their own kind, so the underline
   is drawn in the hairline grey and the full colour arrives on hover. Still an underline: a list a
   reader cannot tell is a list of links is a list of dead ends. The report's titles, related
   occupations and peers were in this rule until the redesign set them as chips, whose white pill
   is the affordance instead. */
.role-market__history th > a,
.role-market__history td > a {
  color: var(--job-ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--job-line-strong);
  text-underline-offset: 0.22em;
}

.role-market__history th > a:hover,
.role-market__history td > a:hover,
.role-market__history th > a:focus-visible,
.role-market__history td > a:focus-visible {
  color: var(--job-brand-strong);
  text-decoration-color: currentColor;
}

/* The two directories, Regions and Requirements.

   One name per line down a 1216px page: twelve regions took a screen and a hundred requirement
   categories took eleven, every entry set as plain ink with nothing to say it could be followed.
   Ruled rows in as many columns as the width allows, each name with its own arrow, so the page
   reads as an index rather than a column of text. The arrow, not colour, carries the affordance,
   which is what section 65 asks of anything a reader has to recognise. Row height is bought with
   padding, as UXD-07 did, so every target stays well past 24px. */
.job-requirements__index {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
  gap: 0 var(--job-space-7);
  max-width: 62rem;
  margin: var(--job-space-2) 0 0;
  padding: 0;
  list-style: none;
}

.job-requirements__index li {
  border-block-start: 1px solid var(--job-line);
}

.job-requirements__index li > a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--job-space-3);
  padding-block: var(--job-space-4);
  color: var(--job-ink);
  font-weight: 500;
  line-height: 1.35;
  text-decoration: none;
}

.job-requirements__index li > a::after {
  content: "\2192";
  flex: none;
  color: var(--job-ink-soft);
  font-weight: 400;
}

.job-requirements__index li > a:hover,
.job-requirements__index li > a:focus-visible {
  color: var(--job-brand-strong);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.job-requirements__index li > a:hover::after,
.job-requirements__index li > a:focus-visible::after {
  color: currentColor;
}

/* ── What to have ready ────────────────────────────────────────────────────────────────────────
   Things you need ready, specification section 20. Numbered because it is a list of eight, ruled
   because it is a list rather than eight cards, and never scored. */
.job-ready {
  display: grid;
  gap: 0;
  max-width: 46rem;
  margin: var(--job-space-2) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: ready;
}

.job-ready__item {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "name tick"
    "means tick"
    "why tick"
    "evidence tick";
  column-gap: var(--job-space-5);
  padding: var(--job-space-6) 0 var(--job-space-6) var(--job-space-7);
  border-block-start: 1px solid var(--job-line);
  counter-increment: ready;
}

/* The reader's own tick, beside the item rather than above it.

   In source it comes first, so a screen reader meets the control before the thing it is about is
   named, and it sat there visually too: a bare box and the word "Done" floating over the title,
   which read as a heading of its own. The grid puts it in the margin at the top right, where a
   control that belongs to a row belongs, and the source order is untouched. A pill, so the whole
   word is the target and it sits on the cream as a control rather than as text. */
.job-ready__tick {
  grid-area: tick;
  display: inline-flex;
  align-items: center;
  align-self: start;
  gap: var(--job-space-2);
  min-height: 2.75rem;
  padding: 0 var(--job-space-4) 0 var(--job-space-3);
  border: 1px solid var(--job-line);
  border-radius: 999px;
  background: var(--job-paper);
  color: var(--job-ink-soft);
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  transition:
    border-color var(--pui-motion-fast, 160ms ease),
    color var(--pui-motion-fast, 160ms ease);
}

.job-ready__tick:hover {
  border-color: var(--job-line-strong);
  color: var(--job-ink);
}

/* Done is said by the box and the word; the tint only reinforces it. */
.job-ready__tick:has(input:checked) {
  border-color: var(--job-brand);
  background: var(--job-brand-soft);
  color: var(--job-brand-strong);
}

.job-ready__tick:has(input:disabled) {
  cursor: default;
  opacity: 0.6;
}

.job-ready__tick input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  margin: 0;
  accent-color: var(--job-brand);
}

.job-ready__name {
  grid-area: name;
}

.job-ready__means {
  grid-area: means;
}

.job-ready__why {
  grid-area: why;
}

.job-ready__evidence {
  grid-area: evidence;
}

/* Said calmly, in one place, before the list. It was a bare paragraph at full page width, set in
   body ink, which read as part of the page's copy rather than as a notice about the boxes. A rule
   on its left and a bounded measure mark it as a notice without making it an alarm: nothing is
   lost, and the wording says so. */
.job-ready__unavailable {
  max-width: 46rem;
  margin: 0;
  padding: var(--job-space-3) var(--job-space-4);
  border-inline-start: 3px solid var(--job-line-strong);
  color: var(--job-ink);
  font-size: 0.9375rem;
  line-height: 1.5;
}

/* The number is a position in a list, not a step in a process and not a score. Light and quiet
   enough that it never reads as a mark out of eight. */
.job-ready__item::before {
  content: counter(ready);
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: var(--job-space-6);
  color: var(--job-ink-soft);
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}

.job-ready__name {
  margin: 0;
  font-size: 1.125rem;
  letter-spacing: -0.01em;
}

.job-ready__means {
  margin: var(--job-space-2) 0 0;
  line-height: 1.55;
}

/* The consequence. Quieter than the definition above it, because it is the reason rather than the
   thing itself. */
.job-ready__why {
  margin: var(--job-space-2) 0 0;
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.job-ready__evidence {
  margin: var(--job-space-3) 0 0;
  font-size: 0.9375rem;
}

/* ── Where to search ───────────────────────────────────────────────────────────────────────────
   Places worth searching, specification section 21. No cards: the page is a list of services and
   a list of categories, and boxing each one would make eight signposts look like eight products. */

/* A section on a page that is made of sections. The stack owns the space between them; this owns
   the space inside one. */
.job-page-section {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--job-space-4);
  align-content: start;
}

/* One size for the heading of a section, wherever the section is. The sections built as
   `.job-page-section` had this scale; the ones built as `.job-account` and the bare sections on
   the index pages fell through to the browser's 24px, so two headings of equal rank on adjacent
   pages were different sizes. */
.job-page-stack > section > h2:not([class]),
.job-page-section > h2 {
  font-size: var(--job-section-size);
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.job-page-section > h2 {
  margin: 0;
}

.job-section-lede {
  max-width: 42rem;
  margin: 0;
  color: var(--job-ink-soft);
  line-height: 1.55;
}

/* The distinction section 21 exists for. Two columns divided by a hairline rather than two boxes
   sitting next to each other: the point is that these are two halves of one comparison. */
.job-contrast {
  /* Two named tracks, not auto-fit. auto-fit divides the row by how many minmax tracks will fit,
     which at this width made three -- so the pair sat in the first two and the comparison had an
     empty column beside it. A comparison has exactly two sides and the grid should say so. */
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--job-space-6) var(--job-space-7);
  max-width: 60rem;
  margin: var(--job-space-2) 0 0;
}

@media (max-width: 720px) {
  .job-contrast {
    grid-template-columns: minmax(0, 1fr);
  }
}

.job-contrast__side {
  display: grid;
  gap: var(--job-space-2);
  align-content: start;
  padding-block-start: var(--job-space-4);
  border-block-start: 2px solid var(--job-line-strong, var(--job-line));
}

.job-contrast__title {
  margin: 0;
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* The answer in two words, before the detail. Somebody who reads only this line has still got the
   distinction the section is for. */
.job-contrast__lede {
  margin: 0;
  font-size: clamp(1.25rem, 2.4vw, 1.5rem);
  font-weight: 300;
  letter-spacing: -0.02em;
}

.job-contrast__list {
  display: grid;
  gap: var(--job-space-2);
  margin: var(--job-space-2) 0 0;
  padding: 0;
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
  line-height: 1.45;
  list-style: none;
}

/* Two columns of services at a comfortable width, one when there is not room. Rows are separated
   by a hairline, in the same language as the kept-occupations list. */
.job-destinations {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  gap: 0 var(--job-space-7);
  margin: var(--job-space-2) 0 0;
  padding: 0;
  list-style: none;
}

.job-destination {
  padding: var(--job-space-5) 0;
  border-block-start: 1px solid var(--job-line);
}

.job-destination__name {
  margin: 0;
  font-size: 1.125rem;
  letter-spacing: -0.01em;
}

.job-destination__link {
  color: var(--job-ink);
  text-decoration: none;
}

/* The mark that says this link leaves the site. Quiet enough to ignore and present enough to
   answer the question before it is asked. */
.job-destination__link::after {
  content: "\2197";
  margin-inline-start: 0.35em;
  color: var(--job-ink-soft);
  font-weight: 400;
}

.job-destination__link:hover,
.job-destination__link:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.job-destination__operator {
  margin: var(--job-space-1) 0 0;
  color: var(--job-ink-soft);
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
}

/* What it actually carries. The reason the page is worth reading rather than a row of names. */
.job-destination__covers {
  max-width: 34rem;
  margin: var(--job-space-2) 0 0;
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.job-kinds {
  display: grid;
  gap: 0;
  margin: var(--job-space-2) 0 0;
  max-width: 54rem;
}

/* Name and note side by side, so the five categories can be scanned by name alone. */
.job-kind {
  display: grid;
  grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
  gap: var(--job-space-2) var(--job-space-6);
  padding: var(--job-space-5) 0;
  border-block-start: 1px solid var(--job-line);
}

@media (max-width: 640px) {
  .job-kind {
    grid-template-columns: minmax(0, 1fr);
  }
}

.job-kind__name {
  margin: 0;
  font-weight: 600;
}

.job-kind__note {
  margin: 0;
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
  line-height: 1.5;
}

/* Notes that are a section of their own already have a heading and the stack's space above them.
   The block's own rule then drew a second line under the first, which reads as a mistake rather
   than as structure. The same holds inside a `.job-account` section: on the job search workspace
   the "Getting ready and where to look" heading was followed by three rem of nothing, a rule, and
   two rem more before its three links. */
.job-page-section > .job-notes,
.job-account > .job-notes {
  margin: 0;
  padding-block-start: 0;
  border-block-start: none;
}

/* On My Career the notes follow a stack of cards rather than ruled rows, so they take back the
   space above them that the rule above removes; still without a rule, as the cards end clearly. */
.job-account--roster > .job-notes {
  margin-block-start: var(--job-space-5);
}

/* ── The rest of a caveat, one click away ──────────────────────────────────────────────────────
   Every figure keeps its caveat in view, the first sentence of what the serving layer wrote, and
   the explanation behind it opens beneath, on the same spot of the page. A native disclosure, not
   a tooltip: it is in the HTML for a crawler, it opens on tap and on Enter, and it needs no
   script. The control is set as a quiet link with a chevron rather than as a button, because it
   discloses text rather than doing anything. */
.job-limitation {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  text-align: left;
}

.job-limitation > p {
  margin: 0;
}

.job-limitation-detail {
  max-width: var(--job-measure-report);
}

.job-limitation-detail > summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--job-link-height);
  color: var(--job-brand);
  font-size: var(--job-text-note);
  font-weight: var(--job-weight-medium);
  cursor: pointer;
  list-style: none;
}

.job-limitation-detail > summary::-webkit-details-marker {
  display: none;
}

/* A chevron that turns when open, so the state is visible as well as announced. */
.job-limitation-detail > summary::before {
  content: "";
  flex: none;
  width: 0.375rem;
  height: 0.375rem;
  margin-inline: 0.125rem 0.1875rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--pui-motion-fast, 160ms ease);
}

.job-limitation-detail[open] > summary::before {
  transform: rotate(45deg);
}

.job-limitation-detail > summary:hover {
  color: var(--job-brand-strong);
}

.job-limitation-detail > p {
  margin: 8px 0 0;
  color: var(--job-ink-soft);
  font-size: var(--job-text-note);
  line-height: 1.5;
}

/* Centred where the band is centred; left-aligned on a phone, where those bands read left. */
.job-market-band--requirements .job-limitation,
.job-market-band--evidence .job-limitation {
  align-items: center;
  text-align: center;
}

@media (max-width: 45rem) {
  .job-market-band--requirements .job-limitation {
    align-items: flex-start;
    text-align: left;
  }
}

@media (prefers-reduced-motion: reduce) {
  .job-limitation-detail > summary::before {
    transition: none;
  }
}

/* ── Monthly history chart ─────────────────────────────────────────────────────────────────────
   Inline SVG, drawn on the server. The published series in the mark green over a faint fill, the
   first and latest months marked and labelled, and this site's average as one red dashed line. The
   figures themselves stay on the page beneath, because a line cannot be read a row at a time.

   The frame holds the plot and the two value labels above its highest point; the months sit
   beneath the frame, outside it. The plot is inset at the sides by half a point so the marks at
   either end are not cut by the column's edge. */
.demand-chart {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.demand-chart__frame {
  position: relative;
  height: 190px;
}

.demand-chart__plot-area {
  position: absolute;
  inset: 28px 8px 0;
}

.demand-chart__plot {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.demand-chart__area {
  fill: var(--job-mark);
  opacity: 0.08;
}

.demand-chart__axis {
  stroke: var(--job-line);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

/* The published figures. Drawn over the average, because they are the evidence and it is the
   reading aid. */
.demand-chart__observed {
  fill: none;
  stroke: var(--job-mark);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

/* The average this site calculates. Dashed and red, so it cannot be mistaken for a published
   series by shape or by colour: the one line here that ONS did not publish. The red is the badge
   red, not a status colour, and nothing on the page reads it as good or bad. */
.demand-chart__smoothed {
  fill: none;
  stroke: var(--job-chart-average);
  stroke-width: 1.5;
  stroke-dasharray: 4 6;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

/* The first and latest months: a ring in the mark green, hollow to the canvas. */
.demand-chart__point {
  position: absolute;
  width: 8px;
  height: 8px;
  box-sizing: border-box;
  border: 2px solid var(--job-mark);
  border-radius: 50%;
  background: var(--job-canvas);
  transform: translate(-50%, -50%);
}

.demand-chart__value {
  position: absolute;
  padding-bottom: 12px;
  transform: translateY(-100%);
  color: var(--job-ink);
  font-size: var(--job-text-small);
  font-weight: var(--job-weight-semibold);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  white-space: nowrap;
  text-shadow: 0 0 3px var(--job-canvas), 0 0 3px var(--job-canvas), 0 0 3px var(--job-canvas);
}

.demand-chart__value--first {
  margin-left: -4px;
}

.demand-chart__value--last {
  margin-left: 4px;
  transform: translate(-100%, -100%);
}

.demand-chart__scale {
  display: flex;
  justify-content: space-between;
  padding-inline: 8px;
  color: var(--job-ink-soft);
  font-size: var(--job-text-small);
}

/* The key marks each line with a rule of its own stroke, so the two are told apart by shape as well
   as by colour: solid for what was published, dashed for what this site calculated. */
.demand-chart__key {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  margin-top: 4px;
  color: var(--job-ink-soft);
  font-size: var(--job-text-small);
}

.demand-chart__key-item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.demand-chart__key-item::before {
  flex: none;
  width: 24px;
  content: "";
}

.demand-chart__key-item--observed::before {
  border-top: 2px solid var(--job-mark);
}

.demand-chart__key-item--average::before {
  height: 0;
  border-top: 2px dashed var(--job-chart-average);
}

.demand-chart__note {
  max-width: var(--job-measure-report);
  margin: 0;
  color: var(--job-ink-soft);
  font-size: var(--job-text-small);
  line-height: 1.5;
}

@media (max-width: 45rem) {
  .demand-chart__frame {
    height: 150px;
  }

  .demand-chart__value,
  .demand-chart__scale,
  .demand-chart__key,
  .demand-chart__note {
    font-size: 0.8125rem;
  }
}

/* What a kept occupation is to the reader. Above the name, small and quiet: it is a label on the
   thing rather than a thing in its own right. */
/* The occupation's status in the reader's own words, as a pill with the data mark's dot: the one
   piece of colour on the card that is about the person rather than the market. */
.job-career__role-kind {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 1.75rem;
  margin: 0;
  padding: 0 0.75rem;
  border-radius: var(--job-radius-pill);
  background: var(--job-brand-soft);
  color: var(--job-brand-strong);
  font-size: 0.8125rem;
  font-weight: 600;
}

.job-career__role-kind::before {
  content: "";
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: var(--job-radius-pill);
  background: var(--job-mark);
}

.job-career__role-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.625rem;
  align-items: center;
}

/* The two controls as one matched pair: the same pill, the same height. "Remove" keeps its danger
   red, and only here takes the pill shape the rest of the page's controls have; elsewhere the danger
   button is unchanged. */
.job-career__role-actions .job-button {
  min-height: var(--job-button-height);
  padding: 0 1.375rem;
  border-radius: var(--job-radius-pill);
  font-weight: 600;
}

.job-career__role-actions .job-button-secondary:hover {
  border-color: var(--job-brand);
  background: var(--job-brand);
  color: var(--job-on-fill);
}

/* The measures.

   Set as a row of figures across the card, divided by hairlines, each with its own period in a tag
   beneath it. In prose the periods ran together and a reader could not see that the advert count is
   June 2026 while the salary beside it is May 2025, a year apart. As measures the distance is
   visible without anybody having to point it out, and the tag keeps the period inseparable from its
   figure. */
.job-career__metrics {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: var(--job-space-4) 0;
  margin: 0;
}

.job-career__metric {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  min-width: 0;
  padding: 0 var(--job-space-6);
  border-left: 1px solid var(--job-line);
}

.job-career__metric:first-child {
  padding-left: 0;
  border-left: none;
}

.job-career__metric:last-child {
  flex: 1 1 16rem;
  padding-right: 0;
}

/* Large, medium and tabular: one weight for every figure on the card, so none outranks another,
   and tabular so figures line up down the list. */
.job-career__metric-value {
  margin: 0;
  font-size: clamp(2rem, 1.62rem + 1.6vw, 2.75rem);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--job-ink);
}

/* The share of adverts, drawn as well as stated: a bar filled to the same share as the figure, so
   it can say nothing the number does not. */
.job-career__metric-value--share {
  display: flex;
  align-items: center;
  gap: var(--job-space-4);
}

.job-career__share {
  flex: 1 1 auto;
  max-width: 15rem;
  height: var(--job-bar-height);
  overflow: hidden;
  border-radius: var(--job-radius-pill);
  background: var(--job-mark-track);
}

.job-career__share-fill {
  display: block;
  height: 100%;
  border-radius: var(--job-radius-bar);
  background: var(--job-mark);
}

.job-career__metric-label {
  margin: 0;
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
  font-weight: 400;
  line-height: 1.45;
}

/* The period is quiet but never absent. It is the part that stops a figure being read as current. */
.job-career__metric-period {
  align-self: flex-start;
  margin: 0.25rem 0 0;
  padding: 0.1875rem 0.625rem;
  border-radius: var(--job-radius-pill);
  background: var(--job-canvas);
  color: var(--job-ink-soft);
  font-size: 0.75rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* The movement: two counts and their months, as a sentence under its own label across the card's
   foot. Still a sentence and never a rate, because setting it as a figure would invite reading a
   difference off the two numbers. */
.job-career__role-movement {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem var(--job-space-4);
  margin: 0;
  padding-top: var(--job-space-4);
  border-top: 1px solid var(--job-line);
  color: var(--job-ink-soft);
  font-size: 0.9375rem;
  font-variant-numeric: tabular-nums;
}

.job-career__role-movement-label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

@media (max-width: 640px) {
  /* A phone: the controls drop beneath the name as a full-width pair, and the measures stack into
     two columns with the share across the foot, as the design's phone board draws them. */
  .job-career__roles li {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--job-space-4);
    padding: 1.375rem var(--job-space-5);
    border-radius: 1.375rem;
  }

  .job-career__role-actions {
    flex-wrap: nowrap;
    gap: var(--job-space-2);
  }

  .job-career__role-actions form {
    flex: 1 1 0;
    min-width: 0;
  }

  .job-career__role-actions .job-button {
    width: 100%;
    min-height: var(--job-target);
    padding: 0 var(--job-space-3);
  }

  .job-career__metrics {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--job-space-5) 0;
    padding-top: var(--job-space-4);
    border-top: 1px solid var(--job-line);
  }

  .job-career__metric {
    padding: 0 0 0 var(--job-space-4);
  }

  .job-career__metric:first-child {
    padding-right: var(--job-space-4);
  }

  .job-career__metric:last-child {
    grid-column: 1 / -1;
    padding-left: 0;
    border-left: none;
  }

  .job-career__role-movement {
    flex-direction: column;
    gap: 0.25rem;
  }
}
