/* One user, eight screens — plain CSS, no framework (docs/technology.md §5). */

:root {
  --ink: #1c1b19;
  --muted: #6b6862;
  --line: #ddd8d0;
  --paper: #fbfaf8;
  --accent: #1a4f7a;
  --warn: #8a5a00;
  --error: #9b2c2c;

  /* One hue per error class. The teacher learns them by colour, so they must
     stay stable across releases. */
  --c-gk: #b45309;
  --c-gz: #7c3aed;
  --c-sl: #1d4ed8;
  --c-df: #0f766e;
  --c-fw: #a21caf;
  --c-kom: #64748b;
  --c-zs: #64748b;
  --c-gr: #be123c;
  --c-tip: #4d7c0f;
  --c-unk: #78716c;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font: 16px/1.55 "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  color: var(--ink);
  background: var(--paper);
}

header {
  display: flex; align-items: baseline; gap: 1.5rem;
  padding: .9rem 1.6rem; border-bottom: 1px solid var(--line);
  background: #fff;
}
.brand { font-weight: 700; text-decoration: none; color: var(--ink); }

/* ── welcome (prompt 7) ──────────────────────────────────────────────────── */

.welcome { max-width: 44rem; }
.welcome h1 { font-size: 1.7rem; margin-bottom: .3rem; }
.welcome h2 { font-size: 1.05rem; margin-top: 1.6rem; }
.welcome ul { padding-left: 1.3rem; }
.welcome li { margin-bottom: .35rem; }
.welcome .btn {
  display: inline-block; padding: .5rem 1rem; border-radius: 4px;
  background: var(--accent); color: #fff; text-decoration: none;
  font-weight: 600;
}
.welcome .btn:hover { background: #144266; }
header nav { margin-left: auto; display: flex; gap: 1.2rem; align-items: baseline; }
header form { margin: 0; }

main { max-width: 78rem; margin: 0 auto; padding: 1.6rem; }
footer {
  max-width: 78rem; margin: 2rem auto; padding: 1rem 1.6rem;
  border-top: 1px solid var(--line);
  display: flex; gap: 1rem; justify-content: space-between;
  color: var(--muted); font-size: .82rem;
}
.commit { font-family: ui-monospace, monospace; }

a { color: var(--accent); }
h1 { font-size: 1.5rem; margin: 0 0 .2rem; }
h1 small { font-weight: 400; color: var(--muted); font-size: 1rem; }
h2 { font-size: 1.05rem; margin: 1.4rem 0 .5rem; }
.meta, .muted { color: var(--muted); font-size: .88rem; }
.error { color: var(--error); }
.ok { color: #166534; }

.banner {
  background: #fff7e6; border-bottom: 1px solid #f0d9a8;
  padding: .6rem 1.6rem; font-size: .88rem; color: var(--warn);
}

/* ── forms ─────────────────────────────────────────────────────────── */

.card {
  background: #fff; border: 1px solid var(--line); border-radius: 6px;
  padding: 1.2rem; max-width: 42rem; display: grid; gap: 1rem;
}
.card.narrow { max-width: 22rem; }
label { display: grid; gap: .3rem; font-weight: 600; }
label small { font-weight: 400; color: var(--muted); }
label.checkbox { display: block; font-weight: 600; }
label.checkbox small { display: block; }
input[type=text], input[type=password], input:not([type]) {
  font: inherit; padding: .45rem .6rem;
  border: 1px solid var(--line); border-radius: 4px; background: #fff;
}
input[type=range] { width: 100%; accent-color: var(--accent); }
output[data-strictness-output] { color: var(--accent); font-variant-numeric: tabular-nums; }
button {
  font: inherit; padding: .45rem .9rem; border-radius: 4px;
  border: 1px solid var(--accent); background: var(--accent); color: #fff;
  cursor: pointer;
}
button.link {
  background: none; border: none; color: var(--accent);
  padding: 0; text-decoration: underline; cursor: pointer; font-size: .85rem;
}
form.inline { display: inline; }

/* ── tables ────────────────────────────────────────────────────────── */

table { border-collapse: collapse; width: 100%; font-size: .92rem; }
th, td { text-align: left; padding: .45rem .6rem; border-bottom: 1px solid var(--line); }
th { font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
td.ctx { color: var(--muted); }

.status { font-size: .78rem; padding: .1rem .45rem; border-radius: 10px; background: #eee; }
.status-done { background: #dcfce7; }
.status-error { background: #fee2e2; }
.status-running, .status-pending { background: #fef3c7; }

/* Where the teacher stands, not where the machine stands. «neu» is the one
   that has to catch the eye in a list of twenty — it is the work not yet
   done; «freigegeben» is finished and may recede. */
.state-neu { background: #dbeafe; color: #1e40af; font-weight: 600; }
.state-arbeit { background: #fef3c7; color: #854d0e; }
.state-freigegeben { background: #dcfce7; color: #166534; }
.state-wartet { background: #f1f0ec; color: var(--muted); }
.state-fehler { background: #fee2e2; color: var(--error); }
h1 .status, h2 .status { vertical-align: middle; margin-left: .5rem; font-weight: 400; }

.profile .bar { width: 50%; }
.profile .bar span { display: block; height: .6rem; background: var(--accent); border-radius: 3px; }

/* ── review ────────────────────────────────────────────────────────── */

.working { color: var(--muted); padding: 2rem 0; }

.review { display: grid; grid-template-columns: minmax(0, 1fr) 22rem; gap: 1.6rem; align-items: start; }
.review > .essay-navigation, .review > .feedback { grid-column: 1 / -1; }
.review > .feedback { display: grid; gap: 1.4rem; }
.essay-navigation { display: flex; justify-content: space-between; align-items: center; }
.essay-navigation .disabled { color: var(--muted); }
@media (max-width: 60rem) {
  .review { grid-template-columns: 1fr; }
  .review > .essay-navigation, .review > .feedback { grid-column: 1; }
}

/* Assignment block — sits above .review so it does not steal a column.
   No grid rule; it lays out as a plain block. */
.assignment {
  background: #fff; border: 1px solid var(--line); border-radius: 6px;
  padding: 1rem 1.4rem; margin: 0 0 1.4rem;
}
.assignment h2 { margin: 0 0 .5rem; }
.assignment blockquote {
  margin: 0; font-style: italic; color: var(--muted);
  border-left: 3px solid var(--line); padding-left: .8rem;
}

.text {
  background: #fff; border: 1px solid var(--line); border-radius: 6px;
  /* 2.6, not 1.9: the correction is written above the line, and it needs
     the room. Below that the suggestions collide with the line above. */
  padding: 1.9rem 1.6rem 1.4rem; line-height: 2.6;
}
.text p { margin: 0 0 1rem; }
.text .quote { background: #f2f0ec; padding: .05em 0; }

/* One custom property per error class, so the underline and the correction
   written above the word cannot drift apart. */
mark.f {
  --f: var(--c-unk);
  background: none;
  border-bottom: 2px solid var(--f);
  color: inherit; padding-bottom: 1px;
}
mark.f-dismissed { border-bottom-style: dotted; opacity: .45; }
mark.f-gk { --f: var(--c-gk); }
mark.f-gz { --f: var(--c-gz); }
mark.f-sl { --f: var(--c-sl); }
mark.f-df { --f: var(--c-df); }
mark.f-fw { --f: var(--c-fw); }
mark.f-kom { --f: var(--c-kom); }
mark.f-zs { --f: var(--c-zs); }
mark.f-gr { --f: var(--c-gr); }
mark.f-tip { --f: var(--c-tip); }

/* The correction above the word — a teacher's pen, in the colour of the
   error class. It is drawn from the `data-fix` attribute and is never a
   text node: the essay in the DOM must stay character-identical to the
   stored text, or every offset after it would be a lie. */
mark.f[data-fix] { position: relative; }
mark.f[data-fix]::after {
  content: attr(data-fix);
  position: absolute;
  left: 0; bottom: 100%;
  font-size: .72em; line-height: 1.25;
  white-space: nowrap;
  color: var(--f);
  pointer-events: none;
}
/* The inner one of two overlapping findings moves up a line, so two
   corrections on the same word do not print on top of each other. */
mark.f[data-fix] mark.f[data-fix]::after { bottom: calc(100% + .95em); }

.findings h2 { margin-top: 0; }
.counts { list-style: none; padding: 0; margin: 0 0 1rem; font-size: .85rem; }
.counts li { display: flex; gap: .4rem; align-items: center; }
.counts b { margin-left: auto; font-variant-numeric: tabular-nums; }

.dot { width: .6rem; height: .6rem; border-radius: 50%; display: inline-block; background: var(--c-unk); }
.dot-gk { background: var(--c-gk); } .dot-gz { background: var(--c-gz); }
.dot-sl { background: var(--c-sl); } .dot-df { background: var(--c-df); }
.dot-fw { background: var(--c-fw); } .dot-kom { background: var(--c-kom); }
.dot-zs { background: var(--c-zs); } .dot-gr { background: var(--c-gr); }
.dot-tip { background: var(--c-tip); }

.finding {
  background: #fff; border: 1px solid var(--line); border-radius: 6px;
  padding: .7rem .8rem; margin-bottom: .6rem; font-size: .9rem;
}
.finding.dismissed { opacity: .5; }
.finding header { display: flex; gap: .4rem; align-items: baseline; flex-wrap: wrap; }
.finding .arrow { color: var(--muted); }
.finding .code { margin-left: auto; font-size: .75rem; color: var(--muted); }
.finding .ctx { color: var(--muted); font-size: .85rem; margin: .4rem 0; }
.finding footer { display: flex; gap: .9rem; }

@media print {
  header, footer, .banner, .findings, button { display: none; }
  body { background: #fff; }
  /* The corrections above the words are the point of the printout, so the
     line height stays generous even though the border and padding go. */
  .text { border: none; padding: 0; line-height: 2.6; }
}

/* explanation from the model — visually subordinate to the finding itself,
   because the finding is deterministic and the explanation is not */
.finding .explain {
  margin: .4rem 0 0; font-size: .88rem;
  border-left: 2px solid var(--line); padding-left: .6rem;
}
.finding .explain .rule { display: block; color: var(--muted); font-size: .8rem; }

.scroll { overflow-x: auto; }
td.zero { color: var(--line); }

/* ── review workflow (prompt 2) ─────────────────────────────────── */

td.actions { white-space: nowrap; }
td.actions .action-link,
td.actions .link {
  font-size: .85rem;
  margin-right: .7rem;
  display: inline-block;
}
td.actions .reprompt { display: inline-block; margin-right: .7rem; }
td.actions .reprompt summary.action-link { cursor: pointer; }
td.actions .reprompt .card { margin-top: .5rem; padding: .7rem; gap: .5rem; }
td.actions .reprompt textarea {
  font: inherit; padding: .4rem .5rem;
  border: 1px solid var(--line); border-radius: 4px; background: #fff;
}

tr.preview-row:empty { display: none; }
tr.preview-row td { background: #fff; padding: 1rem 1.6rem; }

.feedback {
  background: #fff; border: 1px solid var(--line); border-radius: 6px;
  padding: 1rem 1.4rem; margin-bottom: 1.4rem;
}
.feedback h2 { margin-top: 0; }
.feedback-block { margin: .8rem 0; }
.feedback-block h3 { font-size: .98rem; margin: .4rem 0; }
.feedback-block h3 small { font-weight: 400; }
.feedback-block pre {
  white-space: pre-wrap; font: inherit; color: var(--muted);
  background: #f7f5f1; padding: .4rem .6rem; border-radius: 4px;
}

/* The detailed assessment is a <details> element so it is collapsed by
   default. <summary> is the heading — same font weight as h2, same
   margin — so opening it does not change the visual weight the other
   boxes carry. */
details.feedback-block { background: #fff; }
details.feedback-block > summary {
  list-style: none;
  cursor: pointer;
  font-size: 1.05rem;
  font-weight: 600;
  margin: 1.4rem 0 .5rem;
  display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline;
}
details.feedback-block > summary::-webkit-details-marker { display: none; }
details.feedback-block > summary::before {
  content: "▸";
  display: inline-block;
  margin-right: .35rem;
  transition: transform .12s ease-out;
  color: var(--muted);
}
details.feedback-block[open] > summary::before {
  transform: rotate(90deg);
}
details.feedback-block > summary .title { font-weight: 700; }
details.feedback-block > summary .badge {
  font-weight: 400; font-size: .82rem; padding: .1rem .5rem;
  border: 1px solid var(--warn); color: var(--warn); border-radius: 10px;
}
details.feedback-block > summary small { font-weight: 400; }
