/* exgen-ui.css — ExGens delade formspråk.
 *
 * Primitiverna som varje sida bygger av: måttet, rösten, kortet, raden,
 * knapparna, etiketten, chipsen, fälten. Bröts ut ur exam-flow.css när
 * provskaparens formspråk skulle spridas till förbättring, pricing, konto och
 * larare — annars hade varje sida fått sin egen kopia och de hade glidit isär.
 *
 * Prefixet är kvar som .xf-*, men betyder numera "ExGen form" och inte "exam
 * flow". Ett namnbyte hade rört tusentals rader i app.html och js/exam-flow.js
 * utan att ge något tillbaka, och alternativet — dubbla selektorer för varje
 * regel — hade dubblerat filen och skapat en migrering som ingen blir klar med.
 *
 * exam-flow.css innehåller efter utbrytningen bara det som hör provFLÖDET till:
 * framstegslinjen, en-skärm-i-taget, materialläsningen, provläget, rättningen
 * och resultatet. Läser du det som händer på en enskild sida ligger det där.
 *
 * Ytorna och bläcket hämtas från style.css (--t/--t3/--s/--s2/--l2), inte från
 * exgen-tokens.css. Skälet är inte stilistiskt: exgen-tokens.css vänder sina
 * text- och ytvärden i ett @media (prefers-color-scheme: dark), medan style.css
 * sätter sidans faktiska bakgrund utan något sådant block. I mörkt läge blev
 * därför bläcket ljust mot en bakgrund som förblev ljus — .xf-note mätte 2,35:1.
 * style.css-tokens har samma värden i ljust läge och följer den bakgrund som
 * verkligen ritas, i båda lägena. Formtokens (radie, avstånd, typsnitt, rörelse)
 * hämtas fortfarande från exgen-tokens.css, de är färgneutrala.
 *
 * Råa färgvärden som står kvar, och varför:
 *   #00768F + rgba(0,118,143,.07/.22/.28) — den AA-säkra teal-accenten. Själva
 *     hexvärdet finns som style.css --a, men de tre genomskinliga varianterna
 *     saknar motsvarighet (--a-dim är .08, inte .07). Accenten hålls samlad som
 *     ett literalvärde hellre än att splittras på en token och tre rgba-rader
 *     som inte längre syns höra ihop.
 *   #fff — text ovanpå accentfärg.
 */

/* ── Tokens ──────────────────────────────────────────────────────────────── */
/* På :root, inte på #xf, så att varje sida kan bygga av samma värden utan att
   ligga inuti provskaparens behållare. */

:root {
  --xf-measure: 580px;
  --xf-ink: var(--t);
  --xf-ink-2: var(--t3);
  --xf-line: var(--l2);
  --xf-accent: #00768F;          /* AA-säker teal, samma som style.css --a */
  --xf-accent-soft: rgba(0, 118, 143, .07);
  --xf-machine: var(--exgen-navy);
}

/* ── Rörelse ─────────────────────────────────────────────────────────────── */
/* Delad av allt som kommer in på skärmen: skärmbyten, provark, inpass,
   rättningsloggen, begreppen i materialläsningen. */

@keyframes xf-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* ── Mått ────────────────────────────────────────────────────────────────── */
/* En kolumn, samma bredd på varje sida. Det är den enskilt viktigaste orsaken
   till att sidorna känns som samma produkt. */

.xf-measure {
  width: 100%;
  max-width: var(--xf-measure);
  margin-left: auto;
  margin-right: auto;
}

/* ── P.E.R:s röst ────────────────────────────────────────────────────────── */

.xf-per {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  margin-bottom: var(--exgen-space-8);
}

.xf-orb {
  flex: none;
  width: 10px;
  height: 10px;
  margin-top: 7px;
  border-radius: 50%;
  background: var(--xf-accent);
  position: relative;
}

/* Andningsringen är det enda som rör sig när sidan står still. Den säger att
   P.E.R är vaken utan att kräva uppmärksamhet. */
.xf-orb::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 1px solid var(--xf-accent);
  opacity: .3;
  animation: xf-breathe var(--xf-breathe, 3.2s) var(--exgen-motion-ease) infinite;
}

@keyframes xf-breathe {
  0%, 100% { transform: scale(.72); opacity: .35; }
  50%      { transform: scale(1);   opacity: 0;   }
}

/* Snabbare puls när P.E.R har en konkret fråga i fokus. Rörelse som betyder
   något, inte dekoration. Klassen sätts av perPaintSees() i shared.js. */
body.per-focused .xf-orb { --xf-breathe: 2s; }

/* exgen-tokens.css nollställer --exgen-motion-* under reduced-motion, men
   keyframe-varaktigheter går inte genom de tokens. Ringen stoppas här. */
@media (prefers-reduced-motion: reduce) {
  .xf-orb::after { animation: none; }
}

.xf-orb.busy::after { animation-duration: 1.1s; }

.xf-say {
  font-size: clamp(21px, 4.4vw, 27px);
  line-height: var(--exgen-leading-tight);
  letter-spacing: var(--exgen-tracking-tight);
  font-weight: var(--exgen-weight-semibold);
  margin: 0;
}

.xf-say em {
  font-style: normal;
  color: var(--xf-accent);
}

.xf-sub {
  font-size: var(--exgen-text-base);
  line-height: var(--exgen-leading-relaxed);
  color: var(--xf-ink-2);
  margin: 10px 0 0;
}

/* Skrivmarkören syns bara medan en rad skrivs fram. */
.xf-say.typing::after {
  content: "";
  display: inline-block;
  width: 2px;
  height: .95em;
  margin-left: 3px;
  vertical-align: -.12em;
  background: var(--xf-accent);
  animation: xf-caret .9s steps(1) infinite;
}

@keyframes xf-caret { 0%, 49% { opacity: 1 } 50%, 100% { opacity: 0 } }
/* ── Etiketter ───────────────────────────────────────────────────────────── */

.xf-eyebrow {
  font-family: var(--exgen-font-mono);
  font-size: 10.5px;
  letter-spacing: var(--exgen-tracking-wide);
  text-transform: uppercase;
  color: var(--xf-ink-2);
  margin-bottom: var(--exgen-space-3);
}
/* ── Val ─────────────────────────────────────────────────────────────────── */

.xf-opts {
  display: grid;
  gap: 8px;
  margin-bottom: var(--exgen-space-6);
}

.xf-opts.row {
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
}

@media (max-width: 520px) {
  .xf-opts.row { grid-auto-flow: row; }
}

.xf-opt {
  position: relative;
  text-align: left;
  width: 100%;
  padding: 15px 16px;
  background: var(--s);
  border: 1px solid var(--xf-line);
  border-radius: var(--exgen-radius-md);
  cursor: pointer;
  font-family: inherit;
  font-size: var(--exgen-text-base);
  font-weight: var(--exgen-weight-medium);
  color: var(--xf-ink);
  transition: border-color var(--exgen-motion-fast) var(--exgen-motion-ease),
              background var(--exgen-motion-fast) var(--exgen-motion-ease),
              transform var(--exgen-motion-fast) var(--exgen-motion-ease);
}

.xf-opt:hover { border-color: var(--xf-accent); }
.xf-opt:active { transform: scale(.99); }

.xf-opt.sel {
  border-color: var(--xf-accent);
  background: var(--xf-accent-soft);
}

/* Vald kant markeras på insidan så att raden inte hoppar 1px när den väljs. */
.xf-opt.sel::before {
  content: "";
  position: absolute;
  left: 0;
  top: 10px;
  bottom: 10px;
  width: 2px;
  border-radius: 0 2px 2px 0;
  background: var(--xf-accent);
}

.xf-opt small {
  display: block;
  margin-top: 3px;
  font-size: var(--exgen-text-xs);
  font-weight: var(--exgen-weight-regular);
  color: var(--xf-ink-2);
  line-height: var(--exgen-leading-normal);
}
/* ── Chips ───────────────────────────────────────────────────────────────── */

.xf-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-bottom: var(--exgen-space-4);
}

.xf-chip {
  padding: 7px 13px;
  border-radius: var(--exgen-radius-pill);
  border: 1px solid var(--xf-line);
  background: var(--s);
  font-family: inherit;
  font-size: 13.5px;
  color: var(--xf-ink-2);
  cursor: pointer;
  transition: all var(--exgen-motion-fast) var(--exgen-motion-ease);
}

.xf-chip:hover { border-color: var(--xf-accent); color: var(--xf-ink); }

.xf-chip.sel {
  border-color: var(--xf-accent);
  background: var(--xf-accent-soft);
  color: var(--xf-accent);
  font-weight: var(--exgen-weight-medium);
}
/* ── Fält ────────────────────────────────────────────────────────────────── */

.xf-input,
.xf-area {
  width: 100%;
  box-sizing: border-box;
  font-family: inherit;
  font-size: var(--exgen-text-lg);
  color: var(--xf-ink);
  background: var(--s);
  border: 1px solid var(--xf-line);
  border-radius: var(--exgen-radius-md);
  padding: 15px 16px;
  outline: none;
  transition: border-color var(--exgen-motion-fast) var(--exgen-motion-ease),
              box-shadow var(--exgen-motion-fast) var(--exgen-motion-ease);
}

.xf-input:focus,
.xf-area:focus {
  border-color: var(--xf-accent);
  box-shadow: 0 0 0 3px var(--xf-accent-soft);
}

.xf-area {
  min-height: 200px;
  resize: vertical;
  font-size: var(--exgen-text-base);
  line-height: var(--exgen-leading-relaxed);
}

.xf-input::placeholder,
.xf-area::placeholder { color: var(--xf-ink-2); opacity: .7; }
/* ── Kontraktskortet ─────────────────────────────────────────────────────── */

.xf-card {
  border: 1px solid var(--xf-line);
  border-radius: var(--exgen-radius-lg);
  background: var(--s);
  padding: var(--exgen-space-6);
  margin-bottom: var(--exgen-space-6);
}

.xf-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 11px 0;
  border-bottom: 1px solid var(--xf-line);
}

.xf-row:last-child { border-bottom: 0; padding-bottom: 0; }
.xf-row:first-child { padding-top: 0; }

.xf-row dt {
  font-family: var(--exgen-font-mono);
  font-size: 10.5px;
  letter-spacing: var(--exgen-tracking-wide);
  text-transform: uppercase;
  color: var(--xf-ink-2);
  flex: none;
}

.xf-row dd {
  margin: 0;
  text-align: right;
  font-size: var(--exgen-text-sm);
  font-weight: var(--exgen-weight-medium);
}

.xf-row dd small {
  display: block;
  font-weight: var(--exgen-weight-regular);
  color: var(--xf-ink-2);
  font-size: var(--exgen-text-xs);
  margin-top: 2px;
}
/* ── Knappar ─────────────────────────────────────────────────────────────── */

.xf-act {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}

/* Åtgärdsraden ska följa med när listan under den är lång. Modifierare, inte
   en ny primitiv — vokabulären här är avsiktligt arton selektorer kort. */
.xf-act--stick {
  position: sticky;
  top: 0;
  z-index: 2;
}

.xf-btn {
  font-family: inherit;
  font-size: var(--exgen-text-base);
  font-weight: var(--exgen-weight-semibold);
  padding: 14px 26px;
  border-radius: var(--exgen-radius-pill);
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform var(--exgen-motion-fast) var(--exgen-motion-ease),
              box-shadow var(--exgen-motion-fast) var(--exgen-motion-ease),
              opacity var(--exgen-motion-fast) var(--exgen-motion-ease);
}

.xf-btn.primary {
  background: var(--xf-accent);
  color: #fff;
  box-shadow: 0 2px 12px rgba(0, 118, 143, .22);
}

.xf-btn.primary:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 6px 20px rgba(0, 118, 143, .28);
}

.xf-btn.ghost {
  background: transparent;
  color: var(--xf-ink-2);
  border-color: var(--xf-line);
}

.xf-btn.ghost:hover:not(:disabled) { color: var(--xf-ink); border-color: var(--xf-ink-2); }

.xf-btn.quiet {
  background: none;
  border: 0;
  padding: 14px 4px;
  color: var(--xf-ink-2);
  font-weight: var(--exgen-weight-medium);
  font-size: var(--exgen-text-sm);
}

.xf-btn.quiet:hover { color: var(--xf-accent); }

.xf-btn:disabled { opacity: .4; cursor: not-allowed; transform: none; }

.xf-btn:focus-visible,
.xf-opt:focus-visible,
.xf-chip:focus-visible {
  outline: var(--exgen-focus-ring);
  outline-offset: var(--exgen-focus-offset);
}

.xf-note {
  font-size: var(--exgen-text-xs);
  color: var(--xf-ink-2);
  margin-top: var(--exgen-space-4);
  line-height: var(--exgen-leading-normal);
}

.xf-err {
  color: var(--exgen-error-text);
  font-size: var(--exgen-text-sm);
  margin-top: var(--exgen-space-3);
  min-height: 18px;
}

/* ── Skärmar ─────────────────────────────────────────────────────────────── */
/* Bodde i exam-flow.css tills js/xf-screens.js gav dem en andra användare.
   Förbättringssidan kan inte ladda exam-flow.css — den drar med sig .xf-exam
   som position:fixed över hela viewporten på en sida utan prov. app.html laddar
   båda filerna, så flytten syns inte där.

   Behållaren ägs INTE här. exam-flow.css sätter #xf till min-height:100dvh och
   display:flex för provflödets räkning; en annan konsument bestämmer själv.
   flex:1 nedan är helt enkelt inert om föräldern inte är en flexbehållare. */

.xf-screen {
  flex: 1;
  display: none;
  flex-direction: column;
  align-items: center;
  padding: clamp(24px, 6vh, 72px) 20px calc(96px + env(safe-area-inset-bottom, 0px));
}

.xf-screen.on { display: flex; }

.xf-inner {
  width: 100%;
  max-width: var(--xf-measure);
  /* auto-marginal i stället för justify-content:center. Båda centrerar när
     innehållet får plats, men centrering klipper toppen när det inte gör det —
     och resultatskärmen med tolv frågor gör det aldrig. */
  margin: auto 0;
}

/* Varje skärm kommer in genom att lyfta sig själv. Kort och en gång — rörelse
   som säger "ny skärm", inte rörelse som underhållning. */
.xf-screen.on > .xf-inner {
  animation: xf-rise var(--exgen-motion-slow) var(--exgen-motion-ease) both;
}

/* Skärmbytet flyttar fokus till rubriken så att en skärmläsare annonserar den
   nya skärmen. Rubriken är inte interaktiv — den bär tabindex="-1" enbart för
   att gå att fokusera programmatiskt — men Chromium låter den ändå matcha
   :focus-visible och målar sin egen ring (auto 1px rgb(0,95,204), mätt).

   Ringen tas bort. För den som ser är hela skärmbytet återkopplingen; en ram
   runt rubriken tillför ingenting och läser som ett renderingsfel. Fokus
   flyttas fortfarande, så annonseringen och tangentbordsordningen är oförändrade.
   Det här gällde app.html redan innan förbättringssidan fick skärmar. */
.xf-say:focus { outline: none; }

/* Keyframe-varaktigheter går inte genom --exgen-motion-*, som exgen-tokens.css
   nollar under reduced-motion. Lyftet stoppas därför här, bredvid det det
   stänger av. Regeln följde med från exam-flow.css:s samlade motion-block. */
@media (prefers-reduced-motion: reduce) {
  .xf-screen.on > .xf-inner { animation: none !important; opacity: 1 !important; transform: none !important; }
}
