/* The register flow's shared pieces: the progress line, the six-box code
   field, the calmer focus on its fields, and the "prove you're a student"
   step (assets/prove.js). Used by /soon/ (the whole flow, inline in its
   slip), /verify/ (the same proof step for existing links) and /signin/ (the
   code field and the focus). Built on tokens.css and site.css; everything
   here is scoped to .tud-flow or to the component's own classes. */

@font-face {
  font-family: 'Caveat';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  /* Static 700 instance of Caveat-var.woff2, basic Latin only: 17 KB. */
  src: url('/assets/fonts/Caveat-700-latin.woff2') format('woff2');
}

.tud-flow {
  --flow-hand: 'Caveat', 'Segoe Print', 'Bradley Hand', cursive;
  --flow-ink: var(--tud-color-text-primary);
  --flow-orange: var(--tud-color-accent-base);
  /* A 2px edge in the accent TEXT colour, not raw orange: #FF5C26 on the
     cream canvas is under 3:1, and a focus edge has to be seen. */
  --flow-focus: var(--site-accent-text);
  --flow-halo: rgba(255, 92, 38, 0.2);
  --flow-pencil: var(--tud-color-border-strong);
  container-type: inline-size;
}

/* ---------- calmer focus ----------
   site.css gives a focused field a 3px outline at a 3px offset AND an orange
   border AND a glow: three rings, which on the code field read as an alarm.
   Inside the flow a field takes one clear change instead, its border in the
   accent text colour with a soft halo. Buttons and links keep the site ring. */
.tud-flow :is(input, select, textarea):focus-visible {
  outline: none;
  border-color: var(--flow-focus);
  box-shadow: 0 0 0 1px var(--flow-focus), 0 0 0 5px var(--flow-halo);
}
.tud-flow input[aria-invalid="true"] { border-color: var(--tud-color-status-error-text); }

/* ---------- the progress line ----------
   Four stops: Email, Code, About you, Student proof. A done stop is the
   orange dot with a tick, the current one is ringed in ink, a waiting one is
   a dashed pencil circle, and "in review" rings the last one dashed orange.
   The connectors are pencil dashes, the notebook's. */
.tud-steps {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 var(--tud-space-5);
  padding: 0;
  list-style: none;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.2;
}
.tud-steps li {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 6px;
  min-width: 0;
  color: var(--tud-color-text-muted);
}
.tud-steps li + li { flex: 1 1 auto; }
.tud-steps li + li::before {
  content: "";
  flex: 1 1 10px;
  min-width: 8px;
  height: 2px;
  background: repeating-linear-gradient(to right, var(--flow-pencil) 0 4px, transparent 4px 7px);
}
.tud-step-dot {
  position: relative;
  display: grid;
  flex: none;
  place-items: center;
  width: 22px;
  height: 22px;
  border: 1.5px dashed var(--flow-pencil);
  border-radius: 50%;
  font-family: var(--tud-font-secondary);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.tud-step-dot svg { display: none; }
.tud-step-label { white-space: nowrap; }
.tud-steps [data-state="current"],
.tud-steps [data-state="review"] { color: var(--flow-ink); }
.tud-steps [data-state="current"] .tud-step-label,
.tud-steps [data-state="review"] .tud-step-label { font-weight: 800; }
.tud-steps [data-state="current"] .tud-step-dot { border: 2px solid var(--flow-ink); }
.tud-steps [data-state="review"] .tud-step-dot { border: 2px dashed var(--flow-focus); }
.tud-steps [data-state="done"] { color: var(--tud-color-text-secondary); }
.tud-steps [data-state="done"] .tud-step-dot { border: 0; color: #141412; background: var(--flow-orange); }
.tud-steps [data-state="done"] .tud-step-n { display: none; }
.tud-steps [data-state="done"] .tud-step-dot svg { display: block; }

/* A narrow slip keeps every dot but only the current stop's word; the others
   still say theirs to a screen reader. */
@container (max-width: 380px) {
  .tud-steps li:not([aria-current]) .tud-step-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}

/* ---------- the code, six boxes over one field (assets/otp.js) ---------- */
.otp { position: relative; }
.otp-cells {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: clamp(6px, 2cqw, 10px);
}
.otp-cell {
  position: relative;
  display: grid;
  place-items: center;
  height: 58px;
  border: 1.5px solid var(--site-control-border);
  border-radius: 12px;
  color: var(--tud-color-text-primary);
  background: var(--tud-color-bg-surface);
  font-family: var(--tud-font-secondary);
  font-size: 26px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  transition: border-color var(--tud-duration-fast) var(--tud-ease-standard), box-shadow var(--tud-duration-fast) var(--tud-ease-standard);
}
/* The middle gap: a code is read in two threes. */
.otp-cell:nth-child(3) { margin-right: clamp(2px, 1.4cqw, 8px); }
.otp-cell.is-filled { border-color: var(--tud-color-text-primary); }
.otp-cell.is-active { border-color: var(--site-accent-text); box-shadow: 0 0 0 1px var(--site-accent-text), 0 0 0 4px rgba(255, 92, 38, 0.18); }
.otp-cell.is-active:empty::after {
  content: "";
  width: 2px;
  height: 26px;
  border-radius: 1px;
  background: var(--site-accent-text);
}
.otp.is-invalid .otp-cell { border-color: var(--tud-color-status-error-text); }
/* The real field lies over the boxes and takes every tap, paste and autofill;
   its own text and caret are see-through because the boxes draw them. */
.otp .otp-input,
.tud-flow .otp .otp-input,
.tud-flow .field .otp .otp-input {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 12px;
  outline: none;
  color: transparent;
  -webkit-text-fill-color: transparent;
  caret-color: transparent;
  background: transparent;
  font-size: 16px;
  letter-spacing: 0;
  text-indent: 0;
  cursor: text;
}
.otp .otp-input:focus-visible,
.tud-flow .field .otp .otp-input:focus-visible { outline: none; border: 0; box-shadow: none; }
.otp .otp-input::selection { background: transparent; }
.otp .otp-input:-webkit-autofill { -webkit-box-shadow: 0 0 0 60px transparent inset; transition: background-color 9999s; }
.otp .otp-input:disabled + .otp-cells,
.otp:has(.otp-input:disabled) .otp-cell { opacity: 0.6; }
@media (prefers-reduced-motion: no-preference) {
  .otp-cell.is-active:empty::after { animation: otp-caret 1.1s steps(1) infinite; }
  .otp.is-invalid .otp-cells { animation: otp-nope 320ms var(--tud-ease-standard); }
}
@keyframes otp-caret { 50% { opacity: 0; } }
@keyframes otp-nope {
  20% { transform: translateX(-5px); }
  45% { transform: translateX(4px); }
  70% { transform: translateX(-2px); }
}

.form-msg.form-msg--ok:not(:empty) { color: var(--tud-color-status-success-text); background: var(--tud-color-status-success-bg); }
/* A redirection, not an error: a note uses the warm tone, never red. */
.form-msg.form-msg--note:not(:empty) { color: var(--tud-color-status-warning-text); background: var(--tud-color-status-warning-bg); }
.form-msg .link-button { min-height: 32px; color: inherit; font-size: 14px; }

/* ---------- the proof step (assets/prove.js) ---------- */
.pv-title { font-size: 21px; font-weight: 800; line-height: 1.2; letter-spacing: -0.02em; text-wrap: balance; }
.pv-title:focus-visible,
.tud-flow [tabindex="-1"]:focus-visible { outline: none; }
.pv-lede { margin-top: var(--tud-space-2); color: var(--tud-color-text-secondary); font-size: 15px; line-height: 1.5; text-wrap: pretty; }
.pv-checking { min-height: 44px; color: var(--tud-color-text-muted); font-size: 16px; line-height: 1.5; }
.pv-note {
  margin-bottom: var(--tud-space-4);
  padding: var(--tud-space-3) var(--tud-space-4);
  border-radius: var(--tud-radius-md);
  color: var(--tud-color-status-warning-text);
  background: var(--tud-color-status-warning-bg);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.45;
}

.pv-choices { display: grid; gap: var(--tud-space-3); margin-top: var(--tud-space-4); }
@container (min-width: 600px) { .pv-choices { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.pv-choice {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--tud-space-3);
  width: 100%;
  min-height: 76px;
  padding: var(--tud-space-3) var(--tud-space-4);
  border: 1.5px solid var(--tud-color-border-strong);
  border-radius: 14px;
  color: var(--tud-color-text-primary);
  background: var(--tud-color-bg-surface);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--tud-duration-fast) var(--tud-ease-standard), background-color var(--tud-duration-fast) var(--tud-ease-standard);
}
.pv-choice:hover { border-color: var(--tud-color-text-primary); }
.pv-choice[aria-expanded="true"] {
  border-color: var(--site-accent-text);
  background: var(--tud-color-accent-tint);
  box-shadow: inset 0 0 0 1px var(--site-accent-text);
}
.pv-choice-icon { display: grid; width: 32px; color: var(--tud-color-text-primary); }
.pv-choice-text { display: grid; gap: 2px; min-width: 0; }
.pv-choice-title { font-size: 17px; font-weight: 800; line-height: 1.2; letter-spacing: -0.01em; }
.pv-choice-meta { color: var(--tud-color-text-secondary); font-size: 14px; font-weight: 500; line-height: 1.35; }
.pv-choice-mark {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border: 1.5px solid var(--tud-color-border-strong);
  border-radius: 50%;
  color: transparent;
}
.pv-choice[aria-expanded="true"] .pv-choice-mark { border-color: var(--flow-orange); color: #141412; background: var(--flow-orange); }

/* An open lane hangs under the choices, after a pencil line. */
.pv-lane {
  position: relative;
  margin-top: var(--tud-space-5);
  padding-top: var(--tud-space-5);
}
.pv-lane::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: repeating-linear-gradient(to right, var(--flow-pencil) 0 6px, transparent 6px 11px);
}
.pv-form { display: grid; gap: var(--tud-space-4); }
.pv-form .join-step-links { margin-top: calc(var(--tud-space-2) * -1); }
.pv-sent { color: var(--tud-color-text-secondary); font-size: 15px; line-height: 1.5; }
.pv-addr { color: var(--tud-color-text-primary); font-family: var(--tud-font-secondary); font-weight: 700; overflow-wrap: anywhere; }
.pv-lane > .form-msg:not(:empty) { margin-top: var(--tud-space-3); }

.pv-drop { position: relative; border-radius: var(--tud-radius-lg); }
.pv-drop.is-over { outline: 2px dashed var(--site-accent-text); outline-offset: 6px; }
.pv-lane-lead { color: var(--tud-color-text-secondary); font-size: 15px; line-height: 1.5; text-wrap: pretty; }
.pv-pick { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--tud-space-2); margin-top: var(--tud-space-4); }
.pv-pick .btn { min-height: 52px; padding-inline: var(--tud-space-3); }
.pv-drop-hint { display: none; margin-top: var(--tud-space-2); color: var(--tud-color-text-muted); font-size: 13px; text-align: center; }
@media (hover: hover) and (pointer: fine) { .pv-drop-hint { display: block; } }

.pv-preview { display: grid; gap: var(--tud-space-2); }
.pv-preview-frame {
  display: grid;
  place-items: center;
  height: 180px;
  overflow: hidden;
  border: 1.5px solid var(--tud-color-border-strong);
  border-radius: var(--tud-radius-lg);
  background: var(--tud-color-bg-sunken);
}
.pv-preview-frame img { width: 100%; height: 100%; object-fit: contain; }
.pv-preview-none { max-width: 26ch; padding: var(--tud-space-4); color: var(--tud-color-text-muted); font-size: 14px; text-align: center; }
.pv-preview-meta { display: flex; justify-content: space-between; gap: var(--tud-space-3); font-size: 14px; }
.pv-preview-name { min-width: 0; overflow: hidden; font-weight: 700; text-overflow: ellipsis; white-space: nowrap; }
.pv-preview-size { flex: none; color: var(--tud-color-text-muted); font-family: var(--tud-font-secondary); font-variant-numeric: tabular-nums; }
.pv-preview .link-button { justify-self: start; min-height: 40px; }
.pv-lane #sl-pv-send,
.pv-lane [id$="-send"] { margin-top: var(--tud-space-4); }

.pv-progress { display: flex; align-items: center; gap: var(--tud-space-3); margin-top: var(--tud-space-3); }
.pv-progress-track { flex: 1 1 auto; height: 8px; overflow: hidden; border-radius: 4px; background: var(--tud-color-bg-sunken); }
.pv-progress-fill { height: 100%; background: var(--flow-orange); transform: scaleX(0); transform-origin: left center; transition: transform 160ms linear; }
.pv-progress-value { min-width: 4ch; color: var(--tud-color-text-muted); font-family: var(--tud-font-secondary); font-size: 13px; text-align: right; font-variant-numeric: tabular-nums; }

.pv-help { margin-top: var(--tud-space-4); }
.pv-help summary {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  color: var(--site-accent-text);
  font-size: 14px;
  font-weight: 800;
  text-decoration: underline;
  text-underline-offset: 0.18em;
  cursor: pointer;
}
.pv-help-list { display: grid; gap: var(--tud-space-2); margin: 0; padding: 0 0 0 20px; color: var(--tud-color-text-secondary); font-size: 14px; line-height: 1.5; }

/* What happens next, one ruled line each with a pencil dash for a bullet. */
.pv-next { display: grid; gap: var(--tud-space-2); margin: var(--tud-space-4) 0 0; padding: 0; list-style: none; }
.pv-next li { position: relative; padding-left: 22px; color: var(--tud-color-text-secondary); font-size: 16px; line-height: 1.5; }
.pv-next li::before {
  content: "";
  position: absolute;
  top: 0.72em;
  left: 0;
  width: 12px;
  height: 2.5px;
  border-radius: 2px;
  background: var(--flow-orange);
  transform: rotate(-8deg);
}
.pv-actions:not(:empty) { display: grid; gap: var(--tud-space-3); margin-top: var(--tud-space-5); }
.pv-quiet:not(:empty) { margin-top: var(--tud-space-2); }
