/* The volunteer hub — /volunteer and /volunteer/:id.

   Loaded per-controller from the application layout's feature-stylesheet case, not
   on every page. Everything resolves through --zw-* tokens; there are no colour,
   radius, shadow or timing literals here.

   The 3.0 kit ships NO volunteer comp, so nothing below is a translation of a
   supplied screen. It is the vocabulary the shipped 3.0 surfaces already
   established, applied to the page structure that was already here — events_show.css
   in particular, which is the same shape of page (a detail column, a rail, a
   capacity bar, state pills) and had already solved these problems. Copied from
   rather than reinvented.

   Radii were tabulated from the kit's Event page comp BEFORE any of this was
   written, rather than mapped onto the app's nearest rung — that mapping is what
   turned the last kit screen's pills into rounded rectangles. The comp uses 999px
   sixteen times (chips, tags, buttons, progress tracks), 16px for cards, 14px for
   input shells, 12px for small tiles, and 4px for the one small square. */

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

/* Two measures, deliberately different, following the precedent events_show.css set.
   The index is a browse surface and takes the site header's 80rem: a table of roles
   wants every pixel, and narrower than the menu above it reads as a broken page. The
   detail page is a document, and a body column at 80rem runs well past a comfortable
   line length, so it insets to 64rem — the same call, for the same reason, as the
   event page. */
.zw-vol-page {
  width: 100%;
  margin: 0 auto;
  padding: 28px 1rem 72px;
  color: var(--zw-ink-warm);
}

.zw-vol-page--index  { max-width: 80rem; }
.zw-vol-page--detail { max-width: 64rem; }

@media (min-width: 640px)  { .zw-vol-page { padding-inline: 1.5rem; } }
@media (min-width: 1024px) { .zw-vol-page { padding-inline: 2rem; } }

/* The heading is ToolHeadingComponent, reading .zw-tool-masthead__* out of
   zw_components.css. These pages briefly carried their own .zw-vol-title/.zw-vol-dek
   with the Map's values copied in by hand (#1269) while #1268 was consolidating the
   same numbers into the shared rules -- two copies of one measurement, which is how
   the four tools drifted apart in the first place. Deleted rather than kept in sync. */

.zw-vol-note {
  margin: 14px 0 0;
  font-size: 14px;
  color: var(--zw-muted);
}

.zw-vol-note a {
  font-weight: 600;
  color: var(--zw-blue-700);
}

.zw-vol-note a:hover { color: var(--zw-blue-800); text-decoration: underline; }

/* --- filter chips ---------------------------------------------------------------- */

.zw-vol-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 32px;
}

.zw-vol-filters { display: flex; flex-wrap: wrap; gap: 8px; }

/* Pills, not rounded rectangles — the kit uses 999px for every filter chip, and a
   rectangle here reads as a form control rather than a choice.

   The inactive chip's outline is --zw-border-warm-strong, which is the only warm
   border permitted on an interactive outline; the structural hairlines
   (--zw-border-warm and friends) make a control effectively invisible. */
.zw-vol-filter {
  display: inline-flex;
  align-items: center;
  padding: 8px 16px;
  border: 1px solid var(--zw-border-warm-strong);
  border-radius: var(--zw-radius-pill);
  background: transparent;
  font-size: 14px;
  font-weight: 500;
  color: var(--zw-muted);
  transition: color 200ms var(--zw-ease-out), background-color 200ms var(--zw-ease-out),
              border-color 200ms var(--zw-ease-out);
}

.zw-vol-filter:hover {
  border-color: var(--zw-ink-warm);
  color: var(--zw-ink-warm);
}

/* Blue acts. The selected chip is the only blue thing in this row. */
.zw-vol-filter--on {
  border-color: var(--zw-blue-700);
  background: var(--zw-blue-700);
  color: var(--zw-surface);
}

.zw-vol-filter--on:hover {
  border-color: var(--zw-blue-800);
  background: var(--zw-blue-800);
  color: var(--zw-surface);
}

.zw-vol-stats {
  display: none;
  align-items: center;
  gap: 20px;
  font-size: 14px;
  color: var(--zw-muted);
}

@media (min-width: 640px) { .zw-vol-stats { display: flex; } }

.zw-vol-stats__count { font-weight: 700; color: var(--zw-ink-warm); }

.zw-vol-stats__link {
  font-weight: 600;
  color: var(--zw-blue-700);
}

.zw-vol-stats__link:hover { color: var(--zw-blue-800); text-decoration: underline; }

/* --- row table ------------------------------------------------------------------- */

.zw-vol-thead {
  display: none;
  align-items: center;
  padding: 12px 16px;
  margin-top: 20px;
  border-bottom: 1px solid var(--zw-border-warm);
}

@media (min-width: 1024px) { .zw-vol-thead { display: flex; } }

.zw-vol-thead__label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--zw-quiet);
}

/* Column widths are shared by the header and the rows, so they stay in step. */
.zw-vol-col--main       { flex: 1; min-width: 0; }
.zw-vol-col--category   { width: 7rem; }
.zw-vol-col--commitment { width: 8rem; }
.zw-vol-col--location   { width: 7rem; }
.zw-vol-col--action     { width: 8rem; }

.zw-vol-rows > * + * { border-top: 1px solid var(--zw-border-warm); }

.zw-vol-rows + .zw-vol-rows { border-top: 1px solid var(--zw-border-warm); }

.zw-vol-row {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 20px 16px;
  transition: background-color 200ms var(--zw-ease-out);
}

@media (min-width: 1024px) {
  .zw-vol-row { flex-direction: row; align-items: center; gap: 0; }
}

.zw-vol-row:hover { background: var(--zw-surface-warm); }

/* A priority row carries NO ground of its own. The Priority tag is the marker, and a
   tinted row is the one place it cannot be read: the tag's own ground is
   --zw-blue-50 (#f2f6fa) and the warm panel is #f7f5f1, so a blue tag on a warm row
   loses its shape entirely — and the tag only ever appears on a priority row, so the
   two signals collided by construction rather than occasionally. One marker, on
   white, where it reads. Priority rows also still sort to the top.

   This is also why the tag stays a tint rather than the solid blue badge it used to
   be: these rows end in a filled blue Sign Up button, and a second solid blue pill
   at the other end of the same row reads as a second button. */

.zw-vol-row__main { display: flex; align-items: center; gap: 16px; }

/* 12px, flat. The gradient this replaces had no equivalent anywhere in 3.0. */
.zw-vol-row__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border: 1px solid var(--zw-border-warm);
  border-radius: var(--zw-radius-md);
  background: var(--zw-surface-warm);
  color: var(--zw-blue-700);
}

.zw-vol-row__text { min-width: 0; }

.zw-vol-row__badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.zw-vol-row__title {
  font-size: 15px;
  font-weight: 600;
  color: var(--zw-ink-warm);
  transition: color 200ms var(--zw-ease-out);
}

.zw-vol-row__title:hover { color: var(--zw-blue-700); }

.zw-vol-row__desc {
  margin: 3px 0 0;
  font-size: 14px;
  color: var(--zw-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.zw-vol-row__cell {
  display: none;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: var(--zw-muted);
}

@media (min-width: 1024px) { .zw-vol-row__cell { display: flex; } }

.zw-vol-row__dot {
  width: 6px;
  height: 6px;
  flex-shrink: 0;
  border-radius: var(--zw-radius-pill);
  background: var(--zw-blue-700);
}

.zw-vol-row__action { display: flex; }

@media (min-width: 1024px) { .zw-vol-row__action { justify-content: flex-end; } }

/* --- ongoing band ---------------------------------------------------------------- */

.zw-vol-band {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 32px 0 12px;
}

.zw-vol-band__rule { flex: 1; border-top: 1px solid var(--zw-border-warm); }

/* --- closing panel --------------------------------------------------------------- */

.zw-vol-cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  margin-top: 48px;
  padding: 32px;
}

@media (min-width: 640px) {
  .zw-vol-cta { flex-direction: row; align-items: center; padding: 48px; }
}

.zw-vol-cta__title {
  margin: 0 0 8px;
  font-size: 20px;
  font-weight: 600;
  color: var(--zw-ink-warm);
}

.zw-vol-cta__body {
  margin: 0;
  max-width: 28rem;
  color: var(--zw-muted);
  line-height: 1.6;
}

.zw-vol-cta__actions { display: flex; flex-wrap: wrap; gap: 12px; flex-shrink: 0; }

/* --- detail page ----------------------------------------------------------------- */

.zw-vol-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 24px;
  font-size: 14px;
  font-weight: 600;
  color: var(--zw-blue-700);
}

.zw-vol-back:hover { color: var(--zw-blue-800); }

.zw-vol-head {
  padding-bottom: 32px;
  margin-bottom: 32px;
  border-bottom: 1px solid var(--zw-border-warm);
}

.zw-vol-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}

/* Green measures a state, and this is a span rather than a control — which is also
   how green_is_never_a_button_test tells the two apart. */
.zw-vol-status {
  display: inline-flex;
  align-items: center;
  padding: 5px 12px;
  border-radius: var(--zw-radius-pill);
  background: var(--zw-green-100);
  color: var(--zw-green-900);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.zw-vol-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  margin-top: 18px;
  font-size: 14px;
  color: var(--zw-muted);
}

.zw-vol-head__action { margin-top: 24px; }

/* One column until there is room for two; the rail is fixed so the main column takes
   the slack. */
.zw-vol-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
  align-items: start;
}

@media (min-width: 900px) {
  .zw-vol-layout { grid-template-columns: minmax(0, 1fr) 20rem; gap: 48px; }
}

.zw-vol-main { min-width: 0; display: flex; flex-direction: column; gap: 40px; }

.zw-vol-narrow { max-width: 42rem; }

/* --- sections -------------------------------------------------------------------- */

/* These stay <h2> elements. EyebrowComponent would give the same look, but it renders
   a span and is documented as "not itself a heading" — swapping it in here would drop
   three headings out of the document outline for a purely visual match. */
.zw-vol-section__label {
  margin: 0 0 12px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--zw-quiet);
}

.zw-vol-section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}

.zw-vol-section__head .zw-vol-section__label { margin-bottom: 0; }

.zw-vol-section__aside { font-size: 12px; color: var(--zw-quiet); }

.zw-vol-prose { line-height: 1.7; color: var(--zw-muted); }
.zw-vol-prose p { margin: 0 0 12px; }
.zw-vol-prose p:last-child { margin-bottom: 0; }

/* --- responsibilities ------------------------------------------------------------ */

.zw-vol-duties { display: flex; flex-direction: column; gap: 12px; }

.zw-vol-duties__item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 14px;
  color: var(--zw-muted);
}

/* 4px — the kit's one small square. Rounded to a circle this would read as a radio
   button, i.e. "pick one of these" rather than "here is what the role involves".

   The tick's colour lives here rather than on the markup because an SVG presentation
   attribute does not resolve var(); the glyph inherits it via stroke="currentColor".
   Green, not the mint this replaces: mint is the logo and the 2027 goal bar. */
.zw-vol-duties__tick {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  margin-top: 1px;
  border-radius: var(--zw-radius-xs);
  background: var(--zw-green-100);
  color: var(--zw-green-600);
}

/* --- signed-up confirmation ------------------------------------------------------ */

.zw-vol-confirm {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 24px;
  border: 1px solid var(--zw-green-100);
  border-radius: var(--zw-radius-xl);
  background: var(--zw-surface-warm);
}

@media (min-width: 640px) { .zw-vol-confirm { flex-direction: row; align-items: center; } }

.zw-vol-confirm__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  border-radius: var(--zw-radius-md);
  background: var(--zw-green-100);
  color: var(--zw-green-600);
}

.zw-vol-confirm__body { flex: 1; }

.zw-vol-confirm__title {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--zw-ink-warm);
}

.zw-vol-confirm__when {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--zw-quiet);
}

/* --- shifts ---------------------------------------------------------------------- */

.zw-vol-shifts { display: flex; flex-direction: column; gap: 12px; }

/* Wrapping, not a viewport breakpoint. The row lives inside the main column, which
   at this page's 64rem measure is only ~656px once the rail and gutters are taken
   out — so a `min-width: 1024px` media query switches it to a horizontal row in a
   container that can never fit one, and the date wraps to three lines while the
   capacity track collapses to a sliver. Wrapping asks the right question, because
   what matters is how much room this row has, not how wide the window is. */
.zw-vol-shift {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 20px;
  padding: 20px;
  border: 1px solid var(--zw-border-warm);
  border-radius: var(--zw-radius-xl);
  background: var(--zw-surface);
}

.zw-vol-shift--mine {
  border-color: var(--zw-green-100);
  background: var(--zw-surface-warm);
}

.zw-vol-shift__date {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  flex-shrink: 0;
  border: 1px solid var(--zw-border-warm);
  border-radius: var(--zw-radius-md);
  background: var(--zw-surface-warm);
}

.zw-vol-shift--mine .zw-vol-shift__date { background: var(--zw-surface); }

.zw-vol-shift__month {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--zw-green-600);
}

.zw-vol-shift__day {
  font-size: 20px;
  font-weight: 700;
  line-height: 1;
  color: var(--zw-ink-warm);
}

/* A basis wide enough that the date and time sit on one line. Below it the action
   beside them wraps away rather than crushing this column. */
.zw-vol-shift__body { flex: 1 1 15rem; min-width: 0; }

.zw-vol-shift__when {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
}

.zw-vol-shift__day-label {
  font-size: 14px;
  font-weight: 600;
  color: var(--zw-ink-warm);
}

.zw-vol-shift__time { font-size: 14px; color: var(--zw-quiet); }

.zw-vol-shift__status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  font-size: 12px;
}

.zw-vol-shift__mine-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  color: var(--zw-green-900);
}

.zw-vol-shift__mine-label svg { color: var(--zw-green-600); }

.zw-vol-shift__count { color: var(--zw-quiet); }

/* The bar itself is ProgressBarComponent — green measures, sand warns. Only the
   track's width lives here. */
.zw-vol-shift__capacity {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  margin-top: 8px;
}

/* Fixed, and allowed to wrap its label away rather than shrink: a capacity bar that
   has been squeezed to 20px is no longer measuring anything. */
.zw-vol-shift__track { flex: 0 0 auto; width: 11rem; max-width: 100%; }

.zw-vol-shift__fill-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--zw-muted);
  white-space: nowrap;
}

.zw-vol-shift__fill-label--warn { color: var(--zw-sand-ink); }

/* margin-left: auto keeps the control against the right edge while there is room
   beside the body, and is simply ignored once it has wrapped to its own line. */
.zw-vol-shift__action { display: flex; flex: 0 0 auto; margin-left: auto; }

/* Sand warns about a state; the control beside it is still blue, because blue acts.
   This is a span. */
.zw-vol-waiting {
  display: inline-flex;
  align-items: center;
  padding: 8px 14px;
  border-radius: var(--zw-radius-pill);
  background: var(--zw-sand-tint);
  color: var(--zw-sand-ink);
  font-size: 13px;
  font-weight: 600;
}

.zw-vol-waiting-group {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

.zw-vol-waiting-group__cancel {
  font-size: 12px;
  color: var(--zw-quiet);
}

.zw-vol-waiting-group__cancel:hover { color: var(--zw-ink-warm); }

/* button_to wraps its button in a form, and a block-level form between a flex
   container and its button would swallow the layout. These carry the sizing so the
   button inside can stay the shape the design system gives it. */
.zw-vol-post-form { width: 100%; }

/* --- guest signup ---------------------------------------------------------------- */

.zw-vol-guest {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

@media (min-width: 640px) { .zw-vol-guest { flex-direction: row; align-items: center; } }

/* Explicit border-width and padding. form_field_border_test cannot help here — it
   keys off the border-stone-300 + shadow-sm idiom, which these fields never used —
   so the guard against a field collapsing to a borderless ~24px pill is that this
   rule is simply correct. 14px is the kit's input-shell rung. */
.zw-vol-guest__field {
  flex: 1;
  min-width: 0;
  padding: 12px 16px;
  border: 1px solid var(--zw-border-warm-strong);
  border-radius: var(--zw-radius-lg);
  background: var(--zw-surface);
  font-size: 14px;
  color: var(--zw-ink-warm);
}

.zw-vol-guest__field::placeholder { color: var(--zw-quiet); }

.zw-vol-guest__field:focus {
  outline: 2px solid var(--zw-blue-700);
  outline-offset: 1px;
  border-color: var(--zw-blue-700);
}

/* Inside a shift row this form is the widest thing competing for the line, so it is
   what decides whether the row wraps. Its fields flex rather than taking a fixed
   9rem: fixed widths were what forced the row to overflow its column at every
   viewport, and they also cannot fit two-up on a phone. */
.zw-vol-guest--inline {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 8px;
  margin-left: auto;
}

.zw-vol-guest--inline .zw-vol-guest__field {
  flex: 1 1 8rem;
  min-width: 0;
  padding: 9px 12px;
}

/* --- rail ------------------------------------------------------------------------ */

.zw-vol-rail { display: flex; flex-direction: column; gap: 20px; }

/* White, not --zw-panel. The kit's sidebar cards are white; a panel-toned card in
   the rail flattens it against the page. */
.zw-vol-card {
  padding: 24px;
  border: 1px solid var(--zw-border-warm);
  border-radius: var(--zw-radius-xl);
  background: var(--zw-surface);
}

.zw-vol-card__label {
  margin: 0 0 16px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--zw-quiet);
}

.zw-vol-info { margin: 0; }

.zw-vol-info__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 14px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--zw-border-warm);
}

.zw-vol-info__row:last-child {
  padding-bottom: 0;
  margin-bottom: 0;
  border-bottom: 0;
}

.zw-vol-info__term { font-size: 14px; color: var(--zw-muted); }

.zw-vol-info__value {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  text-align: right;
  color: var(--zw-ink-warm);
}

.zw-vol-coord {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}

/* A flat avatar token. The gradient this replaces was the only one on the page and
   has no equivalent in 3.0; --zw-avatar-1..6 exist for exactly this. */
.zw-vol-coord__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  border-radius: var(--zw-radius-pill);
  background: var(--zw-avatar-1);
  color: var(--zw-surface);
  font-size: 14px;
  font-weight: 700;
}

.zw-vol-coord__name {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--zw-ink-warm);
}

.zw-vol-coord__role {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--zw-quiet);
}
