/*
 * Librarium Militaris: the sign-up for the morning email.
 *
 * A <dialog> the browser opens and closes for us, the form inside it, and the
 * chip pickers that say which armies and which kind of game the reader wants.
 * The dialog is part of every page, so this file is too.
 */

@layer components {
  .signupmodal {
    --signupmodal-width: 30rem;
    --signupmodal-inset: var(--space-32);

    /* The reset zeroes every margin; a modal dialog centres itself with this one. */
    margin: auto;
    width: min(var(--signupmodal-width), calc(100vw - var(--signupmodal-inset)));
    max-height: calc(100dvh - var(--signupmodal-inset));
    padding: 0;
    background: transparent;
    color: var(--color-ink);

    &::backdrop {
      background-color: var(--color-backdrop);
      -webkit-backdrop-filter: blur(4px);
      backdrop-filter: blur(4px);
    }

    &[open] { animation: signup-rise var(--transition-rise); }
  }

  @keyframes signup-rise {
    from { opacity: 0; transform: translateY(var(--space-12)); }
    to { opacity: 1; transform: none; }
  }

  /* A fixed bar over a body that scrolls, rather than one scrolling box: the
     pickers make this taller than a short screen, and the close button has to
     stay reachable when it does. */
  .signupmodal__panel {
    display: flex;
    flex-direction: column;
    max-height: calc(100dvh - var(--signupmodal-inset));
    background-color: var(--color-surface);
    /* .panel supplies the recessed plate; the accent edge marks it as the one
       thing on the page asking the reader for something. */
    border-top: 2px solid var(--color-accent);
    border-radius: var(--radius);
  }

  .signupmodal__bar {
    flex: none;
    display: flex;
    justify-content: flex-end;
    padding: var(--space-10) var(--space-10) 0;
  }

  .signupmodal__body {
    overflow-y: auto;
    padding: var(--space-8) var(--space-28) var(--space-28);
  }

  .signupmodal__close {
    display: flex;
    padding: var(--space-4);
    color: var(--color-ink-dim);
    transition: color var(--transition-fast);

    &:hover { color: var(--color-ink-bright); }

    & svg {
      width: var(--space-18);
      height: var(--space-18);
    }

    &:focus-visible {
      outline: var(--focus-ring);
      outline-offset: var(--focus-ring-offset);
    }
  }

  /* ----------------------------------------------------------------- form -- */

  .signup { text-align: center; }

  .signup__sigil {
    display: inline-flex;
    color: var(--color-accent);
    margin-bottom: var(--space-12);

    & svg {
      width: var(--space-32);
      height: var(--space-32);
    }
  }

  .signup__sigil--done { color: var(--color-success); }

  .signup__title {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: var(--text-22);
    line-height: var(--leading-28);
    color: var(--color-ink-bright);
    letter-spacing: var(--tracking-lg);
    text-transform: uppercase;
    margin-bottom: var(--space-8);
  }

  .signup__blurb {
    color: var(--color-ink-soft);
    font-size: var(--text-14);
    line-height: var(--leading-prose);
    margin-bottom: var(--space-24);
  }

  .signup__form {
    display: flex;
    flex-direction: column;
    gap: var(--space-14);
    text-align: left;

    /* Rails wraps a field that failed validation. The wrapper carries no styling
       of its own here, so it must not become a box in the form's own column. */
    & .field_with_errors { display: contents; }
  }

  .signup__field {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
  }

  .signup__label {
    font-family: var(--font-heading);
    font-size: var(--text-12);
    line-height: var(--leading-16);
    letter-spacing: var(--tracking-xl);
    text-transform: uppercase;
    color: var(--color-ink-soft);
  }

  .signup__input {
    width: 100%;
    padding: var(--space-10) var(--space-12);
    appearance: none;
    -webkit-appearance: none;
    background-color: var(--color-field);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    color: var(--color-ink-bright);
    font-size: var(--text-15);
    line-height: var(--leading-24);
    box-shadow: var(--shadow-field);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);

    &::placeholder { color: var(--color-ink-faint); }

    &:focus {
      outline: none;
      border-color: var(--color-accent);
      box-shadow: 0 0 0 1px var(--color-accent), var(--shadow-field);
    }
  }

  .signup__error {
    background-color: var(--color-danger-wash);
    border: 1px solid var(--color-danger);
    border-radius: var(--radius);
    padding: var(--space-8) var(--space-12);
    color: var(--color-danger-ink);
    font-size: var(--text-13);
    line-height: var(--leading-20);
  }

  .signup__note {
    color: var(--color-ink-faint);
    font-size: var(--text-12);
    line-height: var(--leading-16);
    text-align: center;
  }

  /* The honeypot: present for anything that reads the markup, reachable by nobody. */
  .signup__trap {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
  }

  .signup--done .btn-signup--wide { margin-top: var(--space-8); }

  /* -------------------------------------------------------------- pickers -- */

  .pickgroup {
    padding: 0;
    min-width: 0;
  }

  .pickgroup__title {
    display: block;
    padding: 0;
    width: 100%;
    color: var(--color-ink-bright);
    font-family: var(--font-heading);
    font-size: var(--text-12);
    line-height: var(--leading-16);
    letter-spacing: var(--tracking-xl);
    text-transform: uppercase;
    margin-bottom: var(--space-10);
    padding-bottom: var(--space-4);
    border-bottom: 1px solid var(--color-border);
  }

  .pickgroup__chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-6);
  }

  /* The label is the control: the box itself keeps its place in the tab order and
     its keyboard behaviour, and gives up every pixel of its own appearance. */
  .pickchip {
    --pickchip-background: var(--color-surface-sunken);
    --pickchip-color: var(--color-ink-soft);
    --pickchip-border: var(--color-border-strong);

    display: inline-flex;
    align-items: center;
    gap: var(--space-6);
    background-color: var(--pickchip-background);
    border: 1px solid var(--pickchip-border);
    border-radius: var(--radius);
    color: var(--pickchip-color);
    font-size: var(--text-12);
    line-height: var(--leading-16);
    padding: var(--space-5) var(--space-8);
    cursor: pointer;
    user-select: none;
    transition: color var(--transition-fast), background-color var(--transition-fast),
                border-color var(--transition-fast);

    & input {
      appearance: none;
      -webkit-appearance: none;
      width: 0;
      height: 0;
      margin: 0;
      flex: none;
      opacity: 0;
    }

    &:hover {
      --pickchip-color: var(--color-ink-bright);
      --pickchip-border: var(--color-border-hover);
    }

    /* :has() reads the box the label is wrapped around, which is what lets the
       checked state be drawn without a line of JavaScript. */
    &:has(input:checked) {
      --pickchip-background: var(--color-accent-wash);
      --pickchip-border: var(--color-accent);
      --pickchip-color: var(--color-accent);
    }

    &:has(input:focus-visible) {
      outline: var(--focus-ring);
      outline-offset: var(--focus-ring-offset);
    }
  }

  /* "Everything" is a claim about the whole group, so it reads as a lead rather
     than as one more army in the list. */
  .pickchip--all {
    font-family: var(--font-heading);
    letter-spacing: var(--tracking-sm);
    text-transform: uppercase;
  }

  /* The army's own colour, handed in as the dot's one variable. */
  .pickchip__dot {
    --dot-color: transparent;

    width: var(--space-8);
    height: var(--space-8);
    border-radius: var(--radius-pill);
    background-color: var(--dot-color);
    flex: none;
  }
}
