/* build-marker: 2026-08-09-table-middle-rowactions-nowrap */
/* =====================================================================
   The College Prof: design system
   Palette and typography are fixed by the brief. Layout, spacing, and
   the group rail treatment are the design decisions.
   ===================================================================== */

:root {
  --navy:        #172f43;
  --olive:       #474B24;
  --sage-mid:    #7E936B;
  --sage-light:  #9ABD97;
  --sage-pale:   #B6D7B9;
  --surface:     #e1e8ed;
  --ink:         #333333;
  --white:       #ffffff;

  --navy-80:  rgba(23, 47, 67, 0.80);
  --navy-12:  rgba(23, 47, 67, 0.12);
  --navy-06:  rgba(23, 47, 67, 0.06);
  --overlay:  rgba(0, 0, 0, 0.50);

  --font-body: 'Lato', Arial, Helvetica, sans-serif;

  --step--1: 0.8125rem;
  --step-0:  1rem;
  --step-1:  1.1875rem;
  --step-2:  1.4375rem;
  --step-3:  1.875rem;
  --step-4:  2.375rem;

  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;

  --radius:    8px;
  --radius-sm: 6px;
  --shadow:    0 1px 2px rgba(23,47,67,0.06), 0 6px 20px rgba(23,47,67,0.08);
  --shadow-lg: 0 12px 40px rgba(23,47,67,0.18);
  --rail:      4px;
}

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

/* ---------- Native app feel ---------- */
/* Hiding the browser's own address bar and toolbar only gets a PWA
   halfway to feeling like an app. The rest of the way is these: cross
   document navigations that fade rather than flash white between
   pages, no rubber band scroll that reveals what is behind the page,
   no 300ms delay or accidental double tap zoom on a button, and no
   dashed focus/selection callout on things meant to be tapped rather
   than read. */

@view-transition {
  navigation: auto;
}

html {
  -webkit-text-size-adjust: 100%;
  overscroll-behavior-y: contain;
}

body {
  overscroll-behavior-y: contain;
  -webkit-tap-highlight-color: transparent;
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--ink);
  background: var(--surface);
  min-height: 100vh;
}

a, button, .btn, .card, .tabbar__item, .feature, [role="button"] {
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

button, .btn, .tabbar__item, .sidebar__link, .card, .drawer__close {
  transition: transform 120ms ease, opacity 120ms ease, background-color 140ms ease, box-shadow 140ms ease;
}
button:active, .btn:active, .tabbar__item:active, .card:active {
  transform: scale(0.97);
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) {
    animation: none !important;
  }
  button:active, .btn:active, .tabbar__item:active, .card:active { transform: none; }
}

h1, h2, h3, h4 { font-weight: 900; line-height: 1.2; color: var(--navy); margin: 0 0 var(--space-3); letter-spacing: -0.01em; }
h1 { font-size: var(--step-3); }
h2 { font-size: var(--step-2); }
h3 { font-size: var(--step-1); }
p  { margin: 0 0 var(--space-4); }
a  { color: var(--navy); }

:focus-visible {
  outline: 3px solid var(--sage-mid);
  outline-offset: 2px;
  border-radius: 3px;
}

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--navy); color: var(--white);
  padding: var(--space-3) var(--space-4); z-index: 100;
}
.skip-link:focus { left: 0; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- Application shell ---------- */

.shell { display: flex; min-height: 100vh; flex-direction: column; }

.masthead {
  background: var(--navy);
  color: var(--white);
  padding: calc(var(--space-3) + env(safe-area-inset-top, 0px)) var(--space-4) var(--space-3);
  display: flex; align-items: center; gap: var(--space-4);
  position: sticky; top: 0; z-index: 40;
}

.masthead__brand {
  font-weight: 900; font-size: var(--step-1);
  color: var(--white); text-decoration: none;
  letter-spacing: -0.02em; display: flex; align-items: center; gap: var(--space-3);
}

.brand-logo { display: block; width: auto; height: 26px; flex: 0 0 auto; }

.masthead__spacer { margin-left: auto; }

.masthead__user {
  display: flex; align-items: center; gap: var(--space-3);
  font-size: var(--step--1);
}

.avatar {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--sage-mid); color: var(--white);
  display: grid; place-items: center; font-weight: 700; font-size: var(--step--1);
  flex: 0 0 auto;
}

.masthead__meta { display: none; line-height: 1.25; }
.masthead__meta strong { display: block; font-weight: 700; }
.masthead__meta span { color: var(--sage-pale); font-size: 0.75rem; }

.layout { display: flex; flex: 1 1 auto; align-items: flex-start; }

.sidebar {
  display: none;
  width: 232px; flex: 0 0 232px;
  padding: var(--space-5) var(--space-4);
  position: sticky; top: 58px; align-self: flex-start;
  max-height: calc(100vh - 58px);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.sidebar__group { margin-bottom: var(--space-5); }

/* The account footer sits apart from the course work above it: same
   link treatment, but separated by a rule so a reader scanning for a
   course destination stops before reaching it. */
.sidebar__group--account {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--navy-12);
  margin-bottom: var(--space-3);
}

.sidebar__label {
  font-size: 0.6875rem; font-weight: 900; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--olive);
  margin: 0 0 var(--space-2); padding-left: var(--space-3);
}

.sidebar__link {
  display: block; padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm); text-decoration: none;
  color: var(--navy); font-size: var(--step--1); font-weight: 700;
  border-left: var(--rail) solid transparent;
}
.sidebar__link:hover { background: var(--navy-06); }
.sidebar__link[aria-current="page"] { background: var(--white); border-left-color: var(--sage-mid); }
.sidebar__link--pending { color: var(--navy-80); font-weight: 400; }

.main { flex: 1 1 auto; min-width: 0; padding: var(--space-5) var(--space-4) var(--space-7); }

/* ---------- Section tabs ---------- */
/* Facets of a single page, shown on the page itself rather than promoted
   to separate destinations in the main menu. They wrap rather than
   scroll, so no option is hidden off the edge on a narrow screen. */

.tabs {
  display: flex; flex-wrap: wrap; gap: var(--space-2);
  margin: var(--space-4) 0 0;
}
.tabs__link {
  display: inline-flex; align-items: center;
  padding: var(--space-2) var(--space-3);
  border-radius: 99px; text-decoration: none;
  font-size: var(--step--1); font-weight: 700;
  color: var(--navy); background: var(--navy-06);
  border: 1px solid transparent;
}
.tabs__link:hover { background: var(--navy-12); }
.tabs__link[aria-current="page"] { background: var(--navy); color: var(--white); }

/* ---------- Mobile tab bar and full menu drawer ---------- */
/* Below the desktop breakpoint the sidebar is replaced entirely by a
   fixed bottom tab bar of icons, the way a native mobile app presents
   its primary sections, with a "More" button opening every remaining
   destination as a full screen drawer. */

.sidebar__icon { display: inline-flex; flex: 0 0 auto; }
.sidebar__link { display: flex; align-items: center; gap: var(--space-3); }

.main--with-tabbar { padding-bottom: calc(78px + env(safe-area-inset-bottom, 0px)); }

.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  display: flex; background: var(--white); border-top: 1px solid var(--surface);
  box-shadow: 0 -2px 10px rgba(23,47,67,0.08);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  padding-left: env(safe-area-inset-left, 0px);
  padding-right: env(safe-area-inset-right, 0px);
}

.tabbar__item {
  flex: 1 1 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; padding: var(--space-2) 0 var(--space-1);
  color: var(--navy-80); text-decoration: none; background: none; border: 0;
  font: inherit; font-size: 0.6875rem; font-weight: 700; cursor: pointer;
}
.tabbar__item svg { color: var(--navy-80); }
.tabbar__item[aria-current="page"],
.tabbar__item[aria-expanded="true"] { color: var(--navy); }
.tabbar__item[aria-current="page"] svg,
.tabbar__item[aria-expanded="true"] svg { color: var(--sage-mid); }

.drawer {
  position: fixed; inset: 0; z-index: 60; display: none;
}
.drawer.is-open { display: block; }
.drawer::before {
  content: ""; position: absolute; inset: 0; background: rgba(23,47,67,0.5);
}
.drawer__panel {
  position: absolute; right: 0; top: 0; bottom: 0; width: min(320px, 86vw);
  background: var(--white); overflow-y: auto;
  transform: translateX(100%); transition: transform 0.2s ease;
  padding: var(--space-4);
}
.drawer.is-open .drawer__panel { transform: translateX(0); }
.drawer__head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--space-4); padding-bottom: var(--space-3); border-bottom: 1px solid var(--surface);
}
.drawer__head .masthead__brand { color: var(--navy); }
.drawer__close {
  background: none; border: 0; color: var(--navy); cursor: pointer; padding: var(--space-2);
  display: flex;
}

.page-head { margin-bottom: var(--space-5); }
.page-head p { color: var(--olive); margin: 0; }

/* The paragraphs in a page head are zeroed above, so the one holding the
   page's action buttons needs its gap restored here. This used to be
   done with a margin on .btn itself, which meant every button on the
   site carried a 20px top offset and sat low beside anything inline next
   to it: a status pill, a form control, another button. Spacing between
   blocks belongs to the block, not to the component that happens to be
   inside one of them. */
.page-head p + p { margin-top: var(--space-4); }

/* ---------- The group rail: the dashboard signature ---------- */

.rail {
  display: flex; align-items: center; gap: var(--space-3);
  margin: var(--space-6) 0 var(--space-4);
}
.rail:first-of-type { margin-top: var(--space-4); }

.rail__label {
  font-size: 0.6875rem; font-weight: 900; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--olive); white-space: nowrap;
}
.rail__line { flex: 1 1 auto; height: 2px; background: var(--navy-12); }
.rail__count {
  font-size: 0.6875rem; font-weight: 700; color: var(--olive);
  background: var(--sage-pale); border-radius: 99px; padding: 2px 8px;
}

/* ---------- Cards ---------- */

.cards {
  display: grid; gap: var(--space-4);
  grid-template-columns: 1fr;
}

.card {
  background: var(--white);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  border-left: var(--rail) solid var(--sage-pale);
  padding: var(--space-4) var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-2);
  text-decoration: none; color: inherit;
  transition: transform 140ms ease, box-shadow 140ms ease, border-color 140ms ease;
  margin-top:20px;
}
.card:hover, .card:focus-visible { transform: translateY(-2px); box-shadow: var(--shadow-lg); border-left-color: var(--sage-mid); }
.card--pending { cursor: default; }
.card--pending:hover { transform: none; box-shadow: var(--shadow); border-left-color: var(--sage-pale); }

/* A reading with nothing to open, such as a textbook chapter, renders as
   a plain <div> rather than a link, so it must not invite a click. */
.card--static { cursor: default; }
.card--static:hover { transform: none; box-shadow: var(--shadow); border-left-color: var(--sage-pale); }

.card__title { font-weight: 900; color: var(--navy); font-size: var(--step-1); }
.card__body { font-size: var(--step--1); color: var(--ink); margin: 0; }

.card__flag {
  align-self: flex-start; margin-top: var(--space-1);
  font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--olive); background: var(--surface);
  border-radius: 99px; padding: 3px 10px;
}

/* ---------- Statistics strip ---------- */

.stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); margin-bottom: var(--space-4); }
.stat {
  background: var(--navy); color: var(--white);
  border-radius: var(--radius); padding: var(--space-4);
}
.stat__value { font-size: var(--step-3); font-weight: 900; line-height: 1; }
.stat__label { font-size: var(--step--1); color: var(--sage-pale); }

/* ---------- Tables ---------- */

.panel {
  background: var(--white); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: var(--space-5); margin-top: var(--space-5);
}
.table { width: 100%; border-collapse: collapse; font-size: var(--step--1); }
.table th {
  text-align: left; font-size: 0.6875rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--olive);
  border-bottom: 2px solid var(--navy-12); padding: var(--space-2) var(--space-2);
}
.table td { padding: var(--space-3) var(--space-2); border-bottom: 1px solid var(--navy-06); vertical-align: top; }
.table--middle td { vertical-align: middle; }
/* A Reading Week row, in every table that lists the term's weeks. */
tr.week-row--reading { background-color: rgba(0,0,0,0.30); }
/* .btn carries its own vertical-align:middle so it lines up with form
   inputs beside it in a row, but that is inline-level alignment (to
   the surrounding text's baseline/x-height), not true box centering.
   Inside a table cell the td's own vertical-align:middle already does
   correct centering, and the button's inline one fights it, dragging
   the button a few pixels below the row's actual centre. The margin
   reset that used to sit here as well is no longer needed, since .btn
   no longer carries a margin for any other rule to undo. */
.table--middle td .btn { vertical-align: baseline; }
.table tr:last-child td { border-bottom: 0; vertical-align: middle;}

@media (max-width: 700px) {
  /* A table wider than a phone screen scrolls sideways within its own
     panel rather than forcing the whole page to overflow. This is a
     single rule rather than a wrapper element added to every table
     across every phase, so it applies everywhere consistently. */
  .table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; white-space: nowrap; }
  .table thead, .table tbody, .table tr { display: revert; }
}

/* ---------- Forms ---------- */

.form-row { margin-bottom: var(--space-4); }
.form-label { display: block; font-weight: 700; font-size: var(--step--1); color: var(--navy); margin-bottom: var(--space-2); }
.form-hint { font-size: var(--step--1); color: var(--olive); margin-top: var(--space-2); }

.form-input {
  width: 100%; font: inherit; color: var(--ink);
  padding: var(--space-3); border: 1px solid var(--navy-12);
  border-radius: var(--radius-sm); background: var(--white);
}
.form-input:focus { border-color: var(--sage-mid); outline: 3px solid rgba(126,147,107,0.35); outline-offset: 0; }

/* ---------- Rich text editor ----------
   Built by richtext.js on any <textarea data-richtext>, which only ever
   appears in the markup for a signed-in administrator - everyone else
   gets a bare textarea and no editor at all. The textarea itself stays
   in the DOM (hidden) as the field that actually submits with the form;
   .richtext-editor is a contenteditable surface that mirrors it live, so
   bold/italic/list formatting is seen as it's applied rather than typed
   as literal tags. */
.richtext { margin-bottom: 0; }

.richtext-toolbar {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-1);
  padding: var(--space-2); margin-bottom: 0;
  border: 1px solid var(--navy-12); border-bottom: none;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  background: var(--navy-06);
}
.richtext-toolbar__button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; padding: 0;
  color: var(--navy); background: var(--white);
  border: 1px solid var(--navy-12); border-radius: var(--radius-sm);
  cursor: pointer;
}
.richtext-toolbar__button svg { width: 16px; height: 16px; }
.richtext-toolbar__button:hover { border-color: var(--sage-mid); background: var(--sage-pale); }
.richtext-toolbar__button:focus-visible { outline: 3px solid rgba(126,147,107,0.35); outline-offset: 1px; }
.richtext-toolbar__button.is-active { background: var(--sage-mid); border-color: var(--sage-mid); color: var(--white); }
.richtext-toolbar__select {
  height: 2rem; padding: 0 var(--space-2); font-size: var(--step--1);
  color: var(--navy); background: var(--white);
  border: 1px solid var(--navy-12); border-radius: var(--radius-sm);
  cursor: pointer;
}
.richtext-toolbar__select:hover { border-color: var(--sage-mid); }
.richtext-toolbar__select:focus-visible { outline: 3px solid rgba(126,147,107,0.35); outline-offset: 1px; }
.richtext-toolbar__divider { width: 1px; height: 1.5rem; background: var(--navy-12); margin: 0 var(--space-1); }
.richtext-toolbar__hint { font-size: var(--step--1); color: var(--olive); margin-left: auto; }

.richtext-editor {
  min-height: calc(var(--richtext-min-lines, 4) * 1.6em);
  border-top-left-radius: 0; border-top-right-radius: 0;
  line-height: 1.5; cursor: text;
}
.richtext-editor:focus { outline: none; border-color: var(--sage-mid); box-shadow: 0 0 0 3px rgba(126,147,107,0.35); }
.richtext-editor p { margin: 0 0 var(--space-3); }
.richtext-editor p:last-child { margin-bottom: 0; }
.richtext-editor ul, .richtext-editor ol { margin: 0 0 var(--space-3); padding-left: 1.4em; }
.richtext-editor h2, .richtext-editor h3, .richtext-editor h4 { margin: var(--space-4) 0 var(--space-2); color: var(--navy); }
.richtext-editor h2:first-child, .richtext-editor h3:first-child, .richtext-editor h4:first-child { margin-top: 0; }
.richtext-editor:empty:before {
  content: attr(data-placeholder); color: var(--navy-12); color: rgba(23,47,67,0.45);
}
.richtext--invalid .richtext-editor { border-color: #a4443a; box-shadow: 0 0 0 3px rgba(164,68,58,0.2); }
.richtext__error { color: #a4443a; font-size: var(--step--1); margin-top: var(--space-2); display: none; }
.richtext--invalid .richtext__error { display: block; }

/* A field an administrator sees as plain text (everyone but the admin
   role, on every one of these fields) gets a small explicit label
   instead of an editor, so it is clear no formatting will be kept. */
.form-hint--plaintext { font-style: italic; }


.btn {
  display: inline-block; font: inherit; font-weight: 700;
  padding: var(--space-3) var(--space-5); border-radius: var(--radius-sm);
  border: 1px solid transparent; cursor: pointer; text-decoration: none; text-align: center;
}
.btn--primary { background: var(--navy); color: var(--white); }
.btn--primary:hover { background: #0f2231; }
.btn--ghost { background: transparent; color: var(--navy); border-color: var(--navy-12); }
.btn--ghost:hover { background: var(--navy-06); }
.btn--block { display: block; width: 100%; }
.btn--link { background: none; border: 0; padding: 0; color: var(--white); text-decoration: underline; cursor: pointer; font: inherit; }

/* ---------- Flash messages ---------- */

.flash { border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4); margin-bottom: var(--space-4); font-size: var(--step--1); }
.flash--notice { background: var(--sage-pale); color: var(--olive); border-left: var(--rail) solid var(--sage-mid); }
.flash--error  { background: #f6dcdc; color: #6c2020; border-left: var(--rail) solid #a33; }

/* ---------- Authentication screens ---------- */

.auth {
  min-height: 100vh; display: grid; place-items: center;
  padding: var(--space-5) var(--space-4);
  background:
    radial-gradient(1100px 500px at 15% -10%, rgba(154,189,151,0.30), transparent 60%),
    radial-gradient(900px 480px at 110% 110%, rgba(126,147,107,0.28), transparent 60%),
    var(--surface);
}

.auth__card {
  width: 100%; max-width: 420px; background: var(--white);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  padding: var(--space-6) var(--space-5);
}

.auth__brand { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-5); }
.auth__brand strong { font-size: var(--step-1); color: var(--navy); font-weight: 900; letter-spacing: -0.02em; }

.auth__slogan { color: var(--olive); font-size: var(--step--1); margin: calc(var(--space-4) * -1) 0 var(--space-5); }

.auth__links { margin-top: var(--space-5); font-size: var(--step--1); display: flex; justify-content: space-between; gap: var(--space-3); }
.auth__links a { color: var(--olive); }

/* ---------- Modal overlay used throughout the application ---------- */

.overlay {
  position: fixed; inset: 0; background: var(--overlay);
  display: none; place-items: center; padding: var(--space-4); z-index: 70;
}
.overlay[open], .overlay.is-open { display: grid; }
.overlay__panel {
  background: var(--white); border-radius: var(--radius);
  max-width: 560px; width: 100%; padding: var(--space-5);
  box-shadow: var(--shadow-lg); max-height: 85vh; overflow-y: auto;
}

/* ---------- Empty states ---------- */

.empty {
  background: var(--white); border-radius: var(--radius);
  border: 1px dashed var(--navy-12); padding: var(--space-6);
  text-align: center; color: var(--olive);
  margin-top: 20px;
}
.empty h3 { color: var(--navy); }

/* ---------- Responsive ---------- */

@media (min-width: 600px) {
  .cards { grid-template-columns: repeat(2, 1fr); }
  .stats { grid-template-columns: repeat(4, 1fr); }
  .masthead__meta { display: block; }
  .main { padding: var(--space-6) var(--space-5) var(--space-7); }
}

@media (min-width: 900px) {
  .sidebar { display: block; }
  .tabbar, .drawer { display: none; }
  .main--with-tabbar { padding-bottom: var(--space-7); }
  .cards { grid-template-columns: repeat(3, 1fr); }
  .main { padding: var(--space-6) var(--space-6) var(--space-7); }
}

@media (min-width: 1280px) {
  .main { padding-right: var(--space-7); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

@media print {
  .masthead, .sidebar { display: none; }
  body { background: var(--white); }
}

/* ---------- Administration forms (Phase Two) ---------- */

.grid-2 { display: grid; gap: var(--space-4); grid-template-columns: 1fr; }
@media (min-width: 720px) { .grid-2 { grid-template-columns: 1fr 1fr; } }

.muted { color: var(--olive); font-size: var(--step--1); display: block; }
/* .muted is written for a <span>/<div>, but several tables put it
   directly on a <td> for the muted-text look (a term code, a date).
   display:block on a table cell breaks it out of the table's row
   layout entirely in every browser: it stops being a real table cell,
   gets its own independent box and its own border, and vertical-align
   (which only ever applies to display:table-cell) silently stops
   doing anything. This restores real table-cell behaviour whenever
   .muted lands on a <td>, without touching every other use of .muted. */
td.muted { display: table-cell; }
.nowrap { white-space: nowrap; }

.form-input--tight { padding: var(--space-2); font-size: var(--step--1); }

.btn--small { padding: var(--space-2) var(--space-3); font-size: var(--step--1); }

.inline-edit { display: inline; }

.pill {
  display: inline-block; font-size: 0.6875rem; font-weight: 700;
  letter-spacing: 0.05em; text-transform: uppercase;
  padding: 2px 9px; border-radius: 99px; white-space: nowrap;
  vertical-align: middle;
}
.pill--on   { background: var(--sage-pale); color: var(--olive); }
.pill--off  { background: var(--surface); color: var(--olive); }
.pill--warn { background: #f7e6c8; color: #7a5410; }

/* Two or more things sharing one table cell: a status pill beside a
   button, a count beside a pill. Baseline alignment cannot centre items
   of different heights against each other, so the pair is laid out as a
   flex row and centred as boxes. It wraps rather than overflowing when a
   cell is narrow. */
.cell-actions {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--space-2);
}

.filter { display: flex; align-items: flex-end; gap: var(--space-3); flex-wrap: wrap; }
.filter .form-label { margin-bottom: var(--space-2); }
.filter .form-input { max-width: 360px; }

/* ---------- Row actions (WordPress style) and bulk editing ---------- */

.row-actions {
  margin: 4px 0 0; font-size: 0.75rem; color: var(--navy-80);
  white-space: nowrap; overflow-x: auto; display: block;
}
.row-actions > * { display: inline; }
.link-action-form { display: inline; margin: 0; }
.link-action {
  background: none; border: 0; padding: 0; margin: 0; font: inherit; font-size: inherit;
  color: var(--sage-mid); text-decoration: none; cursor: pointer;
}
.link-action:hover { text-decoration: underline; color: var(--navy); }
.link-action--danger { color: #a4443a; }
.link-action--danger:hover { color: #7c332b; }
.row-actions a { font-size: inherit; color: var(--sage-mid); text-decoration: none; }
.row-actions a:hover { text-decoration: underline; color: var(--navy); }

.bulk-bar { background: var(--surface); padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm); margin-bottom: var(--space-4); }
.bulk-bar .form-hint { margin: 0; width: 100%; }
.bulk-bar__actions { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; margin-top: var(--space-3); }

.repeat-row {
  display: grid; grid-template-columns: auto 1fr auto; gap: var(--space-3);
  align-items: start; margin-bottom: var(--space-3);
}
.repeat-row__number {
  width: 28px; height: 28px; border-radius: 50%; flex: 0 0 28px;
  background: var(--navy); color: var(--white);
  display: grid; place-items: center; font-size: var(--step--1); font-weight: 900;
  margin-top: var(--space-2);
}
.repeat-row--eval { grid-template-columns: minmax(0,1fr) 110px minmax(0,1fr) auto; }
@media (max-width: 900px) {
  .repeat-row--eval { grid-template-columns: minmax(0,1fr) 110px auto; }
  .repeat-row--eval input[name="evaluation_notes[]"] { grid-column: 1 / -1; }
}
@media (max-width: 600px) {
  .repeat-row, .repeat-row--eval { grid-template-columns: 1fr; }
  .repeat-row__number { margin-top: 0; }
}

.check-grid { display: grid; gap: var(--space-3); }
.check { display: grid; grid-template-columns: auto 1fr; gap: var(--space-3); align-items: start; font-size: var(--step--1); }
.check input { margin-top: 4px; }

.weight-total { font-weight: 700; font-size: var(--step--1); margin-top: var(--space-3); }
.weight-total--ok  { color: var(--olive); }
.weight-total--off { color: #a33; }

/* ---------- Uniform form controls ----------
   Every single line control shares one height and one vertical rhythm, so
   text inputs, selects, dates, times, numbers, file pickers, and buttons
   all line up on the same baseline in a row. */

:root { --control-height: 46px; }

.form-input,
input[type="text"].form-input,
input[type="email"].form-input,
input[type="url"].form-input,
input[type="tel"].form-input,
input[type="password"].form-input,
input[type="number"].form-input,
input[type="search"].form-input,
input[type="date"].form-input,
input[type="time"].form-input,
input[type="datetime-local"].form-input,
input[type="file"].form-input,
select.form-input {
  height: var(--control-height);
  min-height: var(--control-height);
  padding: 0 var(--space-3);
  line-height: calc(var(--control-height) - 2px);
  font-family: inherit;
  font-size: var(--step-0);
  vertical-align: middle;
  border: 1px solid var(--navy-12);
  border-radius: var(--radius-sm);
  background-color: var(--white);
  color: var(--ink);
  box-sizing: border-box;
  -webkit-appearance: none;
  appearance: none;
}

/* Selects need their own arrow once the native one is removed. */
select.form-input {
  padding-right: calc(var(--space-3) * 2 + 12px);
  background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23172f43' d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.4 0 1.4z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
  background-size: 12px 8px;
}
select.form-input::-ms-expand { display: none; }

/* Safari centres date and time text oddly without this. */
input[type="date"].form-input,
input[type="time"].form-input,
input[type="datetime-local"].form-input {
  -webkit-appearance: none;
  display: block;
  width: 100%;
}

/* The file control has no text baseline of its own. */
input[type="file"].form-input {
  padding-top: 0;
  padding-bottom: 0;
  display: flex;
  align-items: center;
}
input[type="file"].form-input::file-selector-button {
  height: calc(var(--control-height) - 16px);
  margin-right: var(--space-3);
  padding: 0 var(--space-4);
  border: 1px solid var(--navy-12);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--navy);
  font: inherit;
  font-size: var(--step--1);
  font-weight: 700;
  cursor: pointer;
}

/* Textareas keep a matching rhythm without a fixed height. */
textarea.form-input {
  height: auto;
  min-height: calc(var(--control-height) * 2);
  padding: var(--space-3);
  line-height: 1.5;
}

/* The rich text surface built by richtext.js is a contenteditable <div>,
   not a <textarea>, so the bare .form-input rule above would otherwise
   lock it to the single line control height and its content would spill
   out of the border and over whatever follows. It is released from that
   height here, on a two class selector so it wins on specificity rather
   than on source order, and it grows with its content instead. */
.richtext-editor.form-input {
  height: auto;
  min-height: calc(var(--richtext-min-lines, 4) * 1.6em);
  padding: var(--space-3);
  line-height: 1.5;
  overflow-wrap: break-word;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  /* A browser only paints the drag to resize grabber on an element whose
     overflow is something other than visible, and a <div> has no such
     handle of its own the way a <textarea> does. Setting overflow to auto
     alongside a vertical resize gives the editor the same corner grabber
     a plain textarea has. Height stays automatic until the grabber is
     actually dragged, so an untouched field still grows with its text. */
  overflow: auto;
  resize: vertical;
}

/* The compact variant used inside tables. */
.form-input--tight,
select.form-input--tight,
input.form-input--tight {
  height: 38px;
  min-height: 38px;
  line-height: 36px;
  font-size: var(--step--1);
  padding: 0 var(--space-2);
}
textarea.form-input--tight {
  height: auto;
  min-height: 38px;
  line-height: 1.4;
  padding: var(--space-2);
}

/* Buttons sit on the same line as the controls beside them. */
.btn {
  height: var(--control-height);
  min-height: var(--control-height);
  padding: 0 var(--space-5);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  vertical-align: middle;
}
.btn--block { display: flex; width: 100%; }
.btn--small { height: 38px; min-height: 38px; padding: 0 var(--space-3); }
.btn--link { height: auto; min-height: 0; padding: 0; display: inline; }

/* Browsers hide a [hidden] element via display:none in their own
   built-in stylesheet, but every .btn rule above sets its own display
   value, and an author stylesheet always wins over that built-in one
   regardless of selector specificity - so a plain element.hidden =
   true from JavaScript silently did nothing on a button. This is the
   fix for that, general rather than scoped to any one place that
   happened to notice it, since nothing on the site ever wants a
   hidden element to still render. */
[hidden] { display: none !important; }

/* Checkboxes and radios: fixed box, label text centred against it. */
label > input[type="checkbox"],
label > input[type="radio"],
.check input[type="checkbox"],
.check input[type="radio"] {
  width: 20px;
  height: 20px;
  margin: 0 var(--space-3) 0 0;
  flex: 0 0 20px;
  accent-color: var(--sage-mid);
  vertical-align: middle;
}

.form-row > label:has(> input[type="checkbox"]),
.form-row > label:has(> input[type="radio"]) {
  display: flex;
  align-items: center;
  min-height: var(--control-height);
  font-size: var(--step-0);
  gap: 0;
}

.check {
  display: flex;
  align-items: center;
  min-height: var(--control-height);
  gap: 0;
}
.check input { margin-top: 0; }
.check span { line-height: 1.4; }

/* Rows of mixed controls align on their centres. */
.repeat-row,
.repeat-row--eval,
.filter { align-items: center; }
.repeat-row__number { margin-top: 0; align-self: center; }
.repeat-row textarea.form-input { align-self: center; }

/* Fallback for browsers without :has support. */
@supports not selector(:has(*)) {
  .form-row label { display: flex; align-items: center; min-height: var(--control-height); }
}

/* ---------- Lesson planning and reminders (Phase Four) ---------- */

/* Each in-class exercise stacks its fields (exercise type, the
   auto-filled description, instructions, time) one under another,
   the same way a speaker or reading block does, rather than trying to
   fit a select, two text fields, and a button on one row. */
.exercise-block {
  border: 1px solid var(--navy-12);
  border-left: var(--rail) solid var(--sage-light);
  border-radius: var(--radius-sm);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  background: var(--surface);
}
.exercise-block .form-input { background: var(--white); }

.speaker-block,
.reading-block {
  border: 1px solid var(--navy-12);
  border-left: var(--rail) solid var(--sage-light);
  border-radius: var(--radius-sm);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  background: var(--surface);
}
.speaker-block .form-input,
.reading-block .form-input { background: var(--white); }

.check-grid--columns { grid-template-columns: 1fr; }
@media (min-width: 720px) { .check-grid--columns { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .check-grid--columns { grid-template-columns: repeat(3, 1fr); } }

.reminder {
  background: var(--white);
  border-left: var(--rail) solid var(--olive);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-4);
  display: grid;
  gap: var(--space-4);
}
@media (min-width: 800px) {
  .reminder { grid-template-columns: 1fr auto; align-items: center; }
}

.reminder__eyebrow {
  font-size: 0.6875rem; font-weight: 900; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--olive); margin: 0 0 var(--space-1);
}
.reminder__title { font-size: var(--step-1); margin: 0 0 var(--space-2); }
.reminder__meta { font-size: var(--step--1); color: var(--ink); margin: 0 0 var(--space-2); }
.reminder__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }

.overlay__list { list-style: none; margin: 0; padding: 0; }
.overlay__list li { padding: var(--space-3) 0; border-bottom: 1px solid var(--navy-06); }
.overlay__list li:last-child { border-bottom: 0; }
.overlay__list strong { display: block; color: var(--navy); }
.overlay__list span { font-size: var(--step--1); color: var(--olive); }

/* Message list rows: everyone/subject/class stay on one line with an
   ellipsis rather than wrapping, and the sent/read timestamps sit on
   their own line underneath rather than fighting for table columns. */
.message-row {
  display: block; padding: var(--space-3) 0; border-bottom: 1px solid var(--navy-06);
  text-decoration: none; color: inherit;
}
.message-row:last-child { border-bottom: 0; }
.message-row__line {
  display: flex; align-items: baseline; gap: var(--space-2);
  white-space: nowrap; overflow: hidden;
}
.message-row__from { flex: 0 0 auto; font-weight: 700; color: var(--navy); }
.message-row__subject { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; color: var(--navy); }
.message-row__class { flex: 0 0 auto; color: var(--olive); font-size: var(--step--1); }
.message-row__meta { margin-top: 2px; font-size: var(--step--1); color: var(--olive); }
.message-row.is-unread .message-row__subject { font-weight: 700; }

@media print {
  .panel { box-shadow: none; border: 1px solid #ccc; page-break-inside: avoid; }
  .reminder, .btn, form button { display: none; }
}

/* ---------- Assessment builder (Phase Five) ---------- */

.criterion-block {
  border: 1px solid var(--navy-12);
  border-left: var(--rail) solid var(--sage-mid);
  border-radius: var(--radius-sm);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  background: var(--surface);
}
.criterion-block .form-input { background: var(--white); }
.criterion-block .table { background: var(--white); border-radius: var(--radius-sm); }
.criterion-block .table td { vertical-align: middle; }

/* ---------- Content authoring (Phase Six) ---------- */

.repeat-row--term { grid-template-columns: 200px 1fr auto; }
@media (max-width: 800px) { .repeat-row--term { grid-template-columns: 1fr; } }

.option-row {
  display: grid; grid-template-columns: auto 1fr; gap: var(--space-3);
  align-items: center; margin-bottom: var(--space-2);
}
.option-row .check { min-height: 0; }
.option-row--matching { grid-template-columns: auto 1fr 1fr; }
@media (max-width: 700px) { .option-row--matching { grid-template-columns: auto 1fr; } .option-row--matching input[name*="option_match"] { grid-column: 2; } }
