/* Yagit design system -- hand-written, no framework dependency.
   Sidebar-console shell (.app-shell/.app-sidebar/.app-main) for
   authenticated pages, a centered .guest-shell for /login. Forms,
   typography, and plain content still style bare elements directly
   (classless-authoring convention); named hook classes cover structural
   and composite UI: .status, .notice, .impersonation-banner. */

:root {
  --sidebar-bg: #14161f;
  --sidebar-text: #c9cbd8;
  --sidebar-text-active: #ffffff;
  --sidebar-item-hover-bg: #1e2130;
  --sidebar-item-active-bg: #23263a;

  --bg: #f5f6fa;
  --surface: #ffffff;
  --border: #e7e8ee;
  --text: #181a24;
  --text-muted: #6b6f80;
  --text-subtle: #9497a6;

  --accent: #5b5bf5;
  --accent-hover: #4747d1;
  --accent-ink: #ffffff;
  --accent-soft: #edecff;

  --success: #12876b;
  --success-hover: #0d6c55;
  --success-soft: #e3f7f0;
  --danger: #c8412d;
  --danger-hover: #a83322;
  --danger-soft: #fdecec;
  --warn: #a15a00;
  --warn-soft: #fdefdb;

  --role-admin: #7c3aed;
  --role-admin-soft: #f1e9fe;
  --role-teacher: #2563eb;
  --role-teacher-soft: #e9f0fe;
  --role-student: #475569;
  --role-student-soft: #eef1f5;

  --diagram-commit-red: #d6453f;
  --diagram-commit-orange: #dd7a1a;
  --diagram-commit-yellow: #b89412;
  --diagram-commit-green: #2f9e52;
  --diagram-commit-blue: #1f7fbf;
  --diagram-commit-violet: #a83fc0;
  --diagram-commit-magenta: #e60c92;
  --diagram-commit-red-soft: #fcf0f0;
  --diagram-commit-orange-soft: #fcf4ed;
  --diagram-commit-yellow-soft: #f9f6ec;
  --diagram-commit-green-soft: #eef7f1;
  --diagram-commit-blue-soft: #edf5fa;
  --diagram-commit-violet-soft: #f8f0fa;
  --diagram-commit-magenta-soft: #fdecf6;

  /* Shared timing for every animated-diagram transition (frame-to-frame
     morphs, duplicate-and-fly) -- plain ease-in-out per spec, "no
     overshoot, no bounce, no spring/damping". -fast is for the
     duplicate-and-fly guide line, which "draws quickly" rather than
     morphing over a full frame transition. */
  --diagram-transition: 0.55s ease-in-out;
  --diagram-transition-fast: 0.2s ease-in-out;

  --radius-lg: 14px;
  --radius-md: 10px;
  --radius-sm: 7px;
  --shadow: 0 1px 2px rgba(20, 22, 35, .04), 0 8px 24px -12px rgba(20, 22, 35, .10);

  --font-size-base: 14px;
  --space-sm: 0.5rem;
  --space-md: 0.85rem;
  --space-lg: 1.5rem;
}

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

body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Noto Sans, Helvetica, Arial, sans-serif;
  font-size: var(--font-size-base);
  line-height: 1.55;
}

code,
pre {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

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

.app-sidebar {
  flex-shrink: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-md);
  background: var(--sidebar-bg);
  color: var(--sidebar-text);
  padding: var(--space-sm) var(--space-md);
  overflow-x: auto;
}

.sidebar-brand {
  flex-shrink: 0;
  padding: 0;
  color: var(--sidebar-text-active);
  font-weight: 700;
}

.side-nav {
  flex: 1;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.25rem;
  overflow-x: auto;
}

.nav-item {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  gap: 0.4rem;
  padding: 0.4rem 0.6rem;
  border-radius: var(--radius-sm);
  color: var(--sidebar-text);
  white-space: nowrap;
}

.nav-item:hover {
  background: var(--sidebar-item-hover-bg);
  color: var(--sidebar-text-active);
}

.nav-item.active {
  background: var(--sidebar-item-active-bg);
  color: var(--sidebar-text-active);
}

.nav-item-icon {
  display: flex;
}

.nav-item-label {
  display: none;
}

.sidebar-footer {
  display: flex;
  flex-direction: row;
  flex-shrink: 0;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0;
  padding: 0;
  border-top: none;
}

.sidebar-footer-name,
.sidebar-footer-role {
  display: none;
}

.sidebar-footer a {
  color: var(--sidebar-text);
}

.sidebar-footer a:hover {
  color: var(--sidebar-text-active);
}

.app-main {
  flex: 1;
  min-width: 0;
  padding: var(--space-lg);
}

.page-topbar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-lg);
  margin-bottom: var(--space-lg);
}

.page-topbar h1 {
  margin: 0;
}

.guest-shell {
  max-width: 26rem;
  margin: 3rem auto;
  padding: 0 var(--space-lg);
}

.guest-brand {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-lg);
  font-weight: 700;
}

h1,
h2,
h3 {
  line-height: 1.25;
  margin-top: 0;
}

h1 {
  font-size: 1.6rem;
}

h2 {
  font-size: 1.3rem;
}

h3 {
  font-size: 1.1rem;
}

a {
  color: var(--accent);
}

a:hover {
  color: var(--accent-hover);
}

label {
  display: block;
  font-weight: 600;
  margin-top: var(--space-md);
  margin-bottom: 0.25rem;
}

input,
select,
textarea {
  display: block;
  width: 100%;
  padding: 0.45rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text);
  font: inherit;
}

input[type="checkbox"],
input[type="radio"] {
  display: inline-block;
  width: auto;
  padding: 0;
  border: none;
  background: none;
  vertical-align: middle;
  margin-right: 0.4rem;
}

input:focus,
select:focus,
textarea:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px transparent;
}

button,
input[type="submit"],
input[type="button"] {
  display: inline-block;
  width: 100%;
  margin-top: var(--space-md);
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

button:hover,
input[type="submit"]:hover,
input[type="button"]:hover {
  background: var(--border);
  border-color: var(--border);
}

.btn-primary,
button.btn-primary,
input.btn-primary[type="submit"],
input.btn-primary[type="button"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  margin-top: 0;
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--accent);
  border-radius: var(--radius-md);
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
}

.btn-primary:hover,
button.btn-primary:hover,
input.btn-primary[type="submit"]:hover,
input.btn-primary[type="button"]:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}

.btn-success,
button.btn-success,
input.btn-success[type="submit"],
input.btn-success[type="button"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  margin-top: 0;
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--success);
  border-radius: var(--radius-md);
  background: var(--success);
  color: var(--accent-ink);
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
}

.btn-success:hover,
button.btn-success:hover,
input.btn-success[type="submit"]:hover,
input.btn-success[type="button"]:hover {
  background: var(--success-hover);
  border-color: var(--success-hover);
}

.btn-danger,
button.btn-danger,
input.btn-danger[type="submit"],
input.btn-danger[type="button"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  margin-top: 0;
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--danger);
  border-radius: var(--radius-md);
  background: var(--danger);
  color: var(--accent-ink);
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
}

.btn-danger:hover,
button.btn-danger:hover,
input.btn-danger[type="submit"]:hover,
input.btn-danger[type="button"]:hover {
  background: var(--danger-hover);
  border-color: var(--danger-hover);
}

.btn-secondary,
button.btn-secondary,
input.btn-secondary[type="submit"],
input.btn-secondary[type="button"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  margin-top: 0;
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text);
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
}

.btn-secondary:hover,
button.btn-secondary:hover,
input.btn-secondary[type="submit"]:hover,
input.btn-secondary[type="button"]:hover {
  background: var(--bg);
  border-color: var(--text-subtle);
}

.btn-google {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  width: 100%;
  margin-top: var(--space-md);
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text);
  font-weight: 600;
}

.btn-google:hover {
  background: var(--bg);
}

.btn-copy,
button.btn-copy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  min-width: 11rem;
  margin-top: 0;
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text);
  font-weight: 600;
  cursor: pointer;
}

.btn-copy:hover,
button.btn-copy:hover {
  background: var(--bg);
}

.btn-copy.btn-success,
button.btn-copy.btn-success {
  background: #86efac;
  border-color: #86efac;
  color: #000000;
}

.btn-copy.btn-success:hover,
button.btn-copy.btn-success:hover {
  background: #4ade80;
  border-color: #4ade80;
  color: #000000;
}

table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  margin-top: var(--space-md);
  background: var(--surface);
}

th,
td {
  padding: 0.55rem 0.65rem;
  border-bottom: 1px solid var(--border);
  text-align: left;
}

th {
  color: var(--text-muted);
  font-weight: 600;
  font-size: 0.9em;
}

tr:hover td {
  background: var(--bg);
}

.row--late td {
  background: var(--danger-soft);
}

.notice {
  padding: 0.6rem 1rem;
  margin-bottom: 1rem;
  border-radius: var(--radius-md);
}

.notice--warn {
  background: var(--warn-soft);
  color: var(--warn);
}

.notice--ok {
  background: var(--success-soft);
  color: var(--success);
}

.stat-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-bottom: var(--space-lg);
}

.stat-card {
  flex: 1 1 140px;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: var(--space-md);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}

.stat-card-value {
  font-size: 1.6rem;
  font-weight: 700;
  color: var(--text);
}

.stat-card-label {
  color: var(--text-muted);
  font-size: 0.85em;
}

.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: var(--space-lg);
  margin-bottom: var(--space-lg);
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.panel-header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.panel-header-actions label {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.panel-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-bottom: var(--space-md);
}

.panel-toolbar input,
.panel-toolbar select {
  width: auto;
  flex: 1 1 200px;
  margin-top: 0;
}

.panel-toolbar--split {
  justify-content: space-between;
}

#roster-import-button {
  margin-top: var(--space-sm);
}

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border-radius: 999px;
  font-size: 0.78em;
  font-weight: 700;
  color: var(--sidebar-text-active);
}

.avatar--admin {
  background: var(--role-admin);
}

.avatar--teacher {
  background: var(--role-teacher);
}

.avatar--student {
  background: var(--role-student);
}

.badge {
  display: inline-block;
  padding: 0.12rem 0.55rem;
  border-radius: 999px;
  font-size: 0.78em;
  font-weight: 600;
  text-transform: capitalize;
  text-decoration: none;
}

.badge-admin {
  background: var(--role-admin-soft);
  color: var(--role-admin);
}

.badge-teacher {
  background: var(--role-teacher-soft);
  color: var(--role-teacher);
}

.badge-student {
  background: var(--role-student-soft);
  color: var(--role-student);
}

.badge-individual {
  background: var(--role-teacher-soft);
  color: var(--role-teacher);
}

.badge-group {
  background: var(--role-admin-soft);
  color: var(--role-admin);
}

.badge-owner {
  background: var(--role-admin-soft);
  color: var(--role-admin);
}

.badge-template-status--uploaded {
  background: var(--success-soft);
  color: var(--success);
}

.badge-template-status--not_uploaded {
  background: var(--warn-soft);
  color: var(--warn);
}

.uname {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.9em;
  color: var(--text-muted);
}

.tutorial-dashboard-parts {
  font-size: 0.85em;
  color: var(--text-muted);
  letter-spacing: 0.03em;
}

.member-email {
  font-size: 0.85em;
  color: var(--text-muted);
}

.status {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.9em;
  font-weight: 600;
}

.status::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: currentColor;
}

.status--on,
.status--ontime {
  color: var(--success);
}

.status--off,
.status--not-accepted {
  color: var(--text-subtle);
}

.status--late {
  color: var(--danger);
}

.status--missing {
  color: var(--warn);
}

.status--submitted {
  color: var(--success);
}

button.status {
  width: auto;
  margin-top: 0;
  padding: 0.15rem 0.6rem;
  border: 1px solid currentColor;
  border-radius: 999px;
  background: none;
}

button.status--on:hover {
  background: var(--success-soft);
}

button.status--off:hover {
  background: var(--border);
}

.link-action {
  display: inline-block;
  width: auto;
  margin-top: 0;
  padding: 0.12rem 0.65rem;
  border: none;
  border-radius: 999px;
  background: var(--accent-soft);
  font-size: 0.85em;
  font-weight: 600;
  color: var(--accent);
  cursor: pointer;
}

.link-action:hover {
  color: var(--accent-hover);
}

.link-action-form {
  display: inline;
  margin: 0;
}

.link-action--attention {
  background: var(--warn-soft);
  color: var(--warn);
}

.link-action--attention:hover {
  color: var(--warn);
}

.link-action--danger {
  background: var(--danger-soft);
  color: var(--danger);
}

.link-action--danger:hover {
  color: var(--danger);
}

dialog {
  width: 26rem;
  max-width: calc(100vw - 2rem);
  padding: var(--space-lg);
  border: none;
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow);
}

dialog::backdrop {
  background: rgba(20, 22, 35, .5);
}

dialog p {
  margin-top: 0;
  margin-bottom: var(--space-lg);
}

.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-sm);
}

.dialog-actions form {
  margin: 0;
}

.dialog-actions button {
  width: auto;
  margin-top: 0;
}

.commit-list {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.9em;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.commit-list li {
  display: flex;
  gap: 0.75rem;
  padding: 0.4rem 0.65rem;
}

.commit-list li:not(:last-child) {
  border-bottom: 1px solid var(--border);
}

.commit-list--lapsed {
  background: var(--danger-soft);
  border-color: var(--danger);
}

.commit-table {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.commit-table--lapsed {
  background: var(--danger-soft);
  border-color: var(--danger);
}

.commit-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-md);
  margin-top: var(--space-md);
}

.commit-pager-label {
  color: var(--text-muted);
  font-size: 0.9em;
}

.commit-toggle {
  display: inline-block;
  width: auto;
  margin-top: 0;
  padding: 0.12rem 0.65rem;
  border: none;
  border-radius: 999px;
  background: var(--accent-soft);
  font-size: 0.85em;
  font-weight: 600;
  color: var(--accent);
  cursor: pointer;
}

.commit-toggle:hover {
  color: var(--accent-hover);
}

.file-browser {
  display: grid;
  grid-template-columns: minmax(180px, 260px) 1fr;
  gap: var(--space-lg);
  align-items: start;
  margin-top: var(--space-lg);
}

.file-browser-branch-select {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.file-browser-branch-select label {
  margin: 0;
}

.file-browser-branch-select select {
  width: auto;
  margin-top: 0;
}

.browser-content-file-path {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.9em;
  color: var(--text-muted);
  margin-bottom: var(--space-sm);
}

.file-tree {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow-y: auto;
  max-height: 420px;
}

.file-tree-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: 0.4rem 0.65rem;
  color: var(--text);
  cursor: pointer;
}

.file-tree-row:not(:last-child) {
  border-bottom: 1px solid var(--border);
}

.file-tree-row:hover {
  background: var(--accent-soft);
  color: var(--accent);
}

.file-tree-row--parent {
  color: var(--text-muted);
  font-weight: 600;
}

.browser-content {
  min-height: 120px;
}

.file-content {
  margin: 0;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-sm);
  background: var(--bg);
  overflow-x: auto;
  font-size: 0.9em;
  white-space: pre;
}

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

.group-member-list {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  font-size: 0.9em;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.group-member-list li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.65rem;
}

.group-member-list li:not(:last-child) {
  border-bottom: 1px solid var(--border);
}

.assignment-summary {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.6rem 1.5rem;
}

.assignment-summary-label {
  align-self: baseline;
  color: var(--text-muted);
  font-size: 0.85em;
  font-weight: 600;
}

.assignment-summary-value {
  align-self: baseline;
  color: var(--text);
}

.assignment-summary:has(> .assignment-summary-divider) {
  row-gap: var(--space-md);
}

.assignment-summary-divider {
  grid-column: 1 / -1;
  border-top: 1px solid var(--border);
}

.assignment-summary-action-boundary {
  margin-top: var(--space-lg);
  padding-top: var(--space-md);
  border-top: 1px solid var(--border);
}

.teachers-table {
  width: auto;
}

.teacher-identity {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

@media (max-width: 599px) {
  .assignment-summary:has(> .assignment-summary-divider) {
    grid-template-columns: minmax(0, 1fr);
  }

  .assignment-summary:has(> .assignment-summary-divider) .assignment-summary-value {
    min-width: 0;
  }
}

.deadline {
  font-weight: 600;
}

.deadline--lapsed {
  color: var(--danger);
}

.deadline--none {
  color: var(--text-subtle);
  font-weight: 400;
}

.description-content {
  position: relative;
  white-space: pre-wrap;
}

.description-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.description-content--collapsed {
  max-height: 9rem;
  overflow: hidden;
}

.description-content--collapsed::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2.5rem;
  background: linear-gradient(to bottom, transparent, var(--surface));
  pointer-events: none;
}

.markdown-body {
  white-space: normal;
}

.markdown-body > *:first-child {
  margin-top: 0;
}

.markdown-body > *:last-child {
  margin-bottom: 0;
}

.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4 {
  margin-top: var(--space-md);
  margin-bottom: 0.35rem;
}

.markdown-body h1 {
  font-size: 1.25rem;
}

.markdown-body h2 {
  font-size: 1.1rem;
}

.markdown-body h3,
.markdown-body h4 {
  font-size: 1rem;
}

.markdown-body p {
  margin: 0 0 var(--space-sm);
}

.markdown-body ul,
.markdown-body ol {
  margin: 0 0 var(--space-sm);
  padding-left: 1.4rem;
}

.markdown-body li {
  margin-bottom: 0.2rem;
}

.markdown-body code {
  padding: 0.1rem 0.35rem;
  border-radius: var(--radius-sm);
  background: var(--bg);
  font-size: 0.9em;
}

.markdown-body pre {
  margin: 0 0 var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-sm);
  background: var(--bg);
  overflow-x: auto;
}

.markdown-body pre code {
  padding: 0;
  background: none;
}

.markdown-body blockquote {
  margin: 0 0 var(--space-sm);
  padding-left: var(--space-md);
  border-left: 3px solid var(--border);
  color: var(--text-muted);
}

.description-textarea {
  width: 100%;
  min-height: 10rem;
}

.description-textarea[hidden] {
  display: none;
}

.description-textarea--markdown {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

.description-preview-toggle[hidden] {
  display: inline-flex;
  visibility: hidden;
}

.description-panel-toolbar {
  margin-bottom: var(--space-md);
}

.description-panel-toolbar h2 {
  margin: 0 0 var(--space-sm);
}

.description-panel-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: flex-start;
  gap: var(--space-sm) var(--space-md);
}

.description-panel-controls > label {
  display: inline-flex;
  align-items: baseline;
}

.description-preview-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  width: auto;
  margin: 0;
  padding: 0.15rem 0.6rem;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-ink);
  cursor: pointer;
}

.description-preview-toggle:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}

.description-form {
  max-width: none;
}

.description-form .description-textarea {
  max-width: none;
}

.description-live-preview {
  min-height: 10rem;
  max-height: 22rem;
  overflow-y: auto;
}

.impersonation-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 1rem;
  margin-bottom: 1rem;
  background: var(--warn-soft);
  color: var(--warn);
  border-radius: var(--radius-md);
}

.impersonation-banner p {
  margin: 0;
}

.impersonation-banner form {
  margin: 0;
}

.impersonation-banner button {
  width: auto;
  margin-top: 0;
  background: var(--surface);
  color: var(--warn);
  border-color: var(--warn);
}

.dt-picker {
  position: relative;
  margin-top: var(--space-md);
}

.dt-picker-trigger {
  display: flex;
  align-items: center;
  width: 100%;
  margin-top: 0;
  padding: 0.45rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.dt-picker-trigger:hover {
  border-color: var(--accent);
}

.dt-picker-panel {
  position: absolute;
  z-index: 20;
  top: calc(100% + 0.35rem);
  left: 0;
  width: 17rem;
  padding: var(--space-md);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);
}

.dt-picker-calendar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.5rem;
  font-weight: 600;
}

.dt-picker-nav {
  width: auto;
  margin-top: 0;
  padding: 0.15rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  cursor: pointer;
}

.dt-picker-nav:hover {
  background: var(--bg);
}

.dt-picker-weekdays,
.dt-picker-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.15rem;
  text-align: center;
}

.dt-picker-weekdays {
  color: var(--text-muted);
  font-size: 0.78em;
  font-weight: 600;
  margin-bottom: 0.25rem;
}

.dt-picker-day {
  width: auto;
  margin-top: 0;
  padding: 0.3rem 0;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  font: inherit;
  font-size: 0.85em;
  cursor: pointer;
}

.dt-picker-day:hover {
  background: var(--bg);
}

.dt-picker-day--empty {
  cursor: default;
}

.dt-picker-day--empty:hover {
  background: transparent;
}

.dt-picker-day--selected {
  background: var(--accent);
  color: var(--accent-ink);
}

.dt-picker-day--disabled {
  color: var(--text-muted);
  cursor: not-allowed;
  opacity: 0.4;
}

.dt-picker-day--disabled:hover {
  background: transparent;
}

.dt-picker-time {
  margin-top: var(--space-sm);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--border);
}

.dt-picker-time-label {
  margin-top: 0;
  margin-bottom: 0.25rem;
  font-size: 0.85em;
}

.dt-picker-time-fields {
  display: flex;
  align-items: center;
  gap: 0.3rem;
}

.dt-picker-time-fields input {
  width: 3.4rem;
  margin-top: 0;
  padding: 0.3rem 0.4rem;
  text-align: center;
}

.dt-picker-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: var(--space-sm);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--border);
}

@media (min-width: 900px) {
  .app-shell {
    flex-direction: row;
  }

  .app-sidebar {
    width: 236px;
    flex-direction: column;
    align-items: stretch;
    padding: var(--space-md) 0;
    overflow-x: visible;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
  }

  .sidebar-brand {
    padding: 0 var(--space-md) var(--space-lg);
  }

  .side-nav {
    flex-direction: column;
    align-items: stretch;
    overflow-x: visible;
  }

  .nav-item-label {
    display: inline;
  }

  .sidebar-footer {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.2rem;
    margin-top: auto;
    padding: var(--space-md);
    border-top: 1px solid var(--sidebar-item-active-bg);
  }

  .sidebar-footer-name,
  .sidebar-footer-role {
    display: block;
  }

  .sidebar-footer-name {
    color: var(--sidebar-text-active);
    font-weight: 600;
  }

  .sidebar-footer-role {
    color: var(--sidebar-text);
    font-size: 0.85em;
    text-transform: capitalize;
  }

  .app-main {
    height: 100vh;
    overflow-y: auto;
  }
}

.assignment-code-field {
  display: flex;
  align-items: stretch;
  gap: 0;
}

.assignment-code-prefix {
  display: flex;
  align-items: center;
  padding: 0.45rem 0.65rem;
  border: 1px solid var(--border);
  border-right: none;
  border-radius: var(--radius-md) 0 0 var(--radius-md);
  background: var(--bg);
  color: var(--text-muted);
  white-space: nowrap;
}

.assignment-code-field input {
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
}

.code-check {
  font-size: 0.85em;
  font-weight: 600;
}

.code-check--available {
  color: var(--success);
}

.code-check--taken {
  color: var(--danger);
}

.code-check-status {
  display: block;
  min-height: 1.3rem;
  line-height: 1.3rem;
  margin-top: 0.35rem;
}

.tutorial-part {
  margin: 1.25rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}

.tutorial-part:first-child {
  margin-top: 0.75rem;
  padding-top: 0;
  border-top: none;
}

.tutorial-part-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-sm);
}

.tutorial-part-title {
  margin-bottom: 0.2rem;
}

.tutorial-part-description {
  margin: 0;
  font-size: 0.85em;
  color: var(--text-muted);
}

.tutorial-congrats {
  margin: 1rem 0 0;
  padding-top: 0.85rem;
  border-top: 1px solid var(--border);
  font-weight: 600;
  color: var(--success);
}

.tutorial-steps {
  list-style: none;
  margin: 0.75rem 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.tutorial-step {
  display: flex;
  flex-direction: column;
  padding: 0.6rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.tutorial-step-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-sm);
}

.tutorial-step-title {
  font-weight: 600;
}

.tutorial-step-summary {
  font-size: 0.85em;
  color: var(--text-muted);
}

.tutorial-step-autotrack {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.8em;
  font-style: italic;
  color: var(--text-subtle);
}

.tutorial-step--locked {
  opacity: 0.5;
}

.tutorial-step--current {
  border-color: var(--role-teacher);
}

.tutorial-step--complete .tutorial-step-title::before {
  content: "✅ ";
}

.tutorial-step-action {
  margin: 0.85rem 0 0;
}

.btn-toggle-details {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  width: auto;
  margin: 1.5rem 0 0;
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--success);
  border-radius: var(--radius-md);
  background: var(--success-soft);
  color: var(--success);
  font-weight: 600;
  font-size: 0.9em;
  cursor: pointer;
}

.btn-toggle-details:hover {
  background: var(--success);
  color: var(--accent-ink);
}

.tutorial-step-commands {
  margin: 0.5rem 0 0;
  padding-left: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.tutorial-substeps {
  margin: 1rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.tutorial-substep-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  border-bottom: 1px solid var(--border);
}

.tutorial-substep-tab {
  padding: 0.35rem 0.75rem;
  border: none;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--text-muted);
  font-size: 0.85em;
  font-weight: 600;
  cursor: pointer;
}

.tutorial-substep-tab:hover {
  color: var(--text);
}

.tutorial-substep-tab--active {
  border-bottom-color: var(--accent);
  color: var(--accent);
}

.tutorial-substep .tutorial-step-commands {
  margin-top: 0.35rem;
}

.tutorial-step-commands li > code {
  color: var(--accent);
}

.tutorial-step-commands li > p {
  margin: 0.35rem 0 0;
}

.tutorial-step-summary code,
.tutorial-step-commands li > p code {
  padding: 0.1rem 0.35rem;
  border-radius: var(--radius-sm);
  background: var(--bg);
  font-size: 0.9em;
}

.tutorial-glossary {
  margin: 1rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.tutorial-glossary dt {
  font-weight: 600;
}

.tutorial-glossary dd {
  margin: 0.2rem 0 0;
}

.tutorial-diagram-frame-item {
  list-style: none;
  counter-increment: list-item 0;
}

.tutorial-diagram-frame {
  margin: 0.5rem 0 0;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.tutorial-diagram-note {
  margin: 0 0 0.5rem;
  font-size: 0.85em;
  font-style: italic;
  color: var(--text-subtle);
}

.tutorial-diagram-svg {
  display: block;
  width: 100%;
  height: auto;
}

.tutorial-diagram-half-label {
  font-size: 9px;
  font-weight: 600;
  fill: var(--text-subtle);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tutorial-diagram-half-box {
  fill: none;
  stroke: var(--border);
  stroke-width: 1;
}

.tutorial-diagram-node {
  stroke-width: 1.5;
  /* cx/cy are standard CSS-animatable SVG geometry properties (SVG2, all
     evergreen browsers) -- transitioning them directly on the plain
     attribute values the template already emits, rather than requiring
     the animation JS to compute an offsetting transform instead. */
  transition: cx var(--diagram-transition), cy var(--diagram-transition),
    fill var(--diagram-transition), stroke var(--diagram-transition),
    opacity var(--diagram-transition);
}

.tutorial-diagram-edge {
  stroke: var(--text-subtle);
  stroke-width: 1.5;
  transition: x1 var(--diagram-transition), y1 var(--diagram-transition),
    x2 var(--diagram-transition), y2 var(--diagram-transition),
    opacity var(--diagram-transition);
}

.tutorial-diagram-arrowhead {
  fill: var(--text-subtle);
}

.tutorial-diagram-branch-tip-badge {
  fill: var(--surface);
  stroke: var(--success);
  stroke-width: 1;
  transition: x var(--diagram-transition), y var(--diagram-transition),
    opacity var(--diagram-transition);
}

.tutorial-diagram-branch-tip {
  font-size: 9px;
  font-weight: 600;
  fill: var(--success);
  dominant-baseline: central;
  transition: x var(--diagram-transition), y var(--diagram-transition),
    opacity var(--diagram-transition);
}

/* HEAD is deliberately neutral: green remains reserved for named branches.
   Step 14 keeps this marker in all three frames so it moves between the
   branch tip and detached commit through the standard keyed SVG morph. */
.tutorial-diagram-head-badge {
  fill: var(--surface);
  stroke: var(--text-subtle);
  stroke-width: 1;
  transition: x var(--diagram-transition), y var(--diagram-transition),
    opacity var(--diagram-transition);
}

.tutorial-diagram-head {
  font-size: 9px;
  font-weight: 600;
  fill: var(--text-subtle);
  dominant-baseline: central;
  transition: x var(--diagram-transition), y var(--diagram-transition),
    opacity var(--diagram-transition);
}

/* A branch created locally, or an untracked file created only on the local
   disk, has no Remote source to animate from. Its visible parts fade, grow,
   and settle together to make the local-only change perceptible. */
.tutorial-diagram-branch-tip-badge--created,
.tutorial-diagram-branch-tip--created,
.tutorial-diagram-branch-tip-badge--popped,
.tutorial-diagram-branch-tip--popped,
.tutorial-diagram-file-appearance--local-untracked {
  transform-box: fill-box;
  transform-origin: center;
  animation: tutorial-diagram-branch-created 0.52s ease-out;
}

@keyframes tutorial-diagram-branch-created {
  0% { opacity: 0; transform: scale(0.65); }
  35% { opacity: 1; transform: scale(1.2); }
  100% { opacity: 1; transform: scale(1); }
}

/* A branch is still visible before `git branch -d` takes effect. Shrink it,
   rebound once, then remove it so the deletion reads as a deliberate local
   change rather than an unexplained fade. */
.tutorial-diagram-branch-tip-badge--deleted,
.tutorial-diagram-branch-tip--deleted {
  transform-box: fill-box;
  transform-origin: center;
  animation: tutorial-diagram-branch-deleted 0.52s ease-in-out both;
}

@keyframes tutorial-diagram-branch-deleted {
  0%, 20% { opacity: 1; transform: scale(1); }
  55% { opacity: 1; transform: scale(0.65); }
  80% { opacity: 1; transform: scale(1.2); }
  100% { opacity: 0; transform: scale(1); }
}

.tutorial-diagram-tracking-ref {
  font-size: 9px;
  font-weight: 600;
  font-style: italic;
  fill: none;
  stroke: var(--text-subtle);
  stroke-width: 0.5;
  transition: x var(--diagram-transition), y var(--diagram-transition),
    opacity var(--diagram-transition);
}

.tutorial-diagram-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.4rem 0 0;
  /* The SVG's viewBox has a small visual tail below its panels. Lift the
     controls without reflowing the legend so both visible gaps match. */
  transform: translateY(-0.8rem);
}

.tutorial-diagram-playpause {
  flex: 0 0 3rem;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  min-width: 3rem;
  height: 3rem;
  min-height: 3rem;
  aspect-ratio: 1;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-muted);
  font-size: 1.1rem;
  line-height: 1;
}

.tutorial-diagram-playpause:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.tutorial-diagram-progress {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  height: 3rem;
  margin: 0;
  cursor: pointer;
  appearance: none;
  background: transparent;
}

.tutorial-diagram-progress::-webkit-slider-runnable-track {
  height: 0.25rem;
  border-radius: var(--radius-sm);
  background: var(--bg);
}

.tutorial-diagram-progress::-webkit-slider-thumb {
  width: 1rem;
  height: 1rem;
  margin-top: -0.375rem;
  border: 2px solid var(--surface);
  border-radius: 50%;
  appearance: none;
  background: var(--accent);
}

.tutorial-diagram-progress::-moz-range-track {
  height: 0.25rem;
  border-radius: var(--radius-sm);
  background: var(--bg);
}

.tutorial-diagram-progress::-moz-range-thumb {
  width: 0.75rem;
  height: 0.75rem;
  border: 2px solid var(--surface);
  border-radius: 50%;
  background: var(--accent);
}

.tutorial-diagram-progress:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.tutorial-diagram-legend {
  list-style: none;
  margin: 0.25rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.8em;
  color: var(--text-muted);
}

.tutorial-diagram-legend-item {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
}

.tutorial-diagram-legend-dot {
  flex: none;
  width: 0.6em;
  height: 0.6em;
  border-radius: 50%;
  align-self: center;
}

.tutorial-diagram-legend code {
  padding: 0.05rem 0.3rem;
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--accent);
  font-size: 0.9em;
}

.tutorial-diagram-annotation {
  font-style: italic;
  color: var(--text-subtle);
}

.tutorial-diagram-files-box {
  fill: var(--surface);
  stroke: var(--border);
  stroke-width: 1;
  transition: opacity var(--diagram-transition);
}

.tutorial-diagram-files-box-label {
  font-size: 7px;
  font-weight: 600;
  fill: var(--text-subtle);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  transition: opacity var(--diagram-transition);
}

/* The branch name in "Working directory (<branch>)" -- kept visually
   secondary to the box's own uppercase label, and left lowercase/unstyled
   so a branch name doesn't get shouted in caps like the label itself. */
.tutorial-diagram-files-box-label-branch {
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
}

/* A branch switch changes only this label, so give it a temporary pill and
   flash rather than making the otherwise-identical Working directory box look
   like it changed wholesale. */
.tutorial-diagram-files-box-label-branch-highlight {
  fill: var(--accent-soft);
  stroke: var(--accent);
  stroke-width: 0.5;
  transform-box: fill-box;
  transform-origin: center;
  pointer-events: none;
  animation: tutorial-diagram-branch-highlight 1.1s ease-out;
}

.tutorial-diagram-files-box-label-branch--changed {
  animation: tutorial-diagram-branch-switch 1.1s ease-out;
}

@keyframes tutorial-diagram-branch-highlight {
  0% { opacity: 0; transform: scale(0.88); }
  18% { opacity: 1; transform: scale(1.08); }
  45%, 100% { transform: scale(1); }
  100% { opacity: 0; }
}

@keyframes tutorial-diagram-branch-switch {
  0% { fill: var(--text-subtle); opacity: 0.35; }
  18%, 45% { fill: var(--accent); opacity: 1; }
  100% { fill: var(--text-subtle); opacity: 1; }
}

.tutorial-diagram-file-badge {
  fill: var(--surface);
  stroke: var(--border);
  stroke-width: 1;
  transition: x var(--diagram-transition), y var(--diagram-transition),
    width var(--diagram-transition), height var(--diagram-transition),
    rx var(--diagram-transition), ry var(--diagram-transition),
    fill var(--diagram-transition), stroke var(--diagram-transition),
    opacity var(--diagram-transition);
}

/* Border/text color (which commit a file's current content belongs to) is
   set inline per-frame from that node's color_token. This class's own fill
   is a fallback only -- the template overrides it inline with a soft tint
   of that same current commit's color, so the highlight that flags
   unstaged edits reads as "this commit's content, lightly flagged" rather
   than an unrelated color. */
.tutorial-diagram-file-badge--dirty {
  fill: var(--danger-soft);
}

/* Same idea as --dirty above, but for a file that's been staged (git add)
   and not yet committed. Fallback fill only -- the template overrides it
   inline with a soft tint of the *next* commit's color (the same preview
   color the Staging area badge uses), so the highlight ties visually to
   the commit that file is about to become part of. */
.tutorial-diagram-file-badge--staged {
  fill: var(--accent-soft);
}

.tutorial-diagram-file-badge-text {
  font-size: 7px;
  fill: var(--text-muted);
  dominant-baseline: central;
  transition: x var(--diagram-transition), y var(--diagram-transition),
    fill var(--diagram-transition), opacity var(--diagram-transition);
}

.tutorial-diagram-file-badge-text--dirty,
.tutorial-diagram-file-badge-text--staged {
  font-weight: 600;
}

.tutorial-diagram-file-entry--empty {
  font-size: 7.5px;
  font-style: italic;
  fill: var(--text-subtle);
}

/* Fallback fill only -- both the --dirty and --staged notes get their real
   color inline per-frame (current commit's color for --dirty, next
   commit's for --staged; see the badge fill comments above). */
.tutorial-diagram-file-note {
  font-size: 6.5px;
  font-style: italic;
  fill: var(--danger);
  transition: x var(--diagram-transition), y var(--diagram-transition),
    fill var(--diagram-transition), opacity var(--diagram-transition);
}

.tutorial-diagram-file-note--staged {
  fill: var(--accent);
}

/* Terminal-styled typing caption (JS-created, Task 5) rendered above a
   playing frame's SVG -- dramatizes "you just ran this command", separate
   from frame.caption's <title>-only role and the step's own plain-text
   command list. No template currently emits this markup; the class names
   here are the contract Task 5's JS builds its DOM against. */
.tutorial-diagram-caption {
  display: flex;
  align-items: center;
  gap: 0.3em;
  margin: 0 0 0.35rem;
  padding: 0.15rem 0.4rem;
  border-radius: var(--radius-sm);
  background: var(--bg);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.78em;
  color: var(--text-muted);
  transition: background var(--diagram-transition-fast);
}

.tutorial-diagram-caption-prompt {
  flex: none;
  color: var(--accent);
}

.tutorial-diagram-caption-cursor {
  display: inline-block;
  width: 0.5em;
  margin-left: 0.05em;
  border-left: 1px solid currentColor;
  animation: tutorial-diagram-cursor-blink 1s step-end infinite;
}

@keyframes tutorial-diagram-cursor-blink {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}

/* One-shot Enter-keypress cue: JS adds this class once the caption
   finishes typing, and removes it after the animation completes. */
.tutorial-diagram-caption--flash {
  animation: tutorial-diagram-caption-flash 0.35s ease-in-out;
}

@keyframes tutorial-diagram-caption-flash {
  0% { background: var(--bg); }
  30% { background: var(--accent-soft); }
  100% { background: var(--bg); }
}

/* Duplicate-and-fly boundary-crossing treatment (JS-created/positioned,
   Task 6) -- the source element never moves; a temporary duplicate flies
   from source to destination along a JS-computed quadratic arc, dashed
   guide line first. Position/path is driven per-frame by JS (a curved
   path isn't a single CSS-transitionable value), so only the color morph
   and the guide line's draw/fade are CSS transitions here. */
.tutorial-diagram-guide-line {
  fill: none;
  stroke: var(--text-subtle);
  stroke-width: 1;
  stroke-dasharray: 3 3;
  marker-end: url(#tutorial-diagram-arrowhead);
  opacity: 0;
  transition: opacity var(--diagram-transition-fast);
}

.tutorial-diagram-guide-line--visible {
  opacity: 1;
}

.tutorial-diagram-duplicate {
  pointer-events: none;
  transition: fill var(--diagram-transition), stroke var(--diagram-transition);
}

/* Plain-cut override (Task 5's JS, the last-frame-back-to-first-frame wrap
   in a card's loop): applied for one frame just while attributes are
   rewritten, so that specific jump doesn't animate like every other
   frame-to-frame transition does -- "no real git command undoes a push". */
.tutorial-diagram-svg--cut,
.tutorial-diagram-svg--cut * {
  transition: none !important;
}

/* Reduced-motion baseline: every card sits at its own settled target frame
   with no in-progress transition (belt-and-suspenders alongside Task 5's
   JS, which must also skip starting any card's loop under
   prefers-reduced-motion rather than relying on this alone). */
@media (prefers-reduced-motion: reduce) {
  .tutorial-diagram-node,
  .tutorial-diagram-edge,
  .tutorial-diagram-branch-tip-badge,
  .tutorial-diagram-branch-tip,
  .tutorial-diagram-head-badge,
  .tutorial-diagram-head,
  .tutorial-diagram-tracking-ref,
  .tutorial-diagram-file-badge,
  .tutorial-diagram-file-badge-text,
  .tutorial-diagram-file-note,
  .tutorial-diagram-files-box,
  .tutorial-diagram-files-box-label,
  .tutorial-diagram-caption,
  .tutorial-diagram-guide-line,
  .tutorial-diagram-duplicate {
    transition: none;
  }

  .tutorial-diagram-caption-cursor,
  .tutorial-diagram-caption--flash,
  .tutorial-diagram-files-box-label-branch-highlight,
  .tutorial-diagram-files-box-label-branch--changed {
    animation: none;
  }
}

.validator-outcomes {
  list-style: none;
  margin: 0.35rem 0 0;
  padding: 0;
}

.validator-outcome {
  font-size: 0.85em;
  font-weight: 600;
}

.validator-outcome--passed {
  color: var(--success);
}

.validator-outcome--failed {
  color: var(--danger);
}

.validator-outcome--not-tested {
  color: var(--text-muted);
}

button:disabled,
input[type="submit"]:disabled,
input[type="button"]:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.field-hint {
  margin-top: 0.2rem;
  margin-bottom: 0;
  color: var(--text-muted);
  font-size: 0.82em;
}

.field-hint--error {
  color: var(--danger);
  font-weight: 600;
}

.group-size-fields {
  margin-top: var(--space-md);
  padding: var(--space-md);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg);
}

.group-size-fields input.input-invalid {
  border-color: var(--danger);
  background: var(--danger-soft);
}

.group-size-fields input.input-invalid:focus {
  outline-color: var(--danger);
  border-color: var(--danger);
}

.dropzone {
  margin-top: var(--space-md);
  padding: var(--space-lg);
  text-align: center;
  border: 2px dashed var(--border);
  transition: border-color .1s ease, background .1s ease;
}

.dropzone--active {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.dropzone input[type="file"] {
  max-width: 24rem;
  margin: 0 auto;
}

.dropzone-hint {
  margin-top: var(--space-sm);
  margin-bottom: 0;
  color: var(--text-muted);
  font-size: 0.85em;
}

.dropzone-filename {
  margin-top: var(--space-sm);
  margin-bottom: 0;
  font-weight: 600;
}

@media (min-width: 768px) {
  :root {
    --font-size-base: 14px;
    --space-md: 0.7rem;
  }

  main form {
    max-width: 32rem;
  }

  main form.assignment-create-form {
    max-width: none;
  }

  main table form {
    max-width: none;
  }

  main input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
  main select,
  main textarea {
    max-width: 28rem;
  }

  main button[type="submit"],
  main button[type="button"],
  main input[type="submit"],
  main input[type="button"] {
    width: auto;
  }
}
