/*
 * Dev Careers — site styles (feature 002: Site Design System).
 *
 * Contract: specs/002-site-design-system/design-spec.yaml (tokens,
 * geometry, components). Hand-written, no build step, no external
 * resources (FR-002). Section order (YAML css.section_order):
 *   tokens · base · utilities · layout · components · pages · admin ·
 *   responsive · motion · forced-colors
 *
 * Colors: official UCLA palette ONLY (brand.ucla.edu, verified
 * 2026-10-15) and only the approved contrast pairs in YAML
 * tokens.color.approved_pairs. No tints, no custom swatches; red only
 * for error messages. src/tests/test_static_policy.py enforces it.
 *
 * Fluid sizes interpolate from a 360 px viewport (min) to the mockup's
 * 1920 px artboard (max); type uses web sizes (see the tokens). Font ranges keep max <= 2.5 x min so text
 * still reaches 200% under browser zoom (WCAG 1.4.4).
 */

/* ==== Tokens ========================================================== */

:root {
  /* Official UCLA palette (brand.ucla.edu Identity > Colors) */
  --ucla-blue: #2774ae;
  --ucla-gold: #ffd100;
  --ucla-white: #ffffff;
  --ucla-black: #000000;
  --ucla-blue-darkest: #003b5c;
  --ucla-blue-darker: #005587;
  --ucla-blue-lighter: #8bb8e8;
  --ucla-blue-lightest: #daebfe;
  --ucla-gold-darker: #ffc72c;
  --ucla-gold-darkest: #ffb81c;
  /* Error messages only (8.2:1 on white); not a brand swatch. */
  --error-red: #a30000;
  /* Admin posting form error banner ONLY (owner exception 2026-10-21):
   * black 17.4:1, error red 6.8:1, Darker Blue links 6.6:1 on it. */
  --error-red-pale: #fbe5e5;

  /* Color roles */
  --color-text: var(--ucla-black);
  --color-bg: var(--ucla-white);
  --color-heading: var(--ucla-blue);
  --color-link: var(--ucla-blue-darker);
  --color-link-hover: var(--ucla-blue-darkest);
  --color-nav: var(--ucla-blue);
  --color-cta-bg: var(--ucla-gold);
  --color-cta-bg-hover: var(--ucla-gold-darker);
  --color-cta-text: var(--ucla-blue-darker);
  --color-panel-bg: var(--ucla-blue);
  --color-panel-text: var(--ucla-white);
  --color-rule: var(--ucla-blue);
  --color-rule-subtle: var(--ucla-blue-lightest);
  --color-control-border: var(--ucla-blue);
  --color-row-hover: var(--ucla-blue-lightest);
  --color-error: var(--error-red);

  /* Typography (brand-required stack: Helvetica, Arial, Roboto).
   * Web sizes, not the mockup's: its 36 px body / 72 px headings read as
   * "gigantic" in a normal browser (owner, 2026-10-15). The ramp keeps
   * the mockup's hierarchy at about half its size:
   * display 28-40, body 18-20, CTA 21-28, nav 16-18, caption/footer 14-16
   * (CTA label enlarged, owner 2026-10-16). */
  --font-stack: Helvetica, Arial, Roboto, sans-serif;
  --fs-display: clamp(1.75rem, 1.5769rem + 0.7692vw, 2.5rem);
  --fs-body: clamp(1.125rem, 1.0962rem + 0.1282vw, 1.25rem);
  --fs-cta: clamp(1.3125rem, 1.2115rem + 0.4487vw, 1.75rem);
  --fs-nav: clamp(1rem, 0.9712rem + 0.1282vw, 1.125rem);
  --fs-caption: clamp(0.875rem, 0.8462rem + 0.1282vw, 1rem);
  --fs-footer: clamp(0.875rem, 0.8462rem + 0.1282vw, 1rem);
  --fs-ui: 1rem;
  /* Reading columns: full width below 64em; from there 70% of the
   * content, ending near the mockup's right edge (about 1210 of 1728 px
   * at 1920) at web-sized type (owner, 2026-10-16). */
  --measure-body: 100%;
  --measure-display: 100%;

  /* Layout: 1728 px content at the 1920 px artboard (96 px gutters) */
  --content-max: 108rem;
  --gutter: clamp(1rem, -0.1538rem + 5.1282vw, 6rem);
  --container-max: calc(var(--content-max) + 2 * var(--gutter));
  --tap: 44px; /* minimum touch target (constitution Principle VI) */

  /* Vertical rhythm, scaled with the web-sized type (owner, 2026-10-15:
   * the mockup's artboard gaps, e.g. 211 px between sections, were far
   * too loose). Values at 1920: statement 32, heading 24, media 48,
   * section 64, page title 72, major 96, footer 120. */
  --space-statement: clamp(1.5rem, 1.3846rem + 0.5128vw, 2rem);
  --space-heading: clamp(1rem, 0.8846rem + 0.5128vw, 1.5rem);
  --space-media: clamp(2rem, 1.7692rem + 1.0256vw, 3rem);
  --space-section: clamp(2.5rem, 2.1538rem + 1.5385vw, 4rem);
  --space-page-title: clamp(2.5rem, 2.0385rem + 2.0513vw, 4.5rem);
  --space-major: clamp(3rem, 2.3077rem + 3.0769vw, 6rem);
  --space-footer: clamp(4rem, 3.1923rem + 3.5897vw, 7.5rem);
  --space-paragraph: 1.5em;

  /* Masthead, CTA and mission geometry (YAML tokens.layout) */
  --masthead-min-height: clamp(4.5rem, 2.5096rem + 8.8462vw, 13.125rem);
  --logo-height: clamp(2rem, 1.4087rem + 2.6282vw, 4.5625rem);
  /* CTA box 400x128 at 1920 (owner, 2026-10-16; mockup 468x163) */
  --cta-width: clamp(15rem, 12.6923rem + 10.2564vw, 25rem);
  --cta-min-height: clamp(3.5rem, 2.4615rem + 4.6154vw, 8rem);
  --cta-overlap: clamp(1rem, 0.3654rem + 2.8205vw, 3.75rem);
  --mission-card-inset-top: clamp(1rem, 0.3221rem + 3.0128vw, 3.9375rem);
  --mission-card-inset-bottom: clamp(1rem, 0.3654rem + 2.8205vw, 3.75rem);
  --panel-pad-inline-start: clamp(1.25rem, 1.0192rem + 1.0256vw, 2.25rem);
  --panel-pad-block-start: clamp(2rem, 1.5385rem + 2.0513vw, 4rem);
  --panel-pad-block-end: clamp(2rem, 1.5385rem + 2.0513vw, 4rem);
  --card-caption-pad: clamp(1rem, 0.6827rem + 1.4103vw, 2.375rem);

  /* Focus: Darker Blue on light surfaces (7.9:1). NOT visible on
   * UCLA Blue (1.5:1) — .surface-blue switches it to white. */
  --focus-color: var(--ucla-blue-darker);
}

@media (min-width: 64em) {
  :root {
    --measure-body: 70%;
    --measure-display: 70%;
  }
}

/* ==== Base ============================================================ */

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

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
  font-family: var(--font-stack);
  font-size: var(--fs-ui);
  line-height: 1.5;
  color: var(--color-text);
  background: var(--color-bg);
}

main {
  flex: 1 0 auto;
}

/* Admin and error pages keep these heading defaults; public pages use
 * .statement, .page-title and .section-title. */
h1,
h2,
h3 {
  color: var(--color-heading);
  line-height: 1.25;
}

h1 { font-size: 2rem; }
h2 { font-size: 1.5rem; }
h3 { font-size: 1.25rem; }

a {
  color: var(--color-link);
  text-decoration-thickness: 2px;
  text-underline-offset: 2px;
}

a:hover {
  color: var(--color-link-hover);
}

/* Visible, high-contrast focus for keyboard users (WCAG 2.4.7, 1.4.11).
 * Outline (not box-shadow) so it survives forced-colors mode. */
:focus-visible {
  outline: 3px solid var(--focus-color);
  outline-offset: 2px;
}

img,
video {
  max-width: 100%;
  height: auto;
}

/* ==== Utilities ======================================================= */

.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.measure {
  max-width: var(--measure-body);
}

/* Reading copy: never below 18 px (--fs-body min); flush left, ragged right. */
.prose {
  font-size: var(--fs-body);
  line-height: 1.5;
}

.prose > * {
  margin: 0;
}

.prose > * + * {
  margin-block-start: var(--space-paragraph);
}

.u-caps {
  text-transform: uppercase;
}

.surface-blue {
  --focus-color: var(--ucla-white);
  background: var(--color-panel-bg);
  color: var(--color-panel-text);
}

.surface-blue a {
  color: inherit;
  text-decoration: underline;
}


/* Shared public-page headings (mockup: 72 px regular, UCLA Blue) */
.page-title,
.section-title {
  margin: 0;
  font-size: var(--fs-display);
  font-weight: 400;
  line-height: 1.2;
  color: var(--color-heading);
}

/* Vertical gap utilities (YAML tokens.layout.spacing). Declared after
 * the heading rules above so a gap class always wins over their
 * margin reset. */
.gap-statement { margin-block-start: var(--space-statement); }
.gap-heading { margin-block-start: var(--space-heading); }
.gap-media { margin-block-start: var(--space-media); }
.gap-section { margin-block-start: var(--space-section); }
.gap-page-title { margin-block-start: var(--space-page-title); }
.gap-major { margin-block-start: var(--space-major); }

/* Gap above the footer: the mockup's 265 px on public pages (body
 * classes page-*), a section gap on admin and error pages. */
.page-body {
  padding-block-end: var(--space-section);
}

body[class^="page-"] .page-body {
  padding-block-end: var(--space-footer);
}

/* ==== Layout & shell components (masthead, nav, hero, CTA) ========== */

.skip-link {
  position: absolute;
  left: -100vw;
  top: 0;
  z-index: 10;
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0.75rem 1rem;
  background: var(--ucla-blue-darker);
  color: var(--ucla-white);
  font-weight: 700;
}

.skip-link:focus {
  left: 0;
}

/* Mockup: 210 px header zone, logo left, nav right, no rule below. */
.masthead {
  display: flex;
  align-items: center;
  min-height: var(--masthead-min-height);
  background: var(--color-bg);
}

.masthead-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
}

/* Department logo: official artwork, never stretched or recolored.
 * Vertical padding keeps the brand's clear space (one "U" width). */
.masthead-logo {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding-block: calc(var(--logo-height) * 0.33);
}

.masthead-logo img {
  display: block;
  width: auto;
  height: var(--logo-height);
}

/* Link padding sits outside the text so the text aligns to the
 * container edge (right on wide screens, left when it wraps). */
.site-nav {
  margin-inline: -0.5rem;
}

.site-nav__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0 clamp(0.75rem, 1vw, 1.25rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding-inline: 0.5rem;
  font-size: var(--fs-nav);
  font-weight: 400;
  color: var(--color-nav);
  text-decoration: none;
}

.site-nav a:hover,
.site-nav a[aria-current] {
  text-decoration: underline;
  text-decoration-thickness: 3px;
  text-underline-offset: 0.3em;
}

/* Hero: full-bleed media (3:1 from md, 2:1 on phones); no text over it. */
.hero {
  position: relative;
  width: 100%;
}

.hero__media {
  position: relative;
  aspect-ratio: 2 / 1;
  overflow: hidden;
  background: var(--ucla-blue-darkest);
}

@media (min-width: 48em) {
  .hero__media {
    aspect-ratio: 3 / 1;
  }
}

.hero__media > img,
.hero__media > video {
  display: block;
  width: 100%;
  max-width: none;
  height: 100%;
  object-fit: cover;
}

/* Gold CTA box (mockup 468x163 at x=96), rising --cta-overlap over the
 * hero's bottom edge and aligned with the container's content edge.
 * Darker Blue label on Gold = 5.4:1 (the mockup's UCLA Blue is 3.4:1).
 * min-height, never height, so enlarged text spacing just grows it. */
.cta-hero {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--cta-width);
  max-width: calc(100% - 2 * var(--gutter));
  min-height: var(--cta-min-height);
  margin-block-start: calc(-1 * var(--cta-overlap));
  margin-inline-start: calc(max(0px, (100% - var(--container-max)) / 2) + var(--gutter));
  padding: 0.75rem 1rem;
  border: 2px solid transparent;
  background: var(--color-cta-bg);
  color: var(--color-cta-text);
  font-size: var(--fs-cta);
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
}

.cta-hero:hover {
  background: var(--color-cta-bg-hover);
  color: var(--color-cta-text);
}

/* Focus over photos, video or gold: a two-tone ring (Darker Blue
 * outline around a white halo, 7.9:1 against each other) stays >= 3:1
 * whatever is behind it (WCAG 1.4.11, 2.4.7). */
.cta-hero:focus-visible,
.hero__pause:focus-visible {
  outline: 3px solid var(--ucla-blue-darker);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--ucla-white);
}

/* ---- Buttons & forms ------------------------------------------------ */

.btn-primary,
button,
input[type="submit"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap);
  padding: 0.625rem 1.25rem;
  border: 2px solid var(--ucla-blue);
  border-radius: 4px;
  background: var(--ucla-blue);
  color: var(--ucla-white);
  font-family: inherit;
  font-size: 1rem;
  font-weight: bold;
  text-decoration: none;
  cursor: pointer;
}

.btn-primary:hover,
button:hover {
  background: var(--ucla-blue-darker);
  border-color: var(--ucla-blue-darker);
  color: var(--ucla-white);
}

label {
  display: block;
  font-weight: bold;
  margin-top: 1rem;
}

input,
select,
textarea {
  display: block;
  width: 100%;
  max-width: 40rem;
  min-height: var(--tap);
  margin-top: 0.25rem;
  padding: 0.5rem 0.75rem;
  border: 2px solid var(--color-control-border); /* UCLA Blue 5.0:1 (was Lighter Blue 2.0:1) */
  border-radius: 4px;
  font-family: inherit;
  font-size: 1rem;
  color: var(--color-text);
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  border-color: var(--focus-color);
}

/* ---- Tables (admin grid; public lists) ------------------------------ */

table {
  width: 100%;
  border-collapse: collapse;
  margin-block: 1rem;
}

th,
td {
  padding: 0.625rem 0.75rem;
  border-bottom: 1px solid var(--color-rule-subtle);
  text-align: left;
  vertical-align: top;
}

th {
  color: var(--color-link);
  border-bottom: 3px solid var(--color-rule);
}

/* Lightest Blue row hover: black text 17.3:1, Darker Blue links 6.5:1. */
tbody tr:hover {
  background: var(--color-row-hover);
}

/* Sort-header and row links: 44 px touch targets at every width
 * (constitution VI; tablets included). */
th a,
td a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
}

/* ---- Messages & empty states ----------------------------------------- */

.page-message {
  padding-block: 3rem;
  text-align: center;
}

.empty-state {
  padding: 2rem;
  border: 2px dashed var(--ucla-blue-lighter);
  border-radius: 4px;
  text-align: center;
  color: var(--color-text);
}

/* ---- Footer: brand-required global footer, mockup look ------------- */

.site-footer {
  padding-block: 1.5rem 2rem;
  background: var(--color-bg);
  color: var(--color-text);
  font-size: var(--fs-footer);
  line-height: 1.4;
}

.site-footer__inner {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.site-footer__copyright {
  margin: 0;
}

/* The copyright link sits inside a sentence, so it stays underlined
 * (WCAG 1.4.1); the list links below are a link list. */
.site-footer__copyright a {
  color: inherit;
}

.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0 clamp(1rem, 2.5vw, 3rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-footer__links a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  color: inherit;
  text-decoration: none;
}

.site-footer__links a:hover,
.site-footer__links a:focus-visible {
  color: inherit;
  text-decoration: underline;
}

@media (min-width: 64em) {
  .site-footer__inner {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

/* ==== Pages: Home (mockup page 1) ====================================== */

/* 72 px UCLA Blue statement — the Home page's h1. */
.statement {
  max-width: var(--measure-display);
  margin: var(--space-section) 0 0;
  font-size: var(--fs-display);
  font-weight: 400;
  line-height: 1.2;
  color: var(--color-heading);
}

.statement strong {
  font-weight: 700;
}

.photo-band {
  margin-block-start: var(--space-media);
}

.photo-band img {
  display: block;
  width: 100%;
  height: auto;
}

/* Mission band: UCLA Blue panel (white text, 5.0:1) with the photo card
 * overlapping its right edge from lg; stacked below lg. Grid lines are
 * the mockup's container-relative widths (panel 0-1192, card 1032-1718
 * of 1728). */
.mission {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  margin-block-start: var(--space-section);
}

.mission__panel {
  padding: var(--panel-pad-block-start) var(--panel-pad-inline-start) var(--panel-pad-block-end);
}

.mission__heading {
  margin: 0;
  font-size: var(--fs-display);
  font-weight: 400;
  line-height: 1.2;
  color: inherit;
}

.mission__heading strong {
  font-weight: 700;
}

.mission__body {
  margin: var(--space-heading) 0 0;
  font-size: var(--fs-body);
  line-height: 1.5;
}

.mission__cta {
  margin: var(--space-paragraph) 0 0;
  font-size: var(--fs-body);
  line-height: 1.5;
}

.mission__cta a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  font-weight: 700;
  color: inherit;
  text-decoration: underline;
}

.figure-card {
  margin: var(--space-media) 0 0;
  background: var(--ucla-white);
}

.figure-card img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 689 / 541;
  object-fit: cover;
  object-position: 50% 30%;
}

.figure-card figcaption {
  display: grid;
  gap: 0.1em;
  padding: var(--card-caption-pad);
  font-size: var(--fs-caption);
  line-height: 1.3;
  color: var(--color-text);
}

.figure-card__name {
  font-weight: 700;
}

.figure-card__line {
  font-style: italic;
}

@media (min-width: 64em) {
  .mission {
    grid-template-columns:
      [panel-start] minmax(0, 1032fr) [card-start] minmax(0, 160fr)
      [panel-end] minmax(0, 526fr) [card-end] minmax(0, 10fr);
    grid-template-rows:
      [top] var(--mission-card-inset-top) [card-top] auto
      [card-bottom] var(--mission-card-inset-bottom) [bottom];
  }

  /* 21% inline-end padding = the card overlap (13.4% of the panel) plus
   * the mockup's ~82 px gap, so copy always stops before the card. */
  .mission__panel {
    grid-column: panel-start / panel-end;
    grid-row: top / bottom;
    padding-inline: var(--panel-pad-inline-start) 21%;
  }

  .figure-card {
    z-index: 1;
    grid-column: card-start / card-end;
    grid-row: card-top / card-bottom;
    align-self: start;
    margin: 0;
  }
}

/* Hero video pause/play button (inserted by site.js), top-right of the
 * media so it never meets the CTA rising over the bottom-left. A 44x44
 * symbol (owner, 2026-10-16): site.js sets data-icon and the visually
 * hidden label (the accessible name). The symbol is drawn with borders
 * in currentColor (Darker Blue on white, 7.9:1). */
.hero__pause {
  position: absolute;
  top: 0.75rem;
  right: var(--gutter);
  z-index: 2;
  display: grid;
  place-items: center;
  width: var(--tap);
  height: var(--tap);
  padding: 0;
  border: 2px solid var(--ucla-blue-darker);
  border-radius: 4px;
  background: var(--ucla-white);
  color: var(--ucla-blue-darker);
}

.hero__pause::before {
  content: "";
  box-sizing: border-box;
  forced-color-adjust: none;
}

/* Two bars while playing */
.hero__pause[data-icon="pause"]::before {
  width: 18px;
  height: 20px;
  border-inline: 6px solid currentColor;
}

/* A right-pointing triangle while paused, nudged right to look centered */
.hero__pause[data-icon="play"]::before {
  width: 18px;
  height: 22px;
  margin-inline-start: 4px;
  border-block: 11px solid transparent;
  border-inline-start: 18px solid currentColor;
}

.hero__pause:hover {
  border-color: var(--ucla-blue-darker);
  background: var(--ucla-blue-darker);
  color: var(--ucla-white);
}

/* ==== Pages: Open Positions + posting detail (no mockup; tokens only) ==== */

/* Landing spot for sort/back links (#open-positions): a little
 * breathing room above the heading after the jump. */
#open-positions {
  scroll-margin-top: 1.5rem;
}

.filter-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-block: 1rem;
}

.filter-nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0.5rem 0.875rem;
  border: 2px solid var(--ucla-blue-lighter);
  border-radius: 4px;
  color: var(--color-link);
  text-decoration: none;
  font-weight: 700;
}

/* White on UCLA Blue 5.0:1. */
.filter-nav a[aria-current="page"] {
  background: var(--ucla-blue);
  border-color: var(--ucla-blue);
  color: var(--ucla-white);
}

.positions-table td a {
  font-weight: 700;
}

/* Customer 2026-10-23 (1.6.0): the salary value ("$51,336.00 -
 * $92,328.00") stays on ONE line while the window is resized at
 * desktop and tablet widths; below 768 px the phone card layout may
 * wrap it. .table-wrap scrolls sideways if the table outgrows the
 * page, so nowrap cannot break the page layout. */
@media (min-width: 768px) {
  .positions-table td[data-label="Salary"] {
    white-space: nowrap;
  }
}

/* ---- Posting detail ----------------------------------------------------- */

/* The light blue facts box with its own Apply button (owner 2026-10-19):
 * under Req # on narrow screens; from 768 px, on the right, centred
 * against the facts. */
.posting-summary {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem 2rem;
  margin-block: 1.5rem;
  padding: 1rem 1.25rem;
  background: var(--ucla-blue-lightest); /* black text 17.3:1 */
  color: var(--color-text);
}

@media (min-width: 48em) {
  .posting-summary {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

.posting-facts {
  display: grid;
  gap: 0.5rem 2rem;
  min-width: 0;
  margin: 0;
}

.posting-facts div {
  display: flex;
  flex-wrap: wrap;
  column-gap: 0.5rem;
}

/* The UA's 40 px <dd> indent pushed long values past a 320 px screen
 * (found on stage, /open-positions/7): no indent, values may wrap. */
.posting-facts dt {
  /* Below 768 px each value starts under its label (short ones used to
   * sit beside it, long ones under it); from 768 px the grid below puts
   * labels and values in two columns and this has no effect. */
  flex-basis: 100%;
  min-width: min(11rem, 100%); /* fits "Payroll Classification" (1.4.0) */
  font-weight: 700;
}

.posting-facts dd {
  min-width: 0;
  margin: 0;
  overflow-wrap: anywhere;
}

/* From 768 px the facts are a two-column grid, labels | values, so every
 * value starts at the same left edge (seven facts since 1.4.0; long values
 * used to wrap under their labels while short ones sat beside them).
 * The row <div>s step aside; dt/dd keep their list semantics. */
@media (min-width: 48em) {
  .posting-facts {
    grid-template-columns: max-content minmax(0, 1fr);
  }

  .posting-facts div {
    display: contents;
  }
}

.section-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.5rem;
  margin-block: 1.5rem;
}

.section-nav a {
  min-height: var(--tap);
  display: inline-flex;
  align-items: center;
}

.apply-note {
  display: block;
  margin-top: 0.25rem;
  color: var(--color-text);
}

/* ---- Messages (save confirmations — FR-014) ------------------------------- */

.messages {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
}

.message {
  padding: 0.75rem 1rem;
  border-left: 6px solid var(--ucla-blue);
  background: var(--ucla-blue-lightest);
  font-weight: bold;
}

/* Red only for error messages (brand); no tinted background. */
.message-error {
  border-left-color: var(--color-error);
  background: var(--color-bg);
}

/* The posting form's blue box: "Return to Listings" on the left, any save
 * confirmation to its right (owner 2026-10-20). */
.message--action {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.5rem;
}

/* No save confirmation yet: the box holds only the button. */
.message--action > span:empty {
  display: none;
}

/* ---- Admin console extras ------------------------------------------------- */

/* Posting form (new + edit): the fields form one column centered in the
 * page at their own 40rem width, so each label starts at its field's
 * left edge (client 2026-10-21). Headings and banners stay full width. */
.posting-form {
  max-width: 40rem;
  margin-inline: auto;
}

/* Checkboxes on the admin pages (Listing Category options, Enabled):
 * the global input rule above stretches every checkbox into a
 * full-width 44px widget whose option text wraps BELOW it — impossible
 * to tell which name belongs to which box (customer 2026-10-22). The
 * box itself becomes a normal-size checkbox again. */
.page-admin input[type="checkbox"] {
  display: inline-block;
  width: auto;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
}

/* The Listing Category options: side-by-side rows — checkbox left, its
 * text vertically centred next to it — so each name visibly belongs to
 * its own box. The row (not the glyph) carries the 44 px touch target;
 * option names read at normal weight under the bold group label. */
#id_categories label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: var(--tap);
  margin-top: 0;
  font-weight: normal;
}

#id_categories > div + div {
  margin-top: 0.25rem;
}

/* The Enabled row (label and checkbox are siblings in one <p>): centred
 * the same way, for the same reason. */
.posting-form p:has(> input[type="checkbox"]) {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.posting-form p:has(> input[type="checkbox"]) > label {
  margin-top: 0;
}

/* Error banner links jump to #id_<field>; the label and error list sit
 * above the input, so keep them in view (8rem: a three-line error, as
 * long messages wrap at 320 px, plus the label). */
.posting-form :is(input, textarea, select),
.posting-form div[id^="id_"] {
  scroll-margin-top: 8rem;
}

/* Posting form errors (client 2026-10-21). The brand reserves red for error
 * messages and forbids tints; the owner granted an exception for this
 * admin form only, scoped by body.page-admin (test_static_policy enforces
 * it). The banner matches the blue box's shape. */
.page-admin .error-banner {
  margin: 0 0 1rem;
  padding: 0.75rem 1rem;
  border-left: 6px solid var(--color-error);
  background: var(--error-red-pale);
  color: var(--color-text);
  font-weight: bold;
}

.page-admin .error-banner p {
  margin: 0;
}

.page-admin .error-banner ul {
  margin: 0.5rem 0 0;
  padding-left: 1.25rem;
}

/* Required fields: red asterisk after the label. Screen readers already
 * hear "required" from the input's required attribute, so the asterisk
 * has empty alt text. */
.page-admin label.required::after {
  content: " *" / "";
  color: var(--color-error);
}

.page-admin .required-marker {
  color: var(--color-error);
  font-weight: bold;
}

.page-admin .errorlist {
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
  color: var(--color-error);
  font-weight: bold;
}

/* Posting form Summary / Responsibilities / Qualifications: 15 lines to
 * start, then the box grows with its text, no upper limit (client
 * 2026-10-21). Browsers without field-sizing keep the 15 rows and scroll.
 * min-height adds the padding (2 x 0.5rem) and border (2 x 2px). */
textarea.autogrow {
  field-sizing: content;
  line-height: 1.5;
  min-height: calc(15lh + 1rem + 4px);
}

/* Destructive admin action ("Remove"): the brand reserves red for
 * error messages and emergency alerts, so this is a Darker Blue outline
 * button; the label carries the meaning. */
.btn-danger {
  background: var(--ucla-white);
  border-color: var(--ucla-blue-darker);
  color: var(--ucla-blue-darker);
}

.btn-danger:hover {
  background: var(--ucla-blue-darker);
  border-color: var(--ucla-blue-darker);
  color: var(--ucla-white);
}

.empty-state-inline {
  color: var(--color-text);
}

/* Job Listings search + pagination (owner 2026-10-19, 1.3.0). */
.grid-search {
  margin-block: 1rem;
}

.grid-search label {
  margin-top: 0;
}

.grid-search__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.25rem;
}

.grid-search__row input[type="search"] {
  flex: 1 1 16rem;
  max-width: 28rem;
  margin-top: 0;
}

.empty-state__action {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  font-weight: 700;
}

.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.5rem;
  margin-block: 1rem;
}

.pagination a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  font-weight: 700;
}

/* ---- Utilities ----------------------------------------------------------- */

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

/* ---- Responsive tables (FR-021: the PAGE never scrolls sideways) --------- */

/* Wide data tables (public positions list, admin grid, admin list)
 * keep their legacy-parity columns; on phones the table region
 * scrolls WITHIN the page instead of the page scrolling sideways
 * (the pattern users expect from mobile data tables). */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.table-wrap table {
  min-width: 32rem; /* below this, cell text wraps unreadably */
}

/* Secondary/cancel control beside form submits (was unstyled). */
.btn-cancel {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0.625rem 1.25rem;
  border: 2px solid var(--ucla-blue-lighter);
  border-radius: 4px;
  background: var(--color-bg);
  color: var(--ucla-blue-darker);
  font-weight: bold;
  text-decoration: none;
}

.btn-cancel:hover {
  border-color: var(--ucla-blue-darker);
  color: var(--ucla-blue-darkest);
}

/* Standalone links that act as controls get full touch targets
 * (constitution Principle VI: ≥44px). */
.section-nav a,
.back-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
}

/* ---- Phone width (FR-021) ------------------------------------------------ */

@media (max-width: 480px) {
  /* The PUBLIC open-positions list collapses to stacked cards per
   * posting (owner ruling, 2026-10-13: a horizontally scrolling
   * table region is not usable on phones). The admin grid keeps its
   * in-region scroll — its legacy columns are mandated and admin
   * work is desktop-first (FR-010). */
  table.collapse-cards {
    min-width: 0;
  }

  .collapse-cards thead {
    display: none;
  }

  .collapse-cards tr {
    display: block;
    padding: 0.75rem 0;
    border-bottom: 1px solid var(--color-rule-subtle);
  }

  .collapse-cards td {
    display: block;
    padding: 0.25rem 0;
    border-bottom: 0;
    text-align: left;
  }

  .collapse-cards td[data-label]::before {
    content: attr(data-label);
    display: block;
    color: var(--color-text);
    font-size: 0.875rem;
    font-weight: bold;
  }

  /* Tighter cell padding keeps 5-column tables close to the viewport;
   * in-table links get real 44px targets (rows grow taller instead
   * of links staying 17px tall). */
  th,
  td {
    padding: 0.5rem;
  }

  table a {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap);
    min-width: var(--tap);
    white-space: nowrap;
  }

  /* The collapsed cards ARE the mobile layout — no horizontal
   * scroll region for the public list. */
  .collapse-cards a {
    min-width: 0;
    white-space: normal;
  }
}

/* ==== Motion ========================================================== */

/* The hero video itself is handled in site.js (never plays). */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition: none !important;
    animation: none !important;
    scroll-behavior: auto !important;
  }
}

/* ==== Forced colors (Windows High Contrast) ============================ */

@media (forced-colors: active) {
  .cta-hero {
    border-color: ButtonText;
  }

  .hero__pause::before {
    color: ButtonText;
  }

  :focus-visible {
    outline-color: Highlight;
  }
}
