/* Design System 3.0 — shared components.
 *
 * The public counterpart to admin_components.css. Every value here is a token; there
 * are no colour, radius, shadow or timing literals, because a literal is how a
 * component stops following the palette.
 *
 * Linked in the core set in app/views/layouts/application.html.erb, so it is present
 * on every page, and in layouts/component_preview.html.erb so Lookbook resolves the
 * same CSS the app does. A preview that resolves different CSS looks authoritative
 * while being wrong.
 *
 * Durations map to the kit's names: --dur-1 = press (120ms), --dur-2 = ui (200ms),
 * --dur-3 = card (320ms).
 */

/* ---- Button -------------------------------------------------------------------
 * Blue is the only button colour; green is never a button. So the four variants
 * differ in weight, not hue: a filled blue, a white shell, blue on a blue tint, and
 * bare text.
 *
 * Sized by fixed height rather than padding, which is what makes buttons in a row
 * line up. 10px radius comes from --zw-radius-sm; buttons used to hardcode it.
 */
.zw-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--zw-radius-sm);
  font-family: var(--zw-font-sans);
  font-weight: 600;
  letter-spacing: -0.01em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background var(--dur-2) var(--zw-ease-out),
    box-shadow var(--dur-2) var(--zw-ease-out),
    color var(--dur-2) var(--zw-ease-out),
    transform var(--dur-1) var(--zw-ease-out);
}

.zw-btn--md { height: 44px; padding: 0 20px; font-size: 15px; }
.zw-btn--sm { height: 36px; padding: 0 14px; font-size: 14px; }
.zw-btn--full { width: 100%; }

.zw-btn:active:not(:disabled) { transform: scale(0.98); }

.zw-btn:disabled,
.zw-btn[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
}

.zw-btn--primary { background: var(--zw-blue-700); color: #fff; }
.zw-btn--primary:hover:not(:disabled) { background: var(--zw-blue-800); }

.zw-btn--secondary {
  background: var(--zw-surface);
  color: var(--zw-ink);
  border-color: var(--zw-border-warm-2);
}
.zw-btn--secondary:hover:not(:disabled) { box-shadow: var(--zw-shadow-card); }

.zw-btn--quiet { background: var(--zw-blue-50); color: var(--zw-blue-700); }
.zw-btn--quiet:hover:not(:disabled) { background: var(--zw-blue-100); }

/* Not in the kit, which stops at three variants. Kept because the site header's
 * "Sign In" is a text link sitting beside a filled "Sign Up", and the kit's quiet
 * variant is a filled control — using it there would give the header two buttons of
 * near-equal weight and lose the hierarchy. */
.zw-btn--ghost { background: transparent; color: var(--zw-ink-3); }
.zw-btn--ghost:hover:not(:disabled) { color: var(--zw-ink); }

/* Declared AFTER the variants deliberately. `.zw-btn--secondary:hover` also sets
 * box-shadow and carries the same specificity (0,2,0), so with the focus ring declared
 * earlier a keyboard-focused secondary button lost its ring the moment the pointer
 * crossed it. Source order is the only thing separating them — keep this last. */
.zw-btn:focus-visible {
  outline: none;
  box-shadow: var(--zw-shadow-ring);
}

/* ---- Tag ----------------------------------------------------------------------
 * A pill label for place, category, or tool ownership. Pills are only ever tags and
 * segmented controls, which is why a button is never pill-shaped.
 *
 * Text uses each tool's -ink companion rather than its stroke: the strokes do not
 * reach 4.5:1 on their own tints at this size. See brand_tokens.css and
 * test/assets/component_tone_contrast_test.rb.
 */
.zw-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: var(--zw-radius-pill);
  font-size: 14px;
  line-height: 1.2;
  white-space: nowrap;
}

.zw-tag--blue     { color: var(--zw-blue-700);          background: var(--zw-blue-50); }
.zw-tag--green    { color: var(--zw-green-700);         background: var(--zw-green-50); }
.zw-tag--sand     { color: var(--zw-sand-ink);          background: var(--zw-sand-tint); }
.zw-tag--neutral  { color: var(--zw-ink-3);             background: var(--zw-border-warm-grid); }
.zw-tag--actions  { color: var(--zw-tool-actions-ink);  background: var(--zw-tool-actions-tint); }
.zw-tag--calendar { color: var(--zw-tool-clay);         background: var(--zw-tool-calendar-tint); }
.zw-tag--map      { color: var(--zw-tool-map-ink);      background: var(--zw-tool-map-tint); }
.zw-tag--wiki     { color: var(--zw-tool-wiki-ink);     background: var(--zw-tool-wiki-tint); }

/* ---- Eyebrow ------------------------------------------------------------------
 * The small uppercase label above a headline or on a dark field. Always 13px,
 * uppercase, 0.06em. Never the serif, never bold.
 */
.zw-eyebrow {
  display: block;
  font-size: var(--zw-text-xs);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: var(--zw-tracking-eyebrow);
  text-transform: uppercase;
}

.zw-eyebrow--paper { color: var(--zw-quiet); }
.zw-eyebrow--dark  { color: var(--zw-base-quiet); }
.zw-eyebrow--green { color: var(--zw-green-300); }

/* ---- Section heading ----------------------------------------------------------
 * Eyebrow / serif headline / lead. One of the three places Petrona is allowed.
 * Hero is the centred page opener; every headline below it is a section.
 */
.zw-serif { font-family: var(--zw-font-serif); font-weight: 600; }

.zw-section-heading__title {
  margin: 0;
  color: var(--zw-ink);
  text-wrap: balance;
}

.zw-section-heading__lead {
  margin: 0;
  color: var(--zw-ink-3);
  font-size: 19px;
  line-height: 1.6;
}

.zw-section-heading__title + .zw-section-heading__lead { margin-top: var(--space-3); }
.zw-eyebrow + .zw-section-heading__title { margin-top: var(--space-2); }

/* Each layer is narrower than the one above it — 700 then 580 — which is what stops a
 * centred hero reading as a wall of text. */
.zw-section-heading--center {
  text-align: center;
  margin-inline: auto;
}
.zw-section-heading--center .zw-section-heading__title { max-width: 700px; margin-inline: auto; }
.zw-section-heading--center .zw-section-heading__lead  { max-width: 580px; margin-inline: auto; }

.zw-section-heading--left { text-align: left; }

.zw-section-heading--hero .zw-section-heading__title {
  font-size: clamp(44px, 5.9vw, 72px);
  line-height: 1.03;
  letter-spacing: -0.022em;
}

.zw-section-heading--section .zw-section-heading__title {
  font-size: 35px;
  line-height: 1.14;
  letter-spacing: -0.015em;
}

/* ---- Segmented control --------------------------------------------------------
 * A two-or-three-way pill switch. The selected segment is a white pill; unselected
 * text is quiet. Selection is conveyed by aria-selected, not by the pill alone.
 */
.zw-segmented {
  display: inline-flex;
  gap: 2px;
  padding: 4px;
  background: var(--zw-border-warm-grid);
  border-radius: var(--zw-radius-pill);
}

.zw-segmented__option {
  padding: 8px 16px;
  border: none;
  border-radius: var(--zw-radius-pill);
  background: transparent;
  color: var(--zw-ink-3);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition:
    background var(--dur-2) var(--zw-ease-out),
    color var(--dur-2) var(--zw-ease-out);
}

.zw-segmented__option--selected {
  background: var(--zw-surface);
  color: var(--zw-ink);
  box-shadow: var(--zw-shadow-hairline);
}

.zw-segmented__option:focus-visible {
  outline: none;
  box-shadow: var(--zw-shadow-ring);
}

/* ---- Panel --------------------------------------------------------------------
 * The large container behind the tools row, the winbox, and dark ground bands.
 * Panels are structure, not colour blocks: keep the fill warm and let hairlines do
 * the separating.
 */
.zw-panel {
  border: 1px solid transparent;
  border-radius: var(--zw-radius-2xl);
  padding: 28px;
}

/* A heading inside the dark panel inverts. Scoped by containment rather than exposed
 * as an on_dark prop: the ground already knows it is dark, so the heading should not
 * have to be told twice, and a prop would be one more thing to get out of step. */
.zw-panel--dark .zw-section-heading__title { color: var(--zw-surface); }
.zw-panel--dark .zw-section-heading__lead { color: var(--zw-base-body); }

.zw-panel--panel { background: var(--zw-panel);      color: var(--zw-ink); border-color: var(--zw-border-warm); }
.zw-panel--paper { background: var(--zw-paper-3);    color: var(--zw-ink); border-color: var(--zw-border-warm); }
.zw-panel--white { background: var(--zw-surface);    color: var(--zw-ink); border-color: var(--zw-border-warm-2); box-shadow: var(--zw-shadow-hairline); }
.zw-panel--dark  { background: var(--zw-base);       color: var(--zw-base-body); border-color: var(--zw-base-line); }

/* ---- Progress bar -------------------------------------------------------------
 * Green for progress. Mint appears exactly twice in the whole system — the logo and
 * the 2027 goal bar — so it is a named tone rather than a free colour.
 */
.zw-progress {
  overflow: hidden;
  background: var(--zw-border-warm-inner);
  border-radius: var(--zw-radius-pill);
}

.zw-progress__fill {
  height: 100%;
  border-radius: var(--zw-radius-pill);
  transition: width var(--dur-3) var(--zw-ease-out);
}

.zw-progress--green  .zw-progress__fill { background: var(--zw-green-600); }
.zw-progress--mint   .zw-progress__fill { background: var(--zw-mint); }
.zw-progress--sand   .zw-progress__fill { background: var(--zw-sand); }
.zw-progress--onDark .zw-progress__fill { background: var(--zw-green-500); }

.zw-progress--onDark { background: var(--zw-base-panel); }

/* ---- Email signup ------------------------------------------------------------
 * The input shell holding an email field and a blue Sign up button. Under the float
 * shadow the border lightens so the shadow does the work.
 */
.zw-email-signup {
  display: flex;
  gap: var(--space-2);
  padding: 6px;
  background: var(--zw-surface);
  border: 1px solid var(--zw-border-warm-2);
  border-radius: var(--zw-radius-lg);
}

.zw-email-signup--float {
  border-color: var(--zw-border-warm-soft);
  box-shadow: var(--zw-shadow-float);
}

.zw-email-signup--flat { box-shadow: var(--zw-shadow-hairline); }

.zw-email-signup__field {
  flex: 1 1 160px;
  min-width: 0;
  height: 46px;
  padding: 0 14px;
  border: none;
  outline: none;
  background: transparent;
  color: var(--zw-ink);
  font-family: inherit;
  font-size: 16px;
}

.zw-email-signup__field::placeholder { color: var(--zw-faint); }

.zw-email-signup .zw-btn { flex: none; height: 46px; }

/* ---- Empty state -------------------------------------------------------------- */
.zw-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 24px;
  text-align: center;
}

.zw-empty-state__icon { margin-bottom: var(--space-4); color: var(--zw-faint); }

.zw-empty-state__title {
  margin: 0;
  color: var(--zw-ink);
  font-size: 16px;
  font-weight: 600;
}

.zw-empty-state__description {
  margin: var(--space-1) 0 0;
  max-width: 28rem;
  color: var(--zw-ink-3);
  font-size: 14px;
}

.zw-empty-state__action { margin-top: var(--space-4); }

/* ---- Pagination --------------------------------------------------------------- */
.zw-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--zw-border-warm);
  background: var(--zw-surface);
}

.zw-pagination__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.25rem;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--zw-border-warm-2);
  border-radius: var(--zw-radius-md);
  background: var(--zw-surface);
  color: var(--zw-ink-2);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
}

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

.zw-pagination__item--current {
  background: var(--zw-blue-700);
  border-color: var(--zw-blue-700);
  color: #fff;
}

.zw-pagination__gap {
  padding: var(--space-2) var(--space-3);
  color: var(--zw-ink-3);
  font-size: 14px;
}

@media (prefers-reduced-motion: reduce) {
  .zw-btn,
  .zw-segmented__option,
  .zw-progress__fill {
    transition: none;
  }

  .zw-btn:active:not(:disabled) { transform: none; }
}
