/* HR Guru application styles.
 *
 * Layered on top of vendored Pico. Every colour here is derived from a Pico
 * custom property (or `color-mix`ed from one) so the light/dark switch Pico
 * drives from `prefers-color-scheme` keeps working — never introduce a literal
 * hex value in this file, except through a per-theme token declared in
 * section 0 (currently one: the warning amber, which Pico has no hue for).
 *
 * Sections:
 *   0. Tokens           — two supporting text sizes and the warning amber
 *   1. Action rows      — undo Pico's block-level buttons for grouped actions,
 *                         and the filter bar over the employee list
 *   2. Record lists     — <dl> as a label/value grid
 *   3. Badges           — status pills
 *   4. Empty states     — what to show instead of an empty table
 *   5. Kanban           — columns, cards, horizontal overflow
 *   6. Public apply     — the one externally-facing page
 *   7. Flash messages   — Django message tags as tinted articles
 *   8. Nav              — dropdown groups in the top bar, the phone menu
 *   9. Employee list    — page head, headline counts, stacked rows on phones
 */

/* ----------------------------------------------------------------- 0. tokens
 * The app's few additions to Pico's vocabulary. Two supporting text sizes —
 * Pico has headings and body but no scale below <small>, so badges, hints and
 * card metadata each invented a size; these two replace them all. And one
 * semantic colour Pico lacks: a warning amber. The amber is this file's only
 * literal colour, and the exception is deliberate — Pico's mark token, the
 * nearest hue, is pale amber in light but *blue* in dark, so no derivation
 * survives the theme switch. It is defined per-theme exactly the way Pico
 * defines its own tokens (attribute override beats media query).
 */
:root {
  --text-xs: 0.75rem;
  --text-sm: 0.85rem;
  --hrg-warning: #94660a;
}

[data-theme="dark"] {
  --hrg-warning: #e0b04b;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --hrg-warning: #e0b04b;
  }
}

/* A small uppercase label — the style the kanban column headers established,
 * promoted for reuse over section tables (Contracts, Documents). */
.overline {
  margin-bottom: 0.6rem;
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pico-muted-color);
}

/* ---------------------------------------------------------------- 1. actions
 * Pico sets buttons to full width in flow context, so any two of them stack
 * into slabs. `.actions` puts a group back on one line. The selector must be a
 * descendant one: several call sites wrap a single button in an inline <form>
 * for CSRF, so a child selector would match the form and miss the button.
 */
.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  margin-bottom: var(--pico-block-spacing-vertical);
}

.actions form {
  margin: 0;
}

.actions button,
.actions a[role="button"],
.actions input[type="submit"] {
  width: auto;
  margin: 0;
}

/* A row whose actions are secondary to something else on the same line. */
.actions--inline {
  margin-bottom: 0;
}

/* Dense rows — table cells, card footers — use the control size the kanban
 * cards established. The disclosure (`<details>`) variant keeps a rarely-used
 * form (waive-with-reason) folded to one small summary until it is needed. */
.actions--compact button,
.actions--compact [role="button"],
.actions--compact input[type="submit"] {
  padding: 0.2rem 0.6rem;
  font-size: var(--text-xs);
}

.actions--compact input[type="text"] {
  flex: 1 1 8rem;
  height: auto;
  padding: 0.2rem 0.6rem;
  font-size: var(--text-xs);
}

.actions details {
  margin: 0;
  padding: 0;
}

.actions details summary {
  margin: 0;
}

.actions details[open] summary {
  margin-bottom: 0.4rem;
}

/* An input sharing a row with its button — a copy-this-URL field, a filter box.
 * Pico keeps inputs at width:100%, which eats the whole flex basis and wraps
 * the button onto its own line; this lets the input flex instead. */
.actions input[type="text"],
.actions input[type="search"],
.actions input[type="url"] {
  flex: 1 1 20rem;
  width: auto;
  margin: 0;
}

/* A control that qualifies the action next to it — an effective date, an exit
 * reason. Pico's bottom margin would sit it off the button's baseline. */
.actions select,
.actions input[type="date"] {
  margin-bottom: 0;
}

/* A filter bar over a list — the employee register. Pico lays each control out
 * as a full-width block, so a search box and three selects became four slabs
 * that pushed the table below the fold. Here they share one row: the search
 * takes the larger share, the selects split the rest evenly, and each select carries a small overline label so the row scans as one
 * toolbar rather than a form. Wraps to two lines on narrow viewports. */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: flex-end;
  margin-bottom: var(--pico-block-spacing-vertical);
}

.filters input[type="search"] {
  flex: 2 1 14rem;
  width: auto;
  margin: 0;
}

.filters label {
  flex: 1 1 9rem;
  margin: 0;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pico-muted-color);
}

.filters select {
  width: 100%;
  margin: 0.25rem 0 0;
  font-size: var(--text-sm);
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  color: var(--pico-form-element-color);
}

@media (max-width: 40rem) {
  .filters input[type="search"] {
    flex-basis: 100%;
  }

  .filters label {
    flex: 1 1 calc(50% - 1rem);
  }
}

/* ----------------------------------------------------------- 2. record lists
 * Record views (employee, application) use <dl>. Pico leaves it as an indented
 * dictionary list; this makes it a two-column grid that collapses on narrow
 * viewports.
 */
dl {
  display: grid;
  grid-template-columns: minmax(8rem, 14rem) 1fr;
  gap: 0.4rem 1.5rem;
  margin-bottom: var(--pico-block-spacing-vertical);
}

dl > dt {
  margin: 0;
  font-weight: 500;
  color: var(--pico-muted-color);
}

dl > dd {
  margin: 0;
}

@media (max-width: 40rem) {
  dl {
    grid-template-columns: 1fr;
    gap: 0 0;
  }

  dl > dt {
    margin-top: 0.75rem;
    font-size: 0.85em;
  }
}

/* ----------------------------------------------------------------- 3. badges
 * Status is the column people scan. A badge separates it from the surrounding
 * text without adding a colour vocabulary the app doesn't otherwise have: the
 * tint is mixed from the text colour, so it inherits the theme.
 */
.badge {
  display: inline-block;
  padding: 0.1em 0.55em;
  border-radius: 1em;
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1.6;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: var(--pico-muted-color);
  background: color-mix(in srgb, currentColor 12%, transparent);
}

.badge--positive {
  color: var(--pico-ins-color);
}

.badge--negative {
  color: var(--pico-del-color);
}

.badge--muted {
  color: var(--pico-muted-color);
}

.badge--warning {
  color: var(--hrg-warning);
}

.badge--accent {
  color: var(--pico-primary);
}

/* An offer's wording against the clause library's (signing/_wording_diff.html).
 * Pico's own ins/del tokens, so both themes read correctly. */
.wording-diff {
  font-size: var(--text-sm);
  white-space: pre-wrap;
}

.wording-diff__add {
  color: var(--pico-ins-color);
}

.wording-diff__del {
  color: var(--pico-del-color);
}

.wording-diff__hunk,
.wording-diff__file {
  color: var(--pico-muted-color);
}

/* ----------------------------------------------------------- 4. empty states
 * An empty table with headers reads as a broken page. `.empty-state` replaces
 * the table entirely and points at the action that fills it.
 */
.empty-state {
  padding: 2.5rem 1rem;
  text-align: center;
  border: 1px dashed var(--pico-muted-border-color);
  border-radius: var(--pico-border-radius);
  margin-bottom: var(--pico-block-spacing-vertical);
}

.empty-state p {
  margin: 0 0 1rem;
  color: var(--pico-muted-color);
}

.empty-state p:last-child {
  margin-bottom: 0;
}

.empty-state .actions {
  justify-content: center;
  margin-bottom: 0;
}

/* ----------------------------------------------------------------- 5. kanban
 * Columns need a visible container: the board's whole interaction is drag and
 * drop, and an unstyled empty column offers no drop target at all.
 */
/* Boards run wider than the viewport. A persistent thin scrollbar is the
 * honest overflow cue: `scrollbar-width: thin` plus an explicit
 * `scrollbar-color` opts out of overlay scrollbars, so the track shows exactly
 * when there is somewhere to scroll and takes no space when there isn't. */
.kanban-board {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  overflow-x: auto;
  padding-bottom: 0.5rem;
  margin-bottom: var(--pico-block-spacing-vertical);
  scrollbar-width: thin;
  scrollbar-color: var(--pico-muted-border-color) transparent;
}

.kanban-board::-webkit-scrollbar {
  height: 0.5rem;
}

.kanban-board::-webkit-scrollbar-thumb {
  border-radius: 1rem;
  background: var(--pico-muted-border-color);
}

/* 14rem keeps the four-stage Employment spine inside a 1200px container; at
 * 15rem it overflowed by ~45px and clipped the last column's count for nothing.
 * Longer boards (hiring has six stages) still scroll, as they should. */
.kanban-column {
  flex: 0 0 14rem;
  box-sizing: border-box;
  padding: 0.75rem;
  border-radius: var(--pico-border-radius);
  background: var(--pico-card-sectioning-background-color);
}

.kanban-column-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.6rem;
}

.kanban-column-header h4 {
  margin: 0;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--pico-muted-color);
}

.kanban-count {
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--pico-muted-color);
}

.kanban-cards {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 4rem;
}

/* Cards stack a title, optional metadata, and any number of action rows, and
 * not every card has every part. A flex column with one gap spaces them evenly
 * whatever the combination, so no partial needs its own margin modifier. */
.kanban-card {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.4rem;
  box-sizing: border-box;
  margin: 0;
  padding: 0.7rem 0.8rem;
  cursor: grab;
}

.kanban-card:active {
  cursor: grabbing;
}

.kanban-card-title {
  display: block;
  margin: 0;
  font-weight: 600;
  line-height: 1.3;
}

/* The date under a card title, and any other card metadata. */
.kanban-card-meta {
  display: block;
  margin: 0;
  font-size: var(--text-xs);
  line-height: 1.4;
  color: var(--pico-muted-color);
}

/* The gap above owns the spacing between card rows; children contribute none. */
.kanban-card form,
.kanban-card .actions {
  margin: 0;
}

.kanban-card button,
.kanban-card a[role="button"] {
  width: auto;
  margin: 0;
  padding: 0.2rem 0.6rem;
  font-size: var(--text-xs);
}

.kanban-card select,
.kanban-card input[type="date"] {
  margin-bottom: 0.4rem;
  padding: 0.25rem 0.5rem;
  font-size: var(--text-xs);
  height: auto;
}

/* Plain links stay text-width so they read as secondary to the buttons that
 * actually move the card on. */
.kanban-card a:not([role="button"]) {
  align-self: flex-start;
  font-size: var(--text-sm);
}

/* Retained as the board's positioning context. Deliberately carries no edge
 * fade: an unconditional fade greys out the last column on boards that fit,
 * claiming an overflow that isn't there. The scrollbar above does that job. */
.kanban-scroller {
  position: relative;
}

#kanban-error {
  color: var(--pico-del-color);
  margin: 0 0 0.5rem;
}

/* ----------------------------------------------------------- 6. public apply
 * The application form is the only page someone outside the company sees.
 */
.apply-masthead {
  padding: 1rem 0;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--pico-muted-border-color);
}

.apply-masthead .container {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: baseline;
  justify-content: space-between;
}

.apply-masthead strong {
  color: var(--pico-h1-color);
  letter-spacing: 0.02em;
}

.apply-masthead span {
  font-size: var(--text-sm);
  color: var(--pico-muted-color);
}

/* The closed and thanks pages: one narrow column. */
.apply-body {
  max-width: 34rem;
  margin: 0 auto;
}

.apply-footer {
  margin-top: 2.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--pico-muted-border-color);
  font-size: var(--text-sm);
  color: var(--pico-muted-color);
}

/* The application page: a hero, then the advert beside the form card. */
.apply-hero {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem;
  padding-bottom: 2rem;
  margin-bottom: 2rem;
  border-bottom: 1px solid var(--pico-muted-border-color);
}

.apply-hero h1 {
  margin: 0;
  line-height: 1.15;
}

.apply-pill {
  padding: 0.25rem 0.625rem;
  border-radius: 1rem;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--pico-primary);
  background: color-mix(in srgb, var(--pico-primary) 8%, transparent);
}

.apply-layout {
  display: grid;
  gap: 2.5rem;
  align-items: start;
  padding-bottom: 4rem;
}

@media (min-width: 1024px) {
  .apply-layout {
    grid-template-columns: minmax(0, 1fr) minmax(20rem, 26rem);
    gap: 3rem;
  }

  .apply-layout aside {
    position: sticky;
    top: 1.5rem;
  }
}

.apply-advert {
  max-width: 42rem;
}

.apply-advert > p:first-child {
  font-size: 1.125rem;
}

.apply-advert h2 {
  margin: 2.5rem 0 0.75rem;
  font-size: 1.5rem;
}

.apply-ticks {
  padding: 0;
}

.apply-ticks li {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  list-style: none;
}

.apply-ticks svg {
  flex: none;
  margin-top: 0.2rem;
  color: var(--pico-primary);
}

.apply-notice {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  margin-top: 2rem;
  padding: 0.875rem 1rem;
  border: 1px solid var(--hrg-warning);
  border-radius: var(--pico-border-radius);
  background: color-mix(in srgb, var(--hrg-warning) 8%, transparent);
  color: var(--hrg-warning);
  font-size: var(--text-sm);
  font-weight: 500;
}

.apply-notice svg {
  flex: none;
  margin-top: 0.1rem;
}

.apply-card {
  margin: 0;
}

.apply-card header h2 {
  margin: 0;
  font-size: 1.375rem;
}

.apply-card header p {
  margin: 0.375rem 0 0;
}

.apply-card textarea {
  min-height: 7rem;
}

.apply-card button[type="submit"] {
  width: 100%;
}

.apply-card footer p {
  margin: 0;
  font-size: var(--text-sm);
}

.apply-required {
  color: var(--pico-primary);
}

.apply-optional {
  display: inline;
  font-weight: 400;
}

.apply-privacy {
  text-align: center;
}

.field-hint {
  display: block;
  font-size: var(--text-sm);
  color: var(--pico-muted-color);
}

/* Django renders validation errors as <ul class="errorlist">. Left alone it is
 * a bulleted list in body colour, which reads as content rather than as a
 * problem to fix. Global: form errors look the same wherever they appear. */
.errorlist {
  margin: 0 0 0.5rem;
  padding: 0;
  list-style: none;
  color: var(--pico-del-color);
  font-size: var(--text-sm);
}

.errorlist.nonfield {
  padding: 0.6rem 0.8rem;
  border-radius: var(--pico-border-radius);
  background: color-mix(in srgb, var(--pico-del-color) 10%, transparent);
}

/* The starter page (hiring/starter.html): a candidate's private checklist. */
.starter-item {
  margin: 1.5rem 0;
}

.starter-item__head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
  justify-content: space-between;
}

.starter-item__head h2 {
  margin: 0;
  font-size: 1.25rem;
}

/* --------------------------------------------------------- 7. flash messages
 * Django's message tags (`success`, `warning`, `error`, `info`) land on the
 * article as classes but carried no styling, so every outcome read the same.
 * Same idiom as `.errorlist.nonfield`: a tint of the semantic colour, with a
 * solid left edge so the colour registers even on a wide, mostly-empty row.
 */
.message {
  --message-color: var(--pico-muted-color);
  padding: 0.7rem 1rem;
  border-left: 0.2rem solid var(--message-color);
  border-radius: var(--pico-border-radius);
  background: color-mix(in srgb, var(--message-color) 10%, transparent);
  box-shadow: none;
}

.message.success {
  --message-color: var(--pico-ins-color);
}

.message.warning {
  --message-color: var(--hrg-warning);
}

.message.error {
  --message-color: var(--pico-del-color);
}

/* --------------------------------------------------------------------- 8. nav
 * The top bar groups its tail into two Pico dropdowns: the three lifecycle
 * boards, and the session (identity, admin-only manage link, log out). Both
 * sit at the bar's right edge, so their panels open right-aligned — Pico's
 * default left alignment would push them past the viewport.
 */
nav details.dropdown ul {
  left: auto;
  right: 0;
}

/* The log out control is a POST form, not a link, but it lives in a dropdown
 * list — dress the button as the row of a menu, matching Pico's item links. */
nav details.dropdown li form {
  margin: 0;
}

/* Pico pads the li and has item links reclaim it with negative margins so the
 * hover fill spans the row edge to edge; the button copies that geometry. */
nav details.dropdown li form button {
  width: calc(100% + var(--pico-form-element-spacing-horizontal) * 2);
  margin: calc(var(--pico-form-element-spacing-vertical) * -0.5)
    calc(var(--pico-form-element-spacing-horizontal) * -1);
  padding: calc(var(--pico-form-element-spacing-vertical) * 0.5)
    var(--pico-form-element-spacing-horizontal);
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: var(--pico-dropdown-color);
  font-size: inherit;
  text-align: left;
}

nav details.dropdown li form button:hover,
nav details.dropdown li form button:focus-visible {
  background: var(--pico-dropdown-hover-background-color);
}

/* The bar under the nav, and its phone variant: below 40rem the section links
 * no longer fit on one row, so the full bar hides and the same links fold into
 * one "Menu" dropdown (base.html renders both; only one is ever displayed). */
.app-nav-wrap {
  margin-bottom: 2rem;
  border-bottom: 1px solid var(--pico-muted-border-color);
}

.nav-role {
  font-size: var(--text-sm);
  color: var(--pico-muted-color);
}

.nav-compact {
  display: none;
}

@media (max-width: 40rem) {
  .app-nav-wrap {
    margin-bottom: 1.25rem;
  }

  .nav-full {
    display: none;
  }

  .nav-compact {
    display: flex;
  }
}

.app-footer {
  padding-block: 2rem;
}

.app-footer small {
  color: var(--pico-muted-color);
}

/* ------------------------------------------------------- 9. employee list
 * The home page: a heading with its one action, three headline counts, then
 * the filtered table. On phones each row stacks into two lines — name and
 * status, then role and start date — and drops Team and Reports to, which a
 * phone has no width for; they stay one tap away on the employee's page. */
.page-head {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 1.5rem;
}

.page-head hgroup {
  margin: 0;
}

.page-head h1 {
  margin: 0;
  font-size: 1.75rem;
}

.page-head .actions {
  margin: 0;
}

.stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
  margin-bottom: 2rem;
}

.stat {
  margin: 0;
  padding: 1rem 1.25rem;
}

.stat .overline {
  margin-bottom: 0.25rem;
}

.stat strong {
  display: block;
  font-size: 2rem;
  line-height: 1.1;
  color: var(--pico-h1-color);
}

.stat small {
  display: block;
  margin-top: 0.375rem;
  font-size: var(--text-sm);
  color: var(--pico-muted-color);
}

.stat--warning strong {
  color: var(--hrg-warning);
}

.results-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 0.25rem;
  font-size: var(--text-sm);
  color: var(--pico-muted-color);
}

.cell-muted {
  color: var(--pico-muted-color);
}

.cell-sub {
  display: block;
  font-size: var(--text-xs);
  color: var(--pico-muted-color);
}

.col-name a {
  font-weight: 600;
}

.col-name .badge {
  margin-left: 0.375rem;
  vertical-align: middle;
}

@media (max-width: 40rem) {
  .page-head .actions,
  .page-head .actions a {
    width: 100%;
  }

  .stats {
    gap: 0.5rem;
    margin-bottom: 1.25rem;
  }

  .stat {
    padding: 0.75rem;
  }

  .stat .overline {
    font-size: var(--text-xs);
    letter-spacing: 0.03em;
  }

  .stat strong {
    font-size: 1.5rem;
  }

  .stat small {
    display: none;
  }

  table.stack thead {
    display: none;
  }

  table.stack tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.125rem 1rem;
    padding: 0.75rem 0;
    border-bottom: var(--pico-border-width) solid var(--pico-table-border-color);
  }

  table.stack td {
    padding: 0;
    border: 0;
    background: none;
  }

  table.stack .col-team,
  table.stack .col-manager {
    display: none;
  }

  table.stack .col-name {
    grid-column: 1;
    grid-row: 1;
  }

  table.stack .col-status {
    grid-column: 2;
    grid-row: 1;
    text-align: right;
  }

  table.stack .col-role {
    grid-column: 1;
    grid-row: 2;
    font-size: var(--text-sm);
    color: var(--pico-muted-color);
  }

  table.stack .col-start {
    grid-column: 2;
    grid-row: 2;
    text-align: right;
    font-size: var(--text-sm);
  }

  table.stack .col-start .cell-sub {
    display: inline;
    margin-left: 0.25rem;
  }

  table.stack .col-empty {
    grid-column: 1 / -1;
  }
}

