/*
  DCS Job Board — Django app styles.
  Ported from the DCS Job Board prototype's design system (same color
  tokens, type, buttons, cards, tables) and extended to style Django's
  default form rendering ({{ form.as_p }}) and anchor-based tab nav.
*/

/* The hidden attribute sets display:none in the user-agent stylesheet, which
   any author rule setting display beats -- .form-card form > p is display:flex,
   so el.hidden = true silently did nothing. This restores it everywhere. */
[hidden] { display: none !important; }

:root {
  --blue: #2962F0;
  --navy: #274B72;
  --navy-dark: #162F4A;
  --teal: #1FB6A6;
  --mint-bg: #D9F3EF;
  --mint-bg-strong: #BFEDE5;
  --page-bg: #F5F7FA;
  --slate: #6B7C93;
  --white: #FFFFFF;
  --danger: #8C1D18;
  --danger-tint: #FBEAE9;
  --blue-tint: #E4EBFD;
  --amber-tint: #FCEFD9;
  --amber-border: #C98A1A;
  --line: #E1E6EC;
  --field-line: #C9D2DD;
  --focus-ring: #2962F0;

  --font-heading: "Sora", "Segoe UI", Arial, sans-serif;
  /* The logo's own typeface, for the one piece of text that has to pass as part
     of it. Identified off logo.png rather than guessed: single-storey geometric
     a, circular D and e, monolinear strokes, flat terminals on the t. Sora --
     the heading face -- is squarer and read as a different font sitting next to
     the mark. Not used anywhere else; the site's headings stay Sora. */
  --font-brand: "Poppins", var(--font-heading);
  --font-body: "Inter", "Segoe UI", Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--page-bg);
  color: var(--navy-dark);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
}

h1, h2, h3 {
  font-family: var(--font-heading);
  color: var(--navy);
  margin: 0 0 0.5em;
}

h1 { font-size: 1.75rem; }
h2 { font-size: 1.25rem; margin-top: 1.5em; }
h3 { font-size: 1.05rem; margin-bottom: 0.25em; }

p { margin: 0.25em 0; }

a, button, input, select, textarea {
  font-family: inherit;
  font-size: inherit;
}

:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
}

/* ---------- header ---------- */

.site-header {
  background: var(--white);
  border-bottom: 1px solid #E1E6EC;
  padding: 0.75em 1.5em;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75em;
}

.signout-form { margin: 0; }

.brand {
  display: flex;
  align-items: center;
  /* One word space, measured off the logo instead of chosen. The gaps between
     "Dental", "Care" and "Staffing" are 16.5px in a 700x119 PNG, which is
     4.44px once it renders at height:32px -- and 2.42px of that is already
     baked into the image's own right-hand padding. So 2px here, and the join
     reads as the same word space as the two inside the mark. */
  gap: 2px;
  text-decoration: none;
}

/* Never underlined, in any state. It is set to read as part of the logo's own
   lettering, and lettering that underlines itself on hover stops looking like
   lettering. The focus ring is the whole brand, which is the click target. */
.brand,
.brand:hover,
.brand:focus,
.brand:active,
.brand:visited { text-decoration: none; }
.brand:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 4px; }

.brand img {
  height: 32px;
  width: auto;
}

/* Made to read as part of the logo rather than as a caption beside it: same
   blue, same weight, same size.
 
   The size is measured, not chosen, and measured off a capital rather than off
   a whole word -- "Board" carries the ascender of its d, so comparing it with
   the pure caps of "Care" overstated the logo by a whole pixel and sent the
   first two attempts at this too large.
 
   In the 700x119 source the D of "Dental" spans rows 43..80. At the 32px the
   logo renders at, that is a cap height of 9.95px, and Poppins sets a cap at
   0.70em -- confirmed against the render, where 14px produces a 9.78px cap --
   so 0.875rem lands the two cap heights together.
 
   The nudge is measured off the render rather than computed, because the logo
   is a bitmap being scaled down and where its baseline actually lands is not
   worth deriving: at a 1.2px nudge the brand's baseline sat 0.89px above the
   wordmark's, so 2.1px. The baseline is the line the eye reads along; when the
   two cap heights differ by a fraction of a pixel, align the baselines and let
   the cap tops fall where they will.
 
   Sora is the nearest of the two faces the page already loads. The logo's own
   face ships only inside the PNG, so this matches its colour, weight and size
   rather than its exact letter shapes. */
.brand-name {
  font-family: var(--font-brand);
  font-weight: 700;
  color: var(--blue);
  font-size: 0.875rem;
  letter-spacing: -0.01em;
  line-height: 1;
  margin-top: 2.1px;
}

.site-nav {
  display: flex;
  gap: 0.5em;
  flex-wrap: wrap;
}

.nav-btn {
  background: var(--white);
  border: 1px solid var(--navy);
  color: var(--navy);
  padding: 0.5em 1em;
  border-radius: 999px;
  cursor: pointer;
  font-weight: 600;
  text-decoration: none;
  display: inline-block;
}

.nav-btn:hover { background: var(--blue-tint); }

/* ---------- layout ---------- */

.app-main {
  /* One width for every page in the app.
 
     This was 60vw, with the admin tabs opting into a wider 82vw of their own,
     on the reasoning that 60% keeps prose to a readable line length. That is
     sound typography and the wrong trade here: it made the width of the page
     depend on which page you were looking at, so moving between a company and
     the tab that lists it resized everything. This is a tool built around
     tables, not an article, and a consistent frame beats an ideal measure.
 
     Still bounded at both ends -- uncapped it sprawls on an ultrawide monitor,
     and a percentage alone is tighter than the nine-column tables can take on
     a small laptop. The breakpoints below widen it as the viewport shrinks. */
  width: 82vw;
  max-width: 1400px;
  margin: 0 auto;
  padding: 1.5em;
}

/* Cards and tables fill that width, rather than being narrowed a second time. */
.app-main .form-card,
.app-main .table-wrap { max-width: 100%; }

.view-header {
  display: flex;
  align-items: center;
  gap: 1em;
  flex-wrap: wrap;
  margin-bottom: 1em;
}

/* ---------- auth (login) page ---------- */

.auth-center {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 80vh;
}

/* ---------- tabs (anchor-based) ---------- */

.tab-row {
  display: flex;
  gap: 0.5em;
  margin-bottom: 1.25em;
  border-bottom: 2px solid #E1E6EC;
  padding-bottom: 0.5em;
  flex-wrap: wrap;
}

.tab-btn {
  background: var(--white);
  border: 1px solid #E1E6EC;
  color: var(--navy);
  padding: 0.6em 1.1em;
  border-radius: 8px 8px 0 0;
  cursor: pointer;
  font-weight: 600;
  text-decoration: none;
  display: inline-block;
}

.tab-btn[aria-current="page"] {
  background: var(--blue-tint);
  border-color: var(--blue);
  color: var(--navy-dark);
}

/* ---------- cards ---------- */

.card {
  background: var(--white);
  border-radius: 12px;
  padding: 1.5em;
  box-shadow: 0 2px 6px rgba(22, 47, 74, 0.06);
  margin-bottom: 1.5em;
}

.form-card { max-width: 100%; }
.form-card h2 { margin-top: 0; }

/* ---------- buttons ---------- */

.btn {
  border: none;
  border-radius: 8px;
  padding: 0.65em 1.25em;
  font-weight: 600;
  cursor: pointer;
}

.btn-primary { background: var(--blue); color: var(--white); }
.btn-primary:hover { background: #1f4fd1; }

.btn-secondary { background: var(--navy); color: var(--white); }
.btn-secondary:hover { background: var(--navy-dark); }

.btn-danger { background: var(--danger); color: var(--white); }
.btn-danger:hover { background: #6e1611; }

.btn-outline {
  background: var(--white);
  color: var(--navy);
  border: 1px solid var(--navy);
}
.btn-outline:hover { background: var(--blue-tint); }

.btn-small {
  padding: 0.4em 0.85em;
  font-size: 0.85rem;
}

/* ---------- Django default form rendering ({{ form.as_p }}) ---------- */

.form-card form { margin: 0; }

.form-card form > p,
.form-card form .field {
  display: flex;
  flex-direction: column;
  gap: 0.35em;
  margin: 0 0 1.1em;
}

.form-card form > p:last-of-type { margin-bottom: 1.4em; }
.form-card form > .field:last-of-type { margin-bottom: 1.4em; }
.form-card form .field-grid > .field:last-of-type { margin-bottom: 1.1em; }

.form-card form label {
  font-weight: 600;
  color: var(--navy);
}

/* number belongs here with the rest: left out, the lunch length -- the app's
   first number input -- took the browser's default padding and sat visibly
   shorter than the time field beside it. */
.form-card form input[type="text"],
.form-card form input[type="email"],
.form-card form input[type="date"],
.form-card form input[type="time"],
.form-card form input[type="number"],
.form-card form select,
.form-card form textarea {
  border: 1px solid var(--slate);
  border-radius: 6px;
  padding: 0.5em 0.6em;
  background: var(--white);
  color: var(--navy-dark);
  width: 100%;
  max-width: 420px;
  /* Same padding does not mean same height. The a/button/input/select/textarea
     rule above normalises font-family and font-size but stops at line-height,
     so fields keep the user agent's "normal" -- and a time input renders its
     value through a shadow tree whose intrinsic height is not a plain number
     input's. The two then differ by a few pixels side by side, which is
     exactly what the lunch pair showed.

     Pinning both settles it by construction rather than by hoping each
     widget's internals agree: 1.5 matches the body, and the min-height is that
     line plus the 0.5em padding either side plus the two 1px borders, which
     box-sizing: border-box counts inside the height. */
  line-height: 1.5;
  min-height: calc(2.5em + 2px);
}

.form-card form textarea { max-width: 100%; min-height: 5em; }

/* Django's RadioSelect widget renders a plain <ul> of <li><label><input>...
   inside the field's <p> — de-bullet it and lay the options out in a row. */
.form-card form > p > ul,
.form-card form .field > ul {
  list-style: none;
  margin: 0.3em 0 0;
  padding: 0;
  display: flex;
  gap: 1.25em;
  flex-wrap: wrap;
}

.form-card form > p > ul li,
.form-card form .field > ul li {
  display: flex;
  align-items: center;
  gap: 0.4em;
  font-weight: 500;
}

/* Django's validation error list — was rendering as unstyled plain text;
   now reads clearly as a warning. */
.form-card form ul.errorlist {
  list-style: none;
  margin: 0.3em 0;
  padding: 0.6em 0.9em;
  background: var(--danger-tint);
  border: 1px solid var(--danger);
  border-radius: 6px;
  color: var(--danger);
  font-weight: 600;
  font-size: 0.9rem;
}

/* ---------- tables ---------- */

.table-wrap { overflow-x: auto; margin-bottom: 1.5em; }

.data-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--white);
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 2px 6px rgba(22, 47, 74, 0.06);
}

.data-table th, .data-table td {
  text-align: left;
  padding: 0.75em 1em;
  border-bottom: 1px solid #E1E6EC;
  color: var(--navy-dark);
}

.data-table th {
  background: var(--page-bg);
  color: var(--navy);
  font-family: var(--font-heading);
}

.data-table tbody tr:last-child td { border-bottom: none; }



/* ---------- Onboarding wizard ---------- */

/* .btn is used on anchors too (Back, Start onboarding), which are inline. */
a.btn {
  display: inline-block;
  text-decoration: none;
  line-height: normal;
}

.hint {
  color: var(--slate);
  font-size: 0.9rem;
  margin: 0 0 1.2em;
}

.wizard-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5em;
  list-style: none;
  margin: 0 0 1.5em;
  padding: 0;
  font-family: var(--font-heading);
  font-size: 0.9rem;
}

.wizard-steps li {
  background: var(--white);
  border: 1px solid #E1E6EC;
  border-radius: 999px;
  color: var(--slate);
  padding: 0.35em 1em;
}

.wizard-steps li.done {
  background: var(--mint-bg);
  border-color: var(--teal);
  color: var(--navy-dark);
}

.wizard-steps li[aria-current="step"] {
  background: var(--blue);
  border-color: var(--blue);
  color: var(--white);
}

.wizard-actions {
  display: flex;
  align-items: center;
  gap: 0.75em;
  margin-top: 1.4em;
}

.wizard-cancel {
  margin: 1.2em 0 0;
  padding-top: 1.2em;
  border-top: 1px solid #E1E6EC;
}

.location-row {
  background: var(--page-bg);
  border: 1px solid #E1E6EC;
  border-radius: 10px;
  margin: 0 0 1.2em;
  padding: 0.5em 1.2em 1.2em;
}

.location-row legend {
  color: var(--navy-dark);
  font-family: var(--font-heading);
  font-weight: 600;
  padding: 0 0.5em;
}

/* Reuse the .form-card form field styling inside wizard fieldsets. */
.location-row > p {
  margin: 0.9em 0;
}

.location-row label {
  display: block;
  color: var(--navy-dark);
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.3em;
}

.location-row input[type="text"],
.location-row select {
  width: 100%;
  max-width: 26em;
  border: 1px solid #C9D2DD;
  border-radius: 8px;
  font-family: var(--font-body);
  font-size: 0.95rem;
  padding: 0.55em 0.7em;
}

.location-row ul.errorlist {
  color: var(--danger);
  font-size: 0.85rem;
  list-style: none;
  margin: 0.3em 0 0;
  padding: 0;
}

/* ---------- Django messages ---------- */

.messages {
  list-style: none;
  margin: 0 0 1.5em;
  padding: 0;
}

.message {
  border: 1px solid transparent;
  border-radius: 8px;
  font-size: 0.95rem;
  margin-bottom: 0.6em;
  padding: 0.7em 1em;
}

.message-success {
  background: var(--mint-bg);
  border-color: var(--teal);
  color: var(--navy-dark);
}

.message-info {
  background: var(--blue-tint);
  border-color: var(--blue);
  color: var(--navy-dark);
}

.message-warning {
  background: var(--amber-tint);
  border-color: var(--amber-border);
  color: var(--navy-dark);
}

.message-error {
  background: var(--danger-tint);
  border-color: var(--danger);
  color: var(--danger);
}

/* ---------- Existing-offices filter bar ---------- */

.filter-bar {
  display: flex;
  /* Bottom, not centre: the fields are label-over-control now, so their
     controls only line up with the Reset button along their baseline. */
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 0.6em 0.9em;
  margin: 0 0 1.2em;
}

/* One label stacked over its own control. Beside it, a label spends the bar's
   width on words instead of on the field, which the six-control jobs filter
   could not afford -- it wrapped onto a second row. */
.filter-field {
  display: flex;
  flex-direction: column;
  gap: 0.2em;
  min-width: 0;
}

.filter-bar label {
  color: var(--navy-dark);
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
}

.filter-bar input[type="text"],
.filter-bar input[type="date"],
.filter-bar select {
  border: 1px solid #C9D2DD;
  border-radius: 8px;
  font-family: var(--font-body);
  font-size: 0.9rem;
  padding: 0.4em 0.6em;
}

/* Formset-level errors, rendered outside .form-card's scoped rules. */
.form-card > form > ul.errorlist,
ul.errorlist {
  color: var(--danger);
  font-size: 0.9rem;
  list-style: none;
  margin: 0 0 1em;
  padding: 0;
}

/* ---------- Header profile link ---------- */

.header-actions {
  display: flex;
  align-items: center;
  gap: 0.6em;
}

/* a.header-btn rather than .header-btn: a.btn earlier in this file also sets
   display, and at equal specificity the later rule is the one that wins.
   Border, colour, padding and hover all come from .btn .btn-outline .btn-small,
   so these pills match the Sign out button beside them. */
a.header-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
}

.header-btn svg { flex: 0 0 auto; }

.header-btn:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* ---------- Profile page ---------- */

.readonly-value {
  font-family: var(--font-heading);
  font-size: 1.05rem;
  color: var(--navy-dark);
  margin: 0 0 0.4em;
}

.form-card > form > p > label,
.form-card form .field > label {
  display: block;
  color: var(--navy-dark);
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.3em;
}

.form-card > form > p > input[type="text"],
.form-card > form > p > input[type="password"] {
  width: 100%;
  max-width: 26em;
  border: 1px solid #C9D2DD;
  border-radius: 8px;
  font-family: var(--font-body);
  font-size: 0.95rem;
  padding: 0.55em 0.7em;
}


/* ---------- responsive ----------

   Three steps rather than one phone breakpoint. 60% of the viewport is right
   on a desktop and unusable on a phone, so the container widens as the screen
   narrows, and below 640px the tables stop being tables. */

@media (max-width: 1200px) {
  .app-main { width: 92vw; }
}

@media (max-width: 900px) {
  .app-main { width: 94vw; padding: 1.1em; }
  .view-header { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 640px) {
  .app-main { width: 100%; padding: 0.9em; }

  .site-header { padding: 0.6em 0.9em; }
  .header-actions { gap: 0.4em; }

  /* Tabs scroll sideways instead of wrapping into stacked rows, so the
     content below them does not jump down a line at a time. */
  .tab-row {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .tab-row::-webkit-scrollbar { display: none; }
  .tab-btn { white-space: nowrap; }

  /* Full-width controls: a 420px cap on a 390px screen is just an overflow. */
  .form-card form input[type="text"],
  .form-card form input[type="email"],
  .form-card form input[type="date"],
  .form-card form input[type="time"],
  .form-card form input[type="password"],
  .form-card form select,
  .form-card form textarea,
  .filter-bar input[type="text"],
  .filter-bar select {
    max-width: 100%;
    width: 100%;
  }

  .filter-bar { flex-direction: column; align-items: stretch; }
  .wizard-actions { flex-direction: column; align-items: stretch; }
  .wizard-actions .btn { width: 100%; }
  .form-card form .btn[type="submit"] { width: 100%; }

  /* Tables become one card per row. A nine-column table cannot be read by
     scrolling sideways on a phone; the header text moves into each cell as its
     label instead. */
  .data-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .data-table,
  .data-table tbody,
  .data-table tr,
  .data-table td {
    display: block;
    width: 100%;
  }

  .data-table tr {
    background: var(--white);
    border: 1px solid #E1E6EC;
    border-radius: 10px;
    margin-bottom: 0.75em;
    padding: 0.4em 0.85em;
  }

  .data-table td {
    border: none;
    padding: 0.4em 0;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1em;
    text-align: right;
  }

  .data-table td + td { border-top: 1px solid #F0F3F7; }

  .data-table td::before {
    content: attr(data-label);
    font-weight: 600;
    color: var(--navy-dark);
    text-align: left;
    flex: 0 0 42%;
  }

  /* An action cell carries no label and should not be pushed to one side. */
  .data-table td:not([data-label]) { justify-content: flex-end; }
  .data-table td:not([data-label])::before { content: none; }

  .table-wrap { overflow-x: visible; }
}

/* Sorting control for narrow screens, where the clickable headers are hidden.
   Rendered by the sort script and shown only where it is needed. */
.table-sort { display: none; }

@media (max-width: 640px) {
  .table-sort {
    display: flex;
    align-items: center;
    gap: 0.5em;
    margin: 0 0 0.75em;
  }
  .table-sort label { font-size: 0.85rem; font-weight: 600; color: var(--navy-dark); }
  .table-sort select { flex: 1; }
}

/* ---------- location checkbox list ----------

   Replaces a <select multiple>, which needed ctrl-click to pick more than one
   and was unusable on a touch screen. Each row is a full-width click target. */

.choice-list {
  display: grid;
  gap: 0.25em;
  max-height: 16em;
  overflow-y: auto;
  border: 1px solid #C9D2DD;
  border-radius: 8px;
  padding: 0.4em;
  background: var(--white);
}

.choice-list > div { margin: 0; }

.choice-list label {
  display: flex;
  align-items: center;
  gap: 0.65em;
  padding: 0.55em 0.6em;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 500;
  color: var(--navy-dark);
  /* Overrides .form-card > form > p > label, which is a block with a bottom
     margin meant for the label above a field, not for a row in a list. */
  margin: 0;
  font-size: 0.95rem;
}

.choice-list label:hover { background: var(--blue-tint); }

.choice-list label:focus-within {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

.choice-list input[type="checkbox"] {
  width: auto;
  min-width: 1.05em;
  height: 1.05em;
  margin: 0;
  accent-color: var(--blue);
  flex: 0 0 auto;
}

/* Set by the script rather than :has(), so this works in older browsers too. */
.choice-list .is-selected { background: var(--mint-bg); }

.choice-actions {
  display: flex;
  gap: 0.5em;
  margin: 0.5em 0 0;
}

.choice-empty {
  color: var(--slate);
  font-size: 0.9rem;
  padding: 0.6em;
}

@media (max-width: 640px) {
  /* Bigger touch targets, and the list may fill more of a short screen. */
  .choice-list label { padding: 0.75em 0.6em; }
  .choice-list input[type="checkbox"] { min-width: 1.2em; height: 1.2em; }
  .choice-actions .btn { flex: 1; }
}

/* ---------- table column sizing ----------

   Headers wrapped onto two lines while the cells beside them had room to
   spare, because the browser had no reason to prefer one column over another.
   Headers never wrap; the address column absorbs the slack instead. */

.data-table th { white-space: nowrap; }

/* Short, predictable values: never worth a second line. */
.data-table .col-tight { white-space: nowrap; }

/* The one column with genuinely variable length, so it takes the remaining
   width and wraps there rather than squeezing its neighbours. */
.data-table .col-address { min-width: 16em; }

@media (max-width: 640px) {
  /* Stacked cards give every value the full row, so none of this applies. */
  .data-table th { white-space: normal; }
  .data-table .col-address { min-width: 0; }
}

/* The checkbox rows carry their own label styling, so the group heading above
   them must not be restyled by the rule for labels inside a field wrapper. */
.form-card form .field > label {
  display: block;
  color: var(--navy-dark);
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.3em;
}

.form-card form .field .helptext {
  color: var(--slate);
  font-size: 0.85rem;
}

/* ---------- two-column form layout ----------

   Eight stacked fields ran past the fold on a laptop and buried Save changes.
   Paired up they fit in four rows. One column again on a phone, where two
   would leave neither wide enough to read. */

.field-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 1.4em;
}

.field-grid > .field { min-width: 0; }

/* The inputs cap at 420px for a comfortable line length in a single column;
   inside a grid cell that cap just leaves a ragged gap. */
.form-card form .field-grid input,
.form-card form .field-grid select {
  max-width: 100%;
  width: 100%;
}

/* Three and four to a row, for forms whose fields group into one thought per
   line rather than into pairs. The posting form uses both: role with the two
   dates, then the four times that describe the shape of the day. */
.field-grid-3 { grid-template-columns: repeat(3, 1fr); }
.field-grid-4 { grid-template-columns: repeat(4, 1fr); }

@media (max-width: 900px) {
  /* Four time inputs and their labels do not fit a tablet. Two and two keeps
     the pairs together -- start beside end, lunch beside its length -- which
     is the reading that survives losing the single line. */
  .field-grid-4 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .field-grid { grid-template-columns: 1fr; }
  .field-grid-3 { grid-template-columns: 1fr; }
  .field-grid-4 { grid-template-columns: 1fr; }
}

/* ---------- Jobs tab charts ----------

   Colours were validated rather than chosen by eye. The obvious green/red for
   filled against unfilled fails colour-vision separation badly -- deuteranopia
   sees deltaE 4.1 between them, where 8 is the floor -- so the fill is the
   brand blue and red appears only on the unfilled count, beside a word that
   says what it is. Every value is written out as text as well, so nothing here
   depends on telling two colours apart. */

.chart-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1em;
  margin-bottom: 1.5em;
}

.chart-card { padding: 1.1em 1.2em; }

.chart-title {
  margin: 0 0 0.6em;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--slate);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.chart-figure {
  font-family: var(--font-heading);
  font-size: 2.4rem;
  line-height: 1;
  color: var(--navy-dark);
  margin: 0 0 0.5em;
}

.chart-note {
  margin: 0.7em 0 0;
  font-size: 0.85rem;
  color: var(--slate);
}

.chart-note .is-missed { color: #d03b3b; }

.chart-empty {
  margin: 0;
  font-size: 0.88rem;
  color: var(--slate);
}

/* ---------- meter ---------- */

.meter {
  height: 10px;
  border-radius: 999px;
  background: #E7ECF3;
  overflow: hidden;
}

.meter-fill {
  display: block;
  height: 100%;
  background: var(--blue);
  border-radius: 999px;
}

/* ---------- horizontal bars ---------- */

.bar-list, .column-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.bar-row {
  display: grid;
  grid-template-columns: 8.5em 1fr 2em;
  align-items: center;
  gap: 0.6em;
  margin-bottom: 0.45em;
}

.bar-label { font-size: 0.85rem; color: var(--navy-dark); }

.bar-track {
  background: #E7ECF3;
  border-radius: 4px;
  height: 12px;
  overflow: hidden;
}

.bar-fill {
  display: block;
  height: 100%;
  background: var(--blue);
  border-radius: 4px;
}

.bar-value {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--navy-dark);
  text-align: right;
}

/* ---------- columns ---------- */

.column-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.7em;
  align-items: end;
}

.column {
  display: grid;
  grid-template-rows: auto 90px auto;
  gap: 0.35em;
  justify-items: center;
}

.column-value {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--navy-dark);
}

.column-track {
  display: flex;
  align-items: flex-end;
  width: 100%;
  height: 90px;
  background: #E7ECF3;
  border-radius: 4px;
  overflow: hidden;
}

.column-fill {
  display: block;
  width: 100%;
  background: var(--blue);
  border-radius: 4px 4px 0 0;
}

.column-label {
  font-size: 0.78rem;
  color: var(--slate);
  text-align: center;
}

@media (max-width: 900px) {
  .chart-row { grid-template-columns: 1fr; }
}

/* ---------- duplicate-contact prompt ---------- */

.duplicate-check { margin: 0 0 1em; }
.duplicate-check p { margin: 0 0 0.5em; }

.duplicate-list {
  list-style: none;
  margin: 0 0 0.5em;
  padding: 0;
}

.duplicate-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8em;
  padding: 0.4em 0;
}

@media (max-width: 640px) {
  .duplicate-list li { flex-direction: column; align-items: stretch; }
}

/* Status flag beside a heading, e.g. a contact who can no longer sign in. */
.inline-flag {
  margin: 0 0 0 1em;
  padding: 0.25em 0.7em;
  font-size: 0.8rem;
  border-radius: 999px;
}

/* =========================================================================
   Organization edit page

   A company and its locations on one screen. Eight fields per location laid
   out flat meant a three-site company ran to twenty-four of them with Save
   changes far below the fold, so each location collapses to a summary line.
   Everything here is additive: no rule below restyles an existing class.
   ========================================================================= */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- page context strip ---------- */

.crumbs {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.45em;
  font-size: 0.82rem;
  margin: 0 0 0.7em;
}
.crumbs a { color: var(--blue); font-weight: 600; text-decoration: none; }
.crumbs a:hover { text-decoration: underline; }
.crumbs span { color: var(--slate); }

.page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1em;
  margin: 0 0 0.4em;
}
.page-head h1 { margin: 0; }
.page-title { display: flex; align-items: center; flex-wrap: wrap; gap: 0.75em; }

.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  border-radius: 999px;
  border: 1px solid var(--field-line);
  background: var(--white);
  color: var(--slate);
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.2em 0.6em;
  white-space: nowrap;
}
.pill-main { background: var(--mint-bg); border-color: var(--teal); color: var(--navy-dark); }
.pill-active { background: var(--blue-tint); border-color: var(--blue); color: var(--navy-dark); }
.pill-inactive { background: var(--amber-tint); border-color: var(--amber-border); color: var(--navy-dark); }
.pill-status { font-family: var(--font-heading); font-size: 0.75rem; padding: 0.25em 0.7em; }

.page-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.55em;
  font-size: 0.82rem;
  color: var(--slate);
  margin: 0 0 1.5em;
}
.page-meta strong { color: var(--navy-dark); }
.page-meta .sep { color: var(--field-line); }

/* ---------- location accordion ---------- */

.loc-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1em;
  margin: 0 0 0.3em;
}
.loc-head-row h2 { margin: 0; }
.loc-count { color: var(--slate); font-size: 0.95rem; font-weight: 600; }
.loc-head-tools { display: flex; align-items: center; gap: 0.7em; }

.loc-list { display: flex; flex-direction: column; gap: 0.6em; margin: 0 0 1.1em; }

.loc {
  background: var(--white);
  border: 1px solid var(--line);
  /* The main location is marked by the left edge rather than by another pill
     competing with the three already on the summary line. */
  border-left: 3px solid transparent;
  border-radius: 10px;
  box-shadow: 0 1px 3px rgba(22, 47, 74, 0.05);
  margin: 0;
  padding: 0;
  min-width: 0;
}
.loc.is-main { border-left-color: var(--teal); }
.loc.is-open { border-color: var(--blue); box-shadow: 0 2px 8px rgba(41, 98, 240, 0.10); }
.loc.is-inactive .loc-summary-address { color: var(--slate); }

.loc-head {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.5em;
  padding: 0.35em 0.5em 0.35em 0.75em;
}
.loc.is-open .loc-head {
  background: var(--blue-tint);
  border-bottom: 1px solid var(--field-line);
  border-radius: 9px 9px 0 0;
}

/* The radio sits outside the toggle button on purpose: a control nested in a
   button is neither valid HTML nor independently clickable. */
.loc-pick {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.4em;
  border-radius: 8px;
  cursor: pointer;
  margin: 0;
}
.loc-pick:hover { background: rgba(41, 98, 240, 0.07); }
.loc-pick input[type="radio"] {
  width: 1.05em;
  height: 1.05em;
  margin: 0;
  accent-color: var(--blue);
}

.loc-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.6em;
  width: 100%;
  background: none;
  border: none;
  border-radius: 8px;
  padding: 0.55em 0.6em;
  text-align: left;
  cursor: pointer;
  color: inherit;
}
.loc-toggle:hover { background: rgba(41, 98, 240, 0.05); }
.loc.is-open .loc-toggle:hover { background: rgba(255, 255, 255, 0.45); }

.loc-summary { display: flex; align-items: center; flex-wrap: wrap; gap: 0.55em; min-width: 0; }
.loc-summary-address {
  font-family: var(--font-heading);
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--navy-dark);
}
.loc-summary-place { color: var(--slate); font-size: 0.85rem; }

.loc-toggle-side { display: flex; align-items: center; gap: 0.7em; }
.loc-toggle-word { color: var(--blue); font-size: 0.85rem; font-weight: 600; }
.loc-chevron { transition: transform 0.15s ease; color: var(--blue); flex: 0 0 auto; }
.loc.is-open .loc-chevron { transform: rotate(180deg); }

.loc-body { padding: 0.9em 1em 1em; }

/* Six fields in two rows rather than six stacked ones. The columns are uneven
   because the fields are: a ZIP needs a fraction of an address. */
.loc-grid { display: grid; gap: 0 1em; margin: 0; }
.loc-grid-top { grid-template-columns: 3fr 5fr 4fr; }
.loc-grid-bottom { grid-template-columns: 4fr 3fr 5fr; }

.loc .field { display: flex; flex-direction: column; gap: 0.35em; margin: 0 0 1.1em; min-width: 0; }
.loc .field > label { color: var(--navy-dark); font-size: 0.9rem; font-weight: 600; margin: 0; }
.loc .field input[type="text"],
.loc .field select {
  width: 100%;
  max-width: 100%;
  border: 1px solid var(--field-line);
  border-radius: 8px;
  font-family: var(--font-body);
  font-size: 0.95rem;
  padding: 0.55em 0.7em;
  background: var(--white);
  color: var(--navy-dark);
}
.loc .field ul.errorlist {
  color: var(--danger);
  font-size: 0.85rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.loc-flags {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1.4em;
  border-top: 1px solid var(--line);
  padding-top: 0.9em;
  margin-top: 0.1em;
}
.loc-flag {
  display: flex;
  align-items: center;
  gap: 0.6em;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--navy-dark);
}
.loc-flag label { margin: 0; }

/* Yes/No as one segmented control: the same two answers the select offers,
   reached in one click instead of two. */
.segmented {
  display: inline-flex;
  border: 1px solid var(--field-line);
  border-radius: 8px;
  overflow: hidden;
}
.segmented label {
  margin: 0;
  padding: 0.35em 0.85em;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--slate);
  background: var(--white);
  cursor: pointer;
}
.segmented label + label { border-left: 1px solid var(--field-line); }
/* Hidden rather than removed: the radio is still the control, still what the
   keyboard drives and what the formset reads. */
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented label.is-on { background: var(--blue-tint); color: var(--navy-dark); }
.segmented label.is-off-on { background: var(--amber-tint); color: var(--navy-dark); }
.segmented label:focus-within { outline: 2px solid var(--focus-ring); outline-offset: -2px; }

/* ---------- sticky action bar ---------- */

.action-bar {
  position: sticky;
  bottom: 0;
  z-index: 5;
  background: var(--white);
  border-top: 1px solid var(--line);
  box-shadow: 0 -2px 10px rgba(22, 47, 74, 0.07);
  /* Inside the content width, not bled out to the page edge. The negative
     margins here cancelled .app-main's padding, which made this the one thing
     on the page wider than the cards it belongs to. Rounded to match them,
     since it now reads as one. */
  margin: 1.5em 0 0;
  padding: 0.85em 1.5em;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.8em;
}
.action-note { display: flex; align-items: center; gap: 0.5em; font-size: 0.82rem; color: var(--slate); }
.action-buttons { display: flex; align-items: center; gap: 0.7em; }

@media (max-width: 760px) {
  .loc-grid-top,
  .loc-grid-bottom { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 640px) {
  .loc-grid-top,
  .loc-grid-bottom { grid-template-columns: 1fr; }
  .loc-toggle { align-items: flex-start; }
  /* The chevron and the status pill still say what the row is doing. */
  .loc-toggle-word { display: none; }
  .action-bar {
    margin: 1.2em 0 0;
    padding: 0.8em 0.9em;
    flex-direction: column;
    align-items: stretch;
  }
  .action-buttons { flex-direction: column; }
  .action-buttons .btn { width: 100%; }
}

/* An even split gives the word "Yes" as much room as a company name. */
.field-grid-2-1 { grid-template-columns: 2fr 1fr; }

.loc-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  border-radius: 8px;
  padding: 0.45em;
  margin-right: 0.15em;
  color: var(--slate);
  cursor: pointer;
}
.loc-remove:hover { background: var(--danger-tint); color: var(--danger); }

@media (max-width: 640px) {
  .field-grid-2-1 { grid-template-columns: 1fr; }
}

/* =========================================================================
   Grant access tab

   Organization-first: the picker sits in a bar of its own above two panels,
   because everything below it -- which locations can be ticked, who is
   already there, what the footer sentence says -- follows from that one
   choice. Reuses .choice-list for the checklist itself, and the .pill,
   .page-meta, .segmented and .sr-only blocks defined for the organization
   page above.
   ========================================================================= */


.eyebrow {
  font-family: var(--font-heading);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--slate);
  margin: 0 0 0.7em;
}

/* A fieldset used only to give the segmented control a legend. */
.bare-fieldset { border: none; padding: 0; margin: 0; min-width: 0; }

/* ---------- the organization bar ---------- */

.org-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1.2em;
  background: var(--white);
  border-radius: 12px;
  padding: 1em 1.25em;
  box-shadow: 0 2px 6px rgba(22, 47, 74, 0.06);
  margin: 0 0 1.1em;
}
.org-bar-pick { display: flex; align-items: center; flex-wrap: wrap; gap: 0.9em; }
.org-bar-pick label { font-size: 0.75rem; font-weight: 600; color: var(--navy-dark); margin: 0; }
.org-bar-pick select {
  min-width: 18em;
  border: 1px solid var(--field-line);
  border-radius: 8px;
  padding: 0.55em 0.7em;
  background: var(--white);
  color: var(--navy-dark);
  font-size: 0.95rem;
}
.org-bar-facts { display: flex; align-items: center; flex-wrap: wrap; gap: 0.6em; font-size: 0.82rem; color: var(--slate); }
.org-bar-facts strong { color: var(--navy-dark); }
.org-bar-facts .sep { color: var(--field-line); }
.org-bar-facts .btn { margin-left: 0.3em; }

/* ---------- the two panels ---------- */

.grant-grid { display: grid; grid-template-columns: 1.35fr 1fr; gap: 1.1em; align-items: start; }

.panel {
  background: var(--white);
  border-radius: 12px;
  box-shadow: 0 2px 6px rgba(22, 47, 74, 0.06);
  display: flex;
  flex-direction: column;
  margin: 0 0 1.5em;
}
.panel-body { padding: 1.35em 1.35em 0; }
.panel h2 { margin: 0 0 0.25em; font-size: 1.18rem; }
.panel-rule { border-top: 1px solid var(--line); margin: 1.25em 0 1em; }

/* The action sits on the panel rather than at the foot of the page, so the
   sentence saying what is about to happen is next to the button doing it. */
.panel-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.8em;
  background: var(--page-bg);
  border-top: 1px solid var(--line);
  border-radius: 0 0 12px 12px;
  margin-top: 1.25em;
  padding: 0.85em 1.35em;
}
.panel-foot-note { font-size: 0.82rem; color: var(--slate); }
.panel-foot-note strong { color: var(--navy-dark); }

.person-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.8em 1.15em; }
.person-grid .span-2 { grid-column: 1 / -1; }
.person-grid .field { display: flex; flex-direction: column; gap: 0.35em; margin: 0; min-width: 0; }
.person-grid .field > label { color: var(--navy-dark); font-size: 0.75rem; font-weight: 600; margin: 0; }
.person-grid .field input {
  width: 100%;
  border: 1px solid var(--field-line);
  border-radius: 8px;
  font-size: 0.95rem;
  padding: 0.55em 0.7em;
  background: var(--white);
  color: var(--navy-dark);
}

/* ---------- the location checklist's own heading row ---------- */

.chk-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.7em;
  margin: 0 0 0.5em;
}
.chk-head-label { font-size: 0.75rem; font-weight: 600; color: var(--navy-dark); }
.chk-head-tools { display: flex; align-items: center; gap: 0.8em; }
.chk-count { font-size: 0.78rem; color: var(--slate); }
.chk-empty { color: var(--slate); font-size: 0.85rem; padding: 0.7em 0 0; margin: 0; }

.link-btn {
  background: none;
  border: none;
  padding: 0;
  color: var(--blue);
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
}
.link-btn:hover { text-decoration: underline; }

/* ---------- who is already here ---------- */

.who-list { display: flex; flex-direction: column; gap: 0.5em; }
.who { border: 1px solid var(--line); border-radius: 10px; padding: 0.65em 0.8em; }
.who-top { display: flex; align-items: center; justify-content: space-between; gap: 0.6em; }
.who-name { font-family: var(--font-heading); font-size: 0.9rem; font-weight: 600; color: var(--navy-dark); }
.who-email { color: var(--slate); font-size: 0.78rem; margin: 0.1em 0 0; word-break: break-all; }
/* Kept, not dropped: someone whose access was taken away is exactly who an
   admin is most likely to be re-granting. */
.who.is-revoked { opacity: 0.75; }
.who.is-revoked .who-name { color: var(--slate); }

.who-foot {
  border-top: 1px solid var(--line);
  margin-top: 1em;
  padding-top: 0.9em;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.7em;
  font-size: 0.82rem;
  color: var(--slate);
}

/* ---------- the full list, folded away ---------- */

.all-people { margin-top: 0.5em; }
.all-people-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1em;
  margin: 0 0 0.8em;
}
.all-people-head h2 { margin: 0; }
.people-filter {
  border: 1px solid var(--field-line);
  border-radius: 8px;
  padding: 0.45em 0.7em;
  font-size: 0.9rem;
  min-width: 14em;
}


@media (max-width: 980px) {
  .grant-grid { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
  .person-grid { grid-template-columns: 1fr; }
  .org-bar { flex-direction: column; align-items: stretch; }
  .org-bar-pick { flex-direction: column; align-items: stretch; }
  .org-bar-pick select { min-width: 0; width: 100%; }
  .panel-foot { flex-direction: column; align-items: stretch; }
  .panel-foot .btn { width: 100%; }
}

/* Opening a person for editing, from the card that names them. */
.who-actions { margin: 0.35em 0 0; }
.who-actions .link-btn { font-size: 0.78rem; }

/* Step 2 of onboarding, showing back the main location step 1 captured. Its
   own rule rather than .loc-head's: that one is a grid built around a radio
   and a chevron, and this row has neither. The pills and the two text spans
   are shared with the organization page on purpose -- the same location should
   not look like two different things on two screens. */
.onboard-carried-location {
  border: 1px solid var(--field-line);
  border-left: 3px solid var(--teal);
  border-radius: 8px;
  background: var(--white);
  padding: 0.7em 0.9em;
  margin: 0 0 1em;
}
.onboard-carried-edit {
  margin-left: auto;
  color: var(--blue);
  font-size: 0.82rem;
  font-weight: 600;
}

/* How much of the table a filter is hiding. Blank while everything shows, so
   the bar stays quiet until it is actually doing something. */
.filter-count {
  color: var(--slate);
  font-size: 0.82rem;
  margin-left: auto;
}

/* The read-only history under a company's editable detail. */
.change-history { margin-top: 1.5em; }
.change-history h2 { margin-top: 0; }
