/* Wizard pages — shares board.css variables and dark theme */

/* --well (the ground cut below a panel) and --panel-3 (the hover rung) are
   declared in board.css beside the rest of the plate, on `body` so they
   follow the season. This sheet, report.css and admin.css all read them. */

body.wizard { overflow: auto; user-select: text; }

/* board.css lays out the bare <main> as a horizontal flexbox (tray + grid).
   Wizard pages must stack their content vertically instead. */
main.wizard-main {
  display: block;
  height: auto;
  min-height: 0;
}

#wizard-nav {
  display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
  padding: 8px 14px;
  background: var(--panel); border-bottom: 2px solid var(--accent);
  position: sticky; top: 0; z-index: 50;
}
#wizard-nav a {
  color: var(--muted); text-decoration: none;
  font-size: .82rem; font-weight: 600;
  padding: 6px 10px; border-radius: 3px;
  white-space: nowrap;
}
#wizard-nav a:hover { background: var(--panel-3); color: #fff; }
#wizard-nav a.on { background: var(--accent); color: #0f1013; }
/* The right-hand cluster: term chips, Admin, who is signed in, version.
   One container pinned right so its contents keep their places whether or not
   the term chips are rendered — Admin used to jump between pages. */
#wizard-nav .nav-right {
  margin-left: auto; display: flex; align-items: center; gap: 8px;
}
#wizard-nav .nav-term { display: flex; gap: 6px; }
/* who is signed in, on a shared board */
#wizard-nav .nav-who { display: flex; align-items: center; gap: 6px;
                       font-size: .78rem; color: var(--muted); }
#wizard-nav .nav-who button { background: var(--panel-2); color: var(--muted);
                              border: 1px solid var(--line); border-radius: 3px;
                              padding: 3px 9px; cursor: pointer; font-size: .8rem; }
#wizard-nav .nav-who button:hover { background: var(--bad); color: #fff; }
/* The signed-in name is a link to the profile — so it is a control, and it
   wears the same dark pill as the version badge beside it and the ⏻ button
   next to that: three things you can press, all three looking like it.
   Written with the #wizard-nav prefix and its own colours so the generic
   a.on / a:hover nav-step rules cannot repaint it — the same trap the
   version badge hit. */
#wizard-nav a.whoami { display: inline-flex; align-items: center; gap: 5px;
                       color: var(--muted); text-decoration: none;
                       font-family: var(--mono);
                       padding: 3px 9px; border-radius: 3px;
                       border: 1px solid var(--line); background: var(--well); }
#wizard-nav a.whoami:hover { color: var(--fg); border-color: var(--accent); }
#wizard-nav a.whoami .ucode { font-style: normal; font-size: .7rem;
                              opacity: .65; letter-spacing: .02em; }
#wizard-nav a.whoami .vonly { font-style: normal; font-size: .72rem; }
/* 🙋 how many people are waiting at the front door, on the 🛡️ link. Written
   with the full `#wizard-nav a.step.admin` prefix so the generic a.on /
   a:hover nav-step rules cannot repaint it — the trap the version badge and
   the signed-in name both fell into. Absolute, like the bell's count, so a
   number appearing can never move the nav. */
#wizard-nav a.step.admin { position: relative; }
#wizard-nav a.step.admin .admincount { position: absolute; top: -3px; right: -4px;
    font-style: normal; font-size: .58rem; line-height: 1; padding: 2px 4px;
    font-family: var(--mono);
    border-radius: 3px; background: var(--gold); color: #06070a;
    border: 1px solid var(--bg); }
/* 🔔 the unread count on the bell */
#wizard-nav .bell { position: relative; }
#wizard-nav .bell .bellcount { position: absolute; top: -3px; right: -4px;
    font-style: normal; font-size: .58rem; line-height: 1; padding: 2px 4px;
    font-family: var(--mono);
    border-radius: 3px; background: var(--bad); color: #fff;
    border: 1px solid var(--bg); }

/* Which version is this, and when was it last updated. Last in the bar, so it
   sits in the top-right corner whether or not the term chips and the signed-in
   name are there — hence margin-left:auto only when nothing before it already
   pushed the row apart. Hover for the install date. */
/* The badge is an <a> now, so the generic `#wizard-nav a` / `a.on` / `a:hover`
   rules would repaint it as a nav step (accent pill — with the accent-coloured
   number vanishing into it on /changelog). `a.nav-ver` outranks them, so the
   badge keeps its own dark pill and only its border and number react. */
#wizard-nav a.nav-ver { display: flex; align-items: baseline; position: relative;
                        gap: 6px; padding: 3px 9px; border-radius: 3px;
                        border: 1px solid var(--line); background: var(--well);
                        font-family: var(--mono);
                        font-size: .7rem; font-weight: 400; color: var(--muted);
                        white-space: nowrap; cursor: pointer;
                        text-decoration: none; }
#wizard-nav a.nav-ver b { color: var(--text); font-size: .74rem;
                          letter-spacing: .02em; }
#wizard-nav a.nav-ver:hover, #wizard-nav a.nav-ver.on {
  background: var(--well); color: var(--muted); border-color: var(--accent); }
#wizard-nav a.nav-ver.on b, #wizard-nav a.nav-ver:hover b { color: var(--accent); }
/* "there are notes you have not read": a small pulsing dot on the badge */
#wizard-nav .nav-ver .newdot { position: absolute; top: -3px; right: -3px;
                               width: 9px; height: 9px; border-radius: 50%;
                               /* the ring punches the dot out of the badge —
                                  it must stay the badge's own background */
                               background: var(--gold); box-shadow: 0 0 0 2px var(--well);
                               animation: newdot 1.6s ease-in-out infinite; }
@keyframes newdot { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.35); } }
@media (prefers-reduced-motion: reduce) { #wizard-nav .nav-ver .newdot { animation: none; } }
/* On a narrow window the date is what makes the nav wrap onto a second row,
   which costs the board real height — the version itself always stays. */
@media (max-width: 1500px) { #wizard-nav .nav-ver .when { display: none; } }

.wizard-main { padding: 18px 22px; width: 100%; }
.wizard-main h1 { font-family: var(--serif); font-weight: 600;
                  font-size: 1.3rem; margin-bottom: 10px; }
.hint { color: var(--muted); font-size: .85rem; margin-bottom: 14px;
        line-height: 1.5; max-width: 950px; }

.tbl-wrap { overflow: auto; max-height: 70vh; border: 1px solid var(--line);
            border-radius: 4px; margin-bottom: 14px; }
.wizard-main table { border-collapse: collapse; width: 100%; font-size: .82rem; }
.wizard-main th { position: sticky; top: 0; background: var(--panel);
                  padding: 7px 8px; text-align: left; color: var(--muted);
                  font-size: .74rem; z-index: 2; }
.wizard-main td { padding: 4px 8px; border-top: 1px solid var(--line); }
tr.closed { opacity: .42; }

/* Following one lecture across a wide table: the hovered row lights up, and
   clicking it PINS the glow (click again to release) so the row stays
   readable while the table is scrolled sideways or a value is being typed.
   The tint is painted as a background-IMAGE so the sticky first column can
   keep its own opaque background-color underneath. */
.wizard-main tbody tr { --row-tint: transparent; }
.wizard-main tbody tr:hover { --row-tint: rgba(91, 147, 224, .20); }
.wizard-main tbody tr.picked { --row-tint: rgba(91, 147, 224, .34); }
body.spring .wizard-main tbody tr:hover { --row-tint: rgba(231, 139, 184, .20); }
body.spring .wizard-main tbody tr.picked { --row-tint: rgba(231, 139, 184, .34); }
.wizard-main tbody td {
  background-image: linear-gradient(var(--row-tint), var(--row-tint));
  transition: background-image .1s;
}
.wizard-main tbody tr:hover, .wizard-main tbody tr.picked { color: #fff; }
.wizard-main tbody tr:hover td.name, .wizard-main tbody tr.picked td.name { color: var(--text); }
.wizard-main tbody tr.picked td { border-top-color: var(--accent); }
/* rows with unsaved edits — only these are sent when you press Save */
#db tbody tr.edited td.codecol { box-shadow: inset 3px 0 0 var(--ok); }
#db tbody tr.edited td.codecol::after { content: " ✎"; color: var(--ok); }
.wizard-main tbody tr.closed:hover { opacity: .75; }
/* the availability click-grid has its own per-cell hover */
#grid-av tbody tr:hover, #grid-av tbody tr.picked { --row-tint: transparent; }

.wizard-main input, .wizard-main select {
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 2px;
  padding: 4px 6px; font-size: .8rem; width: 72px;
}
.wizard-main select { width: auto; max-width: 180px; }
.wizard-main input.wide { width: 170px; }
.wizard-main input.lect { width: 120px; }
td.name { color: var(--muted); max-width: 190px; overflow: hidden;
          text-overflow: ellipsis; white-space: nowrap; }
/* 🏛 department buttons on 📚 Database: whole faculty vs one department */
.dept-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 0 12px; }
.dtab { font-size: .78rem; font-weight: 700; padding: 4px 12px; border-radius: 3px;
        border: 1px solid var(--line); background: var(--panel); color: var(--muted);
        text-decoration: none; }
.dtab:hover { border-color: var(--accent); color: var(--text); }
.dtab.cur { border-color: var(--accent); color: var(--accent); background: var(--well); }
/* ≠ on a Category: the course's category is not the same for every cohort */
td.catcell { white-space: nowrap; }
.catmix { display: inline-block; margin-left: 4px; padding: 0 6px; border-radius: 3px;
          border: 1px solid var(--warn); color: var(--warn);
          font-size: .74rem; font-weight: 800; cursor: help; }
/* a shared course's other departments, shown inside a department view */
.dother { color: var(--muted); font-size: .74rem; cursor: help; }
/* Database table: keep all columns on one screen */
#db td { padding: 4px 5px; }
#db input[type="number"] { width: 48px; font-family: var(--mono); }
#db select { max-width: 150px; }
#db input[type="checkbox"] { width: 15px; height: 15px; accent-color: var(--accent);
                             cursor: pointer; vertical-align: middle; }
#db td.flag { text-align: center; }
/* The code column stays put while the table scrolls sideways — it is the
   anchor for reading a row, so it needs an opaque base under the row tint. */
#db th.codecol, #db td.codecol { position: sticky; left: 0; z-index: 1;
                                 background-color: var(--bg);
                                 font-family: var(--mono); }
#db th.codecol { background-color: var(--panel); z-index: 3; }
#db tbody tr:hover td.codecol, #db tbody tr.picked td.codecol {
  box-shadow: inset 3px 0 0 var(--accent);
}

/* ---------------------------------------------------------------- sections
   A course with more than one group grows a little tree beneath it, one line
   per group. The lines are drawn like a directory listing on purpose: the
   guide characters carry the "these belong to the row above" meaning, so the
   rows need no heavy borders and the wide table stays readable. */
#db tr.hassections td { border-bottom: none; }
#db tr.hassections td.codecol b { position: relative; }
#db tr.hassections td.codecol b::after {
  content: "▾"; color: var(--accent); font-size: .7em; margin-left: 5px;
}
#db tr.secrow td.seccell {
  padding: 2px 8px 2px 18px;
  background-image: linear-gradient(var(--row-tint), var(--row-tint));
  border-top: none;
  white-space: nowrap;
}
#db tr.secrow:last-child td.seccell { padding-bottom: 6px; }
#db tr.secrow .secguide {
  color: var(--line); font-family: var(--mono);
  margin-right: 8px; user-select: none;
}
#db tr.secrow .sectag {
  font-family: var(--mono); font-size: .72rem;
  color: var(--muted); background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 3px; padding: 1px 7px;
}
#db tr.secrow .sectag b { color: var(--accent); font-weight: 700; }
#db tr.secrow .secwhat {
  color: var(--muted); font-size: .72rem; margin: 0 12px 0 9px;
  display: inline-block; min-width: 104px;
}
#db tr.secrow .secwho { margin-right: 16px; font-size: .78rem; }
#db tr.secrow input.seclect {
  width: 150px; padding: 2px 6px; font-size: .76rem;
}
#db tr.secrow .seclock { color: var(--muted); font-size: .76rem; cursor: help; }
#db tr.secrow .seclock i { opacity: .7; }
/* the whole family lights up together when the course row is hovered/pinned */
#db tr.secrow:hover { --row-tint: rgba(91, 147, 224, .12); }
body.spring #db tr.secrow:hover { --row-tint: rgba(231, 139, 184, .12); }

/* elective requirements — how many electives of each pool a year must pick */
#picks-box { border: 1px solid var(--line); border-radius: 4px; background: var(--panel);
             padding: 10px 14px; margin-bottom: 14px; }
#picks-box > summary { cursor: pointer; font-weight: 700; font-size: .9rem; }
#picks-box .hint { margin: 10px 0; }
.pickwrap { display: flex; gap: 22px; flex-wrap: wrap; }
table.picks { width: auto; }
table.picks th { position: static; background: transparent; text-align: center;
                 padding: 3px 7px; }
table.picks tbody th { text-align: right; color: var(--muted); font-size: .76rem;
                       font-weight: 700; }
table.picks thead th:first-child { color: var(--text); font-size: .8rem; }
table.picks td { padding: 3px 5px; }
table.picks input { width: 54px; text-align: center; font-family: var(--mono); }

/* the one destructive button on the page — parked in the corner, out of the
   way of everything you press by accident */
.corner-actions { float: right; display: flex; gap: 8px; margin: -4px 0 6px 12px; }
.ghost-corner {
  background: transparent; color: #8fe0b0;
  border: 1px solid rgba(78, 201, 129, .45); border-radius: 3px;
  padding: 7px 13px; font-size: .8rem; font-weight: 600; cursor: pointer;
}
.ghost-corner:hover { background: var(--ok); color: #06281a; }
.danger-corner {
  margin: 0;
  background: transparent; color: #f0a99e;
  border: 1px solid rgba(224, 96, 80, .45); border-radius: 3px;
  padding: 7px 13px; font-size: .8rem; font-weight: 600; cursor: pointer;
  transition: background .15s, color .15s;
}
.danger-corner:hover { background: var(--bad); color: #fff;
                       border-color: var(--bad); }
.danger-corner.locked, .danger-corner:disabled {
  color: var(--muted); border-color: var(--line); cursor: not-allowed;
}
.danger-corner.locked:hover { background: transparent; color: var(--muted);
                              border-color: var(--line); }

button.primary { background: var(--accent); color: #0f1013; border: none;
                 border-radius: 3px; padding: 9px 18px; font-weight: 700;
                 cursor: pointer; font-size: .88rem; }
button.primary:hover { filter: brightness(1.15); }
button.ghost { background: var(--panel-2); color: var(--text);
               border: 1px solid var(--line); border-radius: 3px;
               padding: 8px 14px; cursor: pointer; font-size: .82rem; }
.btnrow { display: flex; gap: 10px; margin: 10px 0 18px; flex-wrap: wrap; }

/* lecturer availability grid */
#grid-av { width: auto; }
#grid-av td.cell-av { width: 74px; height: 30px; cursor: pointer;
                      background: rgba(78, 201, 129, .14);
                      border: 1px solid var(--line); }
#grid-av td.cell-av:hover { filter: brightness(1.5); }
#grid-av td.cell-av.blocked { background: rgba(224, 96, 80, .5); }
#grid-av th.dayh, #grid-av th.hourh { cursor: pointer; user-select: none;
                                      font-family: var(--mono); }
#grid-av th.dayh:hover, #grid-av th.hourh:hover { color: #fff; }

/* select lectures */
.selrow { display: flex; gap: 10px; align-items: center;
          padding: 6px 10px; border-radius: 3px; font-size: .84rem;
          /* ruled and capped: name and meta stay one scan apart */
          max-width: 62rem; border-bottom: 1px solid var(--line); }
.selrow:hover { background: var(--panel-2); }
.selrow em { color: var(--muted); font-style: normal; font-size: .74rem;
             margin-left: auto; text-align: right; }
.selrow.notready { opacity: .55; }
.selgroup { margin-bottom: 20px; }
.selgroup h2 { font-size: .95rem; color: var(--muted); margin: 12px 0 6px; }

/* ---------------------------------------------------------------- import tab */
#dropzone {
  border: 2px dashed var(--line); border-radius: 4px;
  padding: 16px 18px; margin: 6px 0 12px; max-width: 1000px;
  background: var(--panel); text-align: center; font-size: .86rem;
  transition: border-color .12s, background .12s;
}
#dropzone.over { border-color: var(--accent); background: var(--panel-2); }
#dropzone b { display: block; margin-bottom: 4px; }
#dropzone button { margin-top: 8px; }
#filelist { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center;
            margin-top: 10px; }
/* 🏛 external timetables: same dropzone look, its own ids */
#extzone {
  border: 2px dashed var(--line); border-radius: 4px;
  padding: 16px 18px; margin: 6px 0 12px; max-width: 1000px;
  background: var(--panel); text-align: center; font-size: .86rem;
  transition: border-color .12s, background .12s;
}
#extzone.over { border-color: var(--accent); background: var(--panel-2); }
#extzone b { display: block; margin-bottom: 4px; }
#extzone button { margin-top: 8px; }
#extfilelist { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center;
               margin-top: 10px; }
.extsec { font-size: .78rem; padding: 1px 0; white-space: nowrap; }
.extsec code { color: var(--accent); font-weight: 700; margin-right: 4px;
               font-family: var(--mono); }
.exttimes { max-width: 560px; overflow-x: auto; }
/* a section's time is a chip: click it and it turns into a day + hour editor */
.xkind { white-space: nowrap; }
.xtime { font: inherit; font-family: var(--mono); font-size: .76rem; color: var(--text);
         background: var(--panel-2); border: 1px solid var(--line);
         border-radius: 3px; padding: 1px 8px; cursor: pointer;
         transition: border-color .12s, background .12s; }
.xtime:hover { border-color: var(--accent); background: var(--well); }
.xtime.moved { border-color: var(--ok); box-shadow: 0 0 0 2px rgba(78, 201, 129, .35); }
.xedit { display: inline-flex; gap: 3px; align-items: center; vertical-align: middle; }
.xedit select { width: auto; max-width: none; padding: 1px 4px; font-size: .76rem; }
/* 🏛 their classroom, typed beside the day and hour — 9em holds "Y (-1B04)"
   and the placeholder without stretching the panel's row */
.xedit .xroom { width: 9em; max-width: none; padding: 1px 4px; font-size: .76rem; }
.xedit button { font: inherit; font-size: .8rem; line-height: 1; padding: 2px 7px;
                border-radius: 3px; border: 1px solid var(--line); cursor: pointer;
                background: var(--panel-2); color: var(--text); }
.xedit .xok { border-color: var(--ok); color: #8fe0b0; }
.xedit .xok:hover { background: var(--ok); color: #06281a; }
.xedit .xno:hover { background: var(--bad); color: #fff; }
.xedit button:disabled { opacity: .5; cursor: progress; }
/* T.Sec / L.Sec of an external course, and the ＋ / ✕ piece controls */
.xsecs { white-space: nowrap; }
.xsec { width: 46px; max-width: 46px; padding: 1px 4px; font-size: .78rem; text-align: center;
        font-family: var(--mono); }
/* 🏷 the v0.43 hint style: what each symbol/colour means, one line per
   family, nothing else — the detail lives in the tooltips */
.symhint { line-height: 1.65; }
.symhint b { color: var(--text); font-weight: 700; }

/* 🏷 legends — one line of small chips explaining the page's symbols and
   colours; the v0.43 replacement for the old paragraph-length hints */
.legend { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 12px; }
.legend .lg {
  font-size: .74rem; color: var(--muted);
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 3px; padding: 3px 10px; white-space: nowrap;
}
.legend .lg b { color: var(--text); }

/* 🏛 External List */
#extlist .timescell { max-width: 340px; }
.tchip {
  display: inline-block; font-size: .74rem; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 3px; padding: 1px 6px; margin: 1px 3px 1px 0;
  white-space: nowrap;
}
.tchip code { color: var(--accent); font-weight: 700; font-family: var(--mono); }
.srcpill {
  display: inline-block; font-size: .72rem; font-weight: 700;
  border-radius: 3px; padding: 2px 8px; white-space: nowrap;
}
.srcpill.out { background: rgba(125, 144, 168, .16); color: #bccadd; }
.srcpill.ext { background: rgba(90, 65, 12, .8); color: #f0d9a0; }
.srcpill.else { background: var(--line); color: var(--muted); }
.copyrow { padding: 3px 8px; cursor: pointer; }

/* 👥 head counts under the cohort-size system: auto = calculated (lilac,
   italic), manual = the user's own override (amber edge) */
.studcell { white-space: nowrap; }
.xstud { width: 58px; max-width: 58px; padding: 1px 4px; font-size: .78rem; text-align: center;
         font-family: var(--mono); }
input.stauto { color: var(--lilac); font-style: italic; }
input.stman { border-color: var(--warn); box-shadow: inset 0 0 0 1px rgba(217, 169, 63, .33); }
.xadd { font: inherit; font-size: .7rem; color: #8fe0b0; background: rgba(78, 201, 129, .12);
        border: 1px dashed rgba(78, 201, 129, .5); border-radius: 3px; padding: 0 7px;
        margin-left: 6px; cursor: pointer; }
.xadd:hover { background: rgba(78, 201, 129, .3); }
.xdel { font: inherit; font-size: .64rem; color: var(--muted); background: transparent;
        border: 0; padding: 0 2px 0 3px; cursor: pointer; vertical-align: middle; }
.xdel:hover { color: #f0a99e; }
.warnnote { color: var(--gold); font-size: .75rem; }
#extpreview tr.off { opacity: .45; }
#ext-box { max-width: 1400px; margin-top: 18px; }
#ext-box > summary { cursor: pointer; font-size: .95rem; font-weight: 600;
                     color: var(--muted); padding: 4px 0; }
#extdb .tiny { color: var(--muted); display: block; margin-bottom: 2px; }
.filechip {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 3px;
  padding: 2px 6px 2px 10px; font-size: .72rem; display: inline-flex;
  align-items: center; gap: 6px;
}
.filechip button {
  background: none; border: none; color: var(--muted); cursor: pointer;
  font-size: .8rem; padding: 0 2px;
}
.filechip button:hover { color: #f0a99e; }
#pastebox { max-width: 1000px; margin-bottom: 12px; }
#pastebox > summary { cursor: pointer; font-size: .86rem; font-weight: 600;
                      color: var(--muted); padding: 4px 0; }
#pastebox textarea, .wizard-main textarea {
  width: 100%; background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 3px; padding: 10px;
  font-family: var(--mono); font-size: .78rem;
}

.impcard {
  border: 1px solid var(--line); border-radius: 4px; background: var(--panel);
  padding: 14px 16px; margin: 16px 0; max-width: 1400px;
}
.impcard > h2 { font-size: 1rem; margin-bottom: 10px; }
.impcard.ok { border-color: rgba(78, 201, 129, .5); }
.srclist { margin-bottom: 10px; }
.srcrow {
  display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap;
  font-size: .78rem; padding: 3px 0; border-bottom: 1px solid var(--line);
}
.srcrow em { color: var(--muted); font-style: normal; font-size: .74rem; }
.srcrow .tag {
  font-size: .66rem; padding: 1px 7px; border-radius: 3px;
  background: rgba(232, 234, 238, .09); color: var(--muted);
}
.impstats { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.impstats .pill {
  font-size: .76rem; font-weight: 600; border-radius: 3px; padding: 3px 11px;
  background: var(--panel-2); border: 1px solid var(--line);
}
.impstats .pill.add { color: #8fe0b0; border-color: rgba(78, 201, 129, .45); }
.impstats .pill.upd { color: #f0d9a0; border-color: rgba(217, 169, 63, .45); }
.impstats .pill.same { color: var(--muted); }
.impstats .pill.picks { cursor: pointer; color: #bccadd;
                        border-color: rgba(125, 144, 168, .45); }
.impstats .pill.picks input { width: auto; vertical-align: middle; margin-right: 4px; }
#impfilters { display: inline-flex; gap: 5px; flex-wrap: wrap; }
#impfilters .ghost { padding: 5px 10px; font-size: .76rem; }
#impfilters .ghost.on { background: var(--accent); color: #0f1013;
                        border-color: var(--accent); }
#imptbl td { padding: 5px 7px; vertical-align: top; }
#imptbl tbody tr.on td.codecol { box-shadow: inset 3px 0 0 var(--ok); }
#imptbl tbody tr.imp-same { opacity: .5; }
#imptbl input[type="checkbox"] { width: 15px; height: 15px;
                                 accent-color: var(--accent); cursor: pointer; }
#imptbl td.name { max-width: 300px; }
.chg {
  display: inline-block; font-size: .7rem; margin: 1px 4px 1px 0;
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 3px; padding: 1px 6px;
}
.chg b { color: #f0d9a0; font-weight: 600; }
#imptbl i { color: var(--muted); font-style: normal; font-size: .72rem; }

/* export tab */
.exportcard { border: 1px solid var(--line); border-radius: 4px;
              padding: 14px 16px; margin-bottom: 14px; max-width: 560px;
              background: var(--panel); }
.exportcard h2 { font-size: 1rem; margin-bottom: 6px; }

/* 🏛 the OBS card: tiles, a spreadsheet-style column strip, rule chips and a
   segmented 0/1 switch — structure instead of a wall of hint text */
.exportcard.obs { max-width: 760px; }
.obs-sheets { display: flex; gap: 10px; margin: 10px 0; }
.obs-tile { flex: 1; border: 1px solid var(--line); border-radius: 3px;
            padding: 8px 12px; background: var(--bg); display: grid;
            grid-template-columns: auto 1fr; column-gap: 10px; align-items: baseline; }
.obs-tile b { font-size: 1.5rem; color: var(--accent); grid-row: 1 / span 2;
              font-family: var(--mono); }
.obs-tile.ext b { color: var(--muted); }
.obs-tile .t { font-weight: 700; font-size: .84rem; }
.obs-tile .d { color: var(--muted); font-size: .74rem; grid-column: 2; }
.obs-schema { display: flex; align-items: stretch; flex-wrap: wrap; gap: 2px;
              margin: 10px 0 8px; }
/* The board speaks English; OBS speaks Turkish. Where a sentence has to name
   a screen, a box or a button the user will look for INSIDE OBS, the Turkish
   name stays and this is the English gloss beside it — quiet, in the muted
   ink, never louder than the instruction it explains. */
.obs-tr { font-style: normal; color: var(--muted); font-size: .92em; }

.obs-schema .oc { border: 1px solid var(--line); border-radius: 2px;
                  background: var(--bg); padding: 2px 7px 3px; font-size: .72rem;
                  color: var(--text); white-space: nowrap; display: flex;
                  flex-direction: column; align-items: center; cursor: default; }
.obs-schema .oc i { font-style: normal; font-weight: 800; font-size: .66rem;
                    color: var(--muted); letter-spacing: .04em;
                    font-family: var(--mono); }
.obs-schema .oc.on { border-color: var(--accent); }
.obs-schema .oc.on i { color: var(--accent); }
.obs-schema .oc.dim { opacity: .45; }
.obs-schema .gap { align-self: center; color: var(--muted); font-size: .66rem;
                   padding: 0 6px; border-left: 1px dashed var(--line);
                   border-right: 1px dashed var(--line); cursor: default; }
.obs-schema .oc.helper { border-style: dashed; color: var(--muted);
                         font-style: italic; }
.obs-rules { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; }
.orule { font-size: .74rem; font-weight: 600; color: var(--muted);
         border: 1px solid var(--line); border-radius: 3px;
         padding: 2px 10px; background: var(--bg); cursor: default; }
.obseg-wrap { display: inline-flex; border: 1px solid var(--line);
              border-radius: 3px; overflow: hidden; }
.obseg { border: 0; background: var(--panel-2); color: var(--muted); font-weight: 800;
         font-size: .82rem; padding: 4px 14px; cursor: pointer; }
.obseg + .obseg { border-left: 1px solid var(--line); }
.obseg:hover { color: var(--text); }
.obseg.cur { background: var(--accent); color: #0f1013; }
/* 📋 the paste form: separator switch, the two sheets as buttons, and the
   text itself on screen — the box IS the deliverable, so it gets room */
.obs-sep { display: flex; align-items: center; gap: 10px; margin: 0 0 8px;
           flex-wrap: wrap; }
.obs-sep .l { font-size: .78rem; color: var(--muted); }
.obs-check { font-size: .74rem; color: var(--muted); display: inline-flex;
             align-items: center; gap: 4px; cursor: pointer; }
.obs-warn { font-size: .74rem; color: #f0d9a0; }
/* a separator this term's own data already contains — the export refuses it */
.obseg.bad { color: #f0d9a0; }
.obseg.bad.cur { background: #8a6114; color: #fff; }
.obs-how { font-size: .76rem; margin: -2px 0 10px; }
.obs-how b { color: var(--text); font-weight: 700; }
.obs-take { display: flex; align-items: center; gap: 8px; margin: 0 0 8px;
            flex-wrap: wrap; }
.obs-take .l { font-size: .74rem; color: var(--muted); }
.obs-take .dept { font-weight: 800; font-size: .78rem; color: var(--text);
                  min-width: 46px; cursor: help; }
.obs-take button { font-size: .76rem; padding: 5px 10px; }
.obs-take button.cur { border-color: var(--accent); color: var(--accent); }
.obs-take button.out { color: var(--muted); }
.obs-take button.external { color: var(--muted); font-style: italic; }
.obs-tile.out b { color: #bccadd; }
.obs-box { margin: 0 0 12px; }
#obs-area { width: 100%; height: 150px; resize: vertical; font-size: .74rem;
            font-family: var(--mono); line-height: 1.45;
            white-space: pre; overflow: auto; background: var(--panel-2);
            color: var(--text); border: 1px solid var(--line);
            border-radius: 3px; padding: 8px 10px; }
.obs-boxbar { display: flex; align-items: center; gap: 8px; margin-top: 8px;
              flex-wrap: wrap; }
.obs-boxbar .l { font-size: .74rem; color: var(--muted); }

.conf { color: #f0a99e; font-size: .82rem; margin: 4px 0; }
.okline { color: #8fe0b0; font-size: .86rem; margin: 8px 0; }

/* board page keeps its fixed layout but gains the wizard nav on top.
   The page is a flex column (board.css): main takes exactly what the
   nav + header band leave, whatever height the band wraps to. */
body.boardpage main { flex: 1 1 auto; height: auto; min-height: 0; }
body.boardpage #auto-btn { font-size: .85rem; }


/* ---- 👁 an administrator looking at somebody else's board ----------------
   Loud on purpose. The pages look identical to your own, so the ONE thing the
   screen must never leave in doubt is whose timetable is on it. */
#viewbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
  padding: 8px 16px;
  background: repeating-linear-gradient(135deg,
      rgba(217, 169, 63, .28) 0 14px, rgba(217, 169, 63, .16) 14px 28px);
  border-bottom: 2px solid rgba(217, 169, 63, .75);
  font-size: .85rem;
}
#viewbar b { color: var(--gold); }
#viewbar button {
  border: 1px solid rgba(232, 234, 238, .35); border-radius: 3px;
  background: rgba(0, 0, 0, .3); color: inherit;
  padding: 4px 14px; font-size: .8rem; font-weight: 600; cursor: pointer;
}
#viewbar button:hover { background: rgba(0, 0, 0, .5); }

/* ---- link-buttons ---------------------------------------------------------
   "Next: Classrooms ➡" and the workbook downloads were bare <a> tags wearing
   an inline style. They read as links in a page full of buttons, which is
   exactly the wrong affordance for the thing you press to move on. These make
   an <a> look and behave like the button it already was. */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 16px; border-radius: 3px;
  font-size: .85rem; font-weight: 600; line-height: 1;
  text-decoration: none; cursor: pointer; white-space: nowrap;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  transition: background .13s, border-color .13s, transform .13s;
  /* .btn is worn by <button> too since v0.61 (a download that can be refused
     is fetched, not linked to), and a <button> does NOT inherit the page's
     font on its own — without this the two sat side by side in two fonts. */
  font-family: inherit;
}
.btn:hover { background: var(--line); border-color: var(--accent); transform: translateY(-1px); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* the one that moves you on: filled, so it reads as the primary action */
.btn.next { background: var(--accent); border-color: var(--accent); color: #0f1013; }
.btn.next:hover { filter: brightness(1.1); background: var(--accent); }
/* A LINK IS A CONTROL, NEVER A WORD IN A SENTENCE. Nothing in this app is a
   bare underlined phrase you have to hover to discover: anything that can be
   pressed wears a border and a surface, so it is found by looking. `.inline`
   is the small one — it sits INSIDE a line of prose (a hint, a notice) at the
   text's own baseline without breaking the rhythm of the line. */
.btn.inline {
  padding: 1px 8px; gap: 5px;
  font-size: .82em; line-height: 1.5;
  vertical-align: baseline;
}
/* downloads: a row of equal siblings, not a sentence of links */
.btnrow.downloads { gap: 8px; flex-wrap: wrap; }
.btn.dl { font-weight: 600; }
.btn.dl b { font-weight: 700; }
.btn.dl .sub { opacity: .6; font-weight: 400; font-size: .76rem; }

/* ---- explanations ---------------------------------------------------------
   The hints were paragraphs of three or four sentences. Nobody reads those on
   a page they open every day; they are scanned, once, and then skipped forever.
   Short lines with a lead-in read faster and survive being skimmed. */
.hint ul { margin: 5px 0 0; padding-left: 1.1rem; }
.hint li { margin: 2px 0; }
.hint b { color: var(--text); }

/* Save sits at the TOP of the Database page: the table is 271 rows long, and
   a button under it is a scroll away from every edit that needs it. */
.btnrow.topsave {
  position: sticky; top: 0; z-index: 5;
  margin: 0 0 10px; padding: 8px 0;
  background: var(--bg); border-bottom: 1px solid var(--line);
}

/* ------------------------------------------------ 📰 patch notes (/changelog)
   Every version is a post, newest first; the running version is marked and
   the badge in the nav lands on it. Kept narrow like reading, not a table. */
.cl-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 18px; max-width: 950px; }
.cl-chip { font-size: .74rem; font-weight: 700; padding: 3px 10px; border-radius: 3px;
           border: 1px solid var(--line); background: var(--panel); color: var(--muted);
           text-decoration: none; font-family: var(--mono); }
.cl-chip:hover { border-color: var(--accent); color: var(--text); }
.cl-chip.cur { border-color: var(--accent); color: var(--accent); background: var(--well); }
.cl-chip.next { border-style: dashed; }
.cl-list { display: flex; flex-direction: column; gap: 16px; max-width: 950px; }
.cl-post { position: relative; border: 1px solid var(--line); border-radius: 4px;
           background: var(--panel); padding: 16px 20px 14px; scroll-margin-top: 70px;
           transition: box-shadow .3s ease, border-color .3s ease; }
.cl-post.cur { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.cl-post.next { border-style: dashed; }
.cl-post.landed { box-shadow: 0 0 0 3px var(--accent),
                              0 0 28px color-mix(in srgb, var(--accent) 45%, transparent); }
.cl-post header { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; }
.cl-post header h2 { flex-basis: 100%; font-size: 1.15rem; margin: 4px 0 2px; }
.cl-ver { font-weight: 800; font-size: .95rem; letter-spacing: .02em;
          padding: 2px 10px; border-radius: 3px; background: var(--well);
          border: 1px solid var(--line); font-family: var(--mono); }
.cl-post.cur .cl-ver { color: var(--accent); border-color: var(--accent); }
.cl-date { color: var(--muted); font-size: .8rem; font-family: var(--mono); }
.cl-cur { color: var(--accent); font-size: .78rem; font-weight: 700; }
.cl-summary { flex-basis: 100%; color: var(--text); font-size: .9rem; line-height: 1.5;
              margin: 0 0 6px; opacity: .92; }
.cl-post h3 { font-size: .82rem; color: var(--muted); font-weight: 700;
              text-transform: uppercase; letter-spacing: .04em; margin: 10px 0 6px; }
.cl-notes { margin: 0 0 4px 18px; padding: 0; line-height: 1.55; font-size: .88rem; }
.cl-notes li { margin: 3px 0; }
.cl-notes li::marker { color: var(--accent); }
.cl-internal { margin-top: 8px; font-size: .8rem; color: var(--muted); }
.cl-internal summary { cursor: pointer; font-weight: 700; }
.cl-internal ul { margin: 6px 0 0 18px; line-height: 1.5; }
/* "↑ top" is a control like any other (see .btn.inline in this file): the
   card only places it, the button style dresses it. */
.cl-top { position: absolute; right: 14px; bottom: 10px; }

/* ============================================================ v0.61 empty
   states. The .skel* classes and the disabled/viewer styles live in
   board.css, which every page loads first; these are the wizard-page
   dressings built on top of them. */

/* One empty card: an icon, ONE sentence, and the link that fixes it. Drawn
   by a page when its own thing is missing, in the place that thing would
   have been — so the next step is on screen instead of a blank table. */
.emptycard {
  margin: 26px auto; max-width: 560px; text-align: center;
  padding: 26px 22px; border: 1px dashed var(--line); border-radius: 4px;
  background: var(--well); color: var(--muted); font-size: .88rem;
  line-height: 1.6;
}
.emptycard .ec-icon { display: block; font-size: 1.9rem; margin-bottom: 8px; }
.emptycard b { color: var(--text); font-weight: 600; }
.emptycard .btn, .emptycard .btn.next { margin-top: 12px; }

/* The road in, when there are no courses at all: five numbered steps, each a
   link, gone the moment the database has something in it. */
#firststeps {
  margin: 14px 0 20px; padding: 14px 16px;
  border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: 4px; background: var(--well);
}
#firststeps h2 { font-size: .95rem; margin: 0 0 4px; color: var(--text); }
#firststeps p.tiny { color: var(--muted); margin: 0 0 10px; }
#firststeps ol {
  list-style: none; display: flex; flex-wrap: wrap; gap: 8px;
  margin: 0; padding: 0; counter-reset: step;
}
#firststeps li { counter-increment: step; }
#firststeps li a, #firststeps li span {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px; border-radius: 3px;
  border: 1px solid var(--line); background: var(--panel-2);
  color: var(--muted); text-decoration: none; font-size: .8rem;
}
#firststeps li a:hover { border-color: var(--accent); color: var(--text); }
#firststeps li a::before, #firststeps li span::before {
  content: counter(step);
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--accent); color: #0f1013;
  font-size: .68rem; font-weight: 700;
}
#firststeps li span { opacity: .6; }

/* 📄 The blank templates card: three downloads, one line each. */
.tplrow { display: flex; flex-wrap: wrap; gap: 10px; margin: 8px 0 0; }
.tplrow .btn.dl { flex-direction: column; align-items: flex-start; gap: 2px; }
.tplrow .btn.dl .sub {
  opacity: .62; font-weight: 400; font-size: .74rem; max-width: 22rem;
  white-space: normal; text-align: left;
}

/* 🌐 the English-names zone (v0.67) is drawn exactly like #extzone */
#namezone { border: 2px dashed var(--line); border-radius: 4px; padding: 14px 16px;
            margin: 8px 0 6px; background: var(--panel); }
#namezone.over { border-color: var(--accent); background: var(--panel-2); }
#namezone .ghost { margin-left: 8px; }

/* 🌐 the publish card (v0.65): the address, the snippet, one primary button
   whose label says what pressing it does now, and a status line in one of
   three inks — muted (not published), --ok (published and current), --warn
   (the board moved since). The stop button is the only red thing here. */
.exportcard.publish { max-width: 760px; border-color: var(--accent); }
.pub-status p { margin: 8px 0 10px; font-size: .82rem; line-height: 1.5; }
.pub-status .pub-off { color: var(--muted); }
.pub-status .pub-on { color: var(--ok); }
.pub-status .pub-stale { color: var(--warn); }
.pub-l { display: block; font-size: .72rem; color: var(--muted); margin: 8px 0 3px;
         font-weight: 600; letter-spacing: .02em; }
.pub-row { display: flex; gap: 6px; align-items: stretch; }
.pub-in { flex: 1; min-width: 0; font-family: var(--mono); font-size: .74rem;
          color: var(--text); background: var(--bg); border: 1px solid var(--line);
          border-radius: 3px; padding: 6px 8px; resize: none; }
.pub-in:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.pub-row .ghost, .pub-row .btnlike { flex: none; align-self: flex-start; }
.btnlike { display: inline-block; text-decoration: none; }
.pub-embed .tiny { margin-top: 8px; }
.pub-embed code { font-family: var(--mono); font-size: .72rem; background: var(--bg);
                  border: 1px solid var(--line); border-radius: 2px; padding: 0 4px; }
.pub-actions { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
button.ghost.danger { color: var(--bad); border-color: rgba(224, 96, 80, .5); }
button.ghost.danger:hover:not(:disabled) { background: rgba(224, 96, 80, .12); }

/* 🔔 the change log's editor (v0.79) — folded inside the publish card, because
   it is the second thing anybody comes to this page for. The entries are drawn
   by the page's own script; everything here is the frame around somebody's
   sentences: two languages side by side on a wide screen, one under the other
   on a narrow one, and the 🗑 that is the whole curation tool at the end of
   every row it can delete. */
.publog { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 10px; }
.publog > summary { cursor: pointer; font-size: .86rem; font-weight: 600;
                    color: var(--muted); padding: 4px 0; }
.publog > summary .tag { display: inline-block; margin-left: 6px; padding: 1px 6px;
                         border-radius: 10px; background: var(--panel-2);
                         border: 1px solid var(--line); color: var(--muted);
                         font-family: var(--mono); font-size: .68rem; }
.publog > .hint { margin: 6px 0 12px; }
.publog-add, .pl-fields { display: grid; grid-template-columns: 1fr 1fr;
                          gap: 2px 12px; }
.publog-add .pub-l, .pl-fields .pub-l { margin-top: 0; }
/* ⚠️ `.wizard-main input` is 72px wide — the wizard's little number boxes —
   and it outranks .pub-in, which gets its width from `flex: 1` and so only
   fills anything inside a .pub-row. There is no flex in these grids, so every
   field has to be told to fill its cell or it sits at 72px with the sentence
   scrolled out of sight (measured in Chrome: 72px in a 213px column). */
.publog-add .pub-in, .pl-fields .pub-in, .pl-lines .pub-in { width: 100%; }
.pl-addrow { grid-column: 1 / -1; display: flex; align-items: center; gap: 10px;
             flex-wrap: wrap; margin-top: 10px; }
.pl-addrow .tiny { flex: 1 1 260px; margin: 0; }
.publog-list { margin-top: 14px; }
.pl-none { color: var(--muted); font-size: .78rem; margin: 6px 0; }
.pl-entry { border: 1px solid var(--line); border-radius: 4px; background: var(--panel-2);
            padding: 10px 12px; margin: 10px 0; }
.pl-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
           margin-bottom: 8px; }
.pl-kind { font-size: .8rem; font-weight: 600; }
.pl-when { font-family: var(--mono); font-size: .72rem; color: var(--muted); }
.pl-by { font-size: .72rem; color: var(--muted); }
/* the entry's own 🗑 sits at the far end of its header — as far from the line
   deletions as the row is wide, because the two are not the same press */
.pl-head .pl-del { margin-left: auto; font-size: .72rem; padding: 2px 8px; }
.pl-lines { list-style: none; margin: 10px 0 0; padding: 0; }
.pl-lines li { display: grid; align-items: center; gap: 6px;
               grid-template-columns: 18px minmax(76px, auto) minmax(60px, 120px) 1fr 1fr auto;
               padding: 3px 0; border-top: 1px solid var(--line); }
.pl-lines li .ico { text-align: center; font-size: .8rem; }
.pl-code { font-family: var(--mono); font-size: .72rem; color: var(--text); }
/* the cohorts are a chip of context, never the row's height: three years of a
   shared course wrapped a 32px row to 63px, and the whole list is in the
   title the script sets */
.pl-lines .who { font-size: .66rem; color: var(--muted); white-space: nowrap;
                 overflow: hidden; text-overflow: ellipsis; }
.pl-lines .pl-del { border: 0; background: none; color: var(--muted); cursor: pointer;
                    font-size: .8rem; padding: 0 4px; }
.pl-lines .pl-del:hover:not(:disabled) { color: #f0a99e; background: none; }
.pl-more { color: var(--muted); font-size: .72rem; margin: 8px 0 0; }
.pl-save { display: flex; justify-content: flex-end; margin-top: 10px; }
.pl-savebtn { font-size: .76rem; padding: 4px 12px; }
@media (max-width: 700px) {
  .publog-add, .pl-fields { grid-template-columns: 1fr; }
  /* the two sentences drop under the row they belong to rather than shrinking
     into two unreadable slivers — the text IS the thing being edited */
  .pl-lines li { grid-template-columns: 18px 1fr auto; }
  .pl-lines li .pub-in { grid-column: 1 / -1; }
}
