/* ==========================================================================
   Team Cobblers — application form
   Near-black ground, off-white type, one electric signal color.
   Tokens follow DESIGN.md. All color in OKLCH.
   ========================================================================== */

:root {
  color-scheme: dark;

  /* ---- Color ---- */
  --ground:       oklch(17% 0.008 260);
  --ground-lift:  oklch(22% 0.010 260);   /* hover wells, pressed states */
  --type:         oklch(96% 0.004 260);
  --type-soft:    oklch(74% 0.008 260);
  --type-faint:   oklch(60% 0.010 260);
  --rule:         oklch(32% 0.012 260);
  /* rule-strong bounds inputs and the A-H key boxes, so it must clear the
     3:1 non-text contrast floor (WCAG 1.4.11), not merely look subtle. */
  --rule-strong:  oklch(55% 0.014 260);
  /* Brand accent #0b6286. Dark, so it works as a FILL with off-white on it
     (6.0:1) but only 2.8:1 against the ground -- it can never be text or a
     hairline here. --signal-lift is the same hue raised to 70% L for those. */
  --signal:       #0b6286;                 /* exact brand accent */
  --signal-deep:  oklch(39% 0.082 233);    /* hover / pressed */
  --signal-lift:  oklch(70% 0.110 233);    /* text, rules, progress on dark */
  --on-signal:    oklch(96% 0.004 260);    /* label on a signal fill */
  --error:        oklch(74% 0.155 25);

  /* ---- Type ---- */
  /* One family, committed weight and size contrast. No second face. */
  --face: "Schibsted Grotesk", ui-sans-serif, system-ui, -apple-system,
          "Segoe UI", Helvetica, Arial, sans-serif;

  --t-display:  clamp(3.375rem, 14vw, 6rem);
  --t-question: clamp(1.9375rem, 7.2vw, 3rem);
  --t-lead:     clamp(1.0625rem, 3.2vw, 1.1875rem);
  --t-body:     1.0625rem;
  --t-meta:     0.6875rem;

  /* ---- Space. Uneven on purpose: tight groups, wide separations. ---- */
  --gutter: clamp(1.5rem, 6vw, 5rem);
  --s-tight: 0.75rem;
  --s-snug:  1.25rem;
  --s-mid:   2rem;
  --s-wide:  3.25rem;

  /* ---- Motion ---- */
  --out: cubic-bezier(.16, 1, .3, 1);   /* ease-out-expo */
  --dur: 380ms;
  --dur-fast: 160ms;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  background: var(--ground);
}

body {
  margin: 0;
  min-height: 100svh;
  background: var(--ground);
  color: var(--type);
  font-family: var(--face);
  font-size: var(--t-body);
  /* Light-on-dark compensation: looser leading, a touch of tracking, one
     weight step up. Perceived weight drops on all three axes, so fix all three. */
  font-weight: 450;
  line-height: 1.58;
  letter-spacing: 0.005em;
  font-kerning: normal;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.sr {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Honeypot. Off-screen rather than display:none so bots still see it. */
.trap {
  position: absolute;
  left: -9999px;
  top: 0;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* ---------------------------------------------------------------- grain --- */

/* On a dark ground the grain has to lift, not multiply. */
.grain {
  position: fixed;
  inset: 0;
  width: 100%; height: 100%;
  opacity: 0.05;
  pointer-events: none;
  z-index: 3;
  mix-blend-mode: overlay;
}

/* -------------------------------------------------------------- progress --- */

.thread {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: 4;
  pointer-events: none;
  background: var(--rule);
}

.thread__stitch { display: none; }

/* Scales rather than animating width. */
.thread__fill {
  position: absolute;
  top: 0; left: 0;
  height: 100%;
  width: 100%;
  background: var(--signal-lift);
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform var(--dur) var(--out);
}

/* ---------------------------------------------------------------- stage --- */

.stage {
  position: relative;
  display: grid;
}

.apply { display: contents; }

.screen {
  grid-area: 1 / 1;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: calc(var(--gutter) + 1.5rem) var(--gutter) var(--gutter);
}

.screen[hidden] { display: none; }

/* Enter/exit. transform + opacity only. */
.screen {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition: opacity var(--dur) var(--out), transform var(--dur) var(--out);
}
.screen.is-active { opacity: 1; transform: none; }
.screen.is-leaving { opacity: 0; transform: translate3d(0, -14px, 0); }

.screen__body {
  width: 100%;
  max-width: 44rem;
  margin-inline: auto;
}

/* ------------------------------------------------------------ 1 · title --- */

/* Title block leads; the quote settles at the foot of the same surface. */
.screen--title {
  display: grid;
  grid-template-rows: 1fr auto;
  /* Grows with viewport height so the block lifts toward centre on tall
     screens instead of stranding 300px of void above it. */
  gap: clamp(var(--s-wide), 13vh, 9rem);
}

/* Bottom-anchored: title, festival line, action and quote read as one block
   with the breathing room gathered above, rather than a hole in the middle. */
.screen__body--title { align-self: end; }
.creed { align-self: end; }

.display {
  margin: 0;
  font-size: var(--t-display);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.033em;
  text-wrap: balance;
}

.festival {
  margin: var(--s-snug) 0 0;
  /* Wide enough to hold the festival name on one line where there is room;
     narrow viewports still wrap at the container. */
  max-width: 48ch;
  font-size: var(--t-lead);
  font-weight: 400;
  line-height: 1.45;
  color: var(--type-soft);
  text-wrap: pretty;
}

.festival__dates {
  display: block;
  margin-top: 0.45rem;
  font-size: var(--t-meta);
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--signal-lift);
}

/* The quote. Same surface as everything else, deliberately quiet. */
.creed {
  margin: 0;
  max-width: 44rem;
  margin-inline: auto;
  width: 100%;
}

.creed blockquote {
  margin: 0;
  max-width: 52ch;
  font-size: 0.9375rem;
  font-weight: 400;
  line-height: 1.62;
  color: var(--type-soft);
  text-wrap: pretty;
}

.creed__mark { display: none; }

.creed figcaption {
  margin: 0.45rem 0 0;
  max-width: 52ch;
  font-size: var(--t-meta);
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--type-faint);
}

/* ------------------------------------------------------------- question --- */

.question {
  margin: 0;
  font-size: var(--t-question);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -0.022em;
  text-wrap: balance;
  max-width: 30ch;
}

.lead {
  margin: var(--s-snug) 0 0;
  max-width: 56ch;
  font-size: var(--t-lead);
  font-weight: 400;
  line-height: 1.55;
  color: var(--type-soft);
  text-wrap: pretty;
}

/* --------------------------------------------------------------- fields --- */

.fields {
  display: flex;
  flex-direction: column;
  gap: var(--s-mid);
}

.field { position: relative; }

/* Screen 2's labels are the questions themselves. */
.field__label {
  display: block;
  margin-bottom: 0.3rem;
  font-size: clamp(1.25rem, 4.6vw, 1.625rem);
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: -0.018em;
  color: var(--type);
}

.field__input {
  display: block;
  width: 100%;
  padding: 0.6rem 0 0.65rem;
  border: 0;
  border-bottom: 1px solid var(--rule-strong);
  border-radius: 0;
  background: transparent;
  color: var(--type);
  font-family: inherit;
  font-size: var(--t-body);
  font-weight: 450;
  line-height: 1.45;
  transition: border-color var(--dur-fast) var(--out),
              box-shadow  var(--dur-fast) var(--out);
  appearance: none;
  -webkit-appearance: none;
}

.field__input--area {
  resize: vertical;
  min-height: 5.5rem;
  margin-top: var(--s-snug);
  max-width: 62ch;
}

.field__input:hover { border-bottom-color: var(--type-faint); }

/* Focus: the rule thickens into signal. No glow. */
.field__input:focus-visible {
  outline: none;
  border-bottom-color: var(--signal-lift);
  box-shadow: 0 1px 0 0 var(--signal-lift);
}

.field__input::placeholder { color: var(--type-faint); }

.field.is-invalid .field__input {
  border-bottom-color: var(--error);
  box-shadow: 0 1px 0 0 var(--error);
}

.field__error {
  margin: 0.55rem 0 0;
  font-size: 0.8125rem;
  font-weight: 450;
  line-height: 1.4;
  color: var(--error);
}
.field__error[hidden] { display: none; }

.field__error--form { margin-top: var(--s-snug); }

/* ---------------------------------------------------------------- roles --- */

.roles {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.roles .question { margin-bottom: var(--s-mid); padding: 0; }

.keys {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.375rem;
}

@media (min-width: 40rem) {
  .keys { grid-template-columns: 1fr 1fr; gap: 0.375rem 1.5rem; }
}

.key {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 2.9rem;
  padding: 0.3rem 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.key input {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
  pointer-events: none;
}

/* The letter box doubles as the visible keyboard shortcut. */
.key__sort {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.9rem;
  height: 1.9rem;
  border: 1px solid var(--rule-strong);
  border-radius: 3px;
  background: transparent;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0;
  /* 12px text: use the soft tone, not faint, to stay comfortably above AA. */
  color: var(--type-soft);
  transition: background-color var(--dur-fast) var(--out),
              border-color    var(--dur-fast) var(--out),
              color           var(--dur-fast) var(--out);
}

.key__name {
  font-size: var(--t-body);
  font-weight: 450;
  line-height: 1.3;
  color: var(--type-soft);
  transition: color var(--dur-fast) var(--out);
}

.key:hover .key__sort { border-color: var(--type-faint); color: var(--type-soft); }
.key:hover .key__name { color: var(--type); }

/* Selected: the key fills with signal and carries a check, never color alone. */
.key input:checked + .key__sort {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--on-signal);
  font-size: 0;
}
.key input:checked + .key__sort::after {
  content: "";
  width: 0.8rem;
  height: 0.45rem;
  border-left: 2px solid var(--on-signal);
  border-bottom: 2px solid var(--on-signal);
  transform: rotate(-45deg) translate(1px, -1px);
}

.key input:checked ~ .key__name { color: var(--type); font-weight: 550; }

.key input:focus-visible + .key__sort {
  outline: 2px solid var(--signal-lift);
  outline-offset: 3px;
}

.roles.is-invalid .key__sort { border-color: var(--error); }

/* --------------------------------------------------------------- action --- */

.press {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 3rem;
  padding: 0.8rem 2rem;
  border: 0;
  border-radius: 3px;
  background: var(--signal);
  color: var(--on-signal);
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 650;
  letter-spacing: 0.01em;
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--out),
              transform        var(--dur-fast) var(--out);
}

.press--lg {
  margin-top: var(--s-wide);
  min-height: 3.375rem;
  padding-inline: 2.5rem;
  font-size: 1.0625rem;
}

.press:hover { background: var(--signal-deep); }
.press:active { background: var(--signal-deep); transform: translateY(1px); }

.press:focus-visible {
  outline: 2px solid var(--type);
  outline-offset: 3px;
}

.press[aria-disabled="true"] {
  background: var(--rule-strong);
  color: var(--type-soft);
  cursor: progress;
}

.nav, .submit-row {
  display: flex;
  align-items: center;
  gap: var(--s-snug);
  margin-top: var(--s-wide);
}

/* Arrow buttons. No added words, per the copy constraint. */
.chevron {
  flex: none;
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  padding: 0;
  border: 1px solid var(--rule-strong);
  border-radius: 3px;
  background: transparent;
  color: var(--type-soft);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--out),
              background-color var(--dur-fast) var(--out),
              color var(--dur-fast) var(--out);
}

.chevron svg {
  width: 1.3rem;
  height: 1.3rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.chevron:hover {
  border-color: var(--type-faint);
  background: var(--ground-lift);
  color: var(--type);
}
.chevron:active { transform: translateY(1px); }
.chevron:focus-visible { outline: 2px solid var(--signal-lift); outline-offset: 3px; }

/* Forward arrow reads as the primary move on its screen. */
.chevron--fwd {
  border-color: var(--signal);
  background: var(--signal);
  color: var(--on-signal);
  margin-left: auto;
}
.chevron--fwd:hover {
  border-color: var(--signal-deep);
  background: var(--signal-deep);
  color: var(--on-signal);
}

.submit-row .press { margin-left: auto; }

/* --------------------------------------------------------------- thanks --- */

.screen--thanks .question {
  max-width: 32ch;
  font-size: clamp(1.5rem, 5.4vw, 2.375rem);
  line-height: 1.18;
}

.thanks__stamp {
  display: block;
  width: 2.5rem;
  height: 2.5rem;
  margin-bottom: var(--s-snug);
  fill: none;
  stroke: var(--signal-lift);
  stroke-width: 3.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.screen--thanks.is-active .thanks__stamp path {
  stroke-dasharray: 52;
  animation: stamp 520ms var(--out) 120ms both;
}

@keyframes stamp {
  from { stroke-dashoffset: 52; }
  to   { stroke-dashoffset: 0; }
}

/* ------------------------------------------------------- no-JS fallback --- */

.no-js .screen { opacity: 1; transform: none; }
.no-js .screen[hidden] { display: flex; }
.no-js .thread,
.no-js .chevron,
.no-js .screen--thanks { display: none; }
.no-js .screen { min-height: 0; padding-block: var(--s-wide); }
.no-js .screen--title { min-height: 100svh; }

/* --------------------------------------------------------------- motion --- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .screen { transform: none !important; }
}

/* ------------------------------------------------------- large viewport --- */

@media (min-width: 64rem) {
  .screen__body, .creed { max-width: 48rem; }
}

/* Short landscape phones: stop forcing a full viewport per screen. */
@media (max-height: 30rem) {
  .screen { min-height: 0; padding-block: var(--s-wide); }
  .screen--title { min-height: 100svh; }
  .press--lg { margin-top: var(--s-mid); }
  .nav, .submit-row { margin-top: var(--s-mid); }
}

@media (forced-colors: active) {
  .key input:checked + .key__sort { forced-color-adjust: none; }
  .chevron, .key__sort { border-color: CanvasText; }
}
