/* Contribute hub: one scroll, no boxes. An opening (kicker, headline, intro, actions), the five ways to help as
   evenly spaced rows split by hairlines, "how it works" as three steps on a line, and a soft full-width closing band.
   Every part fades in as it scrolls into view (`[data-reveal]`, base.css). */

.contribute-opening {
  max-width: var(--width-reading);
  margin: var(--space-12) 0 var(--space-20);
}

.contribute-kicker {
  margin: 0 0 var(--space-3);
  color: var(--color-accent);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.contribute-headline {
  margin: 0 0 var(--space-5);
  font-size: var(--text-title);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
}

.contribute-opening .page-intro {
  margin: 0;
  color: var(--color-text-muted);
}

.contribute-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-8);
}

.contribute-section {
  margin: 0 0 var(--space-20);
}

.contribute-section-title {
  margin: 0 0 var(--space-6);
  font-size: var(--text-h2);
  font-weight: var(--weight-semibold);
}

.contribute-section .page-intro {
  margin: 0 0 var(--space-8);
  color: var(--color-text-muted);
}

/* The five ways: rows of the same shape. Phones: number and icon, then the text, then the button. From 48rem: one
   line each, number | icon | text | button. */
.ways {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: var(--border-width) solid var(--color-border);
}

.way {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    'number icon'
    'body body'
    'start start';
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-8) 0;
  border-bottom: var(--border-width) solid var(--color-border);
}

.way-number {
  grid-area: number;
  color: var(--color-text-faint);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  transition: color var(--duration-base) var(--ease-out);
}

.way-icon {
  grid-area: icon;
  display: grid;
  place-items: center;
  justify-self: start;
  width: var(--size-control-lg);
  height: var(--size-control-lg);
  color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 10%, var(--color-surface));
  border-radius: var(--radius-full);
  transition:
    color var(--duration-base) var(--ease-out),
    background-color var(--duration-base) var(--ease-out),
    scale var(--duration-base) var(--ease-out);
}

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

.way-body h3 {
  margin: 0 0 var(--space-2);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
}

.way-body p {
  margin: 0;
  color: var(--color-text-muted);
}

.way-start {
  grid-area: start;
  justify-self: start;
}

.way-start .icon {
  transition: translate var(--duration-base) var(--ease-out);
}

/* The whole row is a target: the start link's ::after covers it. */
.way-start::after {
  content: '';
  position: absolute;
  inset: 0;
}

.way:hover .way-number {
  color: var(--color-accent);
}

.way:hover .way-icon {
  color: var(--color-on-accent);
  background: var(--color-accent);
  scale: 1.06;
}

.way:hover .way-start {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

.way:hover .way-start .icon {
  translate: var(--space-1) 0;
}

@media (min-width: 48rem) {
  .way {
    grid-template-columns: var(--space-8) auto minmax(0, 1fr) auto;
    grid-template-areas: 'number icon body start';
    gap: var(--space-6);
  }

  .way-start {
    justify-self: end;
  }
}

/* How it works: three steps joined by a line. Phones: down the left; from 48rem: across. */
.timeline {
  display: grid;
  gap: var(--space-8);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.timeline li {
  position: relative;
  padding-left: var(--space-12);
  counter-increment: step;
}

.timeline li::before {
  content: counter(step);
  position: absolute;
  top: 0;
  left: 0;
  display: grid;
  place-items: center;
  width: var(--size-control-sm);
  height: var(--size-control-sm);
  color: var(--color-accent);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-accent);
  border-radius: var(--radius-full);
}

/* The line between the numbers. */
.timeline li:not(:last-child)::after {
  content: '';
  position: absolute;
  top: var(--size-control-sm);
  bottom: calc(-1 * var(--space-8));
  left: calc(var(--size-control-sm) / 2);
  border-left: var(--border-width) solid var(--color-border);
}

.timeline h3 {
  margin: var(--space-1) 0 var(--space-2);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
}

.timeline p {
  margin: 0;
  color: var(--color-text-muted);
}

@media (min-width: 48rem) {
  .timeline {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--grid-gutter);
  }

  .timeline li {
    padding: var(--space-12) var(--space-6) 0 0;
  }

  .timeline li:not(:last-child)::after {
    top: calc(var(--size-control-sm) / 2);
    bottom: auto;
    left: var(--size-control-sm);
    right: calc(-1 * var(--grid-gutter));
    border-left: 0;
    border-top: var(--border-width) solid var(--color-border);
  }
}

/* The closing band: the whole window wide (`.full`), on the soft panel gradient, down to the footer. */
.contribute-closing {
  /* Cancels main's bottom padding and the footer's top margin (layout.css), so the band meets the footer. */
  margin-bottom: calc(-1 * (var(--space-6) + var(--space-20)));
  padding-block: var(--space-20);
  background: var(--gradient-panel);
  text-align: center;
}

.contribute-closing-inner {
  display: grid;
  justify-items: center;
  gap: var(--space-4);
  max-width: var(--width-reading);
  margin: 0 auto;
}

.contribute-closing h2 {
  margin: 0;
  font-size: var(--text-h1);
  font-weight: var(--weight-semibold);
}

.contribute-closing p {
  margin: 0 0 var(--space-4);
  color: var(--color-text-muted);
}

/* The top of each way to help (`ContributeHead`): the five ways as one segmented bar to switch between them (the
   current one filled, scrolling sideways on a phone rather than wrapping), then a centred kicker, title and intro. */
.ways-nav {
  display: flex;
  gap: var(--space-1);
  width: fit-content;
  max-width: 100%;
  margin: var(--space-8) auto 0;
  padding: var(--space-1);
  overflow-x: auto;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-sm);
  scrollbar-width: none;
}

.ways-nav a {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
  white-space: nowrap;
  border-radius: var(--radius-pill);
  transition:
    color var(--duration-base) var(--ease-out),
    background-color var(--duration-base) var(--ease-out);
}

.ways-nav a:hover {
  color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 8%, var(--color-surface));
}

.ways-nav a[aria-current='page'] {
  color: var(--color-on-accent);
  background: var(--color-accent);
}

.contribute-page-head {
  max-width: var(--width-reading);
  margin: var(--space-10) auto var(--space-8);
  text-align: center;
  animation: reveal-in var(--duration-reveal) var(--ease-out) backwards;
}

.contribute-page-head .contribute-kicker {
  display: inline-block;
  text-decoration: none;
}

.contribute-page-head .contribute-kicker:hover {
  text-decoration: underline;
}

.contribute-page-head h1 {
  margin: 0 0 var(--space-3);
  font-size: var(--text-title);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
}

.contribute-page-head p {
  margin: 0;
  color: var(--color-text-muted);
}

/* Add a word (public/js/add.js): the form, the "already in the dictionary" box, then the thank-you card. */
.add {
  max-width: var(--width-form);
  margin: 0 auto;
}

/* Centred under the page head, on a soft card like the decks'. */
.add-form,
.add-card {
  display: grid;
  gap: var(--space-4);
  padding: var(--space-6);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.add-existing {
  padding: var(--space-2) var(--space-3);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
}

.add-existing p,
.add-existing ul {
  margin: var(--space-1) 0;
}

/* After saving: the form gives way to a thank-you. On top, the banner in the toast's gradient with a close button; it
   stays for --duration-notice (paused while hovered or focused; a thin line along its foot shows the time left), then
   folds away and the card slides up into its place (add.js). Under it, the card: the invitation to record the word (a
   title with the word, one line of why, the rose mic disc that starts at a tap) and, last and quiet, "Add another
   word". The banner drops in, the card rises after it. */
.add-done {
  display: grid;
}

.add-card {
  gap: 0;
  padding: 0;
  text-align: center;
  animation: add-rise var(--duration-reveal) var(--ease-out) var(--duration-base) backwards;
}

/* Folding away: the slot's one row shrinks from its height to nothing (grid rows can animate; heights can't). */
.add-banner-slot {
  display: grid;
  grid-template-rows: 1fr;
  scroll-margin-top: var(--space-6);
  transition:
    grid-template-rows var(--duration-reveal) var(--ease-out),
    opacity var(--duration-base);
}

.add-banner-slot.leaving {
  grid-template-rows: 0fr;
  opacity: 0;
}

.add-banner-clip {
  min-height: 0;
  overflow: hidden;
}

.add-banner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  margin: 0 0 var(--space-5);
  padding: var(--space-4) var(--space-12);
  overflow: hidden;
  color: var(--color-on-solid);
  font-weight: var(--weight-medium);
  background: var(--gradient-toast);
  border-radius: var(--radius-md);
  animation: add-rise var(--duration-reveal) var(--ease-out);
}

.add-banner .icon {
  flex: none;
}

/* The time left: a line along the foot that shrinks to nothing; when it is gone, add.js folds the banner away. */
.add-banner::after {
  position: absolute;
  inset: auto 0 0;
  height: var(--border-width-strong);
  content: '';
  background: currentColor;
  opacity: var(--opacity-muted);
  transform-origin: left;
  animation: add-banner-time var(--duration-notice) linear forwards;
}

.add-banner:hover::after,
.add-banner:focus-within::after {
  animation-play-state: paused;
}

@keyframes add-banner-time {
  to {
    transform: scaleX(0);
  }
}

.add-banner-close {
  position: absolute;
  top: 50%;
  right: var(--space-3);
  display: grid;
  place-items: center;
  width: var(--size-control-sm);
  height: var(--size-control-sm);
  padding: 0;
  color: inherit;
  background: none;
  border: 0;
  border-radius: var(--radius-full);
  cursor: pointer;
  transform: translateY(-50%);
  transition: background-color var(--duration-base);
}

.add-banner-close:hover,
.add-banner-close:focus-visible {
  background: color-mix(in srgb, currentColor 20%, transparent);
}

.add-voice,
.add-voice-saved {
  display: grid;
  gap: var(--space-2);
  justify-items: center;
  padding: var(--space-8) var(--space-6) var(--space-4);
  animation: add-rise var(--duration-reveal) var(--ease-out) var(--duration-base) backwards;
}

.add-voice-title {
  margin: 0;
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
}

.add-voice-hint {
  max-width: 28rem;
  margin: 0 0 var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--text-md);
}

.add-voice-saved {
  margin: 0;
  color: var(--color-success);
  font-weight: var(--weight-semibold);
}

/* The recorder's own prompt is unused here (the title above says it). */
.add .recorder-prompt:empty {
  display: none;
}

.add-again {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin: 0 var(--space-6);
  padding: var(--space-4) 0 var(--space-5);
  color: var(--color-text-muted);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  text-decoration: none;
  border-top: var(--border-width) solid var(--color-border);
  transition: color var(--duration-base);
}

.add-again:hover,
.add-again:focus-visible {
  color: var(--color-accent);
}

@keyframes add-rise {
  from {
    opacity: 0;
    transform: translateY(var(--space-2));
  }
}

@media (prefers-reduced-motion: reduce) {
  .add-card,
  .add-banner,
  .add-voice,
  .add-voice-saved {
    animation: none;
  }

  .add-banner-slot {
    transition: none;
  }
}

/* Correct (/contribute/correct, public/js/correct.js): a stack of meaning cards. Three are open; the next two peek
   out below them, smaller, faded and cut off, a hint that more are coming (not focusable: `inert`). An answered card
   fades out to the side and the gap closes (the script animates both); a new card fades in at the back. The fields
   look like text until hovered or focused, so a card reads first and edits second. */
.correct-form {
  display: grid;
  gap: var(--space-4);
  max-width: var(--width-deck);
  margin-inline: auto;
}

.correct-stack {
  display: flex;
  flex-direction: column;
}

.correct-card {
  display: grid;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm);
  transform-origin: top center;
  transition:
    opacity var(--duration-reveal) var(--ease-out),
    scale var(--duration-reveal) var(--ease-out),
    border-color var(--duration-base);
  animation: correct-in var(--duration-reveal) var(--ease-out) backwards;
  animation-delay: calc(var(--correct-index, 0) * var(--duration-reveal-step));
}

@keyframes correct-in {
  from {
    opacity: 0;
    translate: 0 var(--space-3);
  }
}

.correct-card.leaving {
  overflow: hidden;
  pointer-events: none;
}

/* An edited card: its edit is what ✓ saves. */
.correct-card.edited {
  border-color: var(--color-accent);
}

.correct-card[data-slot^='peek'] {
  overflow: hidden;
  margin-top: calc(-1 * var(--space-2));
  box-shadow: none;
  mask-image: linear-gradient(to bottom, black, transparent);
  user-select: none;
}

.correct-card[data-slot='peek-1'] {
  max-height: var(--size-control-xl);
  opacity: var(--opacity-muted);
  scale: 0.96;
}

.correct-card[data-slot='peek-2'] {
  max-height: var(--size-control-lg);
  opacity: calc(var(--opacity-disabled) / 2);
  scale: 0.92;
}

.correct-card-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}

.correct-sense,
.correct-pending,
.correct-label {
  color: var(--color-text-faint);
  font-size: var(--text-sm);
}

.correct-sense {
  flex-shrink: 0;
}

.correct-pending {
  display: block;
}

.correct-label {
  font-weight: var(--weight-medium);
}

.correct-fields {
  display: grid;
  gap: var(--space-3);
}

@media (min-width: 40rem) {
  .correct-fields {
    grid-template-columns: 3fr 2fr;
  }
}

.correct-field {
  display: grid;
  gap: var(--space-1);
  align-content: start;
}

/* Text until hovered or focused, then a field. */
.correct-input {
  width: calc(100% + 2 * var(--space-2));
  padding: var(--space-1) var(--space-2);
  margin-inline: calc(-1 * var(--space-2));
  color: var(--color-text);
  font: inherit;
  line-height: var(--leading-snug);
  background: transparent;
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-sm);
  transition:
    border-color var(--duration-base),
    background-color var(--duration-base);
}

.correct-input:hover {
  border-color: var(--color-border);
}

.correct-input:focus {
  background: var(--color-bg);
  border-color: var(--color-border-control);
}

.correct-input::placeholder {
  color: var(--color-text-placeholder);
}

textarea.correct-input {
  field-sizing: content;
  resize: none;
  overflow: hidden;
}

.correct-headword {
  font-size: var(--text-h2);
  font-weight: var(--weight-semibold);
}

.correct-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  padding-top: var(--space-3);
  border-top: var(--border-width) solid var(--color-border);
}

.correct-answer {
  position: relative;
}

.correct-wrong:hover:not(:disabled) {
  color: var(--color-danger);
  border-color: var(--color-danger);
}

.correct-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-height: var(--size-control-sm);
}

.correct-retry {
  margin-left: var(--space-2);
}

.correct .edit-note {
  color: var(--color-text-faint);
  font-size: var(--text-sm);
  text-align: center;
}
