/* =====================================================================
   Enkoaching — admin portal

   The brand mark is a violet squircle holding a graduation cap over an
   "e" inside a turning arrow, and the wordmark sets "en" in navy against
   "koaching" in violet. Everything below is read off that artwork: the
   violet is the signature, the navy becomes the ink, and the greys carry
   a trace of the same hue so nothing in the interface sits outside the
   palette.

   This is a tool people work in for whole shifts, so the colour is spent
   in two places only — the brand tile and the item you are currently on.
   Records, tables and forms stay quiet around them.
   ===================================================================== */

/* ---------------------------------------------------------------- fonts
   Self-hosted (latin subset). No third-party CDN, so the sign-in screen
   still renders correctly on an offline or firewalled network.

   Outfit is geometric with circular bowls — the same construction as the
   logo's lettering — so headings and figures carry the wordmark's voice.
   Plus Jakarta Sans runs the interface: it holds its shape at the 13px
   this product spends most of its time at, which Outfit does not.
   ---------------------------------------------------------------------- */
@font-face {
  font-family: 'Outfit'; font-style: normal; font-weight: 500;
  font-display: swap; src: url('../fonts/outfit-latin-500-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Outfit'; font-style: normal; font-weight: 600;
  font-display: swap; src: url('../fonts/outfit-latin-600-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Outfit'; font-style: normal; font-weight: 700;
  font-display: swap; src: url('../fonts/outfit-latin-700-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Plus Jakarta Sans'; font-style: normal; font-weight: 400;
  font-display: swap; src: url('../fonts/plus-jakarta-sans-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Plus Jakarta Sans'; font-style: normal; font-weight: 500;
  font-display: swap; src: url('../fonts/plus-jakarta-sans-latin-500-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Plus Jakarta Sans'; font-style: normal; font-weight: 600;
  font-display: swap; src: url('../fonts/plus-jakarta-sans-latin-600-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Plus Jakarta Sans'; font-style: normal; font-weight: 700;
  font-display: swap; src: url('../fonts/plus-jakarta-sans-latin-700-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono'; font-style: normal; font-weight: 400;
  font-display: swap; src: url('../fonts/jetbrains-mono-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono'; font-style: normal; font-weight: 500;
  font-display: swap; src: url('../fonts/jetbrains-mono-latin-500-normal.woff2') format('woff2');
}

:root {
  /* --- brand, sampled from the logo file ------------------------------
     #6f2af5  the "koaching" violet — the signature
     #ad37fc  the light end of the tile's gradient
     #531acc  the dark end of the tile's gradient
     #012964  the "en" navy, which the ink scale is drawn from
     -------------------------------------------------------------------- */
  --brand:      #6f2af5;
  --brand-deep: #5718d0;   /* links and small text, where #6f2af5 is thin */
  --brand-dark: #531acc;
  --brand-lift: #ad37fc;
  --brand-wash: #f1eaff;
  --brand-edge: #ddcbff;
  --brand-grad: linear-gradient(145deg, #ad37fc 0%, #7b2bf7 46%, #531acc 100%);

  /* Ink — the logo's navy pulled toward the brand hue so text and brand
     belong to one family rather than two. */
  --ink:        #17123a;
  --ink-2:      #2a2750;
  --ink-3:      #4b4873;
  --slate:      #6e6b8c;
  --slate-soft: #9b98b4;

  /* Surfaces — faintly violet, never neutral grey */
  --canvas:    #f5f4fb;
  --paper:     #ffffff;
  --paper-2:   #faf9fe;
  --line:      #e6e3f2;
  --line-soft: #efedf8;

  /* The dark side: sidebar and sign-in panel */
  --nav:    #170e38;
  --nav-2:  #22114f;
  --nav-fg: #c3bcdd;
  --nav-dim:#8781a6;

  /* --- states, each far enough from the brand violet to stay legible -- */
  --sea:       #0a7c6b;   /* active, present, paid */
  --sea-wash:  #e3f5f1;
  --sea-edge:  #bfe6de;
  --amber:     #c67f00;   /* due, pending, nearly full */
  --amber-deep:#8f5c00;
  --amber-wash:#fdf3e0;
  --amber-edge:#f2dcae;
  --rose:      #d6305a;   /* failed, overdue, destructive */
  --rose-deep: #a8204a;
  --rose-wash: #fdebf0;
  --rose-edge: #f8ccd9;
  --info:      #2f5bd4;   /* neutral notices */
  --info-wash: #e9effd;
  --info-edge: #c7d6f6;

  /* Older names kept so every screen written before this theme keeps
     working. --tab was the accent; the accent is now the brand. */
  --tab:          var(--brand);
  --tab-deep:     var(--brand-deep);
  --tab-wash:     var(--brand-wash);
  --violet:       var(--info);
  --violet-wash:  var(--info-wash);

  /* Radius carries hierarchy: panels are softest, controls are tighter,
     chips are round, and the brand tile matches the logo's squircle. */
  --radius:      12px;
  --radius-sm:   9px;
  --radius-lg:   18px;
  --radius-pill: 999px;
  --radius-mark: 11px;

  /* Shadows are tinted with the brand rather than black, which is what
     stops the light surfaces reading as plain grey. */
  --shadow-sm: 0 1px 2px rgba(31, 18, 70, .05);
  --shadow:    0 1px 2px rgba(31, 18, 70, .05), 0 8px 20px -10px rgba(31, 18, 70, .16);
  --shadow-lg: 0 24px 56px -16px rgba(31, 18, 70, .3);
  --shadow-brand: 0 6px 18px -6px rgba(111, 42, 245, .5);

  --sidebar-w: 264px;
  --topbar-h:  64px;

  --display: 'Outfit', 'Segoe UI', system-ui, sans-serif;
  --body:    'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
}

/* ---------------------------------------------------------------- reset */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--body);
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-2);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4, h5 {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: -.015em;
  color: var(--ink);
  margin: 0 0 .4em;
  line-height: 1.18;
}
h1 { font-size: 1.6rem; letter-spacing: -.025em; }
h2 { font-size: 1.22rem; letter-spacing: -.02em; }
h3 { font-size: 1.03rem; }
p { margin: 0 0 1em; }
a { color: var(--ink-2); text-decoration: none; }
a:hover { color: var(--brand-deep); }
img { max-width: 100%; display: block; }
hr { border: 0; border-top: 1px solid var(--line); margin: 20px 0; }

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 5px;
}

.ico { width: 18px; height: 18px; flex: none; }
.ico-sm { width: 15px; height: 15px; flex: none; }
.ico-lg { width: 22px; height: 22px; flex: none; }

/* Monospace is reserved for things that are literally records — roll
   numbers, institute codes, ids. It is not used for labels, where it only
   makes small text harder to read. */
.mono {
  font-family: var(--mono); font-size: .78rem; letter-spacing: .01em;
  font-variant-numeric: tabular-nums;
}
/* A quiet label above a value. Sentence case in the interface font: the
   tracked-out capitals this used to carry fought every heading near it. */
.eyebrow {
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--slate);
}

/* ============================================================ APP SHELL */
.shell { display: flex; min-height: 100vh; max-width: 100%; }
body { overflow-x: hidden; }

/* ------------------------------------------------------------ sidebar */
.sidebar {
  width: var(--sidebar-w);
  flex: none;
  background: linear-gradient(180deg, var(--nav) 0%, var(--nav) 42%, var(--nav-2) 100%);
  color: var(--nav-fg);
  display: flex;
  flex-direction: column;
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 60;
}
/* A single wash of the brand violet behind the mark, so the top of the
   panel carries the logo's light instead of the tile sitting on flat
   black. It is the only decoration in here. */
.sidebar::before {
  content: '';
  position: absolute;
  top: -140px; left: -90px;
  width: 340px; height: 340px;
  background: radial-gradient(circle, rgba(140, 56, 252, .34), transparent 68%);
  pointer-events: none;
}
.sidebar > * { position: relative; }

.sidebar-brand {
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 0 18px;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}
.brand-mark {
  width: 36px; height: 36px;
  border-radius: var(--radius-mark);
  background: var(--brand-grad);
  color: #fff;
  display: grid; place-items: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: .9rem;
  letter-spacing: -.01em;
  flex: none;
  overflow: hidden;
}
.brand-mark img { width: 100%; height: 100%; object-fit: cover; }
/* The Enkoaching tile is already a squircle with its own corners, so it
   is shown whole rather than cropped into another rounded box. */
.brand-mark.is-logo { background: none; }
.brand-mark.is-logo img { object-fit: contain; }

.brand-text { min-width: 0; }
.brand-name {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  color: #fff;
  font-size: .97rem;
  letter-spacing: -.015em;
  line-height: 1.15;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand-sub {
  display: block;
  font-size: .71rem;
  color: var(--nav-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.sidebar-scroll { flex: 1; overflow-y: auto; padding: 16px 0 20px; }
.sidebar-scroll::-webkit-scrollbar { width: 6px; }
.sidebar-scroll::-webkit-scrollbar-thumb { background: rgba(255,255,255,.14); border-radius: 3px; }

.nav-group { padding: 0 12px; margin-bottom: 20px; }
.nav-label {
  font-size: .715rem;
  font-weight: 600;
  color: #7d77a0;
  padding: 0 12px 7px;
}
.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  color: var(--nav-fg);
  font-size: .875rem;
  font-weight: 500;
  margin-bottom: 2px;
  transition: background .15s ease, color .15s ease;
}
.nav-item:hover { background: rgba(255, 255, 255, .07); color: #fff; }
/* The one place the full brand gradient appears in the chrome. Where you
   are should be the brightest thing on the screen. */
.nav-item.is-active {
  background: var(--brand-grad);
  color: #fff;
  font-weight: 600;
  box-shadow: var(--shadow-brand);
}
.nav-item .ico { color: inherit; opacity: .7; }
.nav-item:hover .ico { opacity: .95; }
.nav-item.is-active .ico { opacity: 1; }
.nav-count {
  margin-left: auto;
  font-family: var(--mono);
  font-size: .68rem;
  font-variant-numeric: tabular-nums;
  color: var(--nav-dim);
  background: rgba(255,255,255,.08);
  padding: 1px 7px;
  border-radius: var(--radius-pill);
}
.nav-item.is-active .nav-count { color: #fff; background: rgba(255,255,255,.22); }

.sidebar-foot { padding: 12px; border-top: 1px solid rgba(255,255,255,.08); }
.plan-card {
  background: rgba(255, 255, 255, .055);
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: var(--radius);
  padding: 11px 13px;
}
.plan-card .plan-name { color: #fff; font-weight: 600; font-size: .85rem; }
.plan-meter { height: 5px; background: rgba(255,255,255,.14); border-radius: 3px; margin: 8px 0 6px; overflow: hidden; }
.plan-meter span { display: block; height: 100%; background: var(--brand-grad); border-radius: 3px; }
.plan-note { font-size: .7rem; color: var(--nav-dim); font-variant-numeric: tabular-nums; }

/* Whose software this is, kept to a whisper under the tenant's own name. */
.sidebar-credit {
  display: flex; align-items: center; gap: 7px;
  padding: 11px 13px 2px;
  font-size: .7rem; color: #6f6992;
}
.sidebar-credit img { width: 15px; height: 15px; flex: none; }
.sidebar-credit b { color: #9b93bd; font-weight: 600; }

/* ------------------------------------------------------------- topbar */
.main { flex: 1; min-width: 0; margin-left: var(--sidebar-w); display: flex; flex-direction: column; }

.topbar {
  height: var(--topbar-h);
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 22px;
  position: sticky;
  top: 0;
  z-index: 40;
}
.hamburger {
  display: none;
  background: none; border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  width: 36px; height: 36px;
  align-items: center; justify-content: center;
  color: var(--ink-2); cursor: pointer;
}
.topbar-title { font-family: var(--display); font-weight: 600; font-size: .98rem; color: var(--ink); }
.topbar-spacer { flex: 1; }

/* context chips: which institute, campus and batch you are looking at */
.stamp {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: .76rem;
  border: 1px solid var(--line);
  color: var(--slate);
  padding: 4px 11px;
  border-radius: var(--radius-pill);
  background: var(--paper-2);
  white-space: nowrap;
}
.stamp b { color: var(--ink); font-weight: 600; }
.stamp .ico-sm { color: var(--brand); }

.avatar {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--brand-grad); color: #fff;
  display: grid; place-items: center;
  font-family: var(--display); font-size: .78rem; font-weight: 600;
  overflow: hidden; flex: none;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.avatar-lg { width: 68px; height: 68px; font-size: 1.3rem; border-radius: var(--radius-lg); }
.avatar-sm { width: 28px; height: 28px; font-size: .68rem; }

.user-menu { position: relative; }
.user-btn {
  display: flex; align-items: center; gap: 9px;
  background: none; border: 1px solid transparent;
  border-radius: var(--radius); padding: 4px 8px 4px 4px;
  cursor: pointer; color: inherit; font: inherit;
}
.user-btn:hover { border-color: var(--line); background: var(--paper-2); }
.user-btn .who { text-align: left; line-height: 1.15; }
.user-btn .who strong { display: block; font-size: .82rem; color: var(--ink); font-weight: 600; }
.user-btn .who span { font-size: .7rem; color: var(--slate); }

.dropdown {
  position: absolute; right: 0; top: calc(100% + 8px);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  min-width: 216px; padding: 6px;
  display: none; z-index: 50;
}
.dropdown.open { display: block; }
.dropdown-head { padding: 9px 11px; border-bottom: 1px solid var(--line-soft); margin-bottom: 5px; }
.dropdown-head strong { display: block; font-size: .84rem; color: var(--ink); }
.dropdown-head span { font-size: .72rem; color: var(--slate); word-break: break-all; }
.dropdown a, .dropdown button {
  display: flex; align-items: center; gap: 9px;
  width: 100%; padding: 8px 11px;
  border-radius: var(--radius-sm);
  font-size: .84rem; color: var(--ink-2);
  background: none; border: 0; cursor: pointer;
  font: inherit; text-align: left;
}
.dropdown a:hover, .dropdown button:hover { background: var(--paper-2); color: var(--ink); }
.dropdown .danger { color: var(--rose); }
.dropdown .danger:hover { background: var(--rose-wash); }

/* -------------------------------------------------------------- page */
.page { padding: 24px 22px 56px; flex: 1; }
.page-head {
  display: flex; align-items: flex-start; gap: 16px;
  flex-wrap: wrap; margin-bottom: 20px;
}
.page-head .grow { flex: 1; min-width: 240px; }
.page-head h1 { margin-bottom: 3px; }
.page-head .lede { color: var(--slate); font-size: .875rem; margin: 0; }
.page-actions { display: flex; gap: 9px; flex-wrap: wrap; }

.crumbs { display: flex; align-items: center; gap: 6px; margin-bottom: 9px; font-size: .75rem; color: var(--slate); }
.crumbs a { color: var(--slate); }
.crumbs a:hover { color: var(--tab-deep); }
.crumbs .ico-sm { width: 12px; height: 12px; opacity: .5; }

/* ------------------------------------------------------------- cards */
.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.card + .card { margin-top: 18px; }
.card-head {
  padding: 16px 20px;
  border-bottom: 1px solid var(--line-soft);
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.card-head h2, .card-head h3 { margin: 0; }
.card-head .grow { flex: 1; min-width: 160px; }
.card-body { padding: 20px; }
.card-foot {
  padding: 14px 20px;
  border-top: 1px solid var(--line-soft);
  background: var(--paper-2);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}

.grid { display: grid; gap: 18px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-side { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); align-items: start; }
/* On long forms the action panel follows you down the page. */
@media (min-width: 1025px) {
  .aside-sticky { position: sticky; top: calc(var(--topbar-h) + 24px); }
}

/* ---------------------------------------------------------- stat card */
.stat {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 16px 17px;
  box-shadow: var(--shadow-sm);
  position: relative;
  overflow: hidden;
}
/* The hairline ledger rule under the figure. It hangs off the caption
   rather than sitting at a fixed offset: one of these cards shows a campus
   name at a different size, and a magic top: 76px cut straight through it. */
.stat-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.stat-icon {
  width: 32px; height: 32px; border-radius: 9px;
  display: grid; place-items: center;
  background: var(--paper-2); color: var(--ink-3);
  border: 1px solid var(--line);
}
.stat-value {
  font-family: var(--display);
  font-size: 2rem; font-weight: 600; letter-spacing: -.03em;
  color: var(--ink); line-height: 1.15;
  margin: 8px 0 0;
  font-variant-numeric: tabular-nums;
}
.stat-foot {
  font-size: .76rem; color: var(--slate);
  display: flex; align-items: center; gap: 6px;
  margin-top: 13px;
  padding-top: 11px;
  border-top: 1px solid var(--line-soft);
}
.stat.accent .stat-icon { background: var(--brand-wash); color: var(--brand-deep); border-color: var(--brand-edge); }
.stat.sea .stat-icon    { background: var(--sea-wash); color: var(--sea); border-color: var(--sea-edge); }
.stat.violet .stat-icon { background: var(--info-wash); color: var(--info); border-color: var(--info-edge); }
.stat.rose .stat-icon   { background: var(--rose-wash); color: var(--rose); border-color: var(--rose-edge); }
.stat.amber .stat-icon  { background: var(--amber-wash); color: var(--amber-deep); border-color: var(--amber-edge); }

/* ------------------------------------------------------------ buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 15px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-family: var(--body);
  font-size: .855rem; font-weight: 600;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, transform .06s;
  white-space: nowrap;
  line-height: 1.3;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--brand); color: #fff; border-color: var(--brand); }
.btn-primary:hover { background: var(--brand-deep); border-color: var(--brand-deep); color: #fff; box-shadow: var(--shadow-brand); }
/* The gradient button quotes the logo tile; it is for the one action a
   screen most wants you to take, never for a row of equal choices. */
.btn-tab { background: var(--brand-grad); color: #fff; border-color: transparent; }
.btn-tab:hover { color: #fff; box-shadow: var(--shadow-brand); }
.btn-ghost { background: var(--paper); color: var(--ink-2); border-color: var(--line); }
.btn-ghost:hover { background: var(--brand-wash); border-color: var(--brand-edge); color: var(--brand-deep); }
.btn-danger { background: var(--rose); color: #fff; border-color: var(--rose); }
.btn-danger:hover { background: var(--rose-deep); border-color: var(--rose-deep); color: #fff; }
.btn-quiet { background: transparent; color: var(--slate); border-color: transparent; padding: 7px 9px; }
.btn-quiet:hover { background: var(--brand-wash); color: var(--brand-deep); }
.btn-sm { padding: 6px 11px; font-size: .79rem; }
.btn-block { width: 100%; }
.btn:disabled, .btn.is-disabled { opacity: .5; cursor: not-allowed; }
.btn-icon { padding: 7px; width: 32px; height: 32px; }

.btn-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

/* -------------------------------------------------------------- forms */
.form-grid { display: grid; gap: 16px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.field { display: block; min-width: 0; }
.field.full { grid-column: 1 / -1; }
.label {
  display: block;
  font-size: .78rem; font-weight: 600;
  color: var(--ink-2); margin-bottom: 6px;
}
.label .req { color: var(--rose); margin-left: 2px; }
.label .opt { color: var(--slate-soft); font-weight: 400; margin-left: 4px; font-size: .72rem; }

.input, .select, .textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--paper);
  font-family: var(--body);
  font-size: .875rem;
  color: var(--ink);
  transition: border-color .15s, box-shadow .15s;
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--brand-edge); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(111, 42, 245, .14);
}
.input::placeholder, .textarea::placeholder { color: var(--slate-soft); }
.textarea { min-height: 84px; resize: vertical; }
.select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236e6b8c' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 30px;
}
.input.is-invalid, .select.is-invalid, .textarea.is-invalid {
  border-color: var(--rose);
  background: var(--rose-wash);
}
.input[readonly], .input:disabled, .select:disabled { background: var(--paper-2); color: var(--slate); cursor: not-allowed; }
.input-mono { font-family: var(--mono); letter-spacing: .06em; text-transform: uppercase; }

.field-error { color: var(--rose); font-size: .755rem; margin: 5px 0 0; display: flex; gap: 4px; }
.hint { color: var(--slate); font-size: .755rem; margin: 5px 0 0; }

.input-group { display: flex; }
.input-group .input { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.input-group .btn { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; border-left: 0; }

.check {
  display: flex; align-items: flex-start; gap: 9px;
  cursor: pointer; font-size: .845rem; color: var(--ink-2);
  padding: 7px 0;
}
.check input { margin: 2px 0 0; width: 15px; height: 15px; accent-color: var(--brand); cursor: pointer; flex: none; }
.check span small { display: block; color: var(--slate); font-size: .74rem; }

/* toggle */
.switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; }
.switch input { position: absolute; opacity: 0; pointer-events: none; }
.switch .track {
  width: 38px; height: 21px; border-radius: var(--radius-pill);
  background: #cfcade; position: relative; transition: background .18s;
  flex: none;
}
.switch .track::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 17px; height: 17px; border-radius: 50%;
  background: #fff; box-shadow: var(--shadow-sm);
  transition: transform .18s;
}
.switch input:checked + .track { background: var(--sea); }
.switch input:checked + .track::after { transform: translateX(17px); }
.switch input:focus-visible + .track { outline: 2px solid var(--brand); outline-offset: 2px; }
.switch .switch-text { font-size: .845rem; color: var(--ink-2); }

/* file / image picker */
.picker { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.picker-preview {
  width: 68px; height: 68px; border-radius: 12px;
  border: 1px dashed var(--line);
  background: var(--paper-2);
  display: grid; place-items: center;
  overflow: hidden; flex: none;
  color: var(--slate-soft);
}
.picker-preview img { width: 100%; height: 100%; object-fit: cover; }
.picker-actions { display: flex; flex-direction: column; gap: 5px; }
.picker input[type=file] { display: none; }

/* repeatable contact rows */
.repeat-group { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.repeat-head {
  display: flex; align-items: center; gap: 9px;
  padding: 10px 13px;
  background: var(--paper-2);
  border-bottom: 1px solid var(--line-soft);
}
.repeat-head .ico { color: var(--ink-3); }
.repeat-head strong { font-size: .82rem; color: var(--ink); }
.repeat-head .count {
  margin-left: auto; font-family: var(--mono); font-size: .68rem;
  color: var(--slate); background: var(--paper); border: 1px solid var(--line);
  padding: 1px 7px; border-radius: 20px;
}
.repeat-rows { padding: 11px 13px; display: flex; flex-direction: column; gap: 8px; }
.repeat-row { display: flex; gap: 8px; align-items: center; }
.repeat-row .input { flex: 1; }
.repeat-row .input.label-input { max-width: 140px; }
.repeat-row .btn-icon { flex: none; }
.repeat-foot { padding: 0 13px 12px; }
.repeat-empty { color: var(--slate); font-size: .8rem; padding: 4px 0 10px; }

/* -------------------------------------------------------------- table */
.table-wrap { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: .855rem; }
.table th {
  text-align: left;
  font-size: .76rem;
  color: var(--slate);
  font-weight: 600;
  padding: 11px 16px;
  background: var(--paper-2);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.table td { padding: 12px 16px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr { transition: background .12s; }
.table tbody tr:hover { background: var(--paper-2); }
.table .num { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--slate); }
.table .actions { text-align: right; white-space: nowrap; }
/* Keep row actions on one line; wrapping them made tall, ragged rows on
   the wider tables such as fee structure lines. */
.table .actions .btn-row { justify-content: flex-end; flex-wrap: nowrap; }

.cell-main { display: flex; align-items: center; gap: 10px; min-width: 0; }
.cell-main .who { min-width: 0; }
/* Scoped to .who so they never touch the sibling avatar, which needs display:grid */
.cell-main .who strong { display: block; color: var(--ink); font-weight: 600; font-size: .875rem; }
.cell-main .who > span { display: block; color: var(--slate); font-size: .755rem; word-break: break-word; }
/* An internal identifier nobody reads in full. It is here to be recognised
   and copied, not studied, so it is cut rather than allowed to wrap into a
   column of single characters. */
.cell-main .who > span.device-key {
  max-width: 190px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; word-break: normal;
}

/* pills */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: .72rem; font-weight: 600;
  padding: 3px 9px; border-radius: 20px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.pill-on    { background: var(--sea-wash); color: var(--sea); border-color: var(--sea-edge); }
.pill-off   { background: var(--canvas); color: var(--slate); border-color: var(--line); }
.pill-warn  { background: var(--amber-wash); color: var(--amber-deep); border-color: var(--amber-edge); }
.pill-bad   { background: var(--rose-wash); color: var(--rose-deep); border-color: var(--rose-edge); }
.pill-info  { background: var(--info-wash); color: var(--info); border-color: var(--info-edge); }
.pill-brand { background: var(--brand-wash); color: var(--brand-deep); border-color: var(--brand-edge); }
.pill-plain { background: var(--paper-2); color: var(--ink-3); border-color: var(--line); }

.tag-list { display: flex; flex-wrap: wrap; gap: 5px; }

/* filters bar */
.filters {
  display: flex; gap: 9px; flex-wrap: wrap; align-items: center;
}
.filters .search { position: relative; display: block; flex: 1; min-width: 190px; }
.filters .search .ico,
.filters .search .ico-sm {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  color: var(--slate-soft); pointer-events: none;
}
.filters .search .input { padding-left: 34px; }
.filters .select { width: auto; min-width: 138px; }

/* pagination */
.pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
}
.pager-info { font-size: .78rem; color: var(--slate); font-variant-numeric: tabular-nums; }
.pager-links { display: flex; gap: 5px; }
.pager-links a, .pager-links span {
  min-width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: var(--mono); font-size: .74rem;
  color: var(--ink-2); background: var(--paper);
}
.pager-links a:hover { border-color: var(--brand-edge); background: var(--brand-wash); color: var(--brand-deep); }
.pager-links .current { background: var(--brand); color: #fff; border-color: var(--brand); }
.pager-links .disabled { opacity: .4; pointer-events: none; }

/* ------------------------------------------------------------- alerts */
.alert {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--paper);
  font-size: .855rem;
  margin-bottom: 16px;
}
.alert .ico { margin-top: 1px; flex: none; }
.alert-success { background: var(--sea-wash); border-color: var(--sea-edge); color: #065f52; }
.alert-error   { background: var(--rose-wash); border-color: var(--rose-edge); color: var(--rose-deep); }
.alert-warning { background: var(--amber-wash); border-color: var(--amber-edge); color: var(--amber-deep); }
.alert-info    { background: var(--info-wash); border-color: var(--info-edge); color: #23469f; }
.alert .close { margin-left: auto; background: none; border: 0; color: inherit; cursor: pointer; opacity: .6; padding: 0; }
.alert .close:hover { opacity: 1; }

/* toasts */
.toast-stack {
  position: fixed; right: 18px; bottom: 18px;
  display: flex; flex-direction: column; gap: 9px;
  z-index: 200; max-width: min(360px, calc(100vw - 36px));
}
.toast {
  background: var(--ink); color: #fff;
  padding: 11px 14px; border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  font-size: .845rem;
  display: flex; align-items: flex-start; gap: 9px;
  animation: toast-in .22s ease;
}
.toast.good { background: #065f52; }
.toast.bad  { background: var(--rose-deep); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } }

/* ------------------------------------------------------------ empties */
.empty { text-align: center; padding: 46px 20px; }
.empty-mark {
  width: 54px; height: 54px; margin: 0 auto 14px;
  border-radius: var(--radius-lg); display: grid; place-items: center;
  background: var(--brand-wash); border: 1px solid var(--brand-edge);
  color: var(--brand);
}
.empty h3 { margin-bottom: 5px; }
.empty p { color: var(--slate); max-width: 380px; margin: 0 auto 16px; font-size: .865rem; }

/* -------------------------------------------------------------- modal */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(23, 18, 58, .52);
  backdrop-filter: blur(3px);
  display: none; align-items: center; justify-content: center;
  padding: 20px; z-index: 150;
}
.modal-backdrop.open { display: flex; }
.modal {
  background: var(--paper);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  width: 100%; max-width: 440px;
  max-height: 90vh; overflow-y: auto;
  animation: modal-in .18s ease;
}
.modal.wide { max-width: 620px; }
@keyframes modal-in { from { opacity: 0; transform: translateY(10px) scale(.98); } }
.modal-head { padding: 18px 20px 0; }
.modal-head h3 { margin-bottom: 4px; }
.modal-head p { color: var(--slate); font-size: .845rem; margin: 0; }
.modal-body { padding: 16px 20px; }
.modal-foot {
  padding: 14px 20px; border-top: 1px solid var(--line-soft);
  display: flex; gap: 9px; justify-content: flex-end; flex-wrap: wrap;
}

/* ---------------------------------------------- scheduled test picker */
/* The fastest route into marking is a scheduled test, so those are listed
   as big tap targets above the manual pickers. */
.pending-tests { display: grid; gap: 8px; }
.pending-test {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 13px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--tab);
  border-radius: var(--radius);
  background: var(--paper);
  text-decoration: none;
  transition: background .12s ease, border-color .12s ease;
}
.pending-test:hover { background: var(--brand-wash); border-color: var(--brand-edge); border-left-color: var(--brand); }
.pending-test-main { display: grid; gap: 2px; min-width: 0; }
.pending-test-main strong { color: var(--ink); font-size: .875rem; }
.pending-test-main span { color: var(--slate); font-size: .78rem; }
.pending-test-meta { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.pending-test-meta .mono { font-size: .78rem; color: var(--slate); }

@media (max-width: 640px) {
  .pending-test { flex-direction: column; align-items: flex-start; }
}

/* The hidden attribute must win over component display rules. Buttons and
   links set display:inline-flex, which otherwise leaves [hidden] visible. */
[hidden] { display: none !important; }

/* The permanent id sits beside a name: quotable, but never louder than
   the person it belongs to. */
.uid {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--paper-2);
  font-size: .68rem;
  font-weight: 500;
  color: var(--slate);
  letter-spacing: .01em;
  vertical-align: middle;
  white-space: nowrap;
}

/* --------------------------------------------- website settings screen */
.colour-field { display: flex; align-items: center; gap: 8px; }
.colour-dot {
  width: 42px; height: 38px; padding: 3px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--paper); cursor: pointer; flex: none;
}
.colour-field .input { font-size: .82rem; }

.swatches { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.swatch {
  width: 26px; height: 26px; padding: 0;
  border: 1px solid var(--line); border-radius: 8px;
  cursor: pointer; transition: transform .12s ease;
}
.swatch:hover { transform: scale(1.12); }

/* A live sample so the two colours can be judged together rather than
   guessed at from two hex fields. */
.theme-preview {
  margin-top: 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.theme-preview-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px;
  background: var(--preview-ink, #17123a);
}
.theme-preview-mark {
  width: 30px; height: 30px; border-radius: 8px;
  display: grid; place-items: center;
  font-size: .74rem; font-weight: 800; color: var(--ink);
  background: var(--preview-accent, #6f2af5);
}
.theme-preview-name { color: #fff; font-size: .88rem; font-weight: 600; flex: 1; }
.theme-preview-cta {
  padding: 6px 14px; border-radius: 999px;
  font-size: .76rem; font-weight: 600; color: var(--ink);
  background: var(--preview-accent, #6f2af5);
}
.theme-preview-body {
  padding: 16px 14px;
  background: var(--preview-ink, #17123a);
  border-top: 1px solid rgba(255,255,255,.1);
  display: grid; gap: 4px;
}
.theme-preview-body strong { color: #fff; font-size: 1rem; }
.theme-preview-body span { color: rgba(255,255,255,.66); font-size: .8rem; }

.picker-preview-wide { width: 132px; height: 84px; border-radius: var(--radius-sm); }

.gallery-add { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.gallery-add .input, .gallery-add .select { width: auto; flex: 1 1 180px; min-width: 0; }

.gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px; }
.gallery-item {
  margin: 0; border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; background: var(--paper);
}
.gallery-item.is-hidden { opacity: .5; }
.gallery-item img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.gallery-item figcaption {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 10px; font-size: .78rem; color: var(--slate);
  border-top: 1px solid var(--line);
}
.gallery-item figcaption > span:first-child {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

@media (max-width: 640px) {
  .gallery-add .input, .gallery-add .select { flex: 1 1 100%; }
}

/* ------------------------------------------------------ the student card */
.id-card {
  width: 340px; background: #fff; border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden;
  box-shadow: var(--shadow);
}
.id-card-top {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px; background: var(--brand-grad); color: #fff;
}
.id-card-institute { font-size: .76rem; font-weight: 600; }
.id-card-roll { font-size: .76rem; opacity: .8; font-variant-numeric: tabular-nums; }
.id-card-body { display: flex; gap: 14px; padding: 16px 14px 10px; }
.id-card-who { display: grid; gap: 3px; align-content: start; min-width: 0; }
.id-card-who strong { font-size: 1rem; line-height: 1.25; }
.id-card-who span { font-size: .76rem; color: var(--slate); }
.id-card-qr { flex: none; }
.id-card-qr svg { display: block; width: 110px; height: 110px; }
.id-card-barcode { padding: 0 14px 14px; }
.id-card-barcode svg { width: 100%; height: auto; }

.code-strip { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.code-strip img { border: 1px solid var(--line); border-radius: var(--radius-sm); background: #fff; }
.code-strip-bar { height: 70px; width: auto; max-width: 100%; }

.code-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 18px; }
/* Each column stacks: label, code, link — rather than the link flowing
   around an inline-block box and ending up beside it. */
.code-pair > div { display: grid; justify-items: start; align-content: start; }
.code-box {
  margin: 6px 0 8px; padding: 12px; border: 1px solid var(--line);
  border-radius: var(--radius-sm); background: var(--paper-2);
  display: inline-block;
}
.code-box svg { display: block; max-width: 100%; height: auto; }

@media print {
  .id-card { box-shadow: none; border: 1px dashed #999; }
}

/* --------------------------------------------------------- the reports */
.matrix-note.note-miss { background: var(--amber-wash); border-color: var(--amber-edge); color: var(--amber-deep); }
.report-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 10px; }
.report-tile {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 14px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--paper); text-decoration: none; color: inherit;
  transition: border-color .12s ease, transform .12s ease, box-shadow .12s ease;
}
.report-tile:hover { border-color: transparent; transform: translateY(-2px); box-shadow: var(--shadow); }
.report-icon {
  width: 34px; height: 34px; flex: none; border-radius: 9px;
  display: grid; place-items: center; background: var(--paper-2); color: var(--ink);
}
.report-text { display: grid; gap: 3px; min-width: 0; }
.report-text strong { font-size: .92rem; }
.report-text span { font-size: .78rem; color: var(--slate); line-height: 1.45; }

.filters-wide { flex-wrap: wrap; gap: 10px; align-items: flex-end; }
.field-inline { display: grid; gap: 4px; }
.field-inline .label { font-size: .72rem; }

.table-report tfoot td { background: var(--paper-2); border-top: 2px solid var(--line); }

@media print {
  .no-print, .sidebar, .topbar, .page-actions, .btn { display: none !important; }
  .card { border: 0; box-shadow: none; }
  .table-report { font-size: .8rem; }
}

/* ------------------------------------------------- the monthly roster */
.day {
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  margin-bottom: 8px; background: var(--paper);
}
.day-weekend { background: var(--paper-2); }
.day-closed { background: var(--amber-wash); border-color: var(--amber-edge); }
.day-head {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; border-bottom: 1px solid transparent;
}
.day:has(.day-row) .day-head { border-bottom-color: var(--line); }
.day-when { display: flex; align-items: baseline; gap: 7px; min-width: 62px; }
.day-when strong { font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.day-when span { font-size: .74rem; color: var(--slate); text-transform: uppercase; letter-spacing: .05em; }

.day-rows:empty { display: none; }
.day-rows { padding: 8px 12px 10px; display: grid; gap: 6px; }
.day-row {
  display: grid; gap: 6px; align-items: center;
  grid-template-columns: minmax(120px, 1.4fr) 96px 96px minmax(110px, 1fr) minmax(90px, .8fr) auto;
}

@media (max-width: 820px) {
  .day-row { grid-template-columns: 1fr 1fr; }
  .day-row > :last-child { grid-column: 2; justify-self: end; }
}

/* ------------------------------------------------------ holiday picker */
.pick-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 8px; }
.pick {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--paper); cursor: pointer; transition: border-color .12s ease, background .12s ease;
}
.pick:hover { border-color: var(--slate); }
.pick:has(input:checked) { border-color: var(--tab-deep); background: var(--paper-2); }
.pick input { margin-top: 3px; flex: none; }
.pick-body { display: grid; gap: 1px; min-width: 0; }
.pick-body strong { font-size: .86rem; }
.pick-body span { font-size: .74rem; color: var(--slate); }
.row-off, tr.is-off { opacity: .55; }

/* ------------------------------------------------- scanner stations */
.enrol-card { border-left: 3px solid var(--tab-deep); }
.enrol-code {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  font-size: 1.9rem; font-weight: 700; letter-spacing: .16em;
  color: var(--ink); margin: 6px 0 10px;
}
.enrol-code .btn { font-size: .8rem; letter-spacing: 0; font-weight: 600; }

/* The same code, small, on the station's own row — it stays there until
   the station uses it, because whoever types it in is usually standing at
   a different machine and will come back for it. */
.code-chip {
  display: inline-flex; align-items: center; gap: 2px;
  /* Twelve characters somebody has to read off the screen and type into
     another machine. Breaking it across lines makes that harder than it
     needs to be, so the cell scrolls before the code does. */
  white-space: nowrap;
  margin-top: 4px; padding: 1px 3px 1px 9px;
  border: 1px dashed var(--brand-edge);
  background: var(--brand-wash);
  border-radius: var(--radius-pill);
}
.code-chip .mono { color: var(--brand-deep); font-weight: 500; letter-spacing: .06em; }
.code-chip .btn { padding: 4px; color: var(--brand-deep); }
.code-chip .btn:hover { background: transparent; color: var(--ink); }
.how-list { margin: 0 0 12px; padding-left: 18px; display: grid; gap: 7px; }
.how-list li { font-size: .84rem; color: var(--slate); }

/* ------------------------------------------------- the daily register */
.register-bar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 11px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--paper-2);
}
.register-times { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.register-times .label { font-size: .72rem; white-space: nowrap; }
.register-times .input { width: auto; min-width: 112px; }
.register-tally { font-size: .78rem; color: var(--slate); white-space: nowrap; }

@media (max-width: 720px) {
  .register-bar { align-items: stretch; }
  .register-times { justify-content: space-between; }
}

/* ------------------------------------------------ the week at a glance */
/* A timetable is easier to trust when it is read as a week rather than as
   a list of rows, so the saved periods are also laid out by day. */
.week-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px;
}
.week-day {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--paper);
}
.week-day-label {
  padding: 8px 12px;
  background: var(--paper-2);
  border-bottom: 1px solid var(--line);
  font-size: .74rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--slate);
}
.week-slot {
  display: flex;
  gap: 10px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line-soft);
}
.week-slot:last-child { border-bottom: 0; }
.week-slot-time { flex: 0 0 62px; font-size: .76rem; color: var(--tab-deep); padding-top: 1px; }
.week-slot-body { display: grid; gap: 1px; min-width: 0; }
.week-slot-body strong { font-size: .83rem; color: var(--ink); }
.week-slot-body span { font-size: .755rem; color: var(--slate); }

/* -------------------------------------- long scheduled-test lists */
.pending-group { display: grid; gap: 8px; }
.pending-group.is-hidden { display: none; }
.pending-group-label {
  font-size: .72rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--slate);
  margin-top: 6px;
}
.pending-group:first-child .pending-group-label { margin-top: 0; }
.empty-inline {
  margin: 10px 0 0;
  padding: 14px;
  text-align: center;
  color: var(--slate);
  font-size: .82rem;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
}

/* ------------------------------------------- the result date on a sheet */
/* The date lives with the marks, because that is where it is decided. */
.sheet-date {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 11px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--paper-2);
}
.sheet-date .input { width: auto; min-width: 168px; }
.sheet-date-note { font-size: .78rem; color: var(--slate); }
.sheet-date-note.is-warn { color: var(--amber-deep); font-weight: 500; }

@media (max-width: 640px) {
  .sheet-date { align-items: stretch; }
  .sheet-date .input { width: 100%; }
}

/* ------------------------------------------- editable table (lookups) */
/* Small lookup tables are edited in place rather than through a form per
   row, so the inputs sit flush inside the cells. */
.table-edit td { padding-top: 6px; padding-bottom: 6px; vertical-align: middle; }
.table-edit .input-sm {
  padding: 6px 9px;
  font-size: .82rem;
  width: 100%;
}
.check-bare { padding: 0; justify-content: center; }
.check-bare span { display: none; }

/* --------------------------------------- subject rows with a teacher */
/* Each row pairs one subject with the teacher who takes it, so a design
   can give maths and computer science different teachers. */
.subject-rows {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.subject-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
  transition: background .12s ease;
}
.subject-row:last-child { border-bottom: 0; }
.subject-row.on { background: var(--paper-2); }
.subject-row-pick { flex: 0 0 42%; min-width: 0; padding: 0; }
.subject-row-pick span { font-size: .855rem; }
.subject-row-teacher { flex: 1 1 auto; min-width: 0; }
.subject-row-teacher .select { width: 100%; }
.subject-row-teacher .select:disabled { opacity: .45; cursor: not-allowed; }
.select-sm { padding-top: 7px; padding-bottom: 7px; font-size: .82rem; }

@media (max-width: 640px) {
  .subject-row { flex-direction: column; align-items: stretch; gap: 7px; }
  .subject-row-pick { flex: none; }
}

/* ------------------------------------------------ class design preview */
/* Shows what a chosen design contains, right under the picker, so nobody
   has to open another screen to check which subjects are in it. */
.design-preview {
  display: none;
  margin-top: 10px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--tab);
  border-radius: var(--radius);
  background: var(--paper-2);
  padding: 11px 13px;
}
.design-preview.show { display: block; }
.design-preview-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.design-preview-head .ico-sm { color: var(--tab-deep); }
.design-preview-head strong { font-size: .855rem; color: var(--ink); }
.design-preview-desc { margin: 6px 0 0; font-size: .78rem; color: var(--slate); }
.design-preview-desc:empty { display: none; }
.design-preview-subjects {
  display: flex; flex-wrap: wrap; gap: 5px; margin-top: 9px;
}
.design-preview-subjects:empty { display: none; }
.design-preview-subjects .contact-chip { background: var(--paper); font-size: .755rem; }

/* ------------------------------------------- permission matrix (plans/roles) */
.matrix { display: flex; flex-direction: column; gap: 10px; }
.matrix-module {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.matrix-head {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 14px;
  background: var(--paper-2);
  border-bottom: 1px solid var(--line-soft);
}
.matrix-head .ico { color: var(--ink-3); }
.matrix-head strong { font-size: .875rem; color: var(--ink); }
.matrix-head .slug { font-family: var(--mono); font-size: .68rem; color: var(--slate-soft); }
.matrix-head .toggle-all { margin-left: auto; }
.matrix-actions {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 12px 14px;
}
.perm {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 5px 12px 5px 9px;
  font-size: .79rem; cursor: pointer;
  background: var(--paper);
  transition: background .13s, border-color .13s, color .13s;
  user-select: none;
}
.perm input { width: 14px; height: 14px; accent-color: var(--ink); cursor: pointer; }
.perm:hover { border-color: var(--brand-edge); }
.perm:has(input:checked) {
  background: var(--tab-wash);
  border-color: var(--brand-edge);
  color: var(--tab-deep);
  font-weight: 600;
}
.perm input:focus-visible { outline: 2px solid var(--tab-deep); outline-offset: 2px; }

.matrix-note {
  display: flex; gap: 9px; align-items: flex-start;
  background: var(--info-wash); border: 1px solid var(--info-edge);
  color: #23469f; border-radius: var(--radius);
  padding: 11px 13px; font-size: .8rem; margin-bottom: 14px;
}

/* ------------------------------------------------------ detail / meta lists */
.meta-list { display: flex; flex-direction: column; }
.meta-row {
  display: flex; gap: 14px; align-items: baseline;
  padding: 9px 0; border-bottom: 1px dashed var(--line-soft);
}
.meta-row:last-child { border-bottom: 0; }
.meta-row dt { flex: none; width: 122px; color: var(--slate); font-size: .775rem; }
.meta-row dd { margin: 0; flex: 1; color: var(--ink); font-size: .865rem; min-width: 0; word-break: break-word; }

.contact-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.contact-chip {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 4px 10px; font-size: .79rem; background: var(--paper-2);
  color: var(--ink-2);
}
.contact-chip .ico-sm { color: var(--slate); }
.contact-chip.primary { border-color: var(--brand-edge); background: var(--brand-wash); color: var(--brand-deep); }
.contact-chip small { font-family: var(--mono); font-size: .64rem; color: var(--slate); }

.timeline { display: flex; flex-direction: column; gap: 2px; }
.timeline-item {
  display: flex; gap: 11px; padding: 9px 0;
  border-bottom: 1px dashed var(--line-soft);
}
.timeline-item:last-child { border-bottom: 0; }
.timeline-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--tab); margin-top: 7px; flex: none;
}
.timeline-body { min-width: 0; flex: 1; }
.timeline-body strong { font-size: .83rem; color: var(--ink); font-weight: 600; }
.timeline-body p { margin: 0; font-size: .79rem; color: var(--slate); }
.timeline-time { font-family: var(--mono); font-size: .66rem; color: var(--slate-soft); white-space: nowrap; }

.limit-bar { margin-top: 4px; }
.limit-bar .bar { height: 5px; background: var(--line-soft); border-radius: 3px; overflow: hidden; }
.limit-bar .bar span { display: block; height: 100%; background: var(--brand); border-radius: 3px; transition: width .3s; }
.limit-bar.warn .bar span { background: var(--amber); }
.limit-bar.full .bar span { background: var(--rose); }

/* ============================================================== AUTH */
.auth {
  min-height: 100vh;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  background: var(--canvas);
}
.auth-aside {
  background: linear-gradient(165deg, var(--nav) 0%, #1d0f45 55%, var(--nav-2) 100%);
  color: var(--nav-fg);
  padding: 44px 48px;
  display: flex; flex-direction: column;
  position: relative; overflow: hidden;
}
/* One bloom of the brand violet behind the mark. The sign-in screen is
   the only place a stranger meets this product, so the logo's own light
   is the whole decoration. */
.auth-aside::after {
  content: ''; position: absolute;
  top: -180px; left: -140px; width: 540px; height: 540px;
  background: radial-gradient(circle, rgba(140, 56, 252, .4), transparent 66%);
  pointer-events: none;
}
.auth-brand { display: flex; align-items: center; gap: 13px; margin-bottom: auto; position: relative; z-index: 1; }
.auth-brand .brand-mark { width: 46px; height: 46px; font-size: 1.15rem; border-radius: 14px; }
/* Reversed lockup: the tile keeps its colour, the wordmark goes white. */
.auth-brand .brand-name { font-size: 1.42rem; font-weight: 700; letter-spacing: -.035em; }
.auth-brand .brand-sub { font-size: .76rem; color: var(--nav-dim); }

.auth-pitch { position: relative; z-index: 1; max-width: 420px; margin: 40px 0; }
.auth-pitch h2 {
  font-size: 2.1rem; color: #fff; line-height: 1.14;
  letter-spacing: -.03em; margin-bottom: 14px;
}
.auth-pitch p { color: var(--nav-fg); font-size: .93rem; margin-bottom: 26px; }

/* numbered because signing in genuinely is a four-step sequence */
.auth-steps { display: flex; flex-direction: column; gap: 0; position: relative; z-index: 1; }
.auth-step {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 12px 0;
  opacity: .45; transition: opacity .25s;
}
.auth-step.is-current { opacity: 1; }
.auth-step.is-done { opacity: .8; }
.auth-step .n {
  font-family: var(--mono); font-size: .68rem;
  width: 24px; height: 24px; border-radius: 6px;
  border: 1px solid rgba(255,255,255,.22);
  display: grid; place-items: center; flex: none;
  color: var(--nav-fg);
}
.auth-step.is-current .n { background: var(--brand-grad); border-color: transparent; color: #fff; font-weight: 700; }
.auth-step.is-done .n { background: rgba(10,124,107,.3); border-color: rgba(10,124,107,.55); color: #76ddcc; }
.auth-step strong { display: block; color: #fff; font-size: .87rem; font-weight: 600; }
.auth-step > span:last-child span { font-size: .78rem; color: var(--nav-dim); }

.auth-foot { position: relative; z-index: 1; font-size: .72rem; color: #6f6992; }

.auth-main {
  display: flex; align-items: center; justify-content: center;
  padding: 40px 28px;
}
.auth-card {
  width: 100%; max-width: 408px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 32px 30px;
}
.auth-card h1 { font-size: 1.6rem; margin-bottom: 5px; }
.auth-card .lede { color: var(--slate); margin-bottom: 24px; font-size: .875rem; }
.auth-card .field + .field { margin-top: 14px; }
.auth-card .btn-block { margin-top: 20px; }

.auth-institute {
  display: none;
  align-items: center; gap: 11px;
  border: 1px solid var(--sea-edge); background: var(--sea-wash);
  border-radius: var(--radius); padding: 10px 12px;
  margin-bottom: 16px;
}
.auth-institute.show { display: flex; }
.auth-institute .badge {
  width: 36px; height: 36px; border-radius: 9px; flex: none;
  background: var(--paper); display: grid; place-items: center;
  overflow: hidden; border: 1px solid var(--sea-edge);
  font-family: var(--display); font-weight: 600; color: var(--sea);
}
.auth-institute .badge img { width: 100%; height: 100%; object-fit: cover; }
.auth-institute strong { display: block; font-size: .87rem; color: #065f52; }
.auth-institute span { font-family: var(--mono); font-size: .7rem; color: #0a7c6b; }
.auth-institute .change { margin-left: auto; }

.auth-locked { display: none; }
.auth-locked.show { display: block; }

.auth-switch {
  margin-top: 22px; padding-top: 18px;
  border-top: 1px solid var(--line);
  font-size: .8rem; color: var(--slate);
  display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap;
}
.auth-switch a { color: var(--ink); font-weight: 600; }
.auth-switch a:hover { color: var(--tab-deep); }

.pw-wrap { position: relative; }
.pw-wrap .input { padding-right: 40px; }
.pw-toggle {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  background: none; border: 0; color: var(--slate);
  cursor: pointer; padding: 6px; border-radius: 6px;
}
.pw-toggle:hover { color: var(--ink); background: var(--paper-2); }

.pw-meter { margin-top: 7px; }
.pw-meter .bar { height: 4px; background: var(--line-soft); border-radius: 3px; overflow: hidden; }
.pw-meter .bar span { display: block; height: 100%; width: 0; border-radius: 3px; transition: width .25s, background .25s; }
.pw-meter .label { font-size: .72rem; color: var(--slate); margin-top: 4px; display: block; }
.pw-meter.weak .bar span   { width: 33%; background: var(--rose); }
.pw-meter.fair .bar span   { width: 66%; background: var(--amber); }
.pw-meter.strong .bar span { width: 100%; background: var(--sea); }

/* ------------------------------------------------------------ errors */
.error-page {
  min-height: 100vh; display: grid; place-items: center; padding: 30px;
  background: var(--canvas);
}
.error-box { text-align: center; max-width: 430px; }
.error-code {
  font-family: var(--display); font-size: 4.6rem; font-weight: 700;
  color: var(--ink); line-height: 1; letter-spacing: -.04em;
}
.error-box p { color: var(--slate); margin-bottom: 20px; }
.error-trace {
  text-align: left; font-family: var(--mono); font-size: .7rem;
  background: var(--nav); color: var(--nav-fg); padding: 14px;
  border-radius: var(--radius); overflow: auto; max-height: 260px; margin-top: 20px;
}

/* ------------------------------------------- the import preview table */
/* The three outcomes are a traffic light, and the row carries the colour
   rather than only the pill, so a sheet of four hundred can be read by
   scrolling rather than by inspecting each line. */
.table-import td { vertical-align: top; }
.import-ready td     { background: rgba(10, 124, 107, .035); }
.import-duplicate td { background: var(--amber-wash); }
.import-problem td   { background: var(--rose-wash); }
.import-why { color: var(--rose-deep); }
.import-ready .u-block, .import-duplicate .u-block { margin-top: 3px; }
.table-import .pill { margin-bottom: 2px; }

/* -------------------------------------------------------- utilities */
.u-block { display: block; }
/* A stat tile holding a name rather than a figure. */
.u-small-value { font-size: 1.05rem; letter-spacing: -.01em; line-height: 1.3; }
.u-flex { display: flex; }
.u-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.u-center { display: flex; align-items: center; gap: 8px; }
.u-wrap { flex-wrap: wrap; }
.u-grow { flex: 1; min-width: 0; }
.u-right { text-align: right; }
.u-muted { color: var(--slate); }
.u-small { font-size: .78rem; }
.u-mt-0 { margin-top: 0; }
.u-mt { margin-top: 14px; }
.u-mb-0 { margin-bottom: 0; }
.u-mb { margin-bottom: 14px; }
.u-nowrap { white-space: nowrap; }
.u-hide { display: none !important; }
.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;
}

.scrim {
  position: fixed; inset: 0; background: rgba(16,27,45,.45);
  z-index: 55; display: none;
}
.scrim.open { display: block; }

/* ========================================================= RESPONSIVE */
@media (max-width: 1180px) {
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-side { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 1024px) {
  .sidebar { transform: translateX(-100%); transition: transform .24s ease; box-shadow: none; }
  .sidebar.open { transform: translateX(0); box-shadow: var(--shadow-lg); }
  .main { margin-left: 0; }
  .hamburger { display: inline-flex; }
  .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .auth { grid-template-columns: minmax(0, 1fr); }
  .auth-aside { display: none; }
}

@media (max-width: 760px) {
  .page { padding: 18px 14px 48px; }
  .topbar { padding: 0 14px; gap: 8px; }
  .topbar-title { display: none; }

  /* Three stamps do not fit a phone. Keep the campus, which is the one
     that changes what the person is looking at. */
  .stamp-institute, .stamp-batch { display: none; }
  .stamp-campus { max-width: 46vw; min-width: 0; overflow: hidden; }
  .stamp-campus b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
  .grid, .grid-2, .grid-3, .grid-4 { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .form-grid { grid-template-columns: minmax(0, 1fr); }
  .card-body { padding: 15px; }
  .card-head { padding: 13px 15px; }
  .page-head h1 { font-size: 1.32rem; }
  .stat-value { font-size: 1.6rem; }
  .user-btn .who { display: none; }
  .btn { padding: 9px 13px; }

  /* tables reflow into stacked records */
  .table thead { display: none; }
  .table, .table tbody, .table tr, .table td { display: block; width: 100%; }
  .table tr {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    margin-bottom: 10px;
    padding: 4px 0;
    background: var(--paper);
  }
  .table td {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 8px 14px; border-bottom: 0;
    text-align: left !important;
  }
  .table td::before {
    content: attr(data-label);
    flex: none; width: 96px;
    font-family: var(--mono); font-size: .64rem;
    text-transform: uppercase; letter-spacing: .1em;
    color: var(--slate-soft); padding-top: 3px;
  }
  .table td:empty { display: none; }
  .table .actions .btn-row { justify-content: flex-start; }
  /* On a phone the number needs the full line; label and remove share the next. */
  .repeat-row { flex-wrap: wrap; }
  .repeat-row > .input:first-child { flex: 1 1 100%; }
  .repeat-row .input.label-input { flex: 1 1 auto; max-width: none; }
  .meta-row { flex-direction: column; gap: 2px; }
  .meta-row dt { width: auto; }
  .toast-stack { left: 14px; right: 14px; max-width: none; }
}

@media (max-width: 420px) {
  .page-actions { width: 100%; }
  .page-actions .btn { flex: 1; }
  .modal-foot { flex-direction: column-reverse; }
  .modal-foot .btn { width: 100%; }
}

@media print {
  .sidebar, .topbar, .page-actions, .btn, .scrim { display: none !important; }
  .main { margin-left: 0; }
  body { background: #fff; }
  .card { box-shadow: none; border-color: #ccc; }
}

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

/* ============================================================== CHARTS
   Drawn on the server as SVG (see App\Services\Chart). The rules the
   marks follow are in that file; these are the surrounds — the panel,
   the axis text, the legend and the tooltip.

   Axis text wears text tokens, never a series colour: a light hue is
   illegible as words, and identity is carried by the coloured mark
   beside the text rather than by the text itself.
   ===================================================================== */
.chart { position: relative; }
.chart-svg { display: block; width: 100%; height: auto; overflow: visible; }

.ch-y, .ch-x, .ch-row, .ch-end {
  font-family: var(--body);
  fill: var(--slate);
  font-size: 11px;
}
.ch-y { font-size: 10.5px; font-variant-numeric: tabular-nums; }
.ch-row { fill: var(--ink-2); font-size: 11.5px; }
/* The one number worth writing on the chart: the latest, at the end of
   the line, or the value at the tip of a bar. */
.ch-end { fill: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }

/* Pointing at a 4px dot is hopeless, so each point owns a band of the
   plot and the band is what reacts. */
.ch-hit { fill: transparent; cursor: default; }
.ch-hit:hover { fill: rgba(111, 42, 245, .05); }

.chart-key {
  display: flex; flex-wrap: wrap; gap: 14px;
  margin-bottom: 10px;
  font-size: .78rem; color: var(--slate);
}
.chart-key .key { display: inline-flex; align-items: center; gap: 6px; }
.chart-key i { width: 10px; height: 10px; border-radius: 3px; flex: none; }

.chart-tip {
  position: absolute; z-index: 5; pointer-events: none;
  background: var(--ink); color: #fff;
  padding: 7px 10px; border-radius: var(--radius-sm);
  font-size: .76rem; line-height: 1.4;
  box-shadow: var(--shadow-lg);
  transform: translate(-50%, -115%);
  white-space: nowrap;
}
.chart-tip b { display: block; font-weight: 600; color: #fff; }
.chart-tip span { color: rgba(255, 255, 255, .78); }

.spark { display: block; flex: none; }

@media print {
  .ch-hit { display: none; }
  .chart-tip { display: none; }
}

/* ------------------------------------------------------- today's strip
   The one loud thing on the dashboard. Everything under it reports in
   black and white, because six panels all shouting is a screen nobody
   reads — and the thing somebody opens a dashboard for is today.
   ---------------------------------------------------------------------- */
.today {
  display: flex; align-items: center; gap: 30px; flex-wrap: wrap;
  padding: 22px 26px;
  margin-bottom: 18px;
  border-radius: var(--radius-lg);
  background: linear-gradient(135deg, #1d0f45 0%, #3a1490 58%, #6f2af5 100%);
  color: #fff;
  box-shadow: var(--shadow-brand);
  position: relative; overflow: hidden;
}
.today::after {
  content: ''; position: absolute; right: -90px; top: -120px;
  width: 320px; height: 320px; border-radius: 50%;
  background: radial-gradient(circle, rgba(173, 55, 252, .5), transparent 68%);
  pointer-events: none;
}
.today > * { position: relative; }

.today-main { min-width: 170px; }
.today-when { font-size: .78rem; color: rgba(255,255,255,.72); }
.today-figure {
  font-family: var(--display); font-weight: 700;
  font-size: 3.4rem; line-height: 1; letter-spacing: -.045em;
  margin: 6px 0 2px; color: #fff;
  font-variant-numeric: tabular-nums;
}
.today-figure span { font-size: 1.5rem; font-weight: 600; margin-left: 2px; opacity: .75; }
.today-figure-idle { color: rgba(255,255,255,.45); }
.today-caption { font-size: .82rem; color: rgba(255,255,255,.76); margin: 0; }

.today-split { display: flex; gap: 22px; flex-wrap: wrap; flex: 1; }
.today-state { display: grid; gap: 5px; justify-items: start; }
.today-state b {
  font-family: var(--display); font-size: 1.5rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
/* The status pills sit on a dark panel here, so they take their own
   light-on-dark treatment rather than the one meant for white cards. */
.today-state .pill { background: rgba(255,255,255,.14); border-color: transparent; color: #fff; }
.today-state .pill-on   { background: rgba(110, 231, 183, .22); color: #a7f3d0; }
.today-state .pill-warn { background: rgba(252, 211, 77, .2);  color: #fde68a; }
.today-state .pill-bad  { background: rgba(253, 164, 175, .2); color: #fecdd3; }

.today-go {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 10px 16px; border-radius: var(--radius-pill);
  background: rgba(255,255,255,.14); color: #fff;
  font-size: .85rem; font-weight: 600;
  border: 1px solid rgba(255,255,255,.18);
  transition: background .15s;
}
.today-go:hover { background: rgba(255,255,255,.24); color: #fff; }

/* A change against the same period before it. */
.delta { font-weight: 600; font-variant-numeric: tabular-nums; }
.delta.up   { color: var(--sea); }
.delta.down { color: var(--rose-deep); }

.u-pad-sm { padding: 22px 16px; }

@media (max-width: 760px) {
  .today { gap: 20px; padding: 20px; }
  .today-figure { font-size: 2.8rem; }
  .today-go { width: 100%; justify-content: center; }
}

/* The platform console's own strip: the same shape, a cooler ground, so
   the two consoles are recognisably the same product without the master
   screen pretending to be a campus. */
.today-master {
  background: linear-gradient(135deg, #140d33 0%, #2b1263 52%, #531acc 100%);
}

/* A row of the landing page's day-at-a-campus list, in the console. */
.feature-row {
  display: grid; gap: 8px;
  padding: 12px; margin-bottom: 8px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--paper);
}
.feature-row:last-child { margin-bottom: 0; }
.feature-row-top {
  display: grid; gap: 8px; align-items: center;
  grid-template-columns: 110px 170px minmax(0, 1fr) auto;
}
.feature-row textarea { min-height: 58px; }
@media (max-width: 900px) {
  .feature-row-top { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* ------------------------------------------------------------- leads
   One block per person who wrote in, not a table: the message is the
   point and a message does not fit in a cell. The colour on the left
   edge is the state, so a screen of these can be read by scrolling.
   ---------------------------------------------------------------------- */
.lead-list { display: grid; }
.lead {
  display: grid; gap: 18px; grid-template-columns: minmax(0, 1fr) 300px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--line-soft);
  border-left: 3px solid transparent;
}
.lead:last-child { border-bottom: 0; }
.lead-new       { border-left-color: var(--brand); background: var(--brand-wash); }
.lead-contacted { border-left-color: var(--amber); }
.lead-converted { border-left-color: var(--sea); }
.lead-closed    { opacity: .62; }

.lead-who strong { font-size: .98rem; color: var(--ink); }
.lead-facts {
  display: flex; flex-wrap: wrap; gap: 6px 16px;
  margin-top: 10px; font-size: .8rem; color: var(--slate);
}
.lead-facts a, .lead-facts span { display: inline-flex; align-items: center; gap: 5px; }
.lead-facts a:hover { color: var(--brand-deep); }
.lead-said {
  margin: 12px 0 0; padding: 11px 13px;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius-sm); font-size: .87rem; color: var(--ink-2);
}
.lead-note {
  margin: 10px 0 0; font-size: .82rem; color: var(--sea);
  display: flex; align-items: flex-start; gap: 6px;
}
.lead-do { display: grid; gap: 8px; align-content: start; }

@media (max-width: 860px) {
  .lead { grid-template-columns: minmax(0, 1fr); }
}
