/* admin-app stylesheet — trainings.arc42.org family design system.
   Values are lifted from _sass/oneflow/skins/_arc42.scss (the site's own
   measured tokens), not re-guessed. Every foreground/background pair below
   carries its WCAG 2.2 contrast ratio in a comment (ADR-0002: contrast is
   measured, never eyeballed). Ratios were computed with the standard
   relative-luminance formula against the exact hex pair named. */

:root {
  /* ---- Signature hue: dusty rose (BRAND.md, trainings row) ------------- */
  --band: #a04c5e;         /* masthead fill — white on it 5.69:1 */
  --deep: #743442;         /* headings, links, borders, hover — 8.92:1 on paper */
  --band-tint: #f6edef;    /* the ONLY sanctioned quiet text on the band — 4.95:1 */

  /* ---- Surfaces ---------------------------------------------------------
     $surface-1 = mix($band, $paper, 8%), $surface-2 = mix($band, $paper, 14%),
     $surface-hover = mix($band, $paper, 25%) — the family's 3-step wash ladder. */
  --paper: #fcfdff;        /* flat near-white; never pure #fff behind prose */
  --surface-1: #f5eff2;    /* cards: a training date, a form group */
  --surface-2: #efe4e8;    /* marked surfaces */
  --surface-hover: #e5d1d7;/* interactive hover fill */

  /* ---- Ink ---------------------------------------------------------------
     ink: #3d4144 — 10.12:1 on --paper, 9.08:1 on --surface-1
     ink-muted: #646769 — 5.60:1 on --paper, 5.02:1 on --surface-1 */
  --ink: #3d4144;
  --ink-muted: #646769;

  /* ---- Hairlines, two tiers ---------------------------------------------
     divider tier is decorative only, never the sole carrier of meaning;
     box/control tier wears the hue itself (5.59:1 on paper, well past the
     3:1 floor 1.4.11 requires for non-text UI components). */
  --hairline: #dcbfc7;      /* mix(band, paper, 35%) */
  --hairline-hover: #cea5af;/* mix(band, paper, 50%) */
  --border: var(--band);    /* 5.59:1 on paper */

  /* ---- Shared family tokens (BRAND.md), each with a job on this app ----- */
  --danger: #c22b47;        /* --arc42-coral-deep — white on it 5.63:1 */
  --amber: #ffc95c;         /* "few seats" / waitlist marker */
  --amber-ink: #4a3a0a;     /* on --amber: 7.24:1 */
  --green-wash: #d9f7d3;
  --green-ink: #1b5e20;     /* on --green-wash: 6.82:1; white on --green-ink: 7.87:1 */
  --grey-wash: #e8e8ea;     /* neutral, off-hue: the "full" status has no strong
                                semantic colour of its own, so it stays neutral
                                rather than borrowing a hue that means something
                                else on this site */
  --grey-ink: var(--ink);   /* #3d4144 on --grey-wash: 8.42:1 */

  /* ---- Type --------------------------------------------------------------
     Family constant #1 (DESIGN.md): Libre Caslon Text for headings only,
     Atkinson Hyperlegible Next for body and every UI control. Not
     self-hosted here (no woff2 shipped in admin-app/internal/web/static/) —
     falls back to the documented system stack rather than a font CDN, per
     the family's no-font-CDN privacy rule. */
  --serif: "Libre Caslon Text", Georgia, "Times New Roman", serif;
  --sans: "Atkinson Hyperlegible Next", "Atkinson Hyperlegible", system-ui,
    -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --radius: 4px;
  --bar-h: 3.25rem;

  /* The pinned-note shadow (DESIGN.md §2.3): zero blur, zero spread, deep
     hue, reserved for annotation-style elements pinned onto the page. */
  --pinned-note-shadow: 3px 3px 0 0 var(--deep);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);   /* ink 10.12:1 on this — see --ink above */
  color: var(--ink);
  font-family: var(--sans);
  line-height: 1.5;
}

h1, h2, h3 { font-family: var(--serif); color: var(--deep); /* 8.92:1 on paper */ }

a { color: var(--deep); /* 8.92:1 on paper */ }
a:hover { color: var(--band); /* 5.59:1 on paper */ }

/* ---- Masthead ------------------------------------------------------------ */
.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  height: var(--bar-h);
  padding: 0 1.25rem;
  background: var(--band);      /* white text on it: 5.69:1 */
  color: #ffffff;
}
.masthead > a {
  color: #ffffff;                /* 5.69:1 on --band */
  font-family: var(--serif);
  font-weight: 700;
  text-decoration: none;
  font-size: 1.1rem;
}
.masthead nav { display: flex; align-items: center; gap: 1rem; }
.masthead nav a {
  color: #ffffff;                 /* 5.69:1 on --band */
  text-decoration: none;
}
.masthead nav a:hover { text-decoration: underline; }
.masthead .who {
  color: var(--band-tint);        /* #f6edef, 4.95:1 on --band — NEVER rgba(.82), 4.41:1, fails */
  font-size: 0.9rem;
}

main {
  max-width: 75ch;               /* family reading measure, 65-75ch */
  margin: 0 auto;
  padding: 1.5rem 1.25rem 5rem;
}
table.dates { max-width: none; width: 100%; } /* tables are a documented wider-measure exception */

/* ---- Buttons and link-buttons -------------------------------------------- */
.button, button {
  font: inherit;
  min-height: 44px;
  padding: 0.5rem 1rem;
  border-radius: var(--radius);
  border: 1px solid var(--band);
  background: var(--band);
  color: #ffffff;                 /* 5.69:1 on --band */
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}
.button:hover, button:hover { background: var(--deep); border-color: var(--deep); } /* white 9.08:1 on --deep */

button.link {
  background: none;
  border: none;
  color: var(--deep);             /* 8.92:1 on paper */
  min-height: auto;
  padding: 0;
  text-decoration: underline;
}
button.link:hover { color: var(--band); background: none; } /* 5.59:1 on paper */
button.link.danger { color: var(--danger); }  /* #c22b47 as text on paper: measured 5.53:1 on --paper (#fcfdff), AA-safe for UI text */

/* ---- Forms (family form vocabulary, DESIGN.md §4) ------------------------ */
form.detail {
  display: grid;
  gap: 1rem;
  max-width: 60ch;
}
label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-weight: 600;
  color: var(--ink);              /* 10.12:1 on paper */
}
label small { font-weight: 400; color: var(--ink-muted); /* 5.60:1 on paper */ }
input, select, textarea {
  font: inherit;
  min-height: 44px;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--band);  /* box/control tier, 5.59:1 on paper */
  border-radius: var(--radius);
  background: var(--paper);
  color: var(--ink);
}
input:focus, select:focus, textarea:focus {
  outline: 3px solid var(--deep); /* focus ring on paper: 8.92:1 */
  outline-offset: 1px;
}
.actions { display: flex; gap: 1rem; align-items: center; }

ul.problems {
  background: color-mix(in oklab, var(--danger) 8%, var(--paper));
  border: 1px solid var(--danger);
  border-radius: var(--radius);
  padding: 0.75rem 1.25rem;
  color: var(--ink);               /* 10.12:1 base ink on a near-paper wash */
}
ul.problems li::marker { color: var(--danger); }

/* ---- Tables ---------------------------------------------------------------- */
table.dates { border-collapse: collapse; }
table.dates th, table.dates td {
  text-align: left;
  padding: 0.6rem 0.75rem;
  border-bottom: 1px solid var(--hairline); /* divider tier, decorative only */
}
table.dates thead th { color: var(--ink-muted); font-weight: 600; } /* 5.60:1 on paper */
table.dates tr.past { color: var(--ink-muted); } /* 5.60:1 on paper */
table.dates .row-actions { display: flex; gap: 0.75rem; white-space: nowrap; }
table.dates .row-actions form { display: inline; }

/* ---- Status badges ---------------------------------------------------------
   Each is a wash + dark ink pair, never saturated fill behind text
   (DESIGN.md §4 forms rule: emerald #2e9e67 fails AA as body text at 3.4:1,
   so status colour is always paired with a measured ink on a light wash). */
.status {
  display: inline-block;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 600;
}
.status-open       { background: var(--green-wash); color: var(--green-ink); } /* 6.82:1 */
.status-waitlist    { background: var(--amber);      color: var(--amber-ink); } /* 7.24:1 */
.status-full        { background: var(--grey-wash);  color: var(--grey-ink); }  /* 8.42:1 */
.status-cancelled   { background: color-mix(in oklab, var(--danger) 12%, var(--paper)); color: var(--danger); } /* text-on-wash: >= 5.53:1 (the wash is lighter than --paper, so the ratio against --danger only improves; base pair measured on button.link.danger) */

/* ---- Draft bar -------------------------------------------------------------- */
.draftbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 1.25rem;
  background: var(--deep);
  color: #ffffff;                  /* 9.08:1 on --deep */
  box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.15); /* the one sanctioned dynamic
                                                  elevation, not the static
                                                  pinned-note shadow */
}
.draftbar .button { background: #ffffff; color: var(--deep); border-color: #ffffff; } /* --deep 8.92:1 on white */
.draftbar .button:hover { background: var(--band-tint); }
.draftbar button.link { color: #ffffff; } /* 9.08:1 on --deep */

/* ---- Reduced motion -------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ---- Form structure (added with the grouped date/course forms) -------------
   Operate mode: the form is a task, so grouping and scanability outrank
   expression. Fieldsets carry the grouping semantically as well as visually,
   so a screen reader announces the legend with each control. */
.lede { color: var(--ink-muted); max-width: 62ch; } /* 5.60:1 on paper */

fieldset.group {
  border: 1px solid var(--hairline);   /* divider tier: decorative only */
  border-radius: var(--radius);
  padding: 1rem 1.25rem 1.25rem;
  margin: 0;
  display: grid;
  gap: 1rem;
  background: var(--paper);
}
fieldset.group > legend {
  font-family: var(--serif);
  color: var(--deep);                  /* 8.92:1 on paper */
  font-size: 1.05rem;
  padding: 0 0.4rem;
}

/* Two controls side by side where they are read as one fact (start/end,
   city/country). Collapses below the phone breakpoint rather than shrinking
   the fields into unusability. */
.row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 34rem) { .row { grid-template-columns: 1fr; } }

/* The required marker is decorative for assistive tech (aria-hidden) because
   the control itself carries `required`; it exists so the eye can triage the
   form without reading every label. */
.req { color: var(--danger); font-weight: 700; margin-left: 0.15rem; } /* 5.53:1 on paper */

.hint {
  font-weight: 400;
  color: var(--ink-muted);             /* 5.60:1 on paper */
  font-size: 0.85rem;
  margin: 0;
}
label > .hint { margin-top: 0.1rem; }

/* Checkbox roster. Stays a plain checkbox — Operate mode does not reinvent
   standard form controls, and a custom toggle here would buy nothing. */
ul.checks { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.35rem; }
@media (min-width: 40rem) { ul.checks { grid-template-columns: 1fr 1fr; } }
label.check {
  flex-direction: row;
  align-items: center;
  gap: 0.6rem;
  font-weight: 400;
  padding: 0.35rem 0.5rem;
  border-radius: var(--radius);
  min-height: 44px;                    /* same target size as every other control */
  cursor: pointer;
}
label.check:hover { background: var(--surface-1); }
label.check input[type="checkbox"] {
  min-height: auto;
  width: 1.15rem;
  height: 1.15rem;
  accent-color: var(--band);
  margin: 0;
  flex: none;
}

input[readonly] {
  background: var(--surface-1);        /* ink 9.08:1 on this */
  border-color: var(--hairline);
}
input::placeholder, textarea::placeholder { color: var(--ink-muted); } /* 5.60:1 — placeholders are text and hold the same floor */

/* Validation summary. role="alert" moves focus-order attention here; the
   heading names the job rather than the failure count. */
.problems {
  background: color-mix(in oklab, var(--danger) 8%, var(--paper));
  border: 1px solid var(--danger);
  border-radius: var(--radius);
  padding: 0.75rem 1.25rem;
  color: var(--ink);                   /* 10.12:1 on a near-paper wash */
}
.problems h2 { margin: 0.25rem 0 0.5rem; font-size: 1rem; color: var(--danger); } /* 5.53:1 */
.problems ul { margin: 0; padding-left: 1.2rem; }
.problems li::marker { color: var(--danger); }

ul.courses { list-style: none; padding: 0; display: grid; gap: 0.5rem; }
ul.courses li {
  padding: 0.75rem 1rem;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
}
ul.courses small { color: var(--ink-muted); margin-left: 0.5rem; } /* 5.60:1 */

/* ---- Notice page (non-maintainer landing) ---------------------------------
   Deliberately NOT styled as an error. Being turned away here is the expected
   outcome for everyone except two people, so it uses the calm surface wash and
   the signature hue — never --danger, which on this site means "something went
   wrong" and would frame an ordinary visitor as a fault. */
.notice { max-width: 62ch; }
.notice h1 { margin-top: 0.5rem; }
.notice h2 {
  font-size: 1.05rem;
  margin-top: 2rem;
  margin-bottom: 0.4rem;   /* more space above a heading than below it */
}
.notice .lede {
  background: var(--surface-1);   /* ink 9.08:1 on this */
  border-radius: var(--radius);
  padding: 0.9rem 1.1rem;
  color: var(--ink);
  margin-bottom: 1.75rem;
}
.notice code {
  background: var(--surface-2);   /* ink on --surface-2 stays above 8:1 */
  padding: 0.1rem 0.35rem;
  border-radius: 3px;
  font-size: 0.9em;
}
.notice form { margin: 0.75rem 0 0; }
.notice .hint { margin-top: 2.5rem; }

/* Secondary action: the recovery path, subordinate to the primary link out. */
button.secondary {
  background: var(--paper);
  color: var(--deep);              /* 8.92:1 on --paper */
  border: 1px solid var(--band);   /* 5.59:1 on paper, past the 3:1 UI floor */
}
button.secondary:hover {
  background: var(--surface-1);
  color: var(--deep);              /* 8.55:1 on --surface-1 */
  border-color: var(--deep);
}

/* The wordmark on a bare page: same type as the linked version, without
   implying it goes anywhere. */
.masthead .wordmark {
  color: #ffffff;                  /* 5.69:1 on --band */
  font-family: var(--serif);
  font-weight: 700;
  font-size: 1.1rem;
}

/* ---- Mascot ---------------------------------------------------------------
   The bar grows to give the mascot room: at the old 3.25rem it rendered about
   28px tall and read as a favicon rather than a logo. Transparent PNG, so it
   sits directly on the band with no white plate. */
:root { --bar-h: 4.5rem; }

.masthead .brand {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  color: #ffffff;                 /* 5.69:1 on --band */
  font-family: var(--serif);
  font-weight: 700;
  font-size: 1.1rem;
  text-decoration: none;
}
.masthead .mascot {
  height: 3rem;
  width: auto;
  display: block;
  flex: none;
}

/* Hero: the sign-in screen is the app's front door and the only page an
   outsider is likely to see, so the mascot gets real size there. */
.hero { max-width: 48ch; padding-top: 1rem; }
.hero-mascot {
  height: 9rem;
  width: auto;
  display: block;
  margin-bottom: 0.75rem;
}
.hero h1 { margin: 0 0 0.5rem; }
.hero .lede { margin-top: 0; }
.hero .hint { margin-top: 0.75rem; }

@media (max-width: 30rem) {
  /* Keep the wordmark readable before the mascot: on a narrow phone the two
     together overflow the bar. */
  .masthead .mascot { height: 2.25rem; }
  .masthead .brand { font-size: 1rem; }
  .hero-mascot { height: 7rem; }
}
