/* =============================================================================
   LOCK IN — registration form styles

   White ground, Deep Blue type, copper for the things you press. Same five a2co
   colours as the game, used the other way up: the game is a lit object in a dark
   room, this is a document you read in daylight on a phone.

   Readability first. Dark text on white is the highest-contrast pairing available,
   the body type is 17px and up, and line lengths are held short.

   Mobile-first, because nearly every one of these will be filled in one-handed,
   standing up, having just scanned a QR code.
   ========================================================================== */

@font-face {
  font-family: 'Degular Display';
  src: url('fonts/DegularDisplay-Regular.otf') format('opentype');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Degular Display';
  src: url('fonts/DegularDisplay-Medium.otf') format('opentype');
  font-weight: 500;
  font-display: swap;
}

:root {
  --blue:    #12284B;
  --copper:  #b96846;
  --green:   #477066;
  --mustard: #E5D99E;
  --gray:    #5C6170;
  --white:   #FFFFFF;

  /* Deep Blue at low opacity rather than a new grey, so every tone on the page is
     still the brand palette.

     MEASURED against white: --ink is 14.7:1 and --ink-soft is 4.94:1, so both clear
     the 4.5:1 needed for body text. --ink-faint is 2.5:1 and is therefore for
     DECORATION ONLY — borders, dividers, disabled states. It must never carry text
     somebody has to read. Copper on white measures 4.09:1, which is also below the
     bar, so copper is reserved for fills and for text at 24px and up, where the
     large-text threshold of 3:1 applies. */
  --ink:        #12284B;
  --ink-soft:   rgba(18, 40, 75, 0.66);
  --ink-faint:  rgba(18, 40, 75, 0.42);
  --line:       rgba(18, 40, 75, 0.16);
  --line-solid: rgba(18, 40, 75, 0.28);
  --tint:       rgba(18, 40, 75, 0.035);

  --radius: 12px;
}

* { box-sizing: border-box; }

html { background: #F4F5F7; }

body {
  margin: 0;
  padding: 0;
  color: var(--ink);
  font-family: 'Degular Display', system-ui, -apple-system, sans-serif;
  font-weight: 400;
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* The card. On a phone it fills the screen; on a desktop it sits as a sheet on a
   soft grey ground, which is what stops a white page on a white browser looking
   like an unstyled document. */
.page {
  max-width: 620px;
  margin: 0 auto;
  background: var(--white);
  padding: 36px 22px 64px;
  min-height: 100vh;
}
@media (min-width: 660px) {
  .page {
    margin: 40px auto;
    min-height: 0;
    border-radius: 20px;
    padding: 48px 56px 56px;
    box-shadow: 0 2px 40px rgba(18, 40, 75, 0.10);
  }
}

.hidden { display: none !important; }

/* ---- Masthead ------------------------------------------------------------ */
.masthead {
  text-align: center;
  padding-bottom: 28px;
  margin-bottom: 28px;
  border-bottom: 1px solid var(--line);
}

.logo { width: 118px; height: auto; display: block; margin: 0 auto 26px; }

h1 {
  font-weight: 500;
  font-size: 42px;
  line-height: 1.1;
  letter-spacing: 4px;
  margin: 0 0 12px;
  color: var(--ink);
}

.tagline { margin: 0; color: var(--ink-soft); font-size: 17px; }
.tagline strong { color: var(--copper); font-weight: 500; }

/* ---- Prizes -------------------------------------------------------------- */
.prizes {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 34px;
}
.prize {
  background: var(--tint);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 8px;
  text-align: center;
}
.prize-what {
  display: block;
  font-weight: 500;
  font-size: 20px;
  color: var(--ink);
  line-height: 1.2;
}
.prize-for {
  display: block;
  font-size: 13px;
  color: var(--ink-soft);
  margin-top: 4px;
  line-height: 1.3;
}

.prize-daily {
  margin: -22px 0 34px;
  text-align: center;
  font-size: 16px;
  color: var(--ink-soft);
}
.prize-daily strong { color: var(--ink); font-weight: 500; }

/* ---- Fields -------------------------------------------------------------- */
.row.two { display: grid; grid-template-columns: 1fr; }
@media (min-width: 480px) {
  .row.two { grid-template-columns: 1fr 1fr; gap: 16px; }
}

.field { margin-bottom: 20px; }

label {
  display: block;
  font-weight: 500;
  font-size: 15px;
  color: var(--ink);
  margin-bottom: 7px;
  /* Sentence case, not uppercase: uppercase labels are measurably slower to read
     and this form has ten of them. */
}

input[type="text"], input[type="email"], input[type="tel"], select {
  width: 100%;
  padding: 14px 15px;
  background: var(--white);
  border: 1.5px solid var(--line-solid);
  border-radius: var(--radius);
  color: var(--ink);
  font-family: inherit;
  font-size: 17px;
  /* 17px minimum, or iOS Safari zooms the page when a field is focused and the
     layout jumps under the user's thumb. */
  line-height: 1.4;
  appearance: none;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

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

select {
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ink) 50%),
    linear-gradient(135deg, var(--ink) 50%, transparent 50%);
  background-position: calc(100% - 21px) 52%, calc(100% - 15px) 52%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 42px;
  cursor: pointer;
}
select:disabled {
  background-color: var(--tint);
  color: var(--ink-faint);
  cursor: not-allowed;
}
select option { color: var(--ink); }
select optgroup { font-weight: 500; color: var(--ink-soft); }

input:focus, select:focus {
  outline: none;
  border-color: var(--copper);
  box-shadow: 0 0 0 3px rgba(185, 104, 70, 0.16);
}

/* Copper border plus a faint copper wash. The error message beside the field also
   carries a copper dot, so an invalid field is signalled by wording and position as
   well as by colour, which matters for anybody who cannot distinguish it. */
input.invalid, select.invalid {
  border-color: var(--copper);
  background-color: rgba(185, 104, 70, 0.05);
}

.hint { margin: 7px 0 0; font-size: 14px; color: var(--ink-soft); }

.error {
  margin: 7px 0 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  padding-left: 13px;
  position: relative;
}
/* A copper marker beside the message. The field's border also turns copper, so
   the error is carried by position, wording and shape as well as by colour —
   which matters for anybody who cannot distinguish the colour at all. */
.error::before {
  content: '';
  position: absolute;
  left: 0; top: 8px;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--copper);
}
.error:empty { display: none; }
.form-error { text-align: center; margin-top: 16px; font-size: 15px; padding-left: 0; }
.form-error::before { display: none; }

/* ---- Consent ------------------------------------------------------------- */
.consent {
  background: var(--tint);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px;
  margin: 30px 0 20px;
}
.check { display: flex; gap: 14px; align-items: flex-start; cursor: pointer; }
.check input {
  appearance: none;
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  margin: 0;
  border: 2px solid var(--line-solid);
  border-radius: 7px;
  background: var(--white);
  cursor: pointer;
  position: relative;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.check input:checked { background: var(--copper); border-color: var(--copper); }
.check input:checked::after {
  content: '';
  position: absolute;
  left: 8px; top: 3px;
  width: 5px; height: 12px;
  border: solid var(--white);
  border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg);
}
.check input:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(185, 104, 70, 0.22);
}
.check span { font-size: 16px; line-height: 1.5; color: var(--ink); }
.check strong { font-weight: 500; }
.optional { margin: 11px 0 0 40px; font-size: 14px; color: var(--ink-faint); }

/* ---- Privacy notice ------------------------------------------------------ */
.notice {
  border-top: 1px solid var(--line);
  padding-top: 18px;
  margin-bottom: 28px;
}
.notice p {
  margin: 0 0 11px;
  font-size: 14px;
  line-height: 1.65;
  color: var(--ink-soft);
}
.notice p:last-child { margin-bottom: 0; }
.notice strong { color: var(--ink); font-weight: 500; }

/* ---- Buttons ------------------------------------------------------------- */
button {
  width: 100%;
  padding: 18px;
  border: none;
  border-radius: 999px;
  background: var(--copper);
  color: var(--white);
  font-family: inherit;
  font-weight: 500;
  /* 24px is not a style choice. White on copper measures 4.09:1, which passes the
     3:1 large-text threshold but not the 4.5:1 normal-text one, and 24px is where
     "large" begins. Shrinking this text would fail the contrast check. */
  font-size: 24px;
  letter-spacing: 0.4px;
  cursor: pointer;
  transition: transform 0.1s ease, filter 0.15s ease;
}
button:hover { filter: brightness(1.06); }
button:active { transform: scale(0.985); }
button:focus-visible {
  outline: none;
  box-shadow: 0 0 0 4px rgba(185, 104, 70, 0.26);
}

button.secondary {
  background: var(--white);
  border: 1.5px solid var(--line-solid);
  color: var(--ink);
  font-size: 17px;   /* Deep Blue on white is 14.7:1, so any size is fine here. */
  padding: 15px;
}

/* ---- Confirmation -------------------------------------------------------- */
.code-card {
  background: var(--blue);
  border-radius: 20px;
  padding: 30px 20px 26px;
  text-align: center;
  margin-bottom: 28px;
}
.code-label {
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 3px;
  color: var(--mustard);
}
.code {
  margin: 0;
  font-weight: 500;
  font-size: 58px;
  line-height: 1;
  letter-spacing: 9px;
  /* Tabular figures, so six digits sit in an even block instead of jittering on
     the 1s. It has to be readable across a stand. */
  font-variant-numeric: tabular-nums;
  color: var(--white);
}
/* The address the code went to. Smaller than the old six-digit code because an
   email address is longer and must not overflow the card on a narrow phone, but
   still the largest thing in the box -- it is what the student needs to read back
   to check they typed it correctly. */
.code-email {
  margin: 0;
  font-weight: 500;
  font-size: 24px;
  line-height: 1.25;
  color: var(--white);
  word-break: break-all;
}

.keep-warning {
  margin: 0 0 26px;
  padding: 16px 18px;
  border: 1.5px solid var(--copper);
  border-radius: var(--radius);
  background: rgba(185, 104, 70, 0.06);
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink);
}
.keep-warning strong { font-weight: 500; }

.code-note {
  margin: 12px 0 0;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.65);
}

.done-details { margin-bottom: 26px; }
.done-details p {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 18px;
  margin: 0;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
  font-size: 15px;
}
.done-details span { color: var(--ink-faint); flex: 0 0 auto; }
.done-details strong {
  font-weight: 500;
  color: var(--ink);
  text-align: right;
}

/* --- What happens next --------------------------------------------------------
   Over the confirmation, not beside it. The rules that cost somebody something -
   one go a day, two for the week - have to be read before the phone goes back in
   a pocket, and anything sitting alongside the "check your email" panel loses to
   it every time. */
.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 20px;
  overflow-y: auto;                      /* long content on a short phone */
  -webkit-overflow-scrolling: touch;
  /* Scrolling the dialog must not start scrolling the form behind it once it
     reaches the end, which on a phone reads as the dialog jumping. */
  overscroll-behavior: contain;
  background: rgba(18, 40, 75, 0.62);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}
.modal.hidden { display: none; }

/* Focused programmatically when the dialog opens, so it must not draw a focus
   ring: nobody tabbed to it and a box around the whole card looks like an error. */
.modal-card:focus { outline: none; }

.modal-card {
  width: 100%;
  max-width: 30rem;
  /* Horizontal centring ONLY.
     `margin: auto` here overrode align-items: flex-start and centred the card
     vertically. A card taller than the viewport - 1218px against a phone's 700 -
     then overflows ABOVE the scroll origin, and that part cannot be scrolled to:
     the browser only scrolls down. So the dialog opened partway down its own
     content with the practice button already out of reach above.
     This is the fix. The scrollTop and focus handling in form.js are belt to its
     braces, and neither of them could have solved it. */
  margin: 0 auto;
  padding: 26px 22px 22px;
  border-radius: var(--radius);
  background: #fff;
  box-shadow: 0 18px 50px rgba(18, 40, 75, 0.28);
}
.modal-card h2 {
  margin: 0 0 18px;
  font-size: 26px;
  font-weight: 500;
  color: var(--ink);
}
.modal-card h3 {
  margin: 0 0 7px;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.modal-block {
  margin: 0 0 20px;
  padding: 0 0 18px;
  border-bottom: 1px solid var(--line);
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink);
}
.modal-block p { margin: 0 0 8px; }
.modal-block p:last-child { margin-bottom: 0; }
.modal-block strong { font-weight: 500; }
.modal-sub {
  font-size: 14px;
  color: var(--ink-soft);
}

/* The one thing they must not miss, so it is the one thing that is not plain. */
.modal-key {
  padding: 15px 16px;
  border: 1.5px solid var(--copper);
  border-radius: var(--radius);
  background: rgba(185, 104, 70, 0.06);
}
/* The one action available on this screen, so it is the biggest thing on it after
   the heading. Copper because that is the accent reserved for "do this", and full
   width because a phone thumb should not have to aim. */
.practice-cta-big {
  display: block;
  margin: 0 0 14px;
  padding: 22px 20px;
  border: 0;
  border-radius: 14px;
  background: var(--copper);
  color: #fff;
  font-size: 21px;
  font-weight: 500;
  letter-spacing: 0.01em;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  /* A solid slab underneath rather than a soft blur. That is what reads as a
     physical key with a side to it, and it is the same idea as the red button
     they will actually press at the stand. */
  box-shadow: 0 5px 0 #8f4e34, 0 9px 18px rgba(18, 40, 75, 0.22);
  transition: transform 80ms ease, box-shadow 80ms ease, background 120ms ease;
}
.practice-cta-big:hover { background: #c8734f; }

/* Pressed: the button travels the exact height of its own shadow, so it looks
   like it went down rather than like it moved. */
.practice-cta-big:active {
  transform: translateY(5px);
  box-shadow: 0 0 0 #8f4e34, 0 3px 8px rgba(18, 40, 75, 0.18);
}
.practice-cta-big:focus-visible {
  outline: 3px solid var(--blue);
  outline-offset: 4px;
}

@media (prefers-reduced-motion: reduce) {
  .practice-cta-big { transition: none; }
}
.practice-cta-note {
  margin: 0 0 22px;
  font-size: 14px;
  line-height: 1.5;
  text-align: center;
  color: var(--ink-soft);
}
.practice-cta-note strong { font-weight: 500; color: var(--ink); }

/* No rule under the final block: the dismiss button already closes the card. */
.modal-last { border-bottom: 0; padding-bottom: 0; margin-bottom: 20px; }
.modal-close { width: 100%; margin-top: 4px; }

.rules {
  margin: 0 0 28px;
  padding: 18px 20px 18px 38px;
  background: var(--tint);
  border-radius: var(--radius);
  color: var(--ink-soft);
  font-size: 15px;
  line-height: 1.6;
}
.rules li { margin-bottom: 7px; }
.rules li:last-child { margin-bottom: 0; }

/* ---- Prize note ---------------------------------------------------------- */
.prize-note {
  display: inline-block;
  margin-top: 6px;
  font-size: 14px;
  color: var(--ink-faint);
}

/* ---- The rules page ------------------------------------------------------ */
.terms { margin-bottom: 8px; }

.terms-lead {
  margin: 0 0 30px;
  padding: 16px 18px;
  background: var(--tint);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink);
}

.terms h2 {
  margin: 32px 0 10px;
  font-weight: 500;
  /* 19px, not 24: these are signposts through a long page, not headlines
     competing with the one at the top. */
  font-size: 19px;
  letter-spacing: 0.3px;
  color: var(--ink);
}

.terms p,
.terms li {
  margin: 0 0 11px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-soft);
}
.terms strong { color: var(--ink); font-weight: 500; }
.terms ul, .terms ol { margin: 0 0 11px; padding-left: 22px; }
.terms li { margin-bottom: 7px; }

.terms-table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 14px;
}
.terms-table td {
  padding: 11px 4px;
  border-bottom: 1px solid var(--line);
  font-size: 16px;
  color: var(--ink-soft);
  vertical-align: top;
}
.terms-table td:first-child { width: 42%; }
.terms-table strong { color: var(--ink); font-weight: 500; }

.terms-updated {
  margin-top: 30px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: 14px;
  color: var(--ink-faint);
}

/* Copper on white measures 4.09:1 -- below the 4.5:1 that normal-size text needs,
   MEASURED not assumed. So the link TEXT is ink (14.7:1) and the copper moves to
   the underline, where it is decoration rather than something anybody has to
   read. Same accent, same affordance, and it passes. */
.notice a,
.terms-back {
  color: var(--ink);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-color: var(--copper);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.notice a:hover,
.terms-back:hover { text-decoration-thickness: 3px; }
.terms-back { font-size: 16px; }
