/* Shared authentication pages — T1.4
 *
 * Every login portal, the forgotten-password form and the reset form all use
 * this one stylesheet, so they cannot drift apart the way the four login
 * templates did.
 *
 * Everything visual is a token. Change a token here and every role's login page
 * changes with it; that is the point of the block below, and nothing further
 * down should hard-code a colour, a size or a radius.
 *
 * Values are taken from the design handoff (static/omega/tokens.css) so these
 * pages sit in the same family as the rebuilt learner pages, but they are
 * declared independently: the login pages must render before any dashboard
 * stylesheet is involved.
 *
 * Mobile first. The base rules are the phone layout; the one media query adds
 * the wider treatment.
 */

:root {
  /* Surfaces */
  --auth-canvas:        #E7DFCD;
  --auth-surface:       #FFFFFF;
  --auth-surface-tint:  #EEE1C3;
  --auth-border:        #E4DED2;

  /* Ink */
  --auth-ink:           #141210;
  --auth-body:          #4A4234;
  --auth-muted:         #5F574A;

  /* Brand */
  --auth-accent:        #C84E20;
  --auth-accent-hover:  #B9471C;
  --auth-on-accent:     #FFFFFF;

  /* State */
  --auth-danger:        #8C2E12;
  --auth-danger-bg:     #F2DED4;
  --auth-focus:         #1E4E79;

  /* Type */
  --auth-font: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
  --auth-size-title:    26px;
  --auth-size-body:     15px;
  --auth-size-label:    14px;
  --auth-size-small:    13px;
  --auth-weight-title:  700;
  --auth-weight-label:  600;

  /* Spacing — 4px scale */
  --auth-gap-xs: 4px;
  --auth-gap-sm: 8px;
  --auth-gap:    16px;
  --auth-gap-lg: 24px;
  --auth-gap-xl: 32px;

  /* Shape */
  --auth-radius:        12px;
  --auth-radius-input:  10px;
  --auth-border-width:  1px;

  /* Focus — the same ring everywhere, never removed */
  --auth-focus-width:   3px;
  --auth-focus-offset:  2px;

  /* The identity plate. Dark in both themes, because the logo is white. */
  --auth-plate:        #141210;
  --auth-plate-muted:  #C7BEAE;
  --auth-plate-chip:   rgba(244, 236, 216, 0.12);
  --auth-plate-ink:    #F4ECD8;

  /* Controls. 48px comfortably clears the 24x24 minimum WCAG 2.2 asks for. */
  --auth-control-height: 48px;

  /* The two panels. The brand side is dark in EVERY theme — the logo artwork is
   * dark lettering that gets inverted onto it, and a light ground would lose
   * it. The page behind the shell is a shade off the form panel so the shell
   * reads as a card rather than as the whole window. */
  --auth-page:         #DCD2BC;
  --auth-panel:        #F2E8D8;
  --auth-shell-radius: 20px;
  --auth-brand-ring:   rgba(200, 78, 32, 0.10);
}

/* Dark mode uses the same tokens, redefined. Nothing below this block needs to
 * know which theme is active.
 *
 * Three states, and all three have to work:
 *   - no choice made      -> follow the operating system (the media query)
 *   - "light" chosen      -> stay light even on a dark system (:not([light]))
 *   - "dark" chosen       -> go dark even on a light system (the second rule)
 *
 * The two lists below are identical and MUST be changed together. Plain CSS has
 * no way to share declarations between a media query and a bare selector, and
 * duplicating six lines is better than the toggle only working one way round —
 * which is what happened when only the media query existed.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --auth-canvas:       #141210;
    --auth-surface:      #1E1B18;
    --auth-surface-tint: #25211D;
    --auth-border:       #3B352E;
    --auth-ink:          #F4ECD8;
    --auth-body:         #C7BEAE;
    --auth-muted:        #8E8577;
    --auth-accent:       #E0915A;
    --auth-accent-hover: #EEA771;
    --auth-on-accent:    #141210;
    --auth-danger:       #EE9A7E;
    --auth-danger-bg:    #3A211A;
    --auth-focus:        #9CC4E8;
    --auth-plate:        #0E0C0B;
    --auth-page:         #0B0A09;
    --auth-panel:        #2A251F;
    --auth-brand-ring:   rgba(224, 145, 90, 0.09);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --auth-canvas:       #141210;
  --auth-surface:      #1E1B18;
  --auth-surface-tint: #25211D;
  --auth-border:       #3B352E;
  --auth-ink:          #F4ECD8;
  --auth-body:         #C7BEAE;
  --auth-muted:        #8E8577;
  --auth-accent:       #E0915A;
  --auth-accent-hover: #EEA771;
  --auth-on-accent:    #141210;
  --auth-danger:       #EE9A7E;
  --auth-danger-bg:    #3A211A;
  --auth-focus:        #9CC4E8;
  --auth-plate:        #0E0C0B;
  --auth-page:         #0B0A09;
  --auth-panel:        #2A251F;
  --auth-brand-ring:   rgba(224, 145, 90, 0.09);
}

:root[data-theme="light"] { color-scheme: light; }

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

body.auth-body {
  margin: 0;
  min-height: 100vh;
  background: var(--auth-page);
  color: var(--auth-body);
  font-family: var(--auth-font);
  font-size: var(--auth-size-body);
  line-height: 1.55;
}

/* Mobile first: one column — a compact header, then the form, then a footer
 * strip. The two-column arrangement arrives with the wide media query at the
 * bottom of this file.
 *
 * overflow is left VISIBLE so the PAGE scrolls as a document rather than a
 * panel scrolling inside a fixed box; the rings are clipped by .auth-brand
 * itself, which is where that clipping belongs. */
.auth-shell {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  background: var(--auth-panel);
}

/* --- the brand side ----------------------------------------------------- */
.auth-brand {
  /* A hairline where the two panels meet. In the light theme the colours part
   * company on their own; in the dark theme they are close enough that without
   * this the split does not read as a split at all. */
  box-shadow: 0 1px 0 var(--auth-border);
  position: relative;
  display: flex;
  flex-direction: column;
  /* Stacked, this is the whole distance between the mark and everything below
   * it, and at 24px the two ran together. Side by side it does not apply — the
   * pitch is pushed to the foot of the panel by its own auto margin. */
  gap: 44px;
  padding: var(--auth-gap-lg) var(--auth-gap);
  background: var(--auth-plate);
  color: var(--auth-plate-ink);
  overflow: hidden;
}

/* Two large rings, drawn with borders rather than an image so they cost nothing
 * to load and take their colour from the tokens. Decorative: aria-hidden in the
 * markup, and they carry no information. */
.auth-brand-rings { position: absolute; inset: 0; pointer-events: none; }
.auth-brand-rings::before,
.auth-brand-rings::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  border: 40px solid var(--auth-brand-ring);
}
.auth-brand-rings::before { width: 420px; height: 420px; top: -170px; left: -110px; }
.auth-brand-rings::after  { width: 300px; height: 300px; bottom: -160px; right: -120px;
                            border-width: 28px; }

.auth-brand-top,
.auth-brand-pitch { position: relative; }   /* above the rings */

/* Shown in both layouts.
 *
 * It was hidden while stacked for one round, on the reasoning that a phone
 * should open with the form rather than with an advertisement. Precious looked
 * at that and asked for it back: on a phone this panel is the only place the
 * product introduces itself, and a bare header above a form said nothing about
 * what somebody was signing in to.
 *
 * The cost is real and accepted — roughly 200px above the first field on a
 * handset. What makes it tolerable is that the page scrolls normally, so
 * nothing is trapped in a panel or clipped out of reach. */
.auth-brand-pitch {
  margin-top: auto;   /* mark at the head of the panel, pitch at its foot */
}

.auth-pitch-head {
  margin: 0 0 var(--auth-gap-sm);
  font-size: 22px;
  font-weight: var(--auth-weight-title);
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--auth-plate-ink);
  text-wrap: balance;
}

.auth-pitch-body {
  margin: 0 0 var(--auth-gap-lg);
  font-size: var(--auth-size-label);
  color: var(--auth-plate-muted);
  max-width: 42ch;
}

/* --- the form side ------------------------------------------------------ */
.auth-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Anchored near the top rather than centred. The form changes height between
   * the three steps, and centring made it move up and down as somebody worked
   * through them — the field they were about to use kept shifting. */
  align-items: flex-start;
  padding: var(--auth-gap-xl) var(--auth-gap);
  background: var(--auth-panel);
}

.auth-form-column { width: 100%; max-width: 400px; }

/* --- identity ------------------------------------------------------------
 * The mark and the portal name, at the top of the brand panel.
 */
.auth-heading {
  margin: 0;
  font-size: 0;   /* the mark carries the wording; its alt text is the heading */
  line-height: 0;
}

.auth-logo {
  display: block;
  width: auto;
  max-width: 100%;
  height: 26px;
  /* The artwork is dark lettering on transparency — the existing portal page
   * inverts it for dark backgrounds in exactly the same way. The panel behind
   * it is dark in EVERY theme, so this is unconditional rather than
   * theme-dependent, which is what made my first attempt right in one theme and
   * wrong in the other. */
  filter: invert(1);
}

.auth-portal {
  display: inline-block;
  margin-top: var(--auth-gap-sm);
  padding: 2px 10px;
  border-radius: 9999px;
  background: var(--auth-plate-chip);
  color: var(--auth-plate-ink);
  font-size: var(--auth-size-small);
  font-weight: var(--auth-weight-label);
}

/* --- trust markers and footer -------------------------------------------- */
/* On the brand panel, below the pitch. Reassurance for somebody deciding
 * whether this is the right place — not instructions for filling in the form,
 * so it does not stand between the heading and the first field. */
.auth-trust {
  display: flex;
  flex-wrap: wrap;
  gap: var(--auth-gap-sm) var(--auth-gap-lg);
  margin: 0;
  padding: var(--auth-gap) 0 0;
  border-top: var(--auth-border-width) solid var(--auth-plate-chip);
  list-style: none;
  font-size: var(--auth-size-small);
  color: var(--auth-plate-muted);
}
.auth-trust li { display: flex; align-items: center; gap: var(--auth-gap-xs); }
.auth-trust svg { width: 16px; height: 16px; flex: none; color: var(--auth-accent); }

/* --- the parent brand ---------------------------------------------------- */
/* At the foot of the promotional panel, right-aligned — diagonally opposite the
 * Omega mark at its top left, inside the same dark box.
 *
 * In the flow, in both layouts. It spent one round absolutely positioned so it
 * could be a footer strip on mobile, and being out of the flow meant the panel
 * laid the trust markers into the same space and printed one across the other.
 * Back in the flow, that cannot happen. */
.auth-parent {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--auth-gap-sm);
  margin: var(--auth-gap-lg) 0 0;
  font-size: var(--auth-size-small);
  color: var(--auth-plate-muted);
}

/* 20px, against the 26px Omega mark at the head of the panel, so it reads as
 * the smaller of the two. It will not go much below this: it is a hairline
 * wordmark, and once the strokes fall under a pixel it fades to grey however
 * the file is prepared. An SVG would not have that limit. */
.auth-parent-logo {
  display: block;
  width: auto;
  height: 20px;
}

.auth-footer {
  margin-top: var(--auth-gap-xl);
  padding-top: var(--auth-gap);
  border-top: var(--auth-border-width) solid var(--auth-border);
  font-size: var(--auth-size-small);
  color: var(--auth-muted);
}

.auth-title {
  margin: 0 0 var(--auth-gap-xs);
  font-size: var(--auth-size-title);
  font-weight: var(--auth-weight-title);
  letter-spacing: -0.02em;
  color: var(--auth-ink);
}

.auth-lede {
  margin: 0 0 var(--auth-gap-lg);
  font-size: 17px;
  font-weight: var(--auth-weight-label);
  color: var(--auth-ink);
  text-wrap: balance;
}

/* --- the three steps ---------------------------------------------------- */
.auth-steps {
  display: flex;
  gap: var(--auth-gap-xs);
  margin-bottom: var(--auth-gap-xl);
  padding: 0;
  list-style: none;
  font-size: var(--auth-size-small);
  color: var(--auth-muted);
}
.auth-step { display: flex; align-items: center; gap: var(--auth-gap-xs); }
.auth-step + .auth-step::before { content: "›"; margin-right: var(--auth-gap-xs); }
.auth-step[aria-current="step"] { color: var(--auth-ink); font-weight: var(--auth-weight-label); }

/* --- fields -------------------------------------------------------------- */
.auth-field { margin-bottom: var(--auth-gap-lg); }

.auth-label {
  display: block;
  margin-bottom: var(--auth-gap-xs);
  font-size: var(--auth-size-label);
  font-weight: var(--auth-weight-label);
  color: var(--auth-ink);
}

.auth-hint {
  display: block;
  /* A full step, not 4px. A hint pressed against its own field reads as part of
   * the box rather than as guidance about it — most visibly above the home
   * dropdown, where the two were touching. */
  margin-bottom: var(--auth-gap);
  font-size: var(--auth-size-small);
  color: var(--auth-muted);
}

.auth-input,
.auth-select {
  width: 100%;
  min-height: var(--auth-control-height);
  padding: 0 12px;
  font: inherit;
  color: var(--auth-ink);
  background: var(--auth-surface);
  border: var(--auth-border-width) solid var(--auth-border);
  border-radius: var(--auth-radius-input);
}

.auth-input:focus-visible,
.auth-select:focus-visible,
.auth-btn:focus-visible,
.auth-link:focus-visible {
  outline: var(--auth-focus-width) solid var(--auth-focus);
  outline-offset: var(--auth-focus-offset);
}

/* Focus is never removed — only restyled. Taking it away makes the form
 * unusable by keyboard, which is a large share of the people using it. */
.auth-input:focus, .auth-select:focus { border-color: var(--auth-ink); }

.auth-readonly {
  background: var(--auth-surface-tint);
  color: var(--auth-body);
}

/* --- errors -------------------------------------------------------------- */
.auth-error {
  display: flex;
  gap: var(--auth-gap-sm);
  margin-bottom: var(--auth-gap);
  padding: 12px;
  background: var(--auth-danger-bg);
  border: var(--auth-border-width) solid var(--auth-danger);
  border-radius: var(--auth-radius-input);
  color: var(--auth-danger);
  font-size: var(--auth-size-label);
}

/* The error is focused after a failed attempt, so it must show a ring. */
.auth-error:focus-visible {
  outline: var(--auth-focus-width) solid var(--auth-danger);
  outline-offset: var(--auth-focus-offset);
}

/* --- buttons ------------------------------------------------------------- */
.auth-btn {
  margin-top: var(--auth-gap-sm);
  width: 100%;
  min-height: var(--auth-control-height);
  padding: 0 var(--auth-gap-lg);
  font: inherit;
  font-weight: var(--auth-weight-label);
  color: var(--auth-on-accent);
  background: var(--auth-accent);
  border: none;
  border-radius: var(--auth-radius-input);
  cursor: pointer;
}
.auth-btn:hover { background: var(--auth-accent-hover); }

.auth-btn-quiet {
  background: transparent;
  color: var(--auth-ink);
  border: var(--auth-border-width) solid var(--auth-ink);
  margin-top: var(--auth-gap-sm);
}
.auth-btn-quiet:hover { background: var(--auth-surface-tint); }

.auth-links {
  margin-top: var(--auth-gap-lg);
  padding-top: var(--auth-gap-lg);
  border-top: var(--auth-border-width) solid var(--auth-border);
  font-size: var(--auth-size-label);
}

.auth-link { color: var(--auth-accent-hover); font-weight: var(--auth-weight-label); }

.auth-note {
  margin-top: var(--auth-gap);
  font-size: var(--auth-size-small);
  color: var(--auth-muted);
}

/* --- a field with an icon, and the password reveal ----------------------- */
/* The icon is decorative — the label says what the field is. It is there
 * because the design supplied has one, not because it carries meaning, so it is
 * aria-hidden and the field is still fully usable without it. */
.auth-control { position: relative; display: flex; align-items: center; }

.auth-control-icon {
  position: absolute;
  left: 14px;
  width: 18px; height: 18px;
  color: var(--auth-muted);
  pointer-events: none;
}
.auth-control .auth-input { padding-left: 42px; }
.auth-control .auth-input[data-reveal] { padding-right: 48px; }

/* A real button, focusable and labelled, not an icon that only responds to a
 * mouse. It reports its state with aria-pressed. */
.auth-reveal {
  position: absolute;
  right: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px; height: 36px;
  padding: 0;
  background: none;
  border: none;
  border-radius: var(--auth-gap-sm);
  color: var(--auth-muted);
  cursor: pointer;
}
.auth-reveal:hover { color: var(--auth-ink); }
.auth-reveal:focus-visible {
  outline: var(--auth-focus-width) solid var(--auth-focus);
  outline-offset: var(--auth-focus-offset);
}
.auth-reveal svg { width: 18px; height: 18px; }
/* Only one of the two icons shows; which one depends on the pressed state. */
.auth-reveal .auth-reveal-off { display: none; }
.auth-reveal[aria-pressed="true"] .auth-reveal-on  { display: none; }
.auth-reveal[aria-pressed="true"] .auth-reveal-off { display: block; }

/* The label and the forgotten-password link share a line, as in the design. */
.auth-label-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--auth-gap);
}

/* --- the closing note --------------------------------------------------- */
.auth-aside {
  margin-top: var(--auth-gap-lg);
  padding-top: var(--auth-gap-lg);
  border-top: var(--auth-border-width) solid var(--auth-border);
}
.auth-aside-title {
  margin: 0 0 var(--auth-gap-xs);
  font-size: var(--auth-size-label);
  font-weight: var(--auth-weight-label);
  color: var(--auth-ink);
}
.auth-aside p { margin: 0; font-size: var(--auth-size-small); color: var(--auth-muted); }

/* --- the theme toggle ---------------------------------------------------- */
/* It lives on the brand panel, which is dark in every theme and is the top of
 * the page in BOTH layouts — so one set of colours works stacked and side by
 * side, and the control never lands on a ground it was not designed for. */
.auth-brand-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--auth-gap);
}

/* A circle, sized past the 24x24 minimum WCAG 2.2 asks of a target. The word it
 * used to carry now lives in aria-label and title. */
.auth-theme {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 36px;
  height: 36px;
  padding: 0;
  background: var(--auth-plate-chip);
  border: var(--auth-border-width) solid transparent;
  border-radius: 50%;
  color: var(--auth-plate-ink);
  font: inherit;
  cursor: pointer;
}
.auth-theme:hover { border-color: var(--auth-plate-muted); }
.auth-theme:focus-visible {
  outline: var(--auth-focus-width) solid var(--auth-plate-ink);
  outline-offset: var(--auth-focus-offset);
}
.auth-theme svg { width: 17px; height: 17px; flex: none; }

/* aria-pressed is the state, and the state drives the picture: pressed means
 * dark is on, so the button offers the sun. One attribute, no class to keep in
 * step with it. */
.auth-theme .auth-theme-sun { display: none; }
.auth-theme[aria-pressed="true"] .auth-theme-sun  { display: block; }
.auth-theme[aria-pressed="true"] .auth-theme-moon { display: none; }


/* Visible only to screen readers. Used for the live region that announces a
 * failed attempt. */
.auth-sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (min-width: 480px) {
  .auth-brand { padding: var(--auth-gap-xl); }
  .auth-panel { padding: var(--auth-gap-xl); }
}

/* Two columns. Below this the panels stack, because side by side would leave
 * the form about 150px wide. */
@media (min-width: 900px) {
  body.auth-body {
    display: flex;
    padding: var(--auth-gap-lg);
  }

  /* Centred by AUTO MARGINS, not by align-items. Centring a flex child taller
   * than the viewport clips its top and puts it beyond the reach of scrolling;
   * auto margins centre it and still let the page scroll to all of it. */
  .auth-shell {
    margin: auto;
    flex-direction: row;
    /* A floor, not a fixed height. Fixing it is what forced the form panel to
     * scroll inside its own box. */
    min-height: 620px;
    width: 100%;
    max-width: 1180px;
    border-radius: var(--auth-shell-radius);
    overflow: hidden;          /* the rounded corners clip the panels */
  }

  /* The brand side is a fixed share; the form side takes the rest. A fraction
   * each way would let a long headline change how wide the form is. */
  /* Side by side, the hairline moves from the foot of the panel to its edge. */
  .auth-brand {
    flex: 0 0 46%;
    padding: var(--auth-gap-xl) 40px;
    box-shadow: 1px 0 0 var(--auth-border);
  }

  .auth-pitch-head { font-size: 34px; }
  .auth-pitch-body { display: block; }

  /* Still flex-start, inherited from the base rule. Centring here would
   * reintroduce exactly the movement the base rule avoids — the form is a
   * different height at each of the three steps.
   *
   * No overflow-y. The shell grows with the form and the PAGE scrolls, so there
   * is one scrollbar on screen instead of two, and a long step cannot end up
   * scrolling inside a box the size of a card. */
  .auth-panel {
    flex: 1 1 auto;
    padding: 72px 56px var(--auth-gap-xl);
  }

}

/* Respect a stated preference for less movement. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* --- "Keep me signed in" -----------------------------------------------------------
   The fork's auth pages have no checkbox; the staff door carried one in its own inline
   styles. Rewritten here in the auth tokens so the shared template can offer it. */
.auth-check {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 var(--auth-gap);
  cursor: pointer;
  font-size: var(--auth-size-label);
  font-weight: 500;
  color: var(--auth-body);
}
.auth-check input {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 1.5px solid var(--auth-border);
  border-radius: 5px;
  background: var(--auth-surface);
  cursor: pointer;
  position: relative;
}
.auth-check input:checked {
  background: var(--auth-accent);
  border-color: var(--auth-accent);
}
.auth-check input:checked::after {
  content: "";
  position: absolute;
  left: 5px;
  top: 1px;
  width: 4px;
  height: 9px;
  border: solid var(--auth-on-accent);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.auth-check input:focus-visible {
  outline: 2px solid var(--auth-focus);
  outline-offset: 2px;
}

/* The fork only ever put .auth-btn on a <button>, so it relies on button defaults for
   its box. "Change organisation" is a link — it navigates, it does not submit — so the
   class needs to lay out as a block on an anchor too. */
a.auth-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  text-decoration: none;
}
