.auth-page { max-width: 28rem; padding-block: 3rem; }
.auth-form { display: grid; gap: .5rem; margin-block: 1.5rem; }
.auth-form label { font-weight: 600; }
.auth-form input {
  padding: .6rem .75rem;
  border: 1px solid var(--border, #d0d0d8);
  border-radius: .5rem;
  background: var(--bg-elev, #fff);
  color: inherit;
}
.auth-hint { font-size: .875rem; opacity: .75; margin: 0; }
.auth-error { color: var(--danger, #c0392b); font-size: .9rem; }
.auth-providers { display: grid; gap: .5rem; margin-block: 1rem; }

/* .header-actions is display: contents, so its children are direct grid items
   of .header-inner (1fr auto 1fr). A fourth item wrapped onto a second row,
   which is why the account control sat under the bar. Grouping the CTA and the
   account control keeps the header at three grid items. */
.header-end {
  display: flex;
  align-items: center;
  gap: .6rem;
  justify-self: end;
}

/* Deliberately unpositioned: the panel below anchors to .site-header instead,
   so it can hang off the bottom of the bar rather than off the avatar. */
.account-menu { display: inline-flex; align-items: center; }
.account-avatar {
  border: 0; background: none; padding: 0; cursor: pointer; line-height: 0;
}
.account-avatar img { border-radius: 50%; }
/* The avatar is centred in the bar, so anchoring the panel to the avatar
   (top: 100% + .5rem) opened it *inside* the header and the header's bottom
   rule was drawn straight across it. With .account-menu unpositioned, the
   nearest positioned ancestor is .site-header, so `top: 100%` is exactly the
   bottom edge of the bar — whatever the bar happens to measure. */
.account-panel {
  position: absolute;
  top: calc(100% + 10px);
  right: max(var(--header-gutter, 24px), env(safe-area-inset-right));
  left: auto;
  z-index: var(--z-header-popover, 60);
  display: grid;
  min-width: 12rem;
  max-width: calc(100vw - 2rem);
  padding: .4rem;
  background: var(--panel, #fff);
  border: 1px solid var(--border, #d0d0d8);
  border-radius: .85rem;
  box-shadow: var(--shadow-strong, 0 12px 32px rgb(0 0 0 / .14));
}
.account-panel a, .account-panel button {
  padding: .55rem .65rem; text-align: left; border: 0; background: none;
  color: var(--text, inherit); cursor: pointer; border-radius: .55rem;
  font: inherit; font-size: .9rem; font-weight: 600; text-decoration: none;
  transition: background-color .15s ease, color .15s ease;
}
.account-panel a:hover, .account-panel button:hover,
.account-panel a:focus-visible, .account-panel button:focus-visible {
  background: var(--bg-elevated, #f2f2f5);
  color: var(--primary, inherit);
  outline: none;
}

/* A class selector beats the user-agent [hidden] rule, so display: grid above
   would otherwise keep the menu on screen for everyone, signed in or not. */
.account-menu [hidden] { display: none; }

.account-avatar {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
}

.account-username {
  font-size: .9rem;
  font-weight: 600;
  line-height: 1;
  color: var(--text, #0f172a);
  max-width: 9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-username:empty { display: none; }

@media (max-width: 700px) {
  .account-username { display: none; }
}

/* Signup consent checkbox. The label sits beside the box rather than under it
   so the sentence reads as one line of text, and the whole row is a click
   target via the label's `for`. */
.auth-consent {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  margin-top: 0.75rem;
}

.auth-consent input[type='checkbox'] {
  width: 1.05rem;
  height: 1.05rem;
  margin: 0.15rem 0 0;
  flex: none;
  accent-color: var(--accent);
}

.auth-consent label {
  margin: 0;
  font-weight: 400;
  line-height: 1.45;
  cursor: pointer;
}

/* ═══════════════════════════════════════════════════════════
   Joining a class

   Two surfaces, one look: the card on the account page, and the dialog
   the account menu opens from any page. Both were previously styled
   somewhere the page that needed them could not see — the card's rules
   were in admin.css, which the account page does not load, so it
   rendered as bare text at the foot of the page.
   ═══════════════════════════════════════════════════════════ */

/* ── The join code field ────────────────────────────────────
   A code is read off a board or a slip of paper and typed in one go, so
   it gets room to breathe: monospace, tracked out, centred, and
   uppercased on the way in. */
.class-section input[type='text'],
.join-modal__card input[type='text'] {
  width: 100%;
  box-sizing: border-box;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--border, #d0d0d8);
  border-radius: 0.7rem;
  background: var(--bg, #fff);
  color: var(--text, inherit);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-align: center;
  text-transform: uppercase;
  transition: border-color .15s ease, box-shadow .15s ease;
}

.class-section input[type='text']:focus-visible,
.join-modal__card input[type='text']:focus-visible {
  outline: none;
  border-color: var(--primary, #0ea5e9);
  box-shadow: var(--ring, 0 0 0 4px rgb(14 165 233 / .15));
}

.class-section input[type='text']::placeholder,
.join-modal__card input[type='text']::placeholder {
  color: var(--muted, #64748b);
  font-weight: 500;
  letter-spacing: 0.16em;
  opacity: .55;
}

/* ── The card on the account page ───────────────────────────── */
.class-section {
  margin: 2rem 0 1.5rem;
  padding: 1.4rem 1.5rem;
  border: 1px solid var(--border, #d0d0d8);
  border-radius: 1rem;
  background: var(--panel, #fff);
  box-shadow: var(--shadow, 0 4px 20px rgb(15 23 42 / .06));
}

.class-section > h2 {
  margin: 0 0 0.9rem;
  font-size: 1.2rem;
  line-height: 1.2;
}

.class-section p {
  line-height: 1.55;
}

.class-section [data-class-view] > p:first-child {
  margin-top: 0;
}

.class-section .auth-form {
  margin-block: 1.1rem 0.75rem;
  gap: 0.45rem;
}

.class-section .auth-form label {
  font-size: 0.9rem;
}

.class-section .auth-form .btn {
  justify-self: start;
  margin-top: 0.35rem;
}

/* The code the learner joined with, or the one a teacher hands out: a
   value to be read back, so it is set apart from the sentence. */
.class-section [data-class-current-code] {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  border: 1px solid var(--border, #d0d0d8);
  border-radius: 0.45rem;
  background: var(--bg-elevated, #f2f2f5);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.95em;
  letter-spacing: 0.16em;
}

/* ── The dialog, opened from the account menu on any page ───── */
.join-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal, 1000);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

.join-modal[hidden] { display: none; }

.join-modal__scrim {
  position: absolute;
  inset: 0;
  background: rgb(8 12 18 / .55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  animation: join-modal-scrim-in .18s ease both;
}

.join-modal__card {
  position: relative;
  width: min(26rem, 100%);
  max-height: min(90vh, 44rem);
  overflow-y: auto;
  padding: 1.6rem 1.6rem 1.5rem;
  border: 1px solid var(--border, #d0d0d8);
  border-radius: 1.1rem;
  background: var(--panel, #fff);
  color: var(--text, #0f172a);
  box-shadow: 0 24px 60px rgb(8 12 18 / .35);
  animation: join-modal-card-in .22s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.join-modal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}

.join-modal__title {
  margin: 0;
  font-size: 1.3rem;
  line-height: 1.2;
}

/* An × in the corner: the Cancel button is below the fold on a short
   phone once the keyboard is up. */
.join-modal__close {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  margin: -0.25rem -0.35rem 0 0;
  padding: 0;
  border: 0;
  border-radius: 0.55rem;
  background: none;
  color: var(--muted, #64748b);
  font-size: 1.35rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}

.join-modal__close:hover {
  background: var(--bg-elevated, #f2f2f5);
  color: var(--text, inherit);
}

.join-modal__close:focus-visible {
  outline: none;
  box-shadow: var(--ring, 0 0 0 4px rgb(14 165 233 / .15));
}

.join-modal__body {
  margin: 0.5rem 0 1.15rem;
  font-size: 0.94rem;
  line-height: 1.55;
  color: var(--muted, #475569);
}

.join-modal__card label {
  display: block;
  margin-bottom: 0.4rem;
  font-weight: 600;
  font-size: 0.9rem;
}

.join-modal__card .auth-error {
  margin: 0.6rem 0 0;
}

.join-modal__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.15rem;
}

.join-modal__actions .btn {
  flex: 1 1 auto;
  justify-content: center;
}

.join-modal__leave {
  margin: 1.15rem 0 0;
  padding-top: 0.95rem;
  border-top: 1px solid var(--border, #d0d0d8);
}

/* The page behind a dialog must not scroll under it. */
body.join-modal-open {
  overflow: hidden;
}

@keyframes join-modal-scrim-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes join-modal-card-in {
  from { opacity: 0; transform: translateY(10px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .join-modal__scrim,
  .join-modal__card {
    animation: none;
  }
}

/* Which kind of account this is, said first and said plainly. Before this the
   only way to tell was to notice which controls were on the page. */
.class-role {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .5rem;
  margin: 0 0 1rem;
}

.class-role__badge {
  padding: .15rem .6rem;
  border-radius: 999px;
  font-size: .8rem;
  font-weight: 600;
  /* A word as well as a colour, so it reads in greyscale and to anyone who
     cannot tell the two apart. */
  border: 1px solid var(--border, #cbd5e1);
}

.class-role__badge.is-teacher { color: #14532d; background: #dcfce7; border-color: #86efac; }
.class-role__badge.is-student { color: #1e3a5f; background: #dbeafe; border-color: #93c5fd; }

[data-theme="dark"] .class-role__badge.is-teacher { color: #bbf7d0; background: #14361f; }
[data-theme="dark"] .class-role__badge.is-student { color: #bfdbfe; background: #17233b; }

.class-role__note { font-size: .85rem; color: var(--muted, #475569); }

.class-list { margin: .25rem 0 1rem; padding: 0; list-style: none; }

.class-list__item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .35rem;
  padding: .35rem 0;
  border-bottom: 1px solid var(--border, #cbd5e1);
}

.class-list__item:last-child { border-bottom: 0; }

.class-list__code {
  padding: .1rem .4rem;
  border-radius: .25rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-weight: 700;
  letter-spacing: .05em;
  background: var(--bg-elevated, #f1f5f9);
}

/* The role, at the top of the account menu. Not a link and not a control: it
   answers a question rather than offering an action, so it is set apart from
   the menu items under it. */
.account-panel__role {
  margin: 0;
  padding: .5rem .75rem;
  border-bottom: 1px solid var(--border, #cbd5e1);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--muted, #475569);
}

.account-panel__role.is-teacher { color: #15803d; }
[data-theme="dark"] .account-panel__role.is-teacher { color: #86efac; }
