/* The educator free-code form, and the code it hands back.
 *
 * Kept to this page and built on the site's own tokens, so it follows the light/dark toggle
 * without a second theme of its own. The rest of misheard.app has no forms at all; the day this
 * program ends, the file goes with the section rather than leaving rules behind in style.css.
 */

.freecode {
  background: var(--color-primary-highlight);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: clamp(1.4rem, 4vw, 2.25rem);
  max-width: var(--content-narrow);
  margin: 0 auto;
}

.freecode h2 {
  margin: 0 0 var(--space-2);
}

.freecode-lede {
  margin: 0 0 var(--space-6);
  color: var(--color-text-muted);
}

.freecode-form {
  display: grid;
  gap: var(--space-4);
}

/* An explicit display beats the user agent's [hidden] { display: none }, so a bare `hidden`
   attribute does nothing to any of these. The form stayed on screen under its own result the
   first time this ran, which is how the site's help panel used to open on load. */
.freecode-form[hidden],
.code-out[hidden],
[data-freecode][hidden] {
  display: none !important;
}

.field {
  display: grid;
  gap: var(--space-2);
}

.field label {
  font-size: var(--text-sm);
  font-weight: 600;
}

.field input[type="text"],
.field input[type="email"] {
  font: inherit;
  /* 16px or larger, or iOS zooms the page the moment the field is focused and a teacher on a
     phone has to pinch back out to find the button. */
  font-size: max(1rem, 16px);
  padding: 0.8rem 0.875rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  width: 100%;
}

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

.field input:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
  border-color: var(--color-primary);
}

.field-note {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* Which store. No default: a wrong guess spends a code the one-per-address rule then stops
   them replacing, so one extra click buys a whole class of failure out of existence. */
.platform-field {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4) var(--space-4);
  margin: 0;
  display: grid;
  gap: var(--space-2);
}

.platform-field legend {
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 0 var(--space-2);
}

.choice {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  font-size: var(--text-sm);
  font-weight: 400;
  cursor: pointer;
}

.choice input {
  flex: none;
  width: 1.05rem;
  height: 1.05rem;
  accent-color: var(--color-primary);
}

.choice em {
  font-style: normal;
  color: var(--color-text-muted);
}

.platform-field .field-note {
  margin-top: var(--space-1);
}

.optin {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  line-height: 1.45;
}

.optin input {
  margin-top: 0.2rem;
  flex: none;
  width: 1.05rem;
  height: 1.05rem;
  accent-color: var(--color-primary);
}

.freecode-submit {
  justify-self: start;
}

.freecode-fine {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  margin: var(--space-4) 0 0;
  line-height: 1.55;
}

.freecode-status {
  margin: var(--space-3) 0 0;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  min-height: 1.2em;
}

.freecode-status[data-tone="error"] {
  color: var(--color-error);
}

/* The result. One code, large enough to read off a laptop from across a desk. */
.code-out {
  margin-top: var(--space-6);
}

.code-out h3 {
  margin: 0 0 var(--space-3);
  font-size: var(--text-lg);
}

.code-value {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: clamp(1.25rem, 5vw, 1.7rem);
  font-weight: 600;
  letter-spacing: 0.06em;
  background: var(--color-surface);
  border: 1px dashed var(--color-primary);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-3);
  text-align: center;
  overflow-wrap: anywhere;
  /* One tap or click selects the whole code rather than a word of it. */
  user-select: all;
}

/* The scannable version, for the teacher who filled this in on a laptop. White ground always:
   a QR inverted by dark mode does not scan, and the one place this must work is a phone camera
   pointed at a screen. */
.code-scan {
  margin: var(--space-4) 0 0;
  display: grid;
  justify-items: center;
  gap: var(--space-2);
}

.code-scan svg {
  width: min(220px, 60vw);
  height: auto;
  background: #fff;
  padding: var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
}

.code-scan figcaption {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  text-align: center;
  max-width: 34ch;
}

/* What to do with the code. Numbered, because the order is load-bearing: the app is a free
   download and the code unlocks the purchase inside it, so redeeming before installing gives the
   code nothing to attach to. */
.redeem-steps {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}

.redeem-steps h4 {
  margin: 0 0 var(--space-3);
  font-size: var(--text-base);
}

.redeem-steps ol {
  margin: 0;
  padding-left: 1.35em;
  display: grid;
  gap: var(--space-2);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.redeem-steps ol li::marker {
  color: var(--color-primary);
  font-weight: 700;
}

.redeem-steps .field-note {
  margin-top: var(--space-3);
}

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