/*
 * theme_components.css — Component Styles
 * =========================================
 * All component styles for the enterprise bluish theme.
 *
 * RULES (from CLAUDE_UI_LOCK.md):
 *   - Every rule MUST start with .themed
 *   - Every component MUST use tokens from theme_tokens.css
 *   - No inline styles, no arbitrary hex values
 *   - Mobile breakpoints included for every component
 *
 * TABLE OF CONTENTS:
 *   1.  Layout — Sidebar, Header, Page Wrapper
 *   2.  Navigation — Sidebar links, sections, user info
 *   3.  Parent Navbar
 *   4.  Cards & Panels
 *   5.  Buttons
 *   6.  Form Elements
 *   7.  Tables
 *   8.  Badges & Chips
 *   9.  Status Indicators (Attendance)
 *  10.  Alerts & Flash Messages
 *  11.  Modals
 *  12.  Dropdowns
 *  13.  Stats & Metrics
 *  14.  AI & Insights Components
 *  15.  AI Workshop Components
 *  16.  Charts (CSS variables for JS consumption)
 *  17.  Interventions
 *  18.  Responsive — Mobile fixes
 *  19.  Feature Requests
 *  20.  Feature Requests Internal
 *  21.  Manual Schedule Editor
 */


/* =============================================================================
   1. LAYOUT — SIDEBAR, HEADER, PAGE WRAPPER
   ============================================================================= */

.themed .t-sidebar {
  background-color: var(--sidebar-bg);
  border-right: 1px solid var(--sidebar-border);
  box-shadow: var(--shadow-sm);
}

.themed .t-header {
  background-color: var(--header-bg);
  border-bottom: 1px solid var(--header-border);
  box-shadow: var(--shadow-sm);
}

.themed .t-page-wrapper {
  background-color: var(--color-canvas);
  min-height: 100vh;
}

.themed .t-main-content {
  background-color: var(--color-canvas);
}

/* Mobile backdrop for sidebar */
.themed .t-mobile-backdrop {
  background-color: var(--color-overlay);
}


/* =============================================================================
   2. NAVIGATION — SIDEBAR LINKS, SECTIONS, USER INFO
   ============================================================================= */

.themed .t-nav-link {
  display: flex;
  align-items: center;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  color: var(--nav-link-color);
  font-size: var(--text-base);
  font-weight: var(--font-weight-normal);
  transition: background-color var(--transition-fast),
              color var(--transition-fast);
  text-decoration: none;
  gap: var(--space-2-5);
  position: relative;
  /* Invisible left border placeholder — prevents layout shift on active */
  border-left: 3px solid transparent;
}

.themed .t-nav-link:hover {
  background-color: var(--nav-link-hover-bg);
  color: var(--nav-link-hover-color);
  text-decoration: none;
  /* Subtle left border hint on hover — preview of active state */
  border-left-color: var(--color-border);
}

.themed .t-nav-link.active {
  background-color: var(--nav-link-active-bg);
  color: var(--nav-link-active-text);
  font-weight: var(--font-weight-medium);
  border-left-color: var(--nav-link-active-border);
}

/* Left border accent on active nav item — replaced by border-left approach */

.themed .t-nav-link svg {
  flex-shrink: 0;
  width: 1.125rem;
  height: 1.125rem;
  transition: color var(--transition-fast);
}

.themed .t-nav-section-header {
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--nav-section-color);
  text-transform: uppercase;
  letter-spacing: 0.075em;
  padding: var(--space-2) var(--space-4) var(--space-1);
  margin-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  padding-top: var(--space-3);
}

.themed .t-nav-divider {
  border: none;
  border-top: 1px solid var(--color-border);
  margin: var(--space-3) var(--space-3);
}

.themed .t-user-info {
  background-color: var(--nav-user-bg);
  border-top: 1px solid var(--color-border);
  padding: var(--space-3) var(--space-4);
}

/* Logout/action link in user info area */
.themed .t-user-info a {
  color: var(--color-text-subtle);
  transition: color var(--transition-fast);
}
.themed .t-user-info a:hover {
  color: var(--color-text-base);
}

.themed .t-user-avatar {
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-full);
  background-color: var(--color-primary-600);
  color: var(--color-text-inverse);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  flex-shrink: 0;
}

/* ── Avatar Component ─────────────────────────────────────────────────────── */
/* Reusable avatar: photo with initials fallback.                             */
/* Sizes: xs (1.75rem) · sm (2rem) · md (2.5rem) · lg (3rem) · xl (4rem)     */
/* Variants: staff (primary bg) · student (primary-100 bg) · neutral (muted) */

.themed .t-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  flex-shrink: 0;
  overflow: hidden;
  line-height: 1;
}

/* ── Sizes ── */
.themed .t-avatar-xs {
  width: 1.75rem;
  height: 1.75rem;
  font-size: var(--text-xs);
}
.themed .t-avatar-sm {
  width: 2rem;
  height: 2rem;
  font-size: var(--text-xs);
}
.themed .t-avatar-md {
  width: 2.5rem;
  height: 2.5rem;
  font-size: var(--text-sm);
}
.themed .t-avatar-lg {
  width: 3rem;
  height: 3rem;
  font-size: var(--text-base);
}
.themed .t-avatar-xl {
  width: 4rem;
  height: 4rem;
  font-size: var(--text-xl);
}

/* ── Initials variants ── */
.themed .t-avatar-initials {
  font-weight: var(--font-weight-semibold);
}
.themed .t-avatar-staff {
  background-color: var(--color-primary-600);
  color: var(--color-text-inverse);
}
.themed .t-avatar-student {
  background-color: var(--color-primary-100);
  color: var(--color-primary-600);
}
.themed .t-avatar-neutral {
  background-color: var(--color-surface-hover);
  color: var(--color-text-muted);
}

/* ── Image variant ── */
.themed .t-avatar-image {
  object-fit: cover;
  border-radius: var(--radius-full);
}

/* ── Mobile breakpoints (R6) ── */
@media (max-width: 768px) {
  .themed .t-avatar-xl {
    width: 3rem;
    height: 3rem;
    font-size: var(--text-base);
  }
  .themed .t-avatar-lg {
    width: 2.5rem;
    height: 2.5rem;
    font-size: var(--text-sm);
  }
}
@media (max-width: 480px) {
  .themed .t-avatar-xl {
    width: 2.5rem;
    height: 2.5rem;
    font-size: var(--text-sm);
  }
  .themed .t-avatar-lg {
    width: 2rem;
    height: 2rem;
    font-size: var(--text-xs);
  }
}

.themed .t-user-name {
  font-size: var(--text-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-base);
  line-height: var(--leading-tight);
}

.themed .t-user-role {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}


/* =============================================================================
   3. PARENT NAVBAR
   ============================================================================= */

/* The parent navbar is a light/white header that mirrors the admin dashboard
   chrome — so the school's navy, transparent-background logo reads cleanly with
   no white chip, and the brand text is dark (no blue-on-blue). */
.themed .t-parent-navbar {
  background-color: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
}

.themed .t-parent-nav-link {
  display: inline-flex;
  align-items: center;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  font-size: var(--text-base);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
  transition: background-color var(--transition-fast),
              color var(--transition-fast);
  gap: var(--space-2);
}

.themed .t-parent-nav-link:hover {
  background-color: var(--color-surface-hover);
  color: var(--color-text-base);
  text-decoration: none;
}

.themed .t-parent-nav-link.active {
  background-color: var(--color-primary-50);
  color: var(--color-primary-700);
}

/* Component: Parent nav link leading icon */
.themed .t-parent-nav-icon {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
  opacity: 0.9;
}

/* Component: Parent nav unread badge (Messagerie count) */
.themed .t-parent-nav-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.125rem;
  height: 1.125rem;
  margin-left: var(--space-1);
  padding: 0 var(--space-1);
  border-radius: var(--radius-full);
  background-color: var(--color-primary-600);
  color: var(--color-text-inverse);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-bold);
  line-height: 1;
}

/* Component: Parent navbar brand link.
   The global `.themed a` rule (theme_scope.css, specificity 0,1,1) would override
   Tailwind's text colour on the brand anchor; this class (0,2,0) pins it to the
   base text token so it reads dark on the white navbar (mirrors the admin header).
   The nav links already escape via `.t-parent-nav-link`. */
.themed .t-parent-brand {
  color: var(--color-text-base);
  text-decoration: none;
}
.themed .t-parent-brand:hover {
  color: var(--color-text-base);
  text-decoration: none;
  opacity: 0.85;
}

@media (max-width: 768px) {
  .themed .t-parent-nav-badge {
    min-width: 1rem;
    height: 1rem;
  }
  .themed .t-parent-brand {
    font-size: var(--text-base);
  }
}
@media (max-width: 480px) {
  .themed .t-parent-nav-icon {
    width: 0.9375rem;
    height: 0.9375rem;
  }
}

.themed .t-parent-mobile-menu {
  background-color: var(--color-surface);
  border-top: 1px solid var(--color-border);
}

.themed .t-parent-mobile-link {
  display: flex;
  align-items: center;
  padding: var(--space-3) var(--space-4);
  color: var(--color-text-muted);
  font-size: var(--text-base);
  text-decoration: none;
  gap: var(--space-2-5);
  transition: background-color var(--transition-fast);
}

.themed .t-parent-mobile-link:hover {
  background-color: var(--color-surface-hover);
  color: var(--color-text-base);
  text-decoration: none;
}

.themed .t-parent-footer {
  background-color: var(--color-surface);
  border-top: 1px solid var(--color-border);
  color: var(--color-text-subtle);
  font-size: var(--text-sm);
}

/* Component: Parent child card header */
.themed .t-parent-child-header {
  background: linear-gradient(135deg, var(--color-primary-400) 0%, var(--color-primary-500) 100%);
}

/* Component: Parent logout button (primary pill on the white navbar) */
.themed .t-parent-logout-btn {
  background-color: var(--color-primary-600);
  color: var(--color-text-inverse);
}
.themed .t-parent-logout-btn:hover {
  background-color: var(--color-primary-700);
}

@media (max-width: 768px) {
  .themed .t-parent-child-header {
    padding: var(--space-3);
  }
}
@media (max-width: 480px) {
  .themed .t-parent-child-header {
    padding: var(--space-2);
  }
}


/* =============================================================================
   4. CARDS & PANELS
   ============================================================================= */

.themed .t-card {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: box-shadow var(--transition-fast);
}

.themed .t-card-header {
  padding: var(--space-4) var(--space-6);
  border-bottom: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.themed .t-card-title {
  font-size: var(--text-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
  margin: 0;
}

.themed .t-card-subtitle {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin-top: var(--space-0-5);
}

.themed .t-card-body {
  padding: var(--space-6);
}

.themed .t-card-footer {
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--color-border);
  background-color: var(--color-surface-muted);
}

/* Compact card variant */
.themed .t-card-sm .t-card-header {
  padding: var(--space-3) var(--space-4);
}
.themed .t-card-sm .t-card-body {
  padding: var(--space-4);
}

/* Panel — full-width section divider */
.themed .t-panel {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

/* Interactive card — for clickable card links (quick actions, navigation cards) */
.themed .t-card-interactive {
  transition: box-shadow var(--transition-fast),
              transform var(--transition-fast),
              border-color var(--transition-fast);
  cursor: pointer;
}

.themed .t-card-interactive:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
  border-color: var(--color-primary-200);
}

.themed .t-card-interactive:active {
  transform: translateY(0);
  box-shadow: var(--shadow-sm);
}

/* Info panel — highlighted */
.themed .t-panel-info {
  background-color: var(--color-info-bg);
  border: 1px solid var(--color-info-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  color: var(--color-info-text);
  font-size: var(--text-base);
}

/* Warning panel — amber action prompt (e.g. cross-class copy) */
.themed .t-panel-warning {
  background-color: var(--color-warning-bg);
  border: 1px solid var(--color-warning-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  color: var(--color-warning-text);
  font-size: var(--text-base);
}

@media (max-width: 768px) {
  .themed .t-panel-warning {
    padding: var(--space-3);
  }
}

@media (max-width: 480px) {
  .themed .t-panel-warning {
    padding: var(--space-2);
  }
}


/* =============================================================================
   5. BUTTONS
   ============================================================================= */

.themed .t-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  font-weight: var(--font-weight-medium);
  line-height: 1.5;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background-color var(--transition-fast),
              border-color var(--transition-fast),
              color var(--transition-fast),
              box-shadow var(--transition-fast);
  text-decoration: none;
  white-space: nowrap;
  user-select: none;
}

.themed .t-btn:focus-visible {
  outline: 2px solid var(--color-border-focus);
  outline-offset: 2px;
}

.themed .t-btn:disabled,
.themed .t-btn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* Primary */
.themed .t-btn-primary {
  background-color: var(--color-primary-600);
  border-color: var(--color-primary-600);
  color: var(--color-text-inverse);
}
.themed .t-btn-primary:hover {
  background-color: var(--color-primary-700);
  border-color: var(--color-primary-700);
}
.themed .t-btn-primary:active {
  background-color: var(--color-primary-800);
}

/* Secondary */
.themed .t-btn-secondary {
  background-color: var(--color-surface);
  border-color: var(--color-border-strong);
  color: var(--color-text-base);
}
.themed .t-btn-secondary:hover {
  background-color: var(--color-surface-hover);
  border-color: var(--color-border-strong);
}

/* Danger */
.themed .t-btn-danger {
  background-color: var(--color-danger-bg);
  border-color: var(--color-danger-border);
  color: var(--color-danger-text);
}
.themed .t-btn-danger:hover {
  background-color: #fecaca;
  border-color: var(--color-danger-text);
}

/* Ghost */
.themed .t-btn-ghost {
  background-color: transparent;
  border-color: transparent;
  color: var(--color-text-muted);
}
.themed .t-btn-ghost:hover {
  background-color: var(--color-surface-hover);
  color: var(--color-text-base);
}

/* Success */
.themed .t-btn-success {
  background-color: var(--color-success-text);
  border-color: var(--color-success-text);
  color: var(--color-text-inverse);
}
.themed .t-btn-success:hover {
  background-color: #166534;
  border-color: #166534;
}

/* Warning — amber action button (matches t-panel-warning) */
.themed .t-btn-warning {
  background-color: var(--color-warning-icon);
  border-color: var(--color-warning-icon);
  color: var(--color-text-inverse);
}
.themed .t-btn-warning:hover {
  background-color: var(--color-warning-text);
  border-color: var(--color-warning-text);
}

/* Size variants */
.themed .t-btn-sm {
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
  gap: var(--space-1-5);
}

.themed .t-btn-lg {
  padding: var(--space-3) var(--space-6);
  font-size: var(--text-lg);
}

.themed .t-btn-xl {
  padding: var(--space-4) var(--space-8);
  font-size: var(--text-lg);
  font-weight: var(--font-weight-semibold);
}

/* Icon-only button */
.themed .t-btn-icon {
  padding: var(--space-2);
  width: 2.25rem;
  height: 2.25rem;
}
.themed .t-btn-icon.t-btn-sm {
  width: 1.75rem;
  height: 1.75rem;
  padding: var(--space-1);
}


/* =============================================================================
   6. FORM ELEMENTS
   ============================================================================= */

.themed .t-label {
  display: block;
  font-size: var(--text-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-base);
  margin-bottom: var(--space-1-5);
}

.themed .t-label-required::after {
  content: ' *';
  color: var(--color-danger-text);
}

.themed .t-input,
.themed .t-select,
.themed .t-textarea {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-base);
  font-family: var(--font-sans);
  color: var(--color-text-base);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  line-height: var(--leading-normal);
  transition: border-color var(--transition-fast),
              box-shadow var(--transition-fast);
  appearance: none;
  -webkit-appearance: none;
}

.themed .t-input::placeholder,
.themed .t-textarea::placeholder {
  color: var(--color-text-subtle);
}

.themed .t-input:hover,
.themed .t-select:hover,
.themed .t-textarea:hover {
  border-color: var(--color-border-focus);
}

.themed .t-input:focus,
.themed .t-select:focus,
.themed .t-textarea:focus {
  outline: none;
  border-color: var(--color-border-focus);
  box-shadow: 0 0 0 3px var(--color-primary-100);
}

.themed .t-input:disabled,
.themed .t-select:disabled,
.themed .t-textarea:disabled {
  background-color: var(--color-surface-muted);
  color: var(--color-text-subtle);
  cursor: not-allowed;
}

/* Select with caret */
.themed .t-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 1.25rem;
  padding-right: 2.5rem;
}

.themed .t-textarea {
  resize: vertical;
  min-height: 5rem;
}

/* Error state */
.themed .t-input-error {
  border-color: var(--color-border-error);
}
.themed .t-input-error:focus {
  box-shadow: 0 0 0 3px var(--color-danger-bg);
  border-color: var(--color-border-error);
}

/* Checkbox / Radio — defensive override
   t-input sets width:100% which stretches checkboxes into full-width bars.
   This higher-specificity rule (0,3,1) beats t-input (0,2,0) without !important. */
.themed input[type="checkbox"].t-input,
.themed input[type="radio"].t-input {
  display: inline-block;
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  padding: 0;
  accent-color: var(--color-primary-600);
}

/* Dedicated boolean-field hook — prefer t-checkbox over t-input on checkboxes */
.themed .t-checkbox {
  display: inline-block;
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  cursor: pointer;
  padding: 0;
  accent-color: var(--color-primary-600);
}

/* Form group */
.themed .t-form-group {
  margin-bottom: var(--space-5);
}

/* In inline flex rows (filter bars, header forms), remove the bottom margin so
   items-end can properly align form groups with sibling buttons. */
.themed .flex > .t-form-group,
.themed form.flex .t-form-group {
  margin-bottom: 0;
}

/* Form hint / helper text */
.themed .t-form-hint {
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-text-subtle);
}
.themed .t-form-error {
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-danger-text);
}

/* Checkbox / Radio */
.themed .t-checkbox,
.themed .t-radio {
  width: 1rem;
  height: 1rem;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background-color: var(--color-surface);
  cursor: pointer;
  accent-color: var(--color-primary-600);
}

/* Search input with icon */
.themed .t-search-wrapper {
  position: relative;
}
.themed .t-search-wrapper .t-search-icon {
  position: absolute;
  left: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-subtle);
  width: 1rem;
  height: 1rem;
  pointer-events: none;
}
.themed .t-input-search {
  padding-left: 2.25rem;
}


/* =============================================================================
   7. TABLES
   ============================================================================= */

.themed .t-table-wrapper {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  background-color: var(--color-surface);
}

.themed .t-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-base);
}

.themed .t-table thead {
  background-color: var(--color-surface-muted);
  border-bottom: 2px solid var(--color-primary-200);
}

.themed .t-table th {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}

.themed .t-table td {
  padding: var(--space-3) var(--space-4);
  color: var(--color-text-base);
  border-bottom: 1px solid var(--color-border);
  vertical-align: middle;
}

.themed .t-table tbody tr {
  transition: background-color var(--transition-fast);
}

.themed .t-table tbody tr:last-child td {
  border-bottom: none;
}

.themed .t-table tbody tr:hover {
  background-color: var(--color-surface-hover);
}

/* Compact table */
.themed .t-table-compact th,
.themed .t-table-compact td {
  padding: var(--space-2) var(--space-3);
}

/* Striped table */
.themed .t-table-striped tbody tr:nth-child(even) {
  background-color: var(--color-surface-muted);
}

/* Numeric column alignment */
.themed .t-table .t-col-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum';
}

/* Responsive table wrapper */
.themed .t-table-responsive {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--radius-lg);
}


/* Metric tile — used in global metrics dashboard cards */
.themed .t-metric-tile {
  text-align: center;
  padding: var(--space-4);
  background-color: var(--color-surface-muted);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  transition: border-color var(--transition-fast),
              box-shadow var(--transition-fast);
}

.themed .t-metric-tile:hover {
  border-color: var(--color-primary-200);
  box-shadow: var(--shadow-sm);
}


/* =============================================================================
   8. BADGES & CHIPS
   ============================================================================= */

.themed .t-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-0-5) var(--space-2);
  border-radius: var(--radius-full);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  line-height: 1.4;
  white-space: nowrap;
}

.themed .t-badge-success {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
  border: 1px solid var(--color-success-border);
}
.themed .t-badge-warning {
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
  border: 1px solid var(--color-warning-border);
}
.themed .t-badge-danger {
  background-color: var(--color-danger-bg);
  color: var(--color-danger-text);
  border: 1px solid var(--color-danger-border);
}
.themed .t-badge-info {
  background-color: var(--color-info-bg);
  color: var(--color-info-text);
  border: 1px solid var(--color-info-border);
}
.themed .t-badge-neutral {
  background-color: var(--color-surface-muted);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
}
.themed .t-badge-primary {
  background-color: var(--color-primary-50);
  color: var(--color-primary-700);
  border: 1px solid var(--color-primary-200);
}

/* Dot indicator */
.themed .t-badge-dot::before {
  content: '';
  width: 0.375rem;
  height: 0.375rem;
  border-radius: var(--radius-full);
  background-color: currentColor;
  flex-shrink: 0;
}


/* =============================================================================
   9. STATUS INDICATORS — ATTENDANCE
   ============================================================================= */

.themed .t-status-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  padding: var(--space-1-5) var(--space-3);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  border: 1px solid transparent;
  transition: background-color var(--transition-fast),
              box-shadow var(--transition-fast);
  user-select: none;
}

/* Present */
.themed .t-status-present {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
  border-color: var(--color-success-border);
}
.themed .t-status-present.active,
.themed .t-status-present[data-active="true"] {
  background-color: var(--color-success-text);
  color: var(--color-text-inverse);
  box-shadow: 0 0 0 2px var(--color-success-border);
}

/* Absent */
.themed .t-status-absent {
  background-color: var(--color-danger-bg);
  color: var(--color-danger-text);
  border-color: var(--color-danger-border);
}
.themed .t-status-absent.active,
.themed .t-status-absent[data-active="true"] {
  background-color: var(--color-danger-text);
  color: var(--color-text-inverse);
  box-shadow: 0 0 0 2px var(--color-danger-border);
}

/* Late */
.themed .t-status-late {
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
  border-color: var(--color-warning-border);
}
.themed .t-status-late.active,
.themed .t-status-late[data-active="true"] {
  background-color: var(--color-warning-text);
  color: var(--color-text-inverse);
  box-shadow: 0 0 0 2px var(--color-warning-border);
}

/* Excused */
.themed .t-status-excused {
  background-color: var(--color-info-bg);
  color: var(--color-info-text);
  border-color: var(--color-info-border);
}
.themed .t-status-excused.active,
.themed .t-status-excused[data-active="true"] {
  background-color: var(--color-info-text);
  color: var(--color-text-inverse);
  box-shadow: 0 0 0 2px var(--color-info-border);
}

/* Early departure */
.themed .t-status-early {
  background-color: var(--color-surface-muted);
  color: var(--color-text-muted);
  border-color: var(--color-border);
}
.themed .t-status-early.active,
.themed .t-status-early[data-active="true"] {
  background-color: var(--color-text-muted);
  color: var(--color-text-inverse);
}

/* Counter tile for attendance summary */
.themed .t-stat-tile {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  text-align: center;
  box-shadow: var(--shadow-sm);
}

.themed .t-stat-tile-value {
  font-size: var(--text-3xl);
  font-weight: var(--font-weight-bold);
  line-height: 1;
  margin-bottom: var(--space-1);
}

.themed .t-stat-tile-label {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  font-weight: var(--font-weight-medium);
}


/* =============================================================================
   10. ALERTS & FLASH MESSAGES
   ============================================================================= */

.themed .t-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  border-width: 1px;
  border-style: solid;
  border-left-width: 4px;
  font-size: var(--text-base);
}

.themed .t-alert-icon {
  flex-shrink: 0;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 1px;
}

.themed .t-alert-success {
  background-color: var(--color-success-bg);
  border-color: var(--color-success-border);
  color: var(--color-success-text);
}
.themed .t-alert-warning {
  background-color: var(--color-warning-bg);
  border-color: var(--color-warning-border);
  color: var(--color-warning-text);
}
.themed .t-alert-danger {
  background-color: var(--color-danger-bg);
  border-color: var(--color-danger-border);
  color: var(--color-danger-text);
}
.themed .t-alert-info {
  background-color: var(--color-info-bg);
  border-color: var(--color-info-border);
  color: var(--color-info-text);
}


/* =============================================================================
   11. MODALS
   ============================================================================= */

.themed .t-modal-backdrop {
  background-color: var(--color-overlay);
}

.themed .t-modal-panel {
  background-color: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  border: 1px solid var(--color-border);
  overflow: hidden;
}

.themed .t-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-5) var(--space-6);
  border-bottom: 1px solid var(--color-border);
}

.themed .t-modal-title {
  font-size: var(--text-xl);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
  margin: 0;
}

.themed .t-modal-body {
  padding: var(--space-6);
}

.themed .t-modal-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--color-border);
  background-color: var(--color-surface-muted);
}

.themed .t-modal-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-md);
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--color-text-muted);
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.themed .t-modal-close:hover {
  background-color: var(--color-surface-hover);
  color: var(--color-text-base);
}


/* =============================================================================
   12. DROPDOWNS
   ============================================================================= */

.themed .t-dropdown {
  position: relative;
  display: inline-block;
}

.themed .t-dropdown-menu {
  position: absolute;
  z-index: var(--z-dropdown);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  min-width: 10rem;
  overflow: hidden;
  padding: var(--space-1);
}

.themed .t-dropdown-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-base);
  color: var(--color-text-base);
  border-radius: var(--radius-md);
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--transition-fast);
  border: none;
  background: none;
  width: 100%;
  text-align: left;
}

.themed .t-dropdown-item:hover {
  background-color: var(--color-surface-hover);
  text-decoration: none;
}

.themed .t-dropdown-item-danger {
  color: var(--color-danger-text);
}
.themed .t-dropdown-item-danger:hover {
  background-color: var(--color-danger-bg);
}

.themed .t-dropdown-divider {
  border: none;
  border-top: 1px solid var(--color-border);
  margin: var(--space-1) 0;
}

/* Hover-selected item state (used with Alpine :class binding) */
.themed .t-dropdown-item-selected {
  background-color: var(--color-primary-50);
  color: var(--color-primary-700);
  font-weight: var(--font-weight-medium);
}


/* =============================================================================
   12b. COPY PREVIEW PANEL (cross-class lesson log copy hover preview)
   ============================================================================= */

/* Trigger button for the custom parallel-class select */
.themed .t-copy-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-1-5) var(--space-3);
  background-color: var(--color-surface);
  border: 1px solid var(--color-warning-border);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  color: var(--color-text-base);
  cursor: pointer;
  min-width: 14rem;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.themed .t-copy-trigger:hover,
.themed .t-copy-trigger:focus {
  border-color: var(--color-warning-icon);
  box-shadow: 0 0 0 3px var(--color-warning-border);
  outline: none;
}

/* Dropdown menu for the copy selector */
.themed .t-copy-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: var(--z-dropdown);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  min-width: 16rem;
  max-height: 16rem;
  overflow-y: auto;
  padding: var(--space-1);
}

/* Individual option row in the copy selector */
.themed .t-copy-option {
  display: flex;
  flex-direction: column;
  gap: var(--space-0-5);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background-color var(--transition-fast);
  border: none;
  background: none;
  width: 100%;
  text-align: left;
}

.themed .t-copy-option:hover,
.themed .t-copy-option-hovered {
  background-color: var(--color-warning-bg);
}

.themed .t-copy-option-name {
  font-size: var(--text-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-base);
}

.themed .t-copy-option-date {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* Floating preview card — appears beside the dropdown when hovering an option */
.themed .t-copy-preview {
  position: absolute;
  top: 0;
  left: calc(100% + var(--space-3));
  z-index: var(--z-dropdown);
  width: 28rem;
  max-height: 22rem;
  overflow-y: auto;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  padding: var(--space-5);
}

/* Preview header: class name + date */
.themed .t-copy-preview-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

.themed .t-copy-preview-class {
  font-size: var(--text-md);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
}

.themed .t-copy-preview-date {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  white-space: nowrap;
}

/* Section label inside the preview */
.themed .t-copy-preview-label {
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-subtle);
  margin-bottom: var(--space-1);
}

/* Section value inside the preview */
.themed .t-copy-preview-value {
  font-size: var(--text-sm);
  color: var(--color-text-base);
  line-height: 1.6;
  margin-bottom: var(--space-3);
}

.themed .t-copy-preview-value-empty {
  font-size: var(--text-sm);
  color: var(--color-text-subtle);
  font-style: italic;
  margin-bottom: var(--space-3);
}

/* Lesson type badge inside preview */
.themed .t-copy-preview-type {
  display: inline-flex;
  align-items: center;
  padding: var(--space-0-5) var(--space-2);
  background-color: var(--color-primary-50);
  color: var(--color-primary-700);
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
}

/* Footer hint inside the preview */
.themed .t-copy-preview-footer {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
  display: flex;
  align-items: center;
  gap: var(--space-1-5);
}

@media (max-width: 768px) {
  .themed .t-copy-preview {
    position: fixed;
    left: var(--space-4);
    right: var(--space-4);
    top: auto;
    bottom: var(--space-4);
    width: auto;
    max-height: 50vh;
    box-shadow: var(--shadow-xl);
  }

  .themed .t-copy-trigger {
    min-width: 10rem;
  }
}

@media (max-width: 480px) {
  .themed .t-copy-preview {
    left: var(--space-2);
    right: var(--space-2);
    bottom: var(--space-2);
  }

  .themed .t-copy-dropdown {
    min-width: 12rem;
  }
}


/* =============================================================================
   13. STATS & METRICS (Page-level stat cards)
   ============================================================================= */

.themed .t-stats-grid {
  /* Layout (grid columns, gap) handled by Tailwind utilities in templates.
     Theme provides only visual overrides for consistent spacing. */
  gap: var(--space-4);
}

.themed .t-stat-card {
  /* Visual properties only — layout (flex-direction, padding) handled by Tailwind
     in templates, since admin and teacher dashboards use different layouts. */
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--transition-fast),
              transform var(--transition-fast),
              border-color var(--transition-fast);
}

.themed .t-stat-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
  border-color: var(--color-border-strong);
}

/* Clickable stat cards (links) get a more pronounced hover */
.themed a.t-stat-card:hover {
  border-color: var(--color-primary-200);
}

.themed .t-stat-icon {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
}

.themed .t-stat-icon-primary {
  background-color: var(--color-primary-50);
  color: var(--color-primary-600);
}
.themed .t-stat-icon-success {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
}
.themed .t-stat-icon-warning {
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
}
.themed .t-stat-icon-danger {
  background-color: var(--color-danger-bg);
  color: var(--color-danger-text);
}

.themed .t-stat-value {
  font-size: var(--text-3xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-base);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.themed .t-stat-label {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  font-weight: var(--font-weight-medium);
}

.themed .t-stat-change {
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  display: flex;
  align-items: center;
  gap: var(--space-1);
}
.themed .t-stat-change-up { color: var(--color-success-text); }
.themed .t-stat-change-down { color: var(--color-danger-text); }
.themed .t-stat-change-neutral { color: var(--color-text-muted); }

/* Page header with actions */
.themed .t-page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
  flex-wrap: wrap;
}

.themed .t-page-title {
  font-size: var(--text-3xl);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
  margin: 0;
  line-height: var(--leading-tight);
}

.themed .t-page-subtitle {
  font-size: var(--text-base);
  color: var(--color-text-muted);
  margin-top: var(--space-1);
}

.themed .t-section-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.themed .t-section-title {
  font-size: var(--text-xl);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
  margin: 0;
}

/* Separator */
.themed .t-divider {
  border: none;
  border-top: 1px solid var(--color-border);
  margin: var(--space-6) 0;
}


/* =============================================================================
   14. AI & INSIGHTS COMPONENTS
   ============================================================================= */

/* Insight card (severity-colored) */
.themed .t-insight-card {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

.themed .t-insight-card-critical {
  border-left: 4px solid var(--color-danger-text);
}
.themed .t-insight-card-warning {
  border-left: 4px solid var(--color-warning-icon);
}
.themed .t-insight-card-info {
  border-left: 4px solid var(--color-info-icon);
}

/* AI report content */
.themed .t-ai-section-card {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  margin-bottom: var(--space-4);
  break-inside: avoid;
}

/* Entity anonymization badges */
.themed .t-ai-badge {
  display: inline-flex;
  align-items: center;
  padding: var(--space-0-5) var(--space-1-5);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-family: var(--font-mono);
  font-weight: var(--font-weight-semibold);
}
.themed .t-ai-badge-student {
  background-color: var(--color-primary-50);
  color: var(--color-primary-700);
  border: 1px solid var(--color-primary-200);
}
.themed .t-ai-badge-teacher {
  background-color: #f0fdfa;
  color: #0d9488;
  border: 1px solid #99f6e4;
}

/* AI report section body */
.themed .t-ai-section-body {
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
  color: var(--color-text-base);
}
.themed .t-ai-section-body ul {
  list-style: disc;
  padding-left: var(--space-5);
  margin: var(--space-2) 0;
}
.themed .t-ai-section-body li {
  margin-bottom: var(--space-1-5);
}
.themed .t-ai-section-body strong {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
}
.themed .t-ai-section-body p {
  margin-bottom: var(--space-3);
}


/* =============================================================================
   15. AI WORKSHOP COMPONENTS
   ============================================================================= */

.themed .t-workshop-card {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--transition-base);
  overflow: hidden;
}

.themed .t-workshop-card:hover {
  box-shadow: var(--shadow-md);
}

.themed .t-workshop-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
}

/* Source type badge */
.themed .t-workshop-badge-text {
  background-color: var(--color-primary-50);
  color: var(--color-primary-700);
}
.themed .t-workshop-badge-file {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
}

/* Difficulty badges */
.themed .t-difficulty-easy {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
  border: 1px solid var(--color-success-border);
}
.themed .t-difficulty-medium {
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
  border: 1px solid var(--color-warning-border);
}
.themed .t-difficulty-hard {
  background-color: var(--color-danger-bg);
  color: var(--color-danger-text);
  border: 1px solid var(--color-danger-border);
}

/* API usage widget */
.themed .t-api-usage-widget {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}

/* Workshop slide — minimal override, keep fullscreen intact */
.themed .t-workshop-slide-container {
  background-color: var(--color-canvas);
}


/* =============================================================================
   16. CHART CONTAINERS (CSS context for JS)
   ============================================================================= */

/* Chart.js reads CSS vars via getComputedStyle — defined on .themed body */
/* See CLAUDE_UI_LOCK.md §Chart Integration for JS usage */

.themed .t-chart-container {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-6);
}

.themed .t-chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.themed .t-chart-legend-item {
  display: flex;
  align-items: center;
  gap: var(--space-1-5);
}

.themed .t-chart-legend-dot {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: var(--radius-full);
  flex-shrink: 0;
}

/* Correlation indicator display */
.themed .t-correlation-badge {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1-5) var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums;
}
.themed .t-correlation-good {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
}
.themed .t-correlation-ok {
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
}
.themed .t-correlation-poor {
  background-color: var(--color-danger-bg);
  color: var(--color-danger-text);
}


/* =============================================================================
   17. INTERVENTION COMPONENTS
   ============================================================================= */

.themed .t-intervention-card {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4);
}

/* Priority indicators */
.themed .t-priority-urgent {
  border-left: 4px solid var(--color-danger-text);
}
.themed .t-priority-high {
  border-left: 4px solid var(--color-warning-icon);
}
.themed .t-priority-medium {
  border-left: 4px solid var(--color-info-icon);
}
.themed .t-priority-low {
  border-left: 4px solid var(--color-border-strong);
}

/* Timeline item */
.themed .t-timeline-item {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--color-border);
}
.themed .t-timeline-item:last-child {
  border-bottom: none;
}

.themed .t-timeline-dot {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: var(--radius-full);
  background-color: var(--color-primary-600);
  flex-shrink: 0;
  margin-top: 0.375rem;
}

/* Conversation message bubbles — t-msg-* classes are on the outer flex row wrapper,
   not the inner bubble div. Visual styling (bg, color, border-radius) lives in
   Tailwind classes on the inner bubble div. These rules are layout-only. */
.themed .t-msg-bubble {
  max-width: 75%;
}

.themed .t-msg-sent {
  /* layout only — inner bubble div carries bg-blue-600 text-white */
}

.themed .t-msg-received {
  /* layout only — inner bubble div carries bg-white border border-gray-200 */
}

/* Login page container */
.themed .t-auth-card {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  padding: var(--space-8);
  width: 100%;
  max-width: 24rem;
}

.themed .t-auth-logo {
  text-align: center;
  margin-bottom: var(--space-8);
}


/* =============================================================================
   19. LOGIN PAGE — Split-panel layout (Claude-style)
   ============================================================================= */

/* Page wrapper — exact viewport fill, no page scroll on login */
.themed .t-login-page {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
  background-color: var(--color-canvas);
}

/* ── Top navbar ── */
.themed .t-login-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--space-8);
  height: var(--header-height);
  background-color: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}

.themed .t-login-nav-brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.themed .t-login-nav-brand-logo {
  height: 2rem;
  width: auto;
}

.themed .t-login-nav-brand-name {
  font-size: var(--text-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
  letter-spacing: -0.01em;
}

.themed .t-login-nav-links {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.themed .t-login-nav-link {
  font-size: var(--text-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-muted);
  text-decoration: none;
  transition: color var(--transition-fast);
}

.themed .t-login-nav-link:hover {
  color: var(--color-text-base);
}

/* ── Two-column body — fills remaining viewport height ── */
.themed .t-login-body {
  display: grid;
  grid-template-columns: 42fr 58fr;   /* slightly wider visual panel */
  flex: 1;
  height: calc(100vh - var(--header-height));
  overflow: hidden;
}

/* ── Left column — form ── */
.themed .t-login-left {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-8) var(--space-10);
  background-color: var(--color-surface);
  overflow-y: auto;
}

.themed .t-login-form-wrap {
  width: 100%;
  max-width: 24rem;
}

.themed .t-login-form-logo {
  height: 3rem;
  width: auto;
  margin-bottom: var(--space-3);
}

.themed .t-login-form-title {
  font-size: var(--text-2xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-base);
  line-height: var(--leading-tight);
  margin-bottom: var(--space-1);
}

.themed .t-login-form-subtitle {
  font-size: var(--text-base);
  color: var(--color-text-muted);
  margin-bottom: var(--space-4);
}

/* Auth card override inside login — fill full wrap width */
.themed .t-login-left .t-auth-card {
  max-width: 100%;
  box-shadow: var(--shadow-md);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: var(--space-6);
  background-color: var(--color-surface);
}

/* ── Right column — product visual ── */
.themed .t-login-right {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-10) var(--space-10) var(--space-8);
  background: linear-gradient(
    148deg,
    var(--color-primary-50)  0%,
    var(--color-primary-100) 55%,
    var(--color-primary-200) 100%
  );
  position: relative;
  overflow: hidden;
}

/* Subtle dot-grid background decoration */
.themed .t-login-right::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(var(--color-primary-300) 1px, transparent 1px);
  background-size: 28px 28px;
  opacity: 0.25;
  pointer-events: none;
}

.themed .t-login-preview-wrap {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 680px;
  text-align: center;
}

.themed .t-login-preview-img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-xl);
  box-shadow:
    0 0 0 1px var(--color-primary-200),
    var(--shadow-xl);
  display: block;
}

/* Hero slogan block (above preview image) */
.themed .t-login-hero {
  text-align: center;
  margin-bottom: var(--space-8);
}

.themed .t-login-hero-title {
  font-size: 1.75rem;           /* between text-2xl and text-3xl */
  font-weight: var(--font-weight-bold);
  color: var(--color-primary-900);
  letter-spacing: -0.025em;
  line-height: var(--leading-tight);
}

.themed .t-login-hero-slogan {
  margin-top: var(--space-3);
  font-size: var(--text-lg);
  font-style: italic;
  font-weight: var(--font-weight-medium);
  color: var(--color-primary-600);
  line-height: var(--leading-relaxed);
}

/* Blinking cursor shown while the typewriter JS is running */
.themed .t-login-hero-slogan.t-login-slogan-typing::after {
  content: '|';
  color: var(--color-primary-400);
  font-style: normal;
  font-weight: var(--font-weight-normal);
  animation: t-cursor-blink 0.65s step-end infinite;
}

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

.themed .t-login-preview-caption {
  margin-top: var(--space-5);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-primary-700);
}

/* Placeholder shown when login-preview.png not yet provided */
.themed .t-login-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-12) var(--space-10);
  border: 2px dashed var(--color-primary-300);
  border-radius: var(--radius-xl);
  background-color: rgba(255, 255, 255, 0.45);
}

.themed .t-login-placeholder-icon {
  width: 7rem;
  height: auto;
  color: var(--color-primary-400);
}

.themed .t-login-placeholder-label {
  font-size: var(--text-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-primary-700);
}

.themed .t-login-placeholder-hint {
  font-size: var(--text-sm);
  color: var(--color-primary-500);
  text-align: center;
  line-height: var(--leading-relaxed);
}

/* ── Responsive ── */

/* Tablet ≤1024px: single column, hide visual */
@media (max-width: 1024px) {
  .themed .t-login-body {
    grid-template-columns: 1fr;
  }
  .themed .t-login-right {
    display: none;
  }
}

/* Mobile ≤640px: compact navbar, tighter padding */
@media (max-width: 640px) {
  .themed .t-login-nav {
    padding: 0 var(--space-4);
  }
  .themed .t-login-nav-links {
    display: none;
  }
  .themed .t-login-left {
    padding: var(--space-8) var(--space-4);
    align-items: flex-start;
  }
}


/* =============================================================================
   18. RESPONSIVE — MOBILE FIXES
   ============================================================================= */

/* Tablet breakpoint — 768px */
@media (max-width: 768px) {

  /* Disable hover lift on touch devices — tap doesn't need lift feedback */
  .themed .t-stat-card:hover,
  .themed .t-card-interactive:hover {
    transform: none;
  }

  /* Stats grid: tighten gap on tablet */
  .themed .t-stats-grid {
    gap: var(--space-3);
  }

  /* Page header: stack vertically */
  .themed .t-page-header {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-3);
  }

  /* Cards: reduce padding */
  .themed .t-card-header {
    padding: var(--space-4);
  }
  .themed .t-card-body {
    padding: var(--space-4);
  }
  .themed .t-card-footer {
    padding: var(--space-3) var(--space-4);
  }

  /* Modals: full-width on mobile */
  .themed .t-modal-panel {
    margin: var(--space-4);
    border-radius: var(--radius-lg);
  }
  .themed .t-modal-body {
    padding: var(--space-4);
  }
  .themed .t-modal-header,
  .themed .t-modal-footer {
    padding: var(--space-4);
  }

  /* Tables: force scroll wrapper */
  .themed .t-table-responsive {
    overflow-x: auto;
  }

  /* Metric tiles: tighter padding */
  .themed .t-metric-tile {
    padding: var(--space-3);
  }

  /* Buttons: allow wrapping */
  .themed .t-btn-group {
    flex-wrap: wrap;
  }

  /* Workshop cards: full width */
  .themed .t-workshop-grid {
    grid-template-columns: 1fr;
  }

  /* Conversation bubbles */
  .themed .t-msg-bubble {
    max-width: 90%;
  }
}

/* Mobile breakpoint — 480px */
@media (max-width: 480px) {

  /* Disable hover lift on mobile */
  .themed .t-stat-card:hover,
  .themed .t-card-interactive:hover {
    transform: none;
    box-shadow: var(--shadow-sm);
  }

  /* Stats grid: tighten gap on small mobile */
  .themed .t-stats-grid {
    gap: var(--space-2);
  }

  /* Stat tiles for attendance: 2 columns */
  .themed .t-attendance-counters {
    grid-template-columns: repeat(2, 1fr) !important;
  }

  /* Auth card: no horizontal padding */
  .themed .t-auth-card {
    border-radius: 0;
    border-left: none;
    border-right: none;
    padding: var(--space-6) var(--space-4);
    max-width: 100%;
  }

  /* Status buttons: smaller on narrow screens */
  .themed .t-status-btn {
    padding: var(--space-1) var(--space-2);
    font-size: var(--text-sm);
  }

  /* Metric tiles: compact on small screens */
  .themed .t-metric-tile {
    padding: var(--space-2);
  }
  .themed .t-metric-tile:hover {
    box-shadow: none;
  }

  /* Table: reduce cell padding */
  .themed .t-table th,
  .themed .t-table td {
    padding: var(--space-2);
    font-size: var(--text-sm);
  }

  /* Nav link text: slightly smaller */
  .themed .t-nav-link {
    font-size: var(--text-sm);
    padding: var(--space-1-5) var(--space-3);
  }

  /* Button groups: full-width stack */
  .themed .t-btn-group-mobile-stack {
    flex-direction: column;
    width: 100%;
  }
  .themed .t-btn-group-mobile-stack .t-btn {
    width: 100%;
    justify-content: center;
  }

  /* Page title: smaller */
  .themed .t-page-title {
    font-size: var(--text-2xl);
  }
}

/* Large screen — 1280px */
@media (min-width: 1280px) {

  /* Stats grid: restore standard gap on large screens */
  .themed .t-stats-grid {
    gap: var(--space-4);
  }
}

/* ============================================
   Hero / Gamification Banner
   ============================================ */
.themed .t-hero-banner {
  background: linear-gradient(to right, var(--color-primary-600), var(--color-primary-800));
  color: var(--color-text-inverse);
}

/* ============================================================
   TIMETABLE / EMPLOI DU TEMPS
   ============================================================
   Grid: 20 half-hour rows (08:00–18:00) × 6 day columns.
   Row and column positions are computed by TimetableService
   and applied via pre-generated CSS classes (.t-slot-row-N,
   .t-slot-col-N, .t-slot-span-N) — NO inline styles (R1).

   Grid coordinate system:
     Row 1  = 08:00   Row 11 = 13:00
     Row 2  = 08:30   Row 12 = 13:30
     Row 10 = 12:30   Row 20 = 17:30
     Col 1  = Lundi   Col 6  = Samedi
   ============================================================ */

/* Wrapper */
.themed .t-timetable-wrapper {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

/* CSS Grid definition */
.themed .t-timetable-grid {
  display: grid;
  grid-template-columns: 52px repeat(6, 1fr);
  /* Row 1 = day headers; rows 2–33 = thirty-two 15-min slot rows
     (08:00–16:00, 22 px each → 88 px per hour); trailing `auto`
     row hosts the bottom-boundary "16:00" hour label. 15-min
     granularity lets sessions starting at non-30-min boundaries
     (10:15, 14:15) land at their exact wall-clock position. The
     inline style on the parent `.t-timetable-grid` div repeats
     this layout — keep them in sync. */
  grid-template-rows: 52px repeat(32, 22px) auto;
  min-width: 640px;
  position: relative;
}

/* Time label column cells */
.themed .t-timetable-time-label {
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  padding: 2px 6px 0 0;
  font-size: 0.65rem;
  font-weight: 500;
  color: var(--color-text-muted);
  letter-spacing: 0.02em;
  background: var(--color-surface);
  border-right: 1px solid var(--color-border);
}

/* Day header cells */
.themed .t-timetable-day-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 6px 4px;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-text-secondary);
  background: var(--color-surface-alt);
  border-bottom: 2px solid var(--color-border);
  border-right: 1px solid var(--color-border-light);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.themed .t-timetable-day-header.is-today {
  background: var(--color-primary-50);
  color: var(--color-primary-700);
  border-bottom-color: var(--color-primary-400);
}

/* Empty background cells (even rows = alternate shading) */
.themed .t-timetable-cell {
  background: var(--color-surface);
  border-right: 1px solid var(--color-border-light);
  border-bottom: 1px dashed #f0f0f0;
}

.themed .t-timetable-cell:nth-child(even) {
  background: #fafafa;
}

/* Admin mode: clickable empty cells */
.themed .t-timetable-cell.is-clickable {
  cursor: pointer;
  transition: background 0.1s;
  position: relative;
}

.themed .t-timetable-cell.is-clickable:hover {
  background: var(--color-primary-50);
}

/* "+" add hint inside each empty cell (admin mode) */
.themed .t-cell-add-hint {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 300;
  color: #cbd5e1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.1s;
  user-select: none;
}

.themed .t-timetable-cell.is-clickable:hover .t-cell-add-hint {
  opacity: 1;
  color: var(--color-primary-400);
}

/* Today column highlight */
.themed .t-timetable-cell.is-today {
  background: rgba(239, 246, 255, 0.6);
}

/* ── Slot blocks ─────────────────────────────── */

.themed .t-slot-block {
  position: relative;
  margin: 2px;
  border-radius: 6px;
  padding: 4px 6px;
  overflow: hidden;
  font-size: 0.7rem;
  line-height: 1.3;
  cursor: pointer;
  transition: filter 0.15s, box-shadow 0.15s;
  border-left: 3px solid transparent;
  z-index: 1;
}

.themed .t-slot-block:hover {
  filter: brightness(0.95);
  box-shadow: 0 2px 8px rgba(0,0,0,0.12);
}

/* Status variants */
.themed .t-slot-none {
  background: #f8f9fa;
  border-left-color: #cbd5e1;
  color: #64748b;
  border: 1px dashed #cbd5e1;
  border-left: 3px dashed #94a3b8;
}

.themed .t-slot-draft {
  background: #fffbeb;
  border-left-color: #f59e0b;
  color: #92400e;
  border: 1px solid #fde68a;
}

.themed .t-slot-published {
  background: #f0fdf4;
  border-left-color: #22c55e;
  color: #14532d;
  border: 1px solid #bbf7d0;
}

.themed .t-slot-today {
  box-shadow: 0 0 0 2px var(--color-primary-200);
}

/* Slot subject label */
.themed .t-slot-subject {
  font-weight: 700;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Slot class label */
.themed .t-slot-class {
  font-size: 0.65rem;
  opacity: 0.8;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Slot time label */
.themed .t-slot-time {
  font-size: 0.6rem;
  opacity: 0.7;
  margin-top: 2px;
}

/* Admin action buttons inside slot */
.themed .t-slot-actions {
  display: flex;
  gap: 3px;
  margin-top: 3px;
  opacity: 0;
  transition: opacity 0.15s;
}

.themed .t-slot-block:hover .t-slot-actions {
  opacity: 1;
}

.themed .t-slot-action-btn {
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 3px;
  background: rgba(255,255,255,0.7);
  color: #475569;
  cursor: pointer;
  border: none;
  padding: 0;
}

.themed .t-slot-action-btn:hover {
  background: rgba(255,255,255,0.95);
  color: #1e293b;
}

/* ── Legend ─────────────────────────────────── */

.themed .t-timetable-legend {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  align-items: center;
}

.themed .t-legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.75rem;
  color: var(--color-text-secondary);
}

.themed .t-legend-dot {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  flex-shrink: 0;
}

/* ── Pre-generated grid row positions (08:00–15:30) ── */
/* Row 1 = 08:00, Row 2 = 08:30, ..., Row 16 = 15:30   */
/* grid-row offsets +1 because row 1 = day headers     */
/* NOTE: these classes are unused (the template applies grid-row */
/* via inline style). Kept for any future class-based refactor. */
/* Rows 17-20 are out-of-range after the 16:00 cutoff but the    */
/* CSS rules are harmless (they just point past the grid).       */

.themed .t-slot-row-1  { grid-row: 2; }
.themed .t-slot-row-2  { grid-row: 3; }
.themed .t-slot-row-3  { grid-row: 4; }
.themed .t-slot-row-4  { grid-row: 5; }
.themed .t-slot-row-5  { grid-row: 6; }
.themed .t-slot-row-6  { grid-row: 7; }
.themed .t-slot-row-7  { grid-row: 8; }
.themed .t-slot-row-8  { grid-row: 9; }
.themed .t-slot-row-9  { grid-row: 10; }
.themed .t-slot-row-10 { grid-row: 11; }
.themed .t-slot-row-11 { grid-row: 12; }
.themed .t-slot-row-12 { grid-row: 13; }
.themed .t-slot-row-13 { grid-row: 14; }
.themed .t-slot-row-14 { grid-row: 15; }
.themed .t-slot-row-15 { grid-row: 16; }
.themed .t-slot-row-16 { grid-row: 17; }
.themed .t-slot-row-17 { grid-row: 18; }
.themed .t-slot-row-18 { grid-row: 19; }
.themed .t-slot-row-19 { grid-row: 20; }
.themed .t-slot-row-20 { grid-row: 21; }

/* ── Row span classes (duration in 30-min increments) ── */
.themed .t-slot-span-1  { grid-row: span 1; }   /* 30 min  */
.themed .t-slot-span-2  { grid-row: span 2; }   /* 1 hour  */
.themed .t-slot-span-3  { grid-row: span 3; }   /* 1.5 h   */
.themed .t-slot-span-4  { grid-row: span 4; }   /* 2 hours */
.themed .t-slot-span-5  { grid-row: span 5; }   /* 2.5 h   */
.themed .t-slot-span-6  { grid-row: span 6; }   /* 3 hours */
.themed .t-slot-span-8  { grid-row: span 8; }   /* 4 hours */
.themed .t-slot-span-10 { grid-row: span 10; }  /* 5 hours */
.themed .t-slot-span-12 { grid-row: span 12; }  /* 6 hours */

/* ── Day column positions (1=Lundi .. 6=Samedi) ── */
/* +1 offset because column 1 = time labels         */
.themed .t-slot-col-1 { grid-column: 2; }  /* Lundi    */
.themed .t-slot-col-2 { grid-column: 3; }  /* Mardi    */
.themed .t-slot-col-3 { grid-column: 4; }  /* Mercredi */
.themed .t-slot-col-4 { grid-column: 5; }  /* Jeudi    */
.themed .t-slot-col-5 { grid-column: 6; }  /* Vendredi */
.themed .t-slot-col-6 { grid-column: 7; }  /* Samedi   */

/* ── Mobile: collapse grid to vertical day list ── */
@media (max-width: 768px) {
  .themed .t-timetable-grid {
    display: block;
    min-width: unset;
  }

  .themed .t-timetable-wrapper {
    overflow-x: unset;
  }

  .themed .t-slot-block {
    position: static !important;
    margin-bottom: 4px;
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .themed .t-timetable-day-header,
  .themed .t-timetable-time-label {
    display: none;
  }

  .themed .t-slot-actions {
    opacity: 1;
  }
}

@media (max-width: 480px) {
  .themed .t-timetable-wrapper {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  .themed .t-timetable-grid {
    display: grid;
    min-width: 500px;
  }
}

/* =====================================================================
 * EXPLAINER — Interactive Concept Explainer
 * ===================================================================== */

.themed .t-explainer-iframe {
  min-height: 400px;
  overflow: hidden;
  transition: height 0.3s ease;
}

@media (max-width: 768px) {
  .themed .t-explainer-iframe {
    border-radius: 4px;
  }
}

@media (max-width: 480px) {
  .themed .t-explainer-iframe {
    border-radius: 2px;
  }
}

/* =====================================================================
 * BILAN — Bulletin de Notes
 * ===================================================================== */

/* Subject grid table */
.themed .t-bilan-grid {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.themed .t-bilan-grid th {
  background-color: var(--color-surface-alt, #f1f5f9);
  color: var(--color-text-secondary, #64748b);
  font-weight: 600;
  text-align: left;
  padding: 0.625rem 0.75rem;
  border-bottom: 2px solid var(--color-border, #e2e8f0);
  white-space: nowrap;
}

.themed .t-bilan-grid td {
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--color-border, #e2e8f0);
  vertical-align: middle;
}

.themed .t-bilan-grid tr:last-child td {
  border-bottom: none;
}

.themed .t-bilan-grid tr:hover td {
  background-color: var(--color-surface-hover, #f8fafc);
}

/* Cell helpers */
.themed .t-bilan-cell-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono, ui-monospace, monospace);
}

.themed .t-bilan-cell-coeff {
  font-weight: 600;
  color: var(--color-primary, #1e40af);
}

/* Status badges */
.themed .t-bilan-status-draft {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.6rem;
  border-radius: 9999px;
  font-size: 0.75rem;
  font-weight: 600;
  background-color: #fef3c7;
  color: #92400e;
}

.themed .t-bilan-status-published {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.6rem;
  border-radius: 9999px;
  font-size: 0.75rem;
  font-weight: 600;
  background-color: #d1fae5;
  color: #065f46;
}

/* Mention badges */
.themed .t-bilan-mention-tb {
  background-color: #dbeafe;
  color: #1e3a8a;
  padding: 0.2rem 0.6rem;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 700;
}

.themed .t-bilan-mention-b {
  background-color: #e0e7ff;
  color: #3730a3;
  padding: 0.2rem 0.6rem;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 700;
}

.themed .t-bilan-mention-ab {
  background-color: #ede9fe;
  color: #5b21b6;
  padding: 0.2rem 0.6rem;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 700;
}

.themed .t-bilan-mention-passable {
  background-color: #d1fae5;
  color: #065f46;
  padding: 0.2rem 0.6rem;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 700;
}

.themed .t-bilan-mention-insuffisant {
  background-color: #fee2e2;
  color: #991b1b;
  padding: 0.2rem 0.6rem;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 700;
}

/* Subject row within a bilan detail view */
.themed .t-bilan-subject-row {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr 1fr 2fr;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 0.75rem;
  border-bottom: 1px solid var(--color-border, #e2e8f0);
}

.themed .t-bilan-subject-row:last-child {
  border-bottom: none;
}

/* Config command center: grade-level header rows */
.themed .t-bilan-level-header {
  background-color: var(--color-primary-light, #eff6ff);
  color: var(--color-primary, #1e40af);
  font-weight: 600;
  padding: 0.5rem 0.75rem;
  border-left: 3px solid var(--color-primary, #1e40af);
  font-size: 0.875rem;
}

@media (max-width: 768px) {
  .themed .t-bilan-subject-row {
    grid-template-columns: 1fr 1fr;
    gap: 0.375rem;
  }

  .themed .t-bilan-grid th,
  .themed .t-bilan-grid td {
    padding: 0.375rem 0.5rem;
  }
}

@media (max-width: 480px) {
  .themed .t-bilan-subject-row {
    grid-template-columns: 1fr;
  }
}

/* =============================================================================
   FEATURE REQUESTS — Suggestions & Améliorations
   Shared by: list.html, submit.html, my_requests.html,
              internal_list.html, internal_detail.html, _upvote_button.html
   ============================================================================= */

/* Muted badge variant (duplicate status, no-priority) */
.themed .t-badge-muted {
  background-color: #f3f4f6;
  color: #9ca3af;
  border: 1px solid #e5e7eb;
}

/* ---- Feature card (school-facing list) ---- */
.themed .t-feature-card {
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.themed .t-feature-card:hover {
  border-color: var(--color-primary-200, #bfdbfe);
  box-shadow: 0 2px 8px 0 rgba(59, 130, 246, 0.08);
}

.themed .t-feature-card-title {
  color: var(--color-text, #111827);
  line-height: 1.4;
}

.themed .t-feature-card-meta {
  color: var(--color-text-muted, #6b7280);
}

.themed .t-feature-card-preview {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---- Upvote button ---- */
.themed .t-upvote-btn {
  transition: background-color 0.15s ease, color 0.15s ease,
              border-color 0.15s ease, transform 0.1s ease;
  user-select: none;
}

.themed .t-upvote-btn:active:not(:disabled) {
  transform: scale(0.94);
}

.themed .t-upvote-btn-active {
  background-color: var(--color-primary, #2563eb);
  color: #ffffff;
  border-color: var(--color-primary, #2563eb);
}

.themed .t-upvote-btn-active:hover {
  background-color: var(--color-primary-dark, #1d4ed8);
  border-color: var(--color-primary-dark, #1d4ed8);
}

.themed .t-upvote-btn-own {
  opacity: 0.6;
  pointer-events: none;
}

/* ---- Filter bar (internal list) ---- */
.themed .t-fr-filter-bar {
  background-color: #ffffff;
  border: 1px solid var(--color-border, #e2e8f0);
  border-radius: var(--radius-lg, 0.5rem);
  padding: 1rem;
}

/* ---- Stat cards (internal list) ---- */
.themed .t-fr-stat-card {
  transition: box-shadow 0.15s ease;
}

.themed .t-fr-stat-card:hover {
  box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.07);
}

/* ---- Internal table ---- */
.themed .t-internal-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.themed .t-internal-table thead tr {
  background-color: #f9fafb;
}

.themed .t-internal-table thead th {
  padding: 0.75rem 1rem;
  text-align: left;
  font-size: 0.75rem;
  font-weight: 600;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}

.themed .t-internal-table tbody tr {
  border-bottom: 1px solid #f3f4f6;
  transition: background-color 0.1s ease;
}

.themed .t-internal-table tbody tr:hover {
  background-color: #f9fafb;
}

.themed .t-internal-table tbody td {
  padding: 0.875rem 1rem;
  vertical-align: middle;
}

/* ---- Mobile breakpoints ---- */
@media (max-width: 640px) {
  .themed .t-feature-card {
    padding: 1rem;
  }

  .themed .t-fr-filter-bar {
    padding: 0.75rem;
  }

  .themed .t-internal-table thead th,
  .themed .t-internal-table tbody td {
    padding: 0.625rem 0.75rem;
  }
}

/* ==========================================================================
 *  21.  Manual Schedule Editor
 * ========================================================================== */

/* Constraint feedback — cell background colors */
.themed .t-slot-blocked    { background-color: #DB1A1A; border: 2px solid #DB1A1A; cursor: not-allowed; }
.themed .t-slot-warning    { background-color: #FED7AA; border: 2px solid #EA580C; }
.themed .t-slot-neutral    { background-color: #BFDBFE; border: 2px solid #2563EB; }
.themed .t-slot-optimal    { background-color: #A7F3D0; border: 2px solid #059669; }
.themed .t-slot-forced     { background-color: #FECACA; border: 2px dashed #DC2626; cursor: pointer; }

/* Card deck */
.themed .t-editor-card          { cursor: grab; transition: all 0.15s; -webkit-user-select: none; user-select: none; -webkit-user-drag: element; }
.themed .t-editor-card:active   { cursor: grabbing; }
.themed .t-editor-card-selected { box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5); }
.themed .t-editor-card-placed   { opacity: 0.5; cursor: default; -webkit-user-select: none; user-select: none; }
.themed .t-slot-drop-target     { outline: 2px dashed #3B82F6; outline-offset: -2px; }

/* Constraint tooltip */
.themed .t-constraint-tooltip {
  position: absolute;
  z-index: 50;
  min-width: 220px;
  max-width: 300px;
  background: white;
  border: 1px solid #E5E7EB;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  padding: 8px 10px;
  pointer-events: none;
}

/* Active schedule editing warning banner */
.themed .t-active-edit-banner {
  background-color: #FFFBEB;
  border: 1px solid #FDE68A;
  color: #92400E;
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 0.8125rem;
  font-weight: 500;
}

/* Force mode warning banner.
   Phase 9.5: stronger visual emphasis (icon + flex layout + bold).
   Uses danger tokens for fail-safe legibility. */
.themed .t-force-banner {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background-color: var(--color-danger-bg, #FEF2F2);
  border: 1px solid var(--color-danger-border, #FECACA);
  border-left: 4px solid var(--color-danger-text, #991B1B);
  color: var(--color-danger-text, #991B1B);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  line-height: 1.4;
}
.themed .t-force-banner strong {
  font-weight: var(--font-weight-semibold);
}

/* ===================================================================
   TEACHER JOURNAL / SUIVI ÉLÈVES
   =================================================================== */

/* --- Student row in class view --- */
.themed .t-journal-student-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--color-border, #e2e8f0);
  transition: background-color 0.15s;
}
.themed .t-journal-student-row:last-child { border-bottom: none; }
.themed .t-journal-student-row:hover { background-color: var(--color-surface-hover, #f8fafc); }

/* --- Observation chips (inline badges) --- */
.themed .t-journal-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 9999px;
  font-size: 0.6875rem;
  font-weight: 500;
  line-height: 1.4;
  white-space: nowrap;
  cursor: default;
  transition: opacity 0.15s;
}
.themed .t-journal-chip:hover { opacity: 0.85; }
.themed .t-journal-chip-positive { background-color: #DCFCE7; color: #166534; }
.themed .t-journal-chip-neutral  { background-color: #F3F4F6; color: #374151; }
.themed .t-journal-chip-negative { background-color: #FEE2E2; color: #991B1B; }

/* Chip delete button — always visible on touch, hover-reveal on desktop */
.themed .t-journal-chip-delete {
  margin-left: 2px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s;
  font-size: 0.75rem;
  padding: 2px;
}
.themed .t-journal-chip:hover .t-journal-chip-delete { opacity: 0.7; }
.themed .t-journal-chip-delete:hover { opacity: 1; }
@media (hover: none) and (pointer: coarse) {
  .themed .t-journal-chip-delete { opacity: 0.6; }
}

/* --- Quick-add dropdown --- */
.themed .t-journal-quick-add {
  position: relative;
}
.themed .t-journal-type-menu {
  position: absolute;
  right: 0;
  top: 100%;
  z-index: 30;
  min-width: 200px;
  max-height: 300px;
  overflow-y: auto;
  background: white;
  border: 1px solid var(--color-border, #e2e8f0);
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  padding: 4px;
}
.themed .t-journal-type-menu-up {
  top: auto;
  bottom: 100%;
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.1);
}
.themed .t-journal-type-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.8125rem;
  transition: background-color 0.1s;
}
.themed .t-journal-type-item:hover { background-color: var(--color-surface-hover, #f1f5f9); }

/* --- Heatmap grid (GitHub-style) --- */
/* Use CSS custom properties for cell size so one change scales everything */
.themed .t-heatmap-wrapper {
  --hm-cell: 12px;
  --hm-gap: 2px;
  --hm-label-w: 28px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* Month label row — shares the same column sizing as the cell grid */
.themed .t-heatmap-month-row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc(var(--hm-cell) + var(--hm-gap));
  margin-left: calc(var(--hm-label-w) + 4px);
  margin-bottom: 2px;
  height: 16px;
  align-items: end;
}
.themed .t-heatmap-month-label {
  font-size: 0.65rem;
  color: var(--color-text-muted, #94a3b8);
  white-space: nowrap;
  line-height: 1;
}

/* Body: day labels + cell grid side by side */
.themed .t-heatmap-body {
  display: flex;
  align-items: start;
  gap: 4px;
}

.themed .t-journal-heatmap {
  display: inline-grid;
  grid-template-rows: repeat(7, var(--hm-cell));
  grid-auto-flow: column;
  grid-auto-columns: var(--hm-cell);
  gap: var(--hm-gap);
}
.themed .t-journal-heatmap-cell {
  width: var(--hm-cell);
  height: var(--hm-cell);
  border-radius: 2px;
  transition: transform 0.1s;
}
.themed .t-journal-heatmap-cell:hover {
  transform: scale(1.4);
  outline: 1px solid var(--color-border, #94a3b8);
}

/* Legend cells — fixed size, independent of heatmap cell size */
.themed .t-heatmap-legend-cell {
  width: 10px !important;
  height: 10px !important;
}

/* Legend row */
.themed .t-heatmap-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 16px;
  margin-top: 12px;
  font-size: 0.7rem;
  color: var(--color-text-muted, #6b7280);
}

/* Heatmap sentiment colors with intensity levels */
.themed .t-heatmap-empty    { background-color: #F1F5F9; }
.themed .t-heatmap-pos-low  { background-color: #BBF7D0; }
.themed .t-heatmap-pos-med  { background-color: #4ADE80; }
.themed .t-heatmap-pos-high { background-color: #16A34A; }
.themed .t-heatmap-neg-low  { background-color: #FECACA; }
.themed .t-heatmap-neg-med  { background-color: #F87171; }
.themed .t-heatmap-neg-high { background-color: #DC2626; }
.themed .t-heatmap-mix-low  { background-color: #E0E7FF; }
.themed .t-heatmap-mix-med  { background-color: #818CF8; }
.themed .t-heatmap-mix-high { background-color: #4F46E5; }

/* Heatmap day labels — rows match cell rows via same --hm-cell var */
.themed .t-journal-heatmap-labels {
  display: grid;
  grid-template-rows: repeat(7, var(--hm-cell));
  gap: var(--hm-gap);
  width: var(--hm-label-w);
  flex-shrink: 0;
  font-size: 0.6rem;
  color: var(--color-text-muted, #94a3b8);
}
.themed .t-journal-heatmap-label-cell {
  height: var(--hm-cell);
  line-height: var(--hm-cell);
  text-align: right;
  padding-right: 2px;
}

/* --- Timeline entry --- */
.themed .t-journal-timeline-entry {
  display: flex;
  gap: 12px;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--color-border-light, #f1f5f9);
}
.themed .t-journal-timeline-entry:last-child { border-bottom: none; }

.themed .t-journal-timeline-dot {
  flex-shrink: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-top: 4px;
}
.themed .t-journal-timeline-dot-positive { background-color: #22C55E; }
.themed .t-journal-timeline-dot-neutral  { background-color: #6B7280; }
.themed .t-journal-timeline-dot-negative { background-color: #EF4444; }

/* --- Stats card --- */
.themed .t-journal-stat-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 1rem;
  background-color: var(--color-surface, #ffffff);
  border: 1px solid var(--color-border, #e2e8f0);
  border-radius: 8px;
  text-align: center;
}
.themed .t-journal-stat-value {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--color-text, #1e293b);
}
.themed .t-journal-stat-label {
  font-size: 0.75rem;
  color: var(--color-text-muted, #94a3b8);
  margin-top: 2px;
}

/* --- Settings type list --- */
.themed .t-journal-type-row {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 12px;
  padding: 0.625rem 1rem;
  border-bottom: 1px solid var(--color-border, #e2e8f0);
}
.themed .t-journal-type-row:last-child { border-bottom: none; }

.themed .t-journal-type-swatch {
  width: 16px;
  height: 16px;
  border-radius: 4px;
  flex-shrink: 0;
}

/* --- Shared badge --- */
.themed .t-journal-shared-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 0.625rem;
  font-weight: 600;
  background-color: #DBEAFE;
  color: #1E40AF;
}

/* --- Class card for landing --- */
.themed .t-journal-class-card {
  display: flex;
  flex-direction: column;
  padding: 1rem 1.25rem;
  background-color: var(--color-surface, #ffffff);
  border: 1px solid var(--color-border, #e2e8f0);
  border-radius: 8px;
  transition: border-color 0.15s, box-shadow 0.15s;
  cursor: pointer;
  text-decoration: none;
  color: inherit;
}
.themed .t-journal-class-card:hover {
  border-color: var(--color-primary, #3b82f6);
  box-shadow: 0 2px 8px rgba(59, 130, 246, 0.12);
}

/* --- Sentiment summary bar --- */
.themed .t-journal-sentiment-bar {
  display: flex;
  height: 6px;
  border-radius: 3px;
  overflow: hidden;
  background-color: #F1F5F9;
}
.themed .t-journal-sentiment-bar-pos { background-color: #22C55E; }
.themed .t-journal-sentiment-bar-neg { background-color: #EF4444; }
.themed .t-journal-sentiment-bar-neu { background-color: #6B7280; }

/* --- Mobile breakpoints --- */
@media (max-width: 768px) {
  /* Student row: stack name/chips above quick-add button */
  .themed .t-journal-student-row {
    grid-template-columns: 1fr auto;
    gap: 6px;
    padding: 0.625rem 0.75rem;
  }

  /* Heatmap: smaller cells via custom properties — one change scales everything */
  .themed .t-heatmap-wrapper {
    --hm-cell: 10px;
    --hm-gap: 2px;
    --hm-label-w: 24px;
  }
  .themed .t-heatmap-month-label {
    font-size: 0.6rem;
  }

  /* Type list: tighter layout */
  .themed .t-journal-type-row {
    grid-template-columns: auto 1fr auto;
    gap: 8px;
    padding: 0.5rem 0.75rem;
  }

  /* Stats: smaller numbers */
  .themed .t-journal-stat-value {
    font-size: 1.25rem;
  }

  /* Dropdown: full-width on mobile */
  .themed .t-journal-type-menu {
    min-width: 180px;
  }

  /* Timeline: bigger touch targets for action buttons */
  .themed .t-journal-timeline-entry button,
  .themed .t-journal-timeline-entry a {
    min-width: 36px;
    min-height: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* Stat cards: tighter padding */
  .themed .t-journal-stat-card {
    padding: 0.625rem 0.5rem;
  }
}

@media (max-width: 480px) {
  /* Student row: full stack on very small screens */
  .themed .t-journal-student-row {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  /* Type row: hide swatch, simplify */
  .themed .t-journal-type-row {
    grid-template-columns: 1fr auto;
  }
  .themed .t-journal-type-row .t-journal-type-swatch {
    display: none;
  }

  /* Heatmap: smaller cells + tighter gap for narrow phones */
  .themed .t-heatmap-wrapper {
    --hm-cell: 9px;
    --hm-gap: 1.5px;
    --hm-label-w: 22px;
  }
  .themed .t-journal-heatmap-labels {
    font-size: 0.5rem;
  }
  .themed .t-heatmap-month-label {
    font-size: 0.55rem;
  }

  /* Timeline: even bigger touch targets */
  .themed .t-journal-timeline-entry button,
  .themed .t-journal-timeline-entry a {
    min-width: 40px;
    min-height: 40px;
  }

  /* Dropdown: near full-width for easy tapping */
  .themed .t-journal-type-menu {
    min-width: 220px;
    right: -0.5rem;
  }
  .themed .t-journal-type-item {
    padding: 10px 12px;
    font-size: 0.875rem;
  }

  /* Class card: tighter on narrow phones */
  .themed .t-journal-class-card {
    padding: 0.75rem 1rem;
  }
}

/* =============================================================================
   N. SCHEDULING — UNAVAILABILITY GRID (Phase 1)
   Visual click-to-block grid for declaring teacher unavailability
   ============================================================================= */

/* Outer wrapper */
.themed .t-unavail-card {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  overflow: hidden;
}

.themed .t-unavail-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: flex-end;
  padding: var(--space-5);
  border-bottom: 1px solid var(--color-border);
  background-color: var(--color-surface-muted);
}

/* Legend */
.themed .t-unavail-legend {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.themed .t-unavail-legend-swatch {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
}
.themed .t-unavail-legend-swatch-hard {
  background-color: var(--color-danger-bg);
  border-color: var(--color-danger-border);
}
.themed .t-unavail-legend-swatch-soft {
  background-color: var(--color-warning-bg);
  border-color: var(--color-warning-border);
}
.themed .t-unavail-legend-swatch-break {
  background-color: var(--color-surface-muted);
  border-color: var(--color-border);
}

/* Grid table */
.themed .t-unavail-grid {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
}

.themed .t-unavail-grid th,
.themed .t-unavail-grid td {
  padding: var(--space-2);
  border-right: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
  font-size: var(--text-sm);
  text-align: center;
  vertical-align: middle;
}

.themed .t-unavail-grid th:last-child,
.themed .t-unavail-grid td:last-child {
  border-right: 0;
}

.themed .t-unavail-grid thead th {
  background-color: var(--color-surface-muted);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
  position: sticky;
  top: 0;
  z-index: 1;
}

/* Time-label column (left) */
.themed .t-unavail-time-label {
  width: 120px;
  background-color: var(--color-surface-muted);
  color: var(--color-text-muted);
  font-weight: var(--font-weight-medium);
  font-size: var(--text-xs);
  text-align: right;
  padding-right: var(--space-3);
}

/* Cell base */
.themed .t-unavail-cell {
  cursor: pointer;
  user-select: none;
  background-color: var(--color-surface);
  color: var(--color-text-muted);
  transition: background-color var(--transition-fast),
              box-shadow var(--transition-fast);
  height: 44px;
  position: relative;
}

.themed .t-unavail-cell:hover {
  background-color: var(--color-surface-hover);
  box-shadow: inset 0 0 0 1px var(--color-border-strong);
}

.themed .t-unavail-cell:focus-visible {
  outline: 2px solid var(--color-border-focus);
  outline-offset: -2px;
}

/* Cell — empty / available state */
.themed .t-unavail-cell-empty {
  background-color: var(--color-surface);
}

/* Cell — hard block (Obligatoire) */
.themed .t-unavail-cell-hard {
  background-color: var(--color-danger-bg);
  color: var(--color-danger-text);
  font-weight: var(--font-weight-semibold);
}
.themed .t-unavail-cell-hard:hover {
  background-color: var(--color-danger-bg);
  box-shadow: inset 0 0 0 2px var(--color-danger-border);
}

/* Cell — soft preference */
.themed .t-unavail-cell-soft {
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
  font-weight: var(--font-weight-semibold);
}
.themed .t-unavail-cell-soft:hover {
  background-color: var(--color-warning-bg);
  box-shadow: inset 0 0 0 2px var(--color-warning-border);
}

/* Cell — break (greyed out, non-clickable) */
.themed .t-unavail-cell-break {
  background: repeating-linear-gradient(
    45deg,
    var(--color-surface-muted),
    var(--color-surface-muted) 6px,
    var(--color-border) 6px,
    var(--color-border) 7px
  );
  color: var(--color-text-subtle);
  cursor: not-allowed;
}
.themed .t-unavail-cell-break:hover {
  box-shadow: none;
}

/* Cell — period missing on this day */
.themed .t-unavail-cell-missing {
  background-color: var(--color-surface-muted);
  color: var(--color-text-subtle);
  cursor: not-allowed;
}
.themed .t-unavail-cell-missing:hover {
  box-shadow: none;
}

/* Day column when full-day blocked — dim cells */
.themed .t-unavail-day-locked .t-unavail-cell {
  opacity: 0.55;
  pointer-events: none;
}

/* Full-day toggle button (in column header) */
.themed .t-unavail-day-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  margin-top: var(--space-1);
  border-radius: var(--radius-md);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  background-color: var(--color-surface);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
  cursor: pointer;
  transition: background-color var(--transition-fast);
}
.themed .t-unavail-day-toggle:hover {
  background-color: var(--color-surface-hover);
  color: var(--color-text-base);
}
.themed .t-unavail-day-toggle-active {
  background-color: var(--color-danger-bg);
  color: var(--color-danger-text);
  border-color: var(--color-danger-border);
}
.themed .t-unavail-day-toggle-active:hover {
  background-color: var(--color-danger-bg);
}

/* Save bar (sticky bottom) */
.themed .t-unavail-savebar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  justify-content: flex-end;
  padding: var(--space-4) var(--space-5);
  background-color: var(--color-surface-muted);
  border-top: 1px solid var(--color-border);
}

.themed .t-unavail-savebar-status {
  margin-right: auto;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.themed .t-unavail-savebar-status-dirty {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-medium);
}
.themed .t-unavail-savebar-status-clean {
  color: var(--color-success-text);
  font-weight: var(--font-weight-medium);
}

/* Empty state when no teacher selected or no teachers exist */
.themed .t-unavail-empty {
  padding: var(--space-12) var(--space-5);
  text-align: center;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* Mobile: tablets */
@media (max-width: 768px) {
  .themed .t-unavail-toolbar {
    padding: var(--space-3);
  }
  .themed .t-unavail-grid th,
  .themed .t-unavail-grid td {
    padding: var(--space-1);
    font-size: var(--text-xs);
  }
  .themed .t-unavail-time-label {
    width: 80px;
    font-size: 0.65rem;
  }
  .themed .t-unavail-cell {
    height: 36px;
  }
  .themed .t-unavail-day-toggle {
    font-size: 0.65rem;
    padding: 2px 4px;
  }
  .themed .t-unavail-savebar {
    padding: var(--space-3);
  }
}

/* Mobile: phones */
@media (max-width: 480px) {
  .themed .t-unavail-toolbar {
    padding: var(--space-2);
    flex-direction: column;
    align-items: stretch;
  }
  .themed .t-unavail-time-label {
    width: 60px;
    padding: 2px 4px;
  }
  .themed .t-unavail-cell {
    height: 32px;
  }
  .themed .t-unavail-savebar {
    flex-direction: column;
    align-items: stretch;
  }
  .themed .t-unavail-savebar-status {
    margin-right: 0;
    margin-bottom: var(--space-2);
    text-align: center;
  }
}

/* =============================================================================
   N+1. SCHEDULING — CROSS-CONFIG AWARENESS (Phase 8)
   Read-only overlay on the unavailability grid + school-wide conflict report.
   Tokens only — no hard-coded colors.
   ============================================================================= */

/* Legend swatch — small hatched square matching the cell pattern */
.themed .t-unavail-legend-swatch-other-config {
  background: repeating-linear-gradient(
    45deg,
    var(--color-info-bg, #eff6ff),
    var(--color-info-bg, #eff6ff) 4px,
    var(--color-info-border, #bfdbfe) 4px,
    var(--color-info-border, #bfdbfe) 5px
  );
  border-color: var(--color-info-border, #bfdbfe);
}

/* Cell — busy in another config (read-only, hatched diagonal pattern) */
.themed .t-unavail-cell-other-config {
  background: repeating-linear-gradient(
    45deg,
    var(--color-info-bg, #eff6ff),
    var(--color-info-bg, #eff6ff) 6px,
    var(--color-info-border, #bfdbfe) 6px,
    var(--color-info-border, #bfdbfe) 7px
  );
  color: var(--color-info-text, #1e40af);
  cursor: not-allowed;
  font-size: var(--text-xs);
  line-height: 1.2;
  padding: var(--space-1) var(--space-2);
  font-weight: var(--font-weight-semibold);
}
.themed .t-unavail-cell-other-config:hover {
  box-shadow: none;
}
.themed .t-unavail-other-config-label {
  display: block;
  font-weight: var(--font-weight-semibold);
  color: var(--color-info-text, #1e40af);
}
.themed .t-unavail-other-config-class {
  display: block;
  font-size: 0.65rem;
  color: var(--color-text-subtle);
  font-weight: var(--font-weight-normal);
  margin-top: 1px;
}

/* Conflict report — summary card + table */
.themed .t-cross-config-summary {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
}

.themed .t-cross-config-empty {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
}

.themed .t-cross-config-table-wrapper {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  overflow: hidden;
}

.themed .t-cross-config-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
}

.themed .t-cross-config-table thead th {
  background-color: var(--color-surface-muted);
  border-bottom: 1px solid var(--color-border);
}

.themed .t-cross-config-table tbody tr {
  border-bottom: 1px solid var(--color-border);
}
.themed .t-cross-config-table tbody tr:last-child {
  border-bottom: 0;
}
.themed .t-cross-config-row:hover {
  background-color: var(--color-surface-hover);
}

.themed .t-cross-config-side {
  padding: var(--space-2) var(--space-3);
  border-left: 3px solid var(--color-danger-border);
  background-color: var(--color-surface-muted);
  border-radius: var(--radius-md);
}

@media (max-width: 768px) {
  .themed .t-unavail-cell-other-config {
    font-size: 0.6rem;
    padding: 2px;
  }
  .themed .t-unavail-other-config-class {
    display: none;
  }
  .themed .t-cross-config-table thead {
    display: none;
  }
  .themed .t-cross-config-table tbody tr {
    display: block;
    padding: var(--space-3);
    border-bottom: 1px solid var(--color-border);
  }
  .themed .t-cross-config-table tbody td {
    display: block;
    padding: var(--space-1) 0;
  }
}

/* =============================================================================
   N+1. SCHEDULING — UNIFIED WALL-CLOCK SCHEDULE VIEWS (Phase 9)
   Single source of truth: my-schedule + class-schedule + admin teacher view.
   All read from TimetableSlot. Wall-clock CSS Grid layout (reuses
   t-timetable-* base classes from M-Timetable). All colors via tokens.
   Inline grid-row/column allowed per CLAUDE_UI_LOCK R1 (runtime values).
   ============================================================================= */

/* Slot block — colored by subject (border-left + faded bg) */
.themed .t-sched-slot-block {
  position: relative;
  margin: 2px;
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-2);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  font-size: var(--text-xs);
  line-height: 1.2;
  border-radius: var(--radius-md);
  transition: box-shadow var(--transition-fast),
              transform var(--transition-fast);
  cursor: default;
}
.themed .t-sched-slot-block:hover {
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}

.themed .t-sched-slot-subject {
  font-weight: var(--font-weight-semibold);
  font-size: 0.75rem;
}
.themed .t-sched-slot-secondary {
  color: var(--color-text-muted);
  font-size: 0.7rem;
  margin-top: 1px;
}
.themed .t-sched-slot-time {
  color: var(--color-text-subtle);
  font-size: 0.65rem;
  margin-top: 2px;
}

/* Per-slot config pill — visible only when teacher is cross-level */
.themed .t-sched-slot-config-pill {
  position: absolute;
  top: 4px;
  right: 4px;
  font-size: 0.6rem;
  font-weight: var(--font-weight-semibold);
  padding: 1px 5px;
  border-radius: var(--radius-full);
  background-color: var(--color-surface);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
  white-space: nowrap;
  max-width: 80px;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Cross-level banner above the grid */
.themed .t-sched-cross-level-banner {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background-color: var(--color-info-bg, #eff6ff);
  color: var(--color-info-text, #1e40af);
  border: 1px solid var(--color-info-border, #bfdbfe);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
}

/* PDF action group (1 link per active config) */
.themed .t-sched-pdf-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}
.themed .t-sched-pdf-actions-label {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  font-weight: var(--font-weight-medium);
}

/* Empty state */
.themed .t-sched-empty-state {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: var(--space-12) var(--space-5);
  text-align: center;
}

/* Footnote */
.themed .t-sched-footnote {
  margin-top: var(--space-3);
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
  text-align: center;
}

/* Per-Schedule cross-config conflict warning pill (inside slot) —
   appears when both this config AND another config schedule the
   teacher in the same cell. Should never happen post-Phase 8 but
   surfaced for diagnosis if pre-existing data has it. */
.themed .t-sched-cross-conflict-pill {
  position: absolute;
  top: 2px;
  right: 2px;
  font-size: 0.7rem;
  color: var(--color-danger-text);
  background-color: var(--color-danger-bg);
  border: 1px solid var(--color-danger-border);
  border-radius: var(--radius-full);
  padding: 0 4px;
  font-weight: var(--font-weight-semibold);
  line-height: 1.2;
}

/* Empty cell with cross-config overlay — shown in schedule_detail
   teacher view when the teacher is busy in another config but this
   cell is free in this config. Matches Phase 8 unavailability grid
   overlay style for visual consistency. */
.themed .t-sched-other-config-cell {
  background: repeating-linear-gradient(
    45deg,
    var(--color-info-bg, #eff6ff),
    var(--color-info-bg, #eff6ff) 5px,
    var(--color-info-border, #bfdbfe) 5px,
    var(--color-info-border, #bfdbfe) 6px
  );
  color: var(--color-info-text, #1e40af);
  border-radius: var(--radius-md);
  padding: var(--space-1) var(--space-2);
  font-size: 0.7rem;
  line-height: 1.2;
  height: 48px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.themed .t-sched-other-config-label {
  font-weight: var(--font-weight-semibold);
  color: var(--color-info-text, #1e40af);
  font-size: 0.7rem;
}
.themed .t-sched-other-config-class {
  font-size: 0.6rem;
  color: var(--color-text-subtle);
  margin-top: 1px;
}

@media (max-width: 768px) {
  .themed .t-sched-slot-block {
    padding: 4px;
  }
  .themed .t-sched-slot-time {
    display: none;
  }
  .themed .t-sched-slot-config-pill {
    max-width: 50px;
    font-size: 0.55rem;
  }
  .themed .t-sched-pdf-actions {
    width: 100%;
  }
  .themed .t-sched-other-config-cell {
    height: 36px;
    padding: 2px 4px;
  }
  .themed .t-sched-other-config-class {
    display: none;
  }
}

@media (max-width: 480px) {
  .themed .t-sched-slot-secondary {
    font-size: 0.6rem;
  }
  .themed .t-sched-slot-config-pill {
    display: none;
  }
}

/* Phase 9.2 — Activation pending banner (admin schedule_detail) */
.themed .t-sched-pending-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background-color: var(--color-warning-bg, #fffbeb);
  border: 1px solid var(--color-warning-border, #fde68a);
  border-left-width: 4px;
  border-radius: var(--radius-xl);
}

.themed .t-sched-pending-banner-icon {
  flex-shrink: 0;
  color: var(--color-warning-text, #92400e);
  margin-top: 2px;
}

.themed .t-sched-pending-banner-body {
  flex: 1;
  min-width: 0;
}

.themed .t-sched-pending-banner-title {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-text, #92400e);
  margin: 0 0 var(--space-1) 0;
}

.themed .t-sched-pending-banner-text {
  font-size: var(--text-sm);
  color: var(--color-text-base);
  margin: 0;
  line-height: 1.5;
}

.themed .t-sched-pending-banner-text strong {
  font-weight: var(--font-weight-semibold);
}

.themed .t-sched-pending-banner-cta {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background-color: var(--color-success-text, #047857);
  color: #fff;
  border: 0;
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
  transition: background-color var(--transition-fast),
              transform var(--transition-fast);
  white-space: nowrap;
}

.themed .t-sched-pending-banner-cta:hover {
  background-color: var(--color-success-text-hover, #065f46);
  transform: translateY(-1px);
}

@media (max-width: 768px) {
  .themed .t-sched-pending-banner {
    flex-direction: column;
    align-items: stretch;
  }
  .themed .t-sched-pending-banner-cta {
    width: 100%;
    justify-content: center;
  }
}

/* =============================================================================
   Phase 9.5 — Schedule quality surfaces
   Closes audit PARTIALs 7.2 + 7.6 + 9.5: header stats strip,
   per-row comparison badges in the dashboard schedule list, and the
   unplaced-cours warning banner. All colors via tokens, mobile-safe.
   ============================================================================= */

/* Header stats strip (schedule_detail.html top) */
.themed .t-sched-header-stats {
  /* Layout-only — children carry their own colors */
  font-variant-numeric: tabular-nums;
}

.themed .t-sched-stat {
  display: inline-flex;
  align-items: center;
  font-weight: var(--font-weight-medium);
}

.themed .t-sched-stat-error {
  color: var(--color-danger-text);
  font-weight: var(--font-weight-semibold);
}

.themed .t-sched-stat-warning {
  color: var(--color-warning-text);
  font-weight: var(--font-weight-semibold);
}

.themed .t-sched-stat-soft {
  color: var(--color-warning-text);
}

.themed .t-sched-stat-ok {
  color: var(--color-success-text);
  font-weight: var(--font-weight-semibold);
}

/* Schedule list rows (dashboard.html) */
.themed .t-sched-list-row {
  /* hover taken from existing dashboard.html rules */
}

.themed .t-sched-list-badge {
  display: inline-flex;
  align-items: center;
  padding: 1px 6px;
  border-radius: var(--radius-full);
  font-size: 0.65rem;
  font-weight: var(--font-weight-semibold);
  margin-left: var(--space-1);
}

.themed .t-sched-list-badge-ok {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
}

.themed .t-sched-list-badge-incomplete {
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
}

/* Comparison badge: ↓ better / ↑ worse / = same */
.themed .t-sched-list-cmp {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px 8px;
  border-radius: var(--radius-full);
  font-size: 0.7rem;
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}

.themed .t-sched-list-cmp-better {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
}

.themed .t-sched-list-cmp-worse {
  background-color: var(--color-danger-bg);
  color: var(--color-danger-text);
}

.themed .t-sched-list-cmp-same {
  background-color: var(--color-surface-muted);
  color: var(--color-text-muted);
}

/* Unplaced-cours warning banner (schedule_detail.html top) */
.themed .t-sched-unplaced-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background-color: var(--color-warning-bg, #fffbeb);
  border: 1px solid var(--color-warning-border, #fde68a);
  border-left-width: 4px;
  border-radius: var(--radius-xl);
}

.themed .t-sched-unplaced-banner-icon {
  flex-shrink: 0;
  color: var(--color-warning-text, #92400e);
  margin-top: 2px;
}

.themed .t-sched-unplaced-banner-body {
  flex: 1;
  min-width: 0;
}

.themed .t-sched-unplaced-banner-title {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-warning-text, #92400e);
  margin: 0 0 var(--space-1) 0;
}

.themed .t-sched-unplaced-banner-text {
  font-size: var(--text-sm);
  color: var(--color-text-base);
  margin: 0;
  line-height: 1.5;
}

@media (max-width: 768px) {
  .themed .t-sched-list-row {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-2);
  }
  .themed .t-sched-list-cmp {
    align-self: flex-start;
  }
  .themed .t-sched-unplaced-banner {
    flex-direction: column;
  }
}

/* =============================================================================
   N+1. SCHEDULING — BELL PRESETS + CLONE DAY (Phase 2)
   Preset selector card, clone-day controls, per-day slot count badges
   ============================================================================= */

/* Preset selector card (top of config_periods page) */
.themed .t-bell-preset-card {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: var(--space-5);
  margin-bottom: var(--space-6);
}

.themed .t-bell-preset-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-3);
}

.themed .t-bell-preset-option {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background-color: var(--color-surface);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--transition-fast),
              box-shadow var(--transition-fast),
              background-color var(--transition-fast);
  width: 100%;
}
.themed .t-bell-preset-option:hover {
  border-color: var(--color-primary-300);
  background-color: var(--color-surface-hover);
  box-shadow: var(--shadow-sm);
}
.themed .t-bell-preset-option:focus-visible {
  outline: 2px solid var(--color-border-focus);
  outline-offset: 2px;
}
.themed .t-bell-preset-option:disabled,
.themed .t-bell-preset-option[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
  background-color: var(--color-surface-muted);
}

.themed .t-bell-preset-name {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
}

.themed .t-bell-preset-description {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  line-height: 1.4;
}

.themed .t-bell-preset-meta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  align-self: flex-start;
  padding: 2px 8px;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  border-radius: var(--radius-full);
  background-color: var(--color-primary-50);
  color: var(--color-primary-700);
}

/* Day-level slot count badge (next to day name in header) */
.themed .t-bell-day-count {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  border-radius: var(--radius-full);
  background-color: var(--color-surface-muted);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
}
.themed .t-bell-day-count-active {
  background-color: var(--color-primary-50);
  color: var(--color-primary-700);
  border-color: var(--color-primary-200, var(--color-border));
}

/* Week total tile (top right of preset card) */
.themed .t-bell-week-total {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
  border: 1px solid var(--color-success-border);
  border-radius: var(--radius-md);
  font-weight: var(--font-weight-semibold);
}
.themed .t-bell-week-total-value {
  font-size: var(--text-lg);
  line-height: 1;
}
.themed .t-bell-week-total-label {
  font-size: var(--text-xs);
  font-weight: var(--font-weight-normal);
}

/* Clone-day dropdown (Alpine-driven) */
.themed .t-clone-day-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 4px 10px;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  background-color: var(--color-surface);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background-color var(--transition-fast);
}
.themed .t-clone-day-trigger:hover {
  background-color: var(--color-surface-hover);
  color: var(--color-text-base);
}
.themed .t-clone-day-trigger:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.themed .t-clone-day-popover {
  position: absolute;
  z-index: 30;
  margin-top: var(--space-1);
  min-width: 240px;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-3);
}

.themed .t-clone-day-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 4px 6px;
  border-radius: var(--radius-sm);
}
.themed .t-clone-day-row:hover {
  background-color: var(--color-surface-hover);
}
.themed .t-clone-day-row label {
  cursor: pointer;
  flex-grow: 1;
  font-size: var(--text-sm);
}

.themed .t-clone-day-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-border);
}

/* Inline notice banner shown when destructive ops are blocked */
.themed .t-bell-blocked-notice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
  border: 1px solid var(--color-warning-border);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
}

/* Mobile: tablets */
@media (max-width: 768px) {
  .themed .t-bell-preset-card {
    padding: var(--space-3);
  }
  .themed .t-bell-preset-grid {
    grid-template-columns: 1fr;
    gap: var(--space-2);
  }
  .themed .t-bell-preset-option {
    padding: var(--space-3);
  }
  .themed .t-clone-day-popover {
    min-width: 200px;
  }
}

/* Mobile: phones */
@media (max-width: 480px) {
  .themed .t-bell-week-total {
    padding: var(--space-1) var(--space-2);
  }
  .themed .t-bell-week-total-value {
    font-size: var(--text-base);
  }
  .themed .t-clone-day-trigger {
    padding: 3px 8px;
  }
  .themed .t-clone-day-popover {
    min-width: 180px;
    right: 0;
    left: auto;
  }
}

/* =============================================================================
   N+2. SCHEDULING — DASHBOARD STEP STATUS + READINESS PANEL (Phase 3)
   Per-step indicators on the 5-step config checklist + readiness summary
   ============================================================================= */

/* Step row container (replaces hand-rolled Tailwind in dashboard.html) */
.themed .t-step-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-5);
  transition: background-color var(--transition-fast);
}
.themed .t-step-row:hover {
  background-color: var(--color-surface-hover);
}

.themed .t-step-row-content {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-width: 0;
}

.themed .t-step-text {
  min-width: 0;
}

.themed .t-step-label {
  font-weight: var(--font-weight-medium);
  color: var(--color-text-base);
}

.themed .t-step-description {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin-top: 2px;
}

.themed .t-step-detail {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 6px;
  padding: 2px 8px;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  border-radius: var(--radius-full);
  background-color: var(--color-surface-muted);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
}

/* Step status indicator (left circle) */
.themed .t-step-indicator {
  width: 32px;
  height: 32px;
  border-radius: 9999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  flex-shrink: 0;
}

.themed .t-step-indicator-done {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
  border: 1px solid var(--color-success-border);
}
.themed .t-step-indicator-incomplete {
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
  border: 1px solid var(--color-warning-border);
}
.themed .t-step-indicator-optional {
  background-color: var(--color-info-bg);
  color: var(--color-info-text);
  border: 1px solid var(--color-info-border);
}

/* Detail badge variants */
.themed .t-step-detail-done {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
  border-color: var(--color-success-border);
}
.themed .t-step-detail-incomplete {
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
  border-color: var(--color-warning-border);
}
.themed .t-step-detail-optional {
  background-color: var(--color-info-bg);
  color: var(--color-info-text);
  border-color: var(--color-info-border);
}

/* Chevron at right of each row */
.themed .t-step-chevron {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  color: var(--color-text-subtle);
}

/* ----- Readiness panel (above the Generate button) ----- */
.themed .t-readiness {
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-lg);
  border: 1px solid;
  margin-bottom: var(--space-4);
}

.themed .t-readiness-ready {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
  border-color: var(--color-success-border);
}
.themed .t-readiness-warning {
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
  border-color: var(--color-warning-border);
}
.themed .t-readiness-error {
  background-color: var(--color-danger-bg);
  color: var(--color-danger-text);
  border-color: var(--color-danger-border);
}

.themed .t-readiness-header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--font-weight-semibold);
  font-size: var(--text-sm);
}

.themed .t-readiness-list {
  margin-top: var(--space-3);
  padding-left: var(--space-5);
  font-size: var(--text-sm);
}

.themed .t-readiness-list li {
  margin-top: var(--space-1);
  list-style: disc;
}

.themed .t-readiness-fix-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: var(--space-2);
  padding: 2px 8px;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
  color: var(--color-text-base);
  border: 1px solid var(--color-border);
  transition: background-color var(--transition-fast);
}
.themed .t-readiness-fix-link:hover {
  background-color: var(--color-surface-hover);
  text-decoration: none;
}

/* Mobile breakpoints */
@media (max-width: 768px) {
  .themed .t-step-row {
    padding: var(--space-3);
  }
  .themed .t-step-indicator {
    width: 28px;
    height: 28px;
    font-size: var(--text-xs);
  }
  .themed .t-readiness {
    padding: var(--space-3);
  }
  .themed .t-readiness-list {
    padding-left: var(--space-4);
  }
}

@media (max-width: 480px) {
  .themed .t-step-row {
    padding: var(--space-2) var(--space-3);
  }
  .themed .t-step-row-content {
    gap: var(--space-2);
  }
  .themed .t-step-indicator {
    width: 24px;
    height: 24px;
  }
  .themed .t-step-detail {
    font-size: 0.65rem;
    padding: 2px 6px;
  }
  .themed .t-readiness-fix-link {
    display: block;
    margin-left: 0;
    margin-top: 4px;
  }
}

/* =============================================================================
   N+2.5 SCHEDULING — FIRST-RUN BANNER + STEP QUICK ACTIONS (Phase 9.3)
   Closes audit PARTIAL 1.1 + 1.2: tells first-time planners exactly
   where to click + offers one-click sync from inside the step row.
   ============================================================================= */

/* Welcome banner shown only when this config has zero requirements
   AND the school has never generated a schedule for the year. */
.themed .t-first-run-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background-color: var(--color-info-bg, #eff6ff);
  border: 1px solid var(--color-info-border, #bfdbfe);
  border-left-width: 4px;
  border-radius: var(--radius-xl);
}

.themed .t-first-run-banner-icon {
  flex-shrink: 0;
  color: var(--color-info-text, #1e40af);
  margin-top: 2px;
}

.themed .t-first-run-banner-body {
  flex: 1;
  min-width: 0;
}

.themed .t-first-run-banner-title {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-info-text, #1e40af);
  margin: 0 0 var(--space-1) 0;
}

.themed .t-first-run-banner-text {
  font-size: var(--text-sm);
  color: var(--color-text-base);
  margin: 0;
  line-height: 1.5;
}

.themed .t-first-run-banner-text strong {
  font-weight: var(--font-weight-semibold);
}

/* Step row split — link area (flex-1) + sibling action form */
.themed .t-step-row-link {
  text-decoration: none;
  color: inherit;
}

.themed .t-step-row-action {
  flex-shrink: 0;
  border-left: 1px solid var(--color-border);
}

.themed .t-step-quick-action-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  background-color: var(--color-primary, #2563eb);
  color: #fff;
  border: 0;
  border-radius: var(--radius-md);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--transition-fast);
}

.themed .t-step-quick-action-btn:hover {
  background-color: var(--color-primary-hover, #1d4ed8);
}

@media (max-width: 768px) {
  .themed .t-first-run-banner {
    padding: var(--space-3);
  }
  .themed .t-step-row {
    flex-direction: column;
    align-items: stretch;
  }
  .themed .t-step-row-action {
    border-left: 0;
    border-top: 1px solid var(--color-border);
    padding: var(--space-2) var(--space-5) var(--space-3);
    justify-content: flex-end;
  }
  .themed .t-step-quick-action-btn {
    width: 100%;
    justify-content: center;
  }
}

/* =============================================================================
   N+3. SCHEDULING — HOURS CONFIG PROGRESS BAR (Phase 4)
   Visual balance indicator on the per-grade-level hours configuration card
   ============================================================================= */

/* Outer flex container holding the bar + the count label */
.themed .t-hours-progress {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 200px;
}

/* The track (background) */
.themed .t-hours-progress-track {
  position: relative;
  flex: 1 1 auto;
  height: 8px;
  background-color: var(--color-surface-muted);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  overflow: hidden;
  min-width: 100px;
}

/* The fill — width is set via inline style="width: {percent}%"
   (only inline style usage; matches the existing pattern in
   schedule_detail.html slot cells for runtime numeric values).
   Color comes from the variant class below. */
.themed .t-hours-progress-fill {
  position: absolute;
  inset-inline-start: 0;
  top: 0;
  bottom: 0;
  border-radius: var(--radius-full);
  transition: width 200ms ease, background-color 200ms ease;
}

.themed .t-hours-progress-fill-balanced {
  background-color: var(--color-success-text);
}
.themed .t-hours-progress-fill-partial {
  background-color: var(--color-warning-text);
}
.themed .t-hours-progress-fill-overflow {
  background-color: var(--color-danger-text);
}

/* Count label ("12 / 35" or "Équilibré · 35") */
.themed .t-hours-progress-label {
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.themed .t-hours-progress-label-balanced {
  color: var(--color-success-text);
}
.themed .t-hours-progress-label-partial {
  color: var(--color-warning-text);
}
.themed .t-hours-progress-label-overflow {
  color: var(--color-danger-text);
}

/* Mobile: tablets */
@media (max-width: 768px) {
  .themed .t-hours-progress {
    min-width: 140px;
  }
  .themed .t-hours-progress-track {
    min-width: 60px;
    height: 6px;
  }
}

/* Mobile: phones */
@media (max-width: 480px) {
  .themed .t-hours-progress {
    min-width: 0;
    width: 100%;
  }
  .themed .t-hours-progress-label {
    font-size: 0.65rem;
  }
}

/* =============================================================================
   N+4. SCHEDULING — SHARE PAGE (Phase 5)
   Per-teacher rows with PDF + WhatsApp actions on the schedule share page
   ============================================================================= */

/* Outer card */
.themed .t-share-card {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  overflow: hidden;
  margin-bottom: var(--space-6);
}

/* Top action bar — master PDF + batch ZIP buttons */
.themed .t-share-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  background-color: var(--color-surface-muted);
  border-bottom: 1px solid var(--color-border);
}

/* Stats summary (e.g. "12 enseignants — 10 avec téléphone") */
.themed .t-share-stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  margin-right: auto;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.themed .t-share-stat-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 10px;
  border-radius: var(--radius-full);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  font-weight: var(--font-weight-medium);
  font-size: var(--text-xs);
}

/* Teacher list */
.themed .t-share-list {
  display: flex;
  flex-direction: column;
  divide-y: 1px solid var(--color-border);
}

.themed .t-share-row {
  display: grid;
  grid-template-columns: 40px 1fr auto;
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  transition: background-color var(--transition-fast);
}
.themed .t-share-row:last-child {
  border-bottom: 0;
}
.themed .t-share-row:hover {
  background-color: var(--color-surface-hover);
}

.themed .t-share-row-avatar {
  width: 40px;
  height: 40px;
  border-radius: 9999px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: var(--font-weight-semibold);
  font-size: var(--text-sm);
  background-color: var(--color-primary-100, var(--color-surface-muted));
  color: var(--color-primary-700, var(--color-text-base));
  flex-shrink: 0;
}

.themed .t-share-row-info {
  min-width: 0;
}

.themed .t-share-row-name {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
  margin-bottom: 2px;
}

.themed .t-share-row-meta {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.themed .t-share-row-actions {
  display: flex;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* WhatsApp button — green (intentionally close to the WhatsApp brand
   color but using the success token so it stays themeable). */
.themed .t-share-whatsapp-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: var(--space-2) var(--space-3);
  background-color: var(--color-success-text);
  color: var(--color-text-inverse, #fff);
  border: 1px solid var(--color-success-border);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
  transition: filter var(--transition-fast);
}
.themed .t-share-whatsapp-btn:hover {
  filter: brightness(0.92);
  text-decoration: none;
}
.themed .t-share-whatsapp-btn-disabled {
  background-color: var(--color-surface-muted);
  color: var(--color-text-subtle);
  border-color: var(--color-border);
  cursor: not-allowed;
}
.themed .t-share-whatsapp-btn-disabled:hover {
  filter: none;
}

/* No-phone warning badge inside the row meta */
.themed .t-share-no-phone {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--radius-full);
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
  border: 1px solid var(--color-warning-border);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
}

/* Empty state when no teachers have slots */
.themed .t-share-empty {
  padding: var(--space-12);
  text-align: center;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* Mobile: tablets */
@media (max-width: 768px) {
  .themed .t-share-actions {
    padding: var(--space-3);
    flex-direction: column;
    align-items: stretch;
  }
  .themed .t-share-stats {
    margin-right: 0;
    margin-bottom: var(--space-2);
  }
  .themed .t-share-row {
    padding: var(--space-3);
    gap: var(--space-3);
  }
}

/* Mobile: phones */
@media (max-width: 480px) {
  .themed .t-share-row {
    grid-template-columns: 1fr;
  }
  .themed .t-share-row-avatar {
    width: 32px;
    height: 32px;
    font-size: var(--text-xs);
  }
  .themed .t-share-row-actions {
    width: 100%;
    flex-direction: column;
  }
  .themed .t-share-whatsapp-btn {
    justify-content: center;
  }
}

/* =============================================================================
   N+3. SCHEDULING — ACTIVATION HISTORY (Phase 9.6)
   Closes audit FAILs 12.3 + 12.5: per-config activation history page +
   bookmarkable date lookup. All colors via tokens. Mobile breakpoint at 768px
   reflows the table to a card-stack layout for thumb-friendly scrolling.
   ============================================================================= */

/* Date lookup card — sits above the history table */
.themed .t-history-lookup-card {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  box-shadow: var(--shadow-sm);
}

.themed .t-history-lookup-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.themed .t-history-lookup-label {
  font-size: var(--text-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-base);
}

.themed .t-history-lookup-input {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  color: var(--color-text-base);
  background-color: var(--color-surface);
  font-variant-numeric: tabular-nums;
}

.themed .t-history-lookup-input:focus {
  outline: none;
  border-color: var(--color-border-focus);
  box-shadow: 0 0 0 3px rgb(37 99 235 / 0.15);
}

.themed .t-history-lookup-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background-color: var(--color-info-text);
  color: var(--color-text-inverse);
  border: none;
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
  transition: background-color 120ms ease;
}

.themed .t-history-lookup-btn:hover {
  background-color: var(--color-text-link-hover);
}

.themed .t-history-lookup-clear {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  text-decoration: underline;
  margin-left: var(--space-2);
}

.themed .t-history-lookup-clear:hover {
  color: var(--color-text-base);
}

/* Lookup result message — three semantic variants */
.themed .t-history-lookup-result {
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  line-height: 1.5;
}

.themed .t-history-lookup-result-found {
  background-color: var(--color-info-bg);
  color: var(--color-info-text);
  border: 1px solid var(--color-info-border);
}

.themed .t-history-lookup-result-empty {
  background-color: var(--color-surface-muted);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
}

.themed .t-history-lookup-result-error {
  background-color: var(--color-danger-bg);
  color: var(--color-danger-text);
  border: 1px solid var(--color-danger-border);
}

.themed .t-history-lookup-link {
  color: inherit;
  font-weight: var(--font-weight-semibold);
  text-decoration: underline;
}

.themed .t-history-lookup-link:hover {
  text-decoration: none;
}

/* Empty state when no activations exist */
.themed .t-history-empty {
  text-align: center;
  padding: var(--space-10) var(--space-5);
  background-color: var(--color-surface);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
}

/* History table */
.themed .t-history-table-wrapper {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}

.themed .t-history-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-base);
}

.themed .t-history-table thead th {
  text-align: left;
  padding: var(--space-3) var(--space-4);
  background-color: var(--color-surface-muted);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--color-border);
}

.themed .t-history-table tbody tr {
  border-top: 1px solid var(--color-border);
  transition: background-color 80ms ease;
}

.themed .t-history-table tbody tr:first-child {
  border-top: none;
}

.themed .t-history-row:hover {
  background-color: var(--color-surface-hover);
}

.themed .t-history-row td {
  padding: var(--space-3) var(--space-4);
  vertical-align: top;
  color: var(--color-text-base);
}

/* Highlighted row — when the date lookup matches an activation window */
.themed .t-history-row-highlight {
  background-color: var(--color-warning-bg);
}

.themed .t-history-row-highlight:hover {
  background-color: var(--color-warning-bg);
}

.themed .t-history-row-highlight td {
  border-left: 3px solid var(--color-warning-icon);
}

.themed .t-history-row-highlight td:first-child {
  font-weight: var(--font-weight-semibold);
}

/* Period column — "du DD/MM/YYYY HH:MM" / "au DD/MM/YYYY HH:MM" */
.themed .t-history-period {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.themed .t-history-from {
  color: var(--color-text-base);
  font-weight: var(--font-weight-medium);
}

.themed .t-history-to {
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  margin-top: var(--space-0-5);
}

.themed .t-history-active-now {
  color: var(--color-success-text);
  font-weight: var(--font-weight-semibold);
}

/* Schedule link in the planning column */
.themed .t-history-schedule-link {
  color: var(--color-text-link);
  font-weight: var(--font-weight-medium);
  font-variant-numeric: tabular-nums;
}

.themed .t-history-schedule-link:hover {
  color: var(--color-text-link-hover);
  text-decoration: underline;
}

.themed .t-history-note {
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  font-style: italic;
}

.themed .t-history-actor {
  color: var(--color-text-base);
}

/* Status badges — Actif vs Archivé */
.themed .t-history-status-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  border-radius: var(--radius-full);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}

.themed .t-history-status-active {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
  border: 1px solid var(--color-success-border);
}

.themed .t-history-status-archived {
  background-color: var(--color-surface-muted);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
}

/* Mobile reflow — stack table rows as cards for narrow screens */
@media (max-width: 768px) {
  .themed .t-history-lookup-form {
    flex-direction: column;
    align-items: stretch;
  }
  .themed .t-history-lookup-input,
  .themed .t-history-lookup-btn {
    width: 100%;
    justify-content: center;
  }
  .themed .t-history-table thead {
    display: none;
  }
  .themed .t-history-table tbody tr {
    display: block;
    padding: var(--space-3);
    border-top: 1px solid var(--color-border);
  }
  .themed .t-history-row td {
    display: flex;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-1-5) 0;
    border: none;
  }
  .themed .t-history-row td::before {
    content: attr(data-label);
    color: var(--color-text-muted);
    font-weight: var(--font-weight-semibold);
    font-size: var(--text-sm);
  }
  .themed .t-history-row-highlight td {
    border-left: none;
  }
  .themed .t-history-row-highlight {
    border-left: 3px solid var(--color-warning-icon);
    padding-left: calc(var(--space-3) - 3px);
  }
}

/* =============================================================================
   N+4. SCHEDULING — ACTIVATION ERROR BANNER (Phase 9.7)
   Closes audit FAIL 14.5: surfaces background activation failures
   visibly on schedule_detail.html when the Celery task wrote an
   error to `Schedule.activation_error`. Danger palette (4px left
   border) so it dominates the page and the planner cannot miss it.
   ============================================================================= */

.themed .t-sched-activation-error-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background-color: var(--color-danger-bg);
  border: 1px solid var(--color-danger-border);
  border-left-width: 4px;
  border-radius: var(--radius-xl);
}

.themed .t-sched-activation-error-banner-icon {
  flex-shrink: 0;
  color: var(--color-danger-icon);
  margin-top: 2px;
}

.themed .t-sched-activation-error-banner-body {
  flex: 1;
  min-width: 0;
}

.themed .t-sched-activation-error-banner-title {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger-text);
  margin: 0 0 var(--space-1) 0;
}

.themed .t-sched-activation-error-banner-text {
  font-size: var(--text-sm);
  color: var(--color-danger-text);
  margin: 0 0 var(--space-2) 0;
  line-height: 1.5;
  /* Activation errors are often raw exception messages — preserve
     newlines for readability and break long lines instead of
     overflowing the banner. */
  white-space: pre-wrap;
  word-break: break-word;
}

.themed .t-sched-activation-error-banner-hint {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin: 0;
  line-height: 1.5;
}

@media (max-width: 768px) {
  .themed .t-sched-activation-error-banner {
    flex-direction: column;
  }
  .themed .t-sched-activation-error-banner-icon {
    margin-top: 0;
  }
}


/* =============================================================================
   SCHEDULING — SOLVER DIAGNOSIS BANNER (Phase 11 post-pilot UX)
   Closes the pilot UX gap: an OR-Tools INFEASIBLE result historically
   produced a `Schedule(status='draft', slots=0)` with no visible reason
   why. The solver's diagnosis JSON now renders as a prominent danger
   banner with per-conflict French message + actionable CTA (e.g.
   "Créer une session commune" for teacher_overload). Scoped to `.themed`,
   token-only colors, mobile reflow at ≤768px.
   ============================================================================= */

.themed .t-sched-diagnosis-banner {
  padding: var(--space-4) var(--space-5);
  background-color: var(--color-danger-bg);
  border: 1px solid var(--color-danger-border);
  border-left-width: 4px;
  border-radius: var(--radius-xl);
}

.themed .t-sched-diagnosis-banner-header {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  margin-bottom: var(--space-3);
}

.themed .t-sched-diagnosis-banner-icon {
  flex-shrink: 0;
  color: var(--color-danger-icon);
  margin-top: 2px;
}

.themed .t-sched-diagnosis-banner-title {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger-text);
  margin: 0 0 var(--space-1) 0;
}

.themed .t-sched-diagnosis-banner-subtitle {
  font-size: var(--text-sm);
  color: var(--color-danger-text);
  margin: 0;
  line-height: 1.5;
}

.themed .t-sched-diagnosis-banner-list {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-3) 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.themed .t-sched-diagnosis-banner-item {
  background-color: var(--color-surface);
  border: 1px solid var(--color-danger-border);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.themed .t-sched-diagnosis-banner-item-message {
  font-size: var(--text-sm);
  color: var(--color-text);
  line-height: 1.5;
  /* Diagnosis messages can be long and contain numbers/colons —
     wrap normally but break very long words to avoid overflow. */
  word-break: break-word;
}

.themed .t-sched-diagnosis-banner-item-cta {
  align-self: flex-start;
}

.themed .t-sched-diagnosis-banner-hint {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  line-height: 1.5;
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-danger-border);
}

@media (max-width: 768px) {
  .themed .t-sched-diagnosis-banner-header {
    flex-direction: column;
  }
  .themed .t-sched-diagnosis-banner-icon {
    margin-top: 0;
  }
}


/* =============================================================================
   N+5. SCHEDULING — ASYNC MASTER PDF (Phase 9.8)
   Closes audit FAIL 14.3: synchronous WeasyPrint of 30+ pages risked
   request timeouts at 40+ classes. Three card variants for the polling
   page: preparing (info), ready (success), failed (danger). All scoped
   to `.themed`, all colors via tokens, mobile reflow at ≤768px.
   ============================================================================= */

/* Shared shell — all three variants extend this layout */
.themed .t-pdf-preparing-card,
.themed .t-pdf-ready-card,
.themed .t-pdf-failed-card {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  border-radius: var(--radius-xl);
  border: 1px solid;
  border-left-width: 4px;
}

.themed .t-pdf-preparing-icon,
.themed .t-pdf-ready-icon,
.themed .t-pdf-failed-icon {
  flex-shrink: 0;
  margin-top: 2px;
}

.themed .t-pdf-preparing-body,
.themed .t-pdf-ready-body,
.themed .t-pdf-failed-body {
  flex: 1;
  min-width: 0;
}

/* PREPARING (pending / generating) — info palette */
.themed .t-pdf-preparing-card {
  background-color: var(--color-info-bg);
  border-color: var(--color-info-border);
}

.themed .t-pdf-preparing-icon {
  color: var(--color-info-text);
}

.themed .t-pdf-preparing-title {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-info-text);
  margin: 0 0 var(--space-1) 0;
}

.themed .t-pdf-preparing-text {
  font-size: var(--text-sm);
  color: var(--color-text-base);
  line-height: 1.5;
  margin: 0 0 var(--space-2) 0;
}

.themed .t-pdf-preparing-meta {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* READY — success palette + download button */
.themed .t-pdf-ready-card {
  background-color: var(--color-success-bg);
  border-color: var(--color-success-border);
}

.themed .t-pdf-ready-icon {
  color: var(--color-success-icon);
}

.themed .t-pdf-ready-title {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-success-text);
  margin: 0 0 var(--space-1) 0;
}

.themed .t-pdf-ready-text {
  font-size: var(--text-sm);
  color: var(--color-text-base);
  line-height: 1.5;
  margin: 0;
}

.themed .t-pdf-ready-actions {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.themed .t-pdf-ready-download-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background-color: var(--color-success-icon);
  color: var(--color-text-inverse);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
  transition: background-color 120ms ease;
}

.themed .t-pdf-ready-download-btn:hover {
  background-color: var(--color-success-text);
}

.themed .t-pdf-ready-regenerate-link {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  text-decoration: underline;
}

.themed .t-pdf-ready-regenerate-link:hover {
  color: var(--color-text-base);
}

/* FAILED — danger palette */
.themed .t-pdf-failed-card {
  background-color: var(--color-danger-bg);
  border-color: var(--color-danger-border);
}

.themed .t-pdf-failed-icon {
  color: var(--color-danger-icon);
}

.themed .t-pdf-failed-title {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger-text);
  margin: 0 0 var(--space-1) 0;
}

.themed .t-pdf-failed-text {
  font-size: var(--text-sm);
  color: var(--color-danger-text);
  line-height: 1.5;
  margin: 0 0 var(--space-2) 0;
  /* Error messages can be raw exception output — preserve newlines and
     break long lines so the card never overflows. */
  white-space: pre-wrap;
  word-break: break-word;
}

.themed .t-pdf-failed-hint {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin: 0;
}

.themed .t-pdf-failed-actions {
  flex-shrink: 0;
  display: flex;
  align-items: center;
}

.themed .t-pdf-failed-retry-btn {
  display: inline-flex;
  align-items: center;
  padding: var(--space-2) var(--space-4);
  background-color: var(--color-danger-icon);
  color: var(--color-text-inverse);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
  transition: background-color 120ms ease;
}

.themed .t-pdf-failed-retry-btn:hover {
  background-color: var(--color-danger-text);
}

@media (max-width: 768px) {
  .themed .t-pdf-preparing-card,
  .themed .t-pdf-ready-card,
  .themed .t-pdf-failed-card {
    flex-direction: column;
  }
  .themed .t-pdf-preparing-icon,
  .themed .t-pdf-ready-icon,
  .themed .t-pdf-failed-icon {
    margin-top: 0;
  }
  .themed .t-pdf-ready-actions,
  .themed .t-pdf-failed-actions {
    width: 100%;
    flex-direction: column;
    align-items: stretch;
  }
  .themed .t-pdf-ready-download-btn,
  .themed .t-pdf-failed-retry-btn {
    justify-content: center;
  }
}

/* ============================================================
 * Phase 10 — Tactical Mode (M7)
 * Dense full-week board: rows=classes, cols=days×periods.
 * All classes scoped to .themed and use design tokens.
 * Mobile: ≤900px shows fallback banner, hides grid (touch
 * drag-and-drop on a 30+ column grid is unworkable).
 * ============================================================ */

/* ---- Page layout ---- */

.themed .t-tactical-page {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  min-height: calc(100vh - 4rem);
}

.themed .t-tactical-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm, 0 1px 2px 0 rgba(0, 0, 0, 0.04));
}

.themed .t-tactical-toolbar-left,
.themed .t-tactical-toolbar-right {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.themed .t-tactical-toolbar-title {
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--color-text-base);
  line-height: 1.2;
}

.themed .t-tactical-toolbar-meta {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  margin-top: var(--space-0-5);
}

.themed .t-tactical-toolbar-divider {
  width: 1px;
  height: 24px;
  background-color: var(--color-border);
}

/* ---- Stats strip ---- */

.themed .t-tactical-stats {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-2-5) var(--space-4);
  background-color: var(--color-surface-muted);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-size: 0.8125rem;
}

.themed .t-tactical-stat {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.themed .t-tactical-stat-label {
  color: var(--color-text-muted);
}

.themed .t-tactical-stat-value {
  font-weight: 600;
  color: var(--color-text-base);
}

.themed .t-tactical-stat-value-warning {
  color: var(--color-warning-text);
}

.themed .t-tactical-stat-value-danger {
  color: var(--color-danger-text);
}

.themed .t-tactical-progress {
  flex: 1 1 200px;
  height: 6px;
  background-color: var(--color-border);
  border-radius: var(--radius-full);
  overflow: hidden;
  min-width: 120px;
}

.themed .t-tactical-progress-fill {
  height: 100%;
  background-color: var(--color-info-text);
  border-radius: var(--radius-full);
  transition: width 200ms ease-out;
}

.themed .t-tactical-progress-fill-success {
  background-color: var(--color-success-icon);
}

/* ---- Force-mode banner (similar to manual editor's t-force-banner
 *      but tactical has its own copy so the layouts can diverge) ---- */

.themed .t-tactical-force-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2-5);
  padding: var(--space-3) var(--space-4);
  background-color: var(--color-danger-bg);
  border: 1px solid var(--color-danger-border);
  border-left: 4px solid var(--color-danger-icon);
  border-radius: var(--radius-md);
  color: var(--color-danger-text);
  font-size: 0.875rem;
  line-height: 1.5;
}

.themed .t-tactical-force-banner-icon {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  color: var(--color-danger-icon);
}

.themed .t-tactical-force-banner strong {
  font-weight: 600;
}

/* ---- Active-schedule banner ---- */

.themed .t-tactical-active-banner {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2-5) var(--space-4);
  background-color: var(--color-warning-bg);
  border: 1px solid var(--color-warning-border);
  border-left: 4px solid var(--color-warning-icon);
  border-radius: var(--radius-md);
  color: var(--color-warning-text);
  font-size: 0.8125rem;
  font-weight: 500;
}

.themed .t-tactical-active-banner-icon {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  color: var(--color-warning-icon);
}

/* ---- Main layout: grid + inspector side-by-side ---- */

.themed .t-tactical-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: var(--space-3);
  align-items: stretch;
  transition: grid-template-columns 220ms ease;
}

/* Inspector collapsed → second column shrinks to a thin rail (40px),
   the grid takes the rest. Transition makes the resize feel smooth.
   The rail itself remains clickable to re-expand. */
.themed .t-tactical-layout-inspector-collapsed {
  grid-template-columns: minmax(0, 1fr) 40px;
}

.themed .t-tactical-grid-wrap {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: auto;
  max-height: calc(100vh - 22rem);
  position: relative;
}

/* ---- Dense grid ---- */

.themed .t-tactical-grid {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
  font-size: 0.625rem;        /* 10px — dense aSc-style */
  table-layout: fixed;
}

.themed .t-tactical-grid thead th {
  position: sticky;
  top: 0;
  z-index: 3;
  background-color: var(--color-surface-muted);
  border-bottom: 1px solid var(--color-border);
  border-right: 1px solid var(--color-border);
  padding: var(--space-1) var(--space-1-5);
  font-weight: 600;
  color: var(--color-text-muted);
  text-align: center;
  white-space: nowrap;
}

.themed .t-tactical-grid-corner {
  z-index: 4 !important;          /* above day headers + above tbody */
  left: 0;
  position: sticky;
  background-color: var(--color-surface-muted);
  border-right: 1px solid var(--color-border);
  text-align: left;
  padding: 2px var(--space-2);
  width: 80px;
  min-width: 80px;
  max-width: 80px;
}

.themed .t-tactical-day-header {
  border-left: 2px solid var(--color-border);
}

.themed .t-tactical-day-header-name {
  display: block;
  font-size: 0.75rem;
  color: var(--color-text-base);
  text-transform: capitalize;
}

.themed .t-tactical-period-header {
  font-size: 0.5625rem;       /* 9px — minimal column width */
  font-weight: 600;
  color: var(--color-text-muted);
  min-width: 0;
  width: auto;
  padding: 2px 1px !important;
}

.themed .t-tactical-period-header-time {
  display: block;
  font-size: 0.5rem;
  font-weight: 400;
  color: var(--color-text-muted);
  margin-top: 0;
}

.themed .t-tactical-period-break-header {
  background-color: var(--color-surface-hover) !important;
  color: var(--color-text-muted);
  font-style: italic;
}

.themed .t-tactical-grid tbody td {
  border-right: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
  padding: 0;
  height: 28px;             /* Dense — aSc-style row height */
  position: relative;
  vertical-align: top;
  background-color: var(--color-surface);
}

.themed .t-tactical-class-cell {
  position: sticky;
  left: 0;
  z-index: 2;
  background-color: var(--color-surface) !important;
  padding: 2px var(--space-2);
  font-weight: 600;
  color: var(--color-text-base);
  text-align: left;
  vertical-align: middle;
  white-space: nowrap;
  width: 80px;
  min-width: 80px;
  max-width: 80px;
  border-right: 1px solid var(--color-border);
}

.themed .t-tactical-class-name {
  display: block;
  font-size: 0.6875rem;
  color: var(--color-text-base);
  line-height: 1.1;
}

.themed .t-tactical-class-grade {
  display: block;
  font-size: 0.5625rem;
  font-weight: 400;
  color: var(--color-text-muted);
  margin-top: 0;
  line-height: 1;
}

/* ---- Cell states (drag/hint) ---- */

.themed .t-tactical-cell {
  cursor: pointer;
  transition: background-color 80ms ease, box-shadow 80ms ease;
}

.themed .t-tactical-cell:hover {
  background-color: var(--color-surface-hover);
}

.themed .t-tactical-cell-day-divider {
  border-left: 2px solid var(--color-border);
}

.themed .t-tactical-cell-break {
  cursor: not-allowed;
  background-color: var(--color-surface-hover) !important;
  background-image: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 4px,
    rgba(148, 163, 184, 0.15) 4px,
    rgba(148, 163, 184, 0.15) 8px
  );
}

/* ---- Phase 10.1 — hint overlays via border + glow ----
   Subject identity (the saturated slot color) must stay visible
   during a pick. So instead of replacing the cell background,
   we layer a colored ring + soft inner glow on top via
   `box-shadow: inset`. Empty cells also get a faint background
   tint so the hint reads at-a-glance even where there's no
   slot underneath; occupied cells show the saturated subject
   color through the transparent middle of the box-shadow.

   `box-shadow: inset` doesn't paint over child elements, so the
   slot div's saturated color stays untouched — the ring sits
   on the cell's border, the glow softly fades inward.

   `!important` on background-color ensures Tailwind utility
   classes don't override the empty-cell tint. */
/* Phase 10.1 hotfix #2 — readability bump.
   Pre-fix users couldn't tell hint colors apart at a glance in a
   dense grid (rings were 2px and the green/red blended into the
   surrounding cells). Two changes:
     1. Bump rings to 3px — more prominent without dominating the
        subject color. Slot-level rules below match.
     2. Animate green (optimal) cells with a gentle ring pulse so
        actionable cells "breathe" — the eye lands there first.
        Animate red (blocked) cells with a marching diagonal hatch
        ("interdit" effect) instead of a flash, because blocked
        cells are typically numerous (50+ on a busy schedule) and
        flashing all of them would be visually painful. */
.themed .t-tactical-cell-blocked {
  background-color: var(--color-danger-bg) !important;
  background-image: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 5px,
    var(--color-danger-border) 5px,
    var(--color-danger-border) 6px
  );
  box-shadow: inset 0 0 0 3px var(--color-danger-icon),
              inset 0 0 12px 0 rgba(220, 38, 38, 0.30);
  animation: t-tactical-blocked-hatch-march 1.4s linear infinite;
}

.themed .t-tactical-cell-warning {
  background-color: var(--color-warning-bg) !important;
  box-shadow: inset 0 0 0 3px var(--color-warning-icon),
              inset 0 0 10px 0 rgba(245, 158, 11, 0.28);
}

.themed .t-tactical-cell-optimal {
  background-color: var(--color-success-bg) !important;
  box-shadow: inset 0 0 0 3px var(--color-success-icon),
              inset 0 0 14px 0 rgba(34, 197, 94, 0.32);
  animation: t-tactical-cell-optimal-pulse 1.5s ease-in-out infinite;
}

/* Same-class swap target hint. Phase 10.1 hotfix #2 keeps the
   info-blue pulse but bumps to 3px ring + glyph. */
.themed .t-tactical-cell-swap {
  background-color: var(--color-info-bg) !important;
  box-shadow: inset 0 0 0 3px var(--color-info-icon),
              inset 0 0 12px 0 rgba(59, 130, 246, 0.32);
  animation: t-tactical-swap-pulse 2.4s ease-in-out infinite;
}

.themed .t-tactical-cell-neutral {
  background-color: var(--color-info-bg) !important;
  box-shadow: inset 0 0 0 1px var(--color-info-border);
}

/* Phase 10.1 hotfix #2 — corner hint glyph.
   Bottom-right of every hint cell carries a tiny ✓ / ✕ / ! / ↔
   icon in a white pill. Reinforces the color signal for at-a-glance
   reading + colorblind accessibility. Bottom-right placement avoids
   the lock icon (top-right of the slot) and the force-violation
   glyph (top-left of the slot). z-index 3 keeps it above the slot
   div's saturated background even on occupied cells. */
.themed .t-tactical-cell-blocked::before,
.themed .t-tactical-cell-warning::before,
.themed .t-tactical-cell-optimal::before,
.themed .t-tactical-cell-swap::before {
  position: absolute;
  bottom: 1px;
  right: 1px;
  width: 12px;
  height: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.625rem;
  font-weight: 700;
  line-height: 1;
  background-color: #ffffff;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.30);
  pointer-events: none;
  z-index: 3;
  /* Reset text-shadow inherited from text-on-* cells (which would
     blur the colored glyph on top of the saturated subject bg). */
  text-shadow: none;
}

.themed .t-tactical-cell-blocked::before {
  content: '✕';
  color: var(--color-danger-icon);
}

.themed .t-tactical-cell-warning::before {
  content: '!';
  color: var(--color-warning-icon);
}

.themed .t-tactical-cell-optimal::before {
  content: '✓';
  color: var(--color-success-icon);
}

.themed .t-tactical-cell-swap::before {
  content: '↔';
  color: var(--color-info-icon);
}

.themed .t-tactical-cell-drop-target {
  outline: 2px solid var(--color-info-text);
  outline-offset: -2px;
  background-color: var(--color-info-bg) !important;
}

.themed .t-tactical-cell-swap-target {
  outline: 2px solid var(--color-warning-icon);
  outline-offset: -2px;
}

/* Phase 10.1 — hint ring/glow on the slot itself.
   The td-level `box-shadow: inset` declared above paints the
   ring on EMPTY cells (where the slot div is absent). On occupied
   cells the slot div fills 100% of the td and visually covers the
   td's inset shadow, so we duplicate the shadow via a descendant
   selector — applied to the slot box, the inset paints on top of
   the saturated subject background. Subject identity stays
   visible in the centre; the colored ring + soft inner glow at
   the edges signal the hint state. */
.themed .t-tactical-cell-blocked > .t-tactical-slot {
  box-shadow: inset 0 0 0 3px var(--color-danger-icon),
              inset 0 0 12px 0 rgba(220, 38, 38, 0.40);
}

.themed .t-tactical-cell-warning > .t-tactical-slot {
  box-shadow: inset 0 0 0 3px var(--color-warning-icon),
              inset 0 0 10px 0 rgba(245, 158, 11, 0.32);
}

/* Phase 10.1 hotfix #2 — slot-level optimal pulse.
   Mirrors the td-level pulse so the actionable signal is also
   visible on occupied cells (where the slot covers the td's
   inset shadow). Same 1.5s cadence so empty + occupied optimal
   cells pulse in sync. */
.themed .t-tactical-cell-optimal > .t-tactical-slot {
  box-shadow: inset 0 0 0 3px var(--color-success-icon),
              inset 0 0 14px 0 rgba(34, 197, 94, 0.42);
  animation: t-tactical-slot-optimal-pulse 1.5s ease-in-out infinite;
}

.themed .t-tactical-cell-swap > .t-tactical-slot {
  box-shadow: inset 0 0 0 3px var(--color-info-icon),
              inset 0 0 12px 0 rgba(59, 130, 246, 0.40);
}

.themed .t-tactical-cell-neutral > .t-tactical-slot {
  box-shadow: inset 0 0 0 1px var(--color-info-border);
}

/* ---- Slot block (placement) ---- */

/* Phase 10.1 — saturated edge-to-edge subject block.
   No border-radius, no margin, no left-color accent — the cell's
   table border separates blocks visually. The full subject color
   fills the cell; text contrast is handled by `t-tactical-cell-text-on-*`
   classes (light or dark) applied alongside this one. */
.themed .t-tactical-slot {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100%;
  padding: 0 2px;
  cursor: grab;
  /* `overflow: visible` so the styled tooltip pseudo-element
     (anchored to this slot via `[data-tooltip]:hover::after`)
     can extend above the slot. The inner subject-code span
     handles its own text truncation via ellipsis. */
  overflow: visible;
  user-select: none;
  position: relative;
}

.themed .t-tactical-slot:active {
  cursor: grabbing;
}

.themed .t-tactical-slot-locked {
  cursor: not-allowed;
}

.themed .t-tactical-slot-carrying {
  opacity: 0.4;
  outline: 2px dashed var(--color-info-text);
  outline-offset: -2px;
}

.themed .t-tactical-slot-subject {
  font-weight: 600;
  font-size: 0.6875rem;
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.themed .t-tactical-slot-teacher {
  font-size: 0.625rem;
  font-weight: 400;
  color: var(--color-text-muted);
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 1px;
}

/* Dense subject-code chip — replaces subject_name + teacher_name in
   the grid cell. Full label surfaces in the cell's `title` tooltip.
   Phase 10.1: text color inherits from the parent `.t-tactical-slot`
   which carries a `t-tactical-cell-text-on-light` or
   `t-tactical-cell-text-on-dark` class chosen server-side via
   the WCAG luminance helper. */
.themed .t-tactical-slot-code {
  font-weight: 700;
  font-size: 0.75rem;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 100%;
  text-align: center;
  color: inherit;
}

.themed .t-tactical-slot-lock-icon {
  position: absolute;
  top: 0;
  right: 1px;
  font-size: 0.5rem;
  color: var(--color-warning-icon);
  pointer-events: none;
}

/* Phase 11 post-pilot — joint session marker.
   Small diamond glyph in the top-left of the slot block signals that
   this slot belongs to a JointSessionGroup. Dragging it moves all
   sibling classes atomically. Positioned top-left to leave the
   top-right corner free for the lock icon (slots can be both joint
   AND locked). Uses the info-icon token (contrast against saturated
   subject background covered by light/dark text override below). */
.themed .t-tactical-slot-joint-icon {
  position: absolute;
  top: 0;
  left: 1px;
  font-size: 0.55rem;
  font-weight: 700;
  color: var(--color-info-icon);
  pointer-events: none;
  line-height: 1;
}

/* Same contrast override as lock-icon: the saturated subject colors
   underneath swing between light + dark, so we override based on
   the precomputed `text_on` class. */
.themed .t-tactical-cell-text-on-light .t-tactical-slot-joint-icon {
  color: rgba(255, 255, 255, 0.95);
  text-shadow: 0 0 1px rgba(0, 0, 0, 0.35);
}
.themed .t-tactical-cell-text-on-dark .t-tactical-slot-joint-icon {
  color: rgba(0, 0, 0, 0.85);
}

/* Styled hover tooltip for slot blocks. Replaces the native
   browser `title` attribute (ugly OS styling + 600ms delay).
   Uses `data-tooltip` attribute + `::after` pseudo-element. The
   tooltip appears above the slot with a small arrow, fades in
   after a short delay, and wraps long content.

   Why no JS: pure CSS keeps the implementation cheap and
   reliable. The trade-off is no viewport-aware repositioning;
   slots in the very top row may have the tooltip clipped. Given
   the dense grid is meant to be viewed across the full week
   landscape, this is acceptable. */
.themed .t-tactical-slot[data-tooltip] {
  /* Allow the absolute-positioned tooltip to reference this slot. */
  /* The .t-tactical-cell already has `position: relative`. The
     slot inherits that frame; the tooltip overflows the cell
     visibly thanks to the grid wrapper's overflow allowance. */
}

.themed .t-tactical-slot[data-tooltip]:hover::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  background-color: var(--color-text-base);
  color: var(--color-text-inverse);
  padding: 6px 10px;
  border-radius: var(--radius-md);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  text-align: center;
  white-space: normal;
  max-width: 240px;
  width: max-content;
  line-height: 1.4;
  box-shadow: 0 4px 12px rgba(15, 23, 42, 0.18);
  pointer-events: none;
  animation: t-tactical-tooltip-in 120ms ease-out 250ms backwards;
}

.themed .t-tactical-slot[data-tooltip]:hover::before {
  content: '';
  position: absolute;
  bottom: calc(100% + 1px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  width: 0;
  height: 0;
  border: 5px solid transparent;
  border-top-color: var(--color-text-base);
  pointer-events: none;
  animation: t-tactical-tooltip-in 120ms ease-out 250ms backwards;
}

@keyframes t-tactical-tooltip-in {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(2px);
  }
  to {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}

/* While carrying a slot, hide tooltips — they'd flicker as the
   cursor crosses cells during drag and add visual noise. */
.themed .t-tactical-page:has(.t-tactical-slot-carrying)
  .t-tactical-slot[data-tooltip]:hover::after,
.themed .t-tactical-page:has(.t-tactical-slot-carrying)
  .t-tactical-slot[data-tooltip]:hover::before {
  display: none;
}

/* ---- Inspector ---- */

.themed .t-tactical-inspector {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  font-size: 0.8125rem;
  position: sticky;
  top: var(--space-2);
  align-self: flex-start;
  max-height: calc(100vh - 22rem);
  overflow-y: auto;
  transition: padding 220ms ease;
}

/* Collapsed inspector — narrow vertical rail. Padding shrinks,
   contents hide via `x-show`, and the toggle button becomes the
   full clickable area. The rail keeps the same border/background
   so it visually attaches to the layout grid. */
.themed .t-tactical-inspector-collapsed {
  padding: var(--space-2) 0;
  gap: 0;
  align-items: center;
  overflow: hidden;
}

.themed .t-tactical-inspector-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  width: 100%;
}

.themed .t-tactical-inspector-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--color-text-muted);
  border-radius: var(--radius-sm);
  transition: background-color 120ms ease, color 120ms ease;
  font-family: inherit;
}

/* Expanded state — small icon button anchored top-right of the
   inspector, doesn't disturb section layout. */
/* Expanded state — small icon button anchored top-right of the
   inspector, with a subtle pill background so it's visually
   discoverable rather than melting into the panel. */
.themed .t-tactical-inspector:not(.t-tactical-inspector-collapsed)
  .t-tactical-inspector-toggle {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  width: 28px;
  height: 28px;
  padding: 0;
  background-color: var(--color-surface-muted);
  border: 1px solid var(--color-border);
  z-index: 2;
}

.themed .t-tactical-inspector:not(.t-tactical-inspector-collapsed)
  .t-tactical-inspector-toggle:hover {
  background-color: var(--color-info-bg);
  border-color: var(--color-info-border);
  color: var(--color-info-text);
}

/* Collapsed state — toggle becomes the entire rail. Vertical text
   for the "Inspecteur" label, large click target. */
.themed .t-tactical-inspector-collapsed .t-tactical-inspector-toggle {
  width: 100%;
  flex-direction: column;
  padding: var(--space-3) 0;
  flex: 1 1 auto;
  align-items: center;
  justify-content: flex-start;
  gap: var(--space-3);
  color: var(--color-text-muted);
  min-height: 200px;
}

.themed .t-tactical-inspector-collapsed .t-tactical-inspector-toggle:hover {
  background-color: var(--color-surface-hover);
  color: var(--color-info-text);
}

.themed .t-tactical-inspector-toggle-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  /* Path is chevron-left by default. Rotate 180° when expanded
     so the arrow points right (collapse direction). Smooth
     transition makes the toggle feel responsive. */
  transition: transform 200ms ease;
}

.themed .t-tactical-inspector:not(.t-tactical-inspector-collapsed)
  .t-tactical-inspector-toggle-icon {
  transform: rotate(180deg);
}

.themed .t-tactical-inspector-collapsed .t-tactical-inspector-toggle-icon {
  width: 18px;
  height: 18px;
}

/* Vertical "Inspecteur" label — only shown when collapsed. */
.themed .t-tactical-inspector-toggle-label {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  white-space: nowrap;
}

.themed .t-tactical-inspector-section + .t-tactical-inspector-section {
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}

.themed .t-tactical-inspector-label {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}

.themed .t-tactical-inspector-empty {
  color: var(--color-text-muted);
  font-style: italic;
  font-size: 0.8125rem;
}

.themed .t-tactical-inspector-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-2-5);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-border);
  background-color: var(--color-surface-muted);
}

.themed .t-tactical-inspector-card-subject {
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--color-text-base);
}

.themed .t-tactical-inspector-card-meta {
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

.themed .t-tactical-inspector-card-progress {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  margin-top: var(--space-1);
}

.themed .t-tactical-inspector-card-hint {
  font-size: 0.6875rem;
  color: var(--color-text-muted);
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px dashed var(--color-border);
  line-height: 1.4;
}

/* Workflow help list — shown in the inspector empty state.
   Indented numbered list with kbd-chip support. */
.themed .t-tactical-help-list {
  list-style-position: inside;
  list-style-type: decimal;
  font-size: 0.75rem;
  color: var(--color-text-muted);
  line-height: 1.5;
  margin: var(--space-2) 0 0;
  padding-left: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1-5);
}

.themed .t-tactical-help-list > li {
  padding-left: 2px;
}

.themed .t-tactical-help-list strong {
  color: var(--color-text-base);
  font-weight: 600;
}

.themed .t-tactical-help-sublist {
  list-style-type: disc;
  list-style-position: outside;
  margin: var(--space-1) 0 0 var(--space-5);
  padding: 0;
  font-size: 0.6875rem;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Permissive-philosophy callout — appears below the workflow help
   list. Reminds the planificateur that hints don't block moves;
   only Publish enforces hard constraints (and Mode force bypasses
   even that). Info-tinted block to set it apart from instructions. */
.themed .t-tactical-help-philosophy {
  margin-top: var(--space-3);
  padding: var(--space-2-5);
  border-left: 3px solid var(--color-info-text);
  background-color: var(--color-info-bg);
  border-radius: var(--radius-sm);
  font-size: 0.6875rem;
  color: var(--color-text-base);
  line-height: 1.5;
}

.themed .t-tactical-help-philosophy strong {
  color: var(--color-info-text);
  font-weight: 600;
}

.themed .t-tactical-help-philosophy em {
  font-style: normal;
  font-weight: 600;
  color: var(--color-text-base);
}

.themed .t-tactical-legend {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
  font-size: 0.6875rem;
  color: var(--color-text-muted);
}

.themed .t-tactical-legend-item {
  display: flex;
  align-items: center;
  gap: var(--space-1-5);
}

.themed .t-tactical-legend-swatch {
  width: 10px;
  height: 10px;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}

.themed .t-tactical-legend-swatch-blocked {
  background-color: var(--color-danger-bg);
  border: 1px solid var(--color-danger-border);
}

.themed .t-tactical-legend-swatch-warning {
  background-color: var(--color-warning-bg);
  border: 1px solid var(--color-warning-border);
}

.themed .t-tactical-legend-swatch-optimal {
  background-color: var(--color-success-bg);
  border: 1px solid var(--color-success-border);
}

.themed .t-tactical-legend-swatch-neutral {
  background-color: var(--color-info-bg);
  border: 1px solid var(--color-info-border);
}

.themed .t-tactical-shortcuts {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: 0.6875rem;
  color: var(--color-text-muted);
}

.themed .t-tactical-shortcut {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
}

.themed .t-tactical-kbd {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 0.625rem;
  font-weight: 600;
  padding: 1px 5px;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text-base);
  white-space: nowrap;
}

/* ---- Park tray ---- */

.themed .t-tactical-park-tray {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.themed .t-tactical-park-tray-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-2-5) var(--space-4);
  background-color: var(--color-surface-muted);
  border-bottom: 1px solid var(--color-border);
  cursor: pointer;
  user-select: none;
}

.themed .t-tactical-park-tray-collapsed .t-tactical-park-tray-header {
  border-bottom: none;
}

.themed .t-tactical-park-tray-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-text-base);
}

.themed .t-tactical-park-tray-count {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-2);
  height: 18px;
  font-size: 0.6875rem;
  font-weight: 600;
  background-color: var(--color-warning-bg);
  border: 1px solid var(--color-warning-border);
  color: var(--color-warning-text);
  border-radius: var(--radius-full);
}

.themed .t-tactical-park-tray-count-empty {
  background-color: var(--color-surface-hover);
  border-color: var(--color-border);
  color: var(--color-text-muted);
}

.themed .t-tactical-park-tray-toggle-icon {
  width: 14px;
  height: 14px;
  color: var(--color-text-muted);
  transition: transform 150ms ease;
}

.themed .t-tactical-park-tray-collapsed .t-tactical-park-tray-toggle-icon {
  transform: rotate(-90deg);
}

.themed .t-tactical-park-tray-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  min-height: 60px;
  align-items: flex-start;
}

.themed .t-tactical-park-tray-list-drop-target {
  outline: 2px dashed var(--color-info-text);
  outline-offset: -2px;
  background-color: var(--color-info-bg);
}

.themed .t-tactical-park-tray-empty {
  color: var(--color-text-muted);
  font-style: italic;
  font-size: 0.75rem;
}

.themed .t-tactical-park-card {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: var(--space-1-5) var(--space-2);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-muted);
  cursor: grab;
  font-size: 0.75rem;
  min-width: 110px;
  user-select: none;
}

.themed .t-tactical-park-card:active {
  cursor: grabbing;
}

.themed .t-tactical-park-card-carrying {
  opacity: 0.4;
  outline: 2px dashed var(--color-info-text);
  outline-offset: -2px;
}

.themed .t-tactical-park-card-subject {
  font-weight: 600;
  color: var(--color-text-base);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.themed .t-tactical-park-card-meta {
  font-size: 0.625rem;
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- Toast ---- */

.themed .t-tactical-toast {
  /* Inline + centered — between the stats strip and the grid. The
     planner's eyes are on the grid so feedback should sit on the
     centre line, not at the corner of the screen. */
  margin: 0 auto var(--space-3) auto;
  width: fit-content;
  min-width: 280px;
  max-width: min(640px, 90%);
  padding: var(--space-2-5) var(--space-4);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md, 0 4px 12px rgba(0, 0, 0, 0.08));
  font-size: 0.8125rem;
  line-height: 1.45;
  border: 1px solid;
  text-align: center;
}

.themed .t-tactical-toast-success {
  background-color: var(--color-success-bg);
  border-color: var(--color-success-border);
  color: var(--color-success-text);
}

.themed .t-tactical-toast-error {
  background-color: var(--color-danger-bg);
  border-color: var(--color-danger-border);
  color: var(--color-danger-text);
}

.themed .t-tactical-toast-warning {
  background-color: var(--color-warning-bg);
  border-color: var(--color-warning-border);
  color: var(--color-warning-text);
}

.themed .t-tactical-toast-info {
  background-color: var(--color-info-bg);
  border-color: var(--color-info-border);
  color: var(--color-info-text);
}

.themed .t-tactical-toast-list {
  margin-top: var(--space-1);
  padding-left: var(--space-4);
  list-style: disc;
}

.themed .t-tactical-toast-action {
  margin-top: var(--space-2);
  display: flex;
  gap: var(--space-2);
  justify-content: flex-end;
}

/* ---- Publish dialog ---- */

.themed .t-tactical-dialog-overlay {
  position: fixed;
  inset: 0;
  background-color: rgba(15, 23, 42, 0.45);
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
}

.themed .t-tactical-dialog {
  background-color: var(--color-surface);
  border-radius: var(--radius-xl);
  border: 1px solid var(--color-border);
  width: 100%;
  max-width: 520px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: var(--shadow-xl, 0 20px 50px rgba(0, 0, 0, 0.25));
}

.themed .t-tactical-dialog-header {
  padding: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.themed .t-tactical-dialog-title {
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--color-text-base);
}

.themed .t-tactical-dialog-subtitle {
  font-size: 0.8125rem;
  color: var(--color-text-muted);
  margin-top: var(--space-1);
}

.themed .t-tactical-dialog-body {
  padding: var(--space-4);
  overflow-y: auto;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.themed .t-tactical-dialog-footer {
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border);
  background-color: var(--color-surface-muted);
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
}

.themed .t-tactical-publish-counts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2);
}

.themed .t-tactical-publish-count {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--space-3) var(--space-2);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-muted);
  border: 1px solid var(--color-border);
}

.themed .t-tactical-publish-count-num {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--color-text-base);
  line-height: 1;
}

.themed .t-tactical-publish-count-label {
  font-size: 0.6875rem;
  color: var(--color-text-muted);
  margin-top: var(--space-1);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.themed .t-tactical-publish-count-creates {
  border-left: 3px solid var(--color-success-icon);
}

.themed .t-tactical-publish-count-deletes {
  border-left: 3px solid var(--color-danger-icon);
}

.themed .t-tactical-publish-count-moves {
  border-left: 3px solid var(--color-info-text);
}

.themed .t-tactical-publish-warning {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-2-5) var(--space-3);
  background-color: var(--color-warning-bg);
  border: 1px solid var(--color-warning-border);
  border-left: 3px solid var(--color-warning-icon);
  border-radius: var(--radius-md);
  color: var(--color-warning-text);
  font-size: 0.8125rem;
}

.themed .t-tactical-publish-error {
  background-color: var(--color-danger-bg);
  border-color: var(--color-danger-border);
  border-left-color: var(--color-danger-icon);
  color: var(--color-danger-text);
}

/* ---- Mobile fallback banner — touch DnD on a 30+ col grid is unworkable ---- */

.themed .t-tactical-mobile-banner {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-6) var(--space-4);
  background-color: var(--color-info-bg);
  border: 1px solid var(--color-info-border);
  border-radius: var(--radius-lg);
  text-align: center;
}

.themed .t-tactical-mobile-banner-icon {
  width: 48px;
  height: 48px;
  color: var(--color-info-text);
}

.themed .t-tactical-mobile-banner-title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--color-text-base);
}

.themed .t-tactical-mobile-banner-body {
  font-size: 0.8125rem;
  color: var(--color-text-muted);
  max-width: 32ch;
  line-height: 1.5;
}

.themed .t-tactical-mobile-banner-cta {
  margin-top: var(--space-2);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background-color: var(--color-primary-bg, var(--color-info-text));
  color: var(--color-text-inverse);
  border-radius: var(--radius-md);
  font-size: 0.8125rem;
  font-weight: 500;
  text-decoration: none;
}

@media (max-width: 900px) {
  .themed .t-tactical-mobile-banner {
    display: flex;
  }
  .themed .t-tactical-layout,
  .themed .t-tactical-park-tray,
  .themed .t-tactical-stats,
  .themed .t-tactical-toolbar {
    display: none;
  }
}

@media (max-width: 1280px) {
  .themed .t-tactical-layout {
    grid-template-columns: minmax(0, 1fr) 280px;
  }
}

/* ════════════════════════════════════════════════════════════════
 * Phase 10.1 — Tactical Mode Visual Density Pass
 *
 * Adds:
 *   1. Saturated subject text contrast (light vs dark per slot)
 *   2. Force-violation dashed red ring + warning glyph
 *   3. Toolbar violation pill (count + cycle button)
 *   4. Animations: swap-pulse, force-march, violation-pulse
 *
 * Hint colors are handled above via box-shadow inset (border + glow)
 * so subject identity stays visible while a card is in the air.
 * ════════════════════════════════════════════════════════════════ */

/* ---- Phase 10.1 — text-on contrast ----
   `_text_on_for_color()` (WCAG luminance, threshold 0.55) chooses
   light or dark text per subject color. We also drop a small
   text-shadow so the code stays legible even when the saturated
   color is on the boundary (yellow/lime/cyan). */
.themed .t-tactical-cell-text-on-light {
  color: #ffffff;
  text-shadow: 0 1px 2px rgba(15, 23, 42, 0.35);
}

.themed .t-tactical-cell-text-on-dark {
  color: rgba(15, 23, 42, 0.92);
  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.45);
}

/* Lock icon inherits text color so it reads on both light and dark
   subject backgrounds. The original amber-warning hard-coded color
   washed out on yellow/orange subjects. */
.themed .t-tactical-cell-text-on-light .t-tactical-slot-lock-icon {
  color: rgba(255, 255, 255, 0.85);
}

.themed .t-tactical-cell-text-on-dark .t-tactical-slot-lock-icon {
  color: rgba(15, 23, 42, 0.7);
}

/* ---- Phase 10.1 — force-violation ring ----
   A dashed red ring marches around the slot when its current
   placement would fail a hard constraint at publish (teacher
   conflict, hard unavailability, cross-config block).

   `::after` pseudo-element overlays the slot so the saturated
   subject color underneath stays visible — the ring itself is
   the violation indicator, not a tint over the subject. The
   `border-style: dashed` + animation moves the dash pattern,
   giving an "alive" hazard feel without being garish. */
.themed .t-tactical-cell-force-violation {
  /* Slot background stays the saturated subject color; the ring
     sits on top of it via the pseudo-element below. */
}

.themed .t-tactical-cell-force-violation::after {
  content: '';
  position: absolute;
  inset: 0;
  border: 2px dashed var(--color-danger-icon);
  pointer-events: none;
  animation: t-tactical-force-march 1.6s linear infinite;
  /* Without `box-sizing` the dashed border can render OUTSIDE the
     cell's clip area — explicit `border-box` keeps it inside. */
  box-sizing: border-box;
  /* z-index above the saturated background but below the lock
     icon and warning glyph so they remain clickable. */
  z-index: 1;
}

/* Warning glyph in the top-left corner of every force-violating
   cell. Sits above the dashed ring, has its own white pill
   background so it reads on any subject color. */
.themed .t-tactical-cell-violation-glyph {
  position: absolute;
  top: 1px;
  left: 1px;
  width: 14px;
  height: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.625rem;
  font-weight: 700;
  color: var(--color-danger-icon);
  background-color: #ffffff;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.25);
  pointer-events: none;
  /* Above the ::after ring (z-index: 1) so the glyph sits on top. */
  z-index: 2;
  /* Defensive — prevent text-shadow inherited from text-on-light
     parent leaking into the glyph and blurring its red glyph. */
  text-shadow: none;
}

/* `cycleForceViolations()` adds this class for ~1.2s after a
   click on the toolbar pill — pulses the targeted cell so the
   planificateur sees where it landed after the smooth-scroll. */
.themed .t-tactical-cell-violation-pulse {
  animation: t-tactical-violation-pulse-burst 1.2s ease-out;
  /* z-index pop so the pulse reads above neighbouring cells. */
  z-index: 5;
}

/* ---- Phase 10.1 — toolbar violation pill ----
   Visible only when `forceViolations.size > 0` (Alpine `x-show`).
   Same pulsing-dashed look as the cell ring so the planificateur
   visually links the toolbar count to the affected cells. Click
   cycles through the violations (smooth-scroll + pulse). */
.themed .t-tactical-violation-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 4px 10px;
  background-color: var(--color-danger-bg);
  color: var(--color-danger-text);
  border: 1.5px dashed var(--color-danger-icon);
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 120ms ease, transform 120ms ease;
  animation: t-tactical-force-march 2.2s linear infinite;
}

.themed .t-tactical-violation-pill:hover {
  background-color: var(--color-danger-border);
  transform: translateY(-1px);
}

.themed .t-tactical-violation-pill:active {
  transform: translateY(0);
}

.themed .t-tactical-violation-pill-glyph {
  font-size: 0.875rem;
  line-height: 1;
}

.themed .t-tactical-violation-pill-count {
  font-weight: 700;
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

.themed .t-tactical-violation-pill-label {
  font-size: 0.75rem;
  text-transform: lowercase;
  letter-spacing: 0.01em;
}

/* ---- Phase 10.1 — animations ---- */

/* Marching-ants effect for dashed borders. Shifts the dash
   offset over time so the ring animates around the slot. The
   exact distance (12px) matches `border: 2px dashed` repeat
   roughly so there's no visible "snap". */
@keyframes t-tactical-force-march {
  from { background-position: 0 0; }
  to   { background-position: 12px 0; }
}

/* Soft pulse used by `cell-swap` while a card is in the air.
   Just opacity + box-shadow strength — no scale change so the cell
   footprint stays stable in the dense grid.
   Phase 10.1 hotfix #2: ring bumped to 3px to match the static
   rule (otherwise the animation would snap on every cycle). */
@keyframes t-tactical-swap-pulse {
  0%, 100% {
    box-shadow: inset 0 0 0 3px var(--color-info-icon),
                inset 0 0 10px 0 rgba(59, 130, 246, 0.22);
  }
  50% {
    box-shadow: inset 0 0 0 3px var(--color-info-icon),
                inset 0 0 16px 2px rgba(59, 130, 246, 0.40);
  }
}

/* Phase 10.1 hotfix #2 — gentle green pulse on optimal cells
   (the actionable drop targets). 1.5s cycle with a soft glow
   intensification at the midpoint. Two flavors: td-level (for
   empty cells) and slot-level (for occupied cells), kept in sync
   so a row of optimal cells pulses uniformly. */
@keyframes t-tactical-cell-optimal-pulse {
  0%, 100% {
    box-shadow: inset 0 0 0 3px var(--color-success-icon),
                inset 0 0 12px 0 rgba(34, 197, 94, 0.28);
  }
  50% {
    box-shadow: inset 0 0 0 3px var(--color-success-icon),
                inset 0 0 20px 2px rgba(34, 197, 94, 0.55);
  }
}

@keyframes t-tactical-slot-optimal-pulse {
  0%, 100% {
    box-shadow: inset 0 0 0 3px var(--color-success-icon),
                inset 0 0 14px 0 rgba(34, 197, 94, 0.42);
  }
  50% {
    box-shadow: inset 0 0 0 3px var(--color-success-icon),
                inset 0 0 22px 2px rgba(34, 197, 94, 0.65);
  }
}

/* Phase 10.1 hotfix #2 — marching diagonal hatch on blocked cells.
   Conveys "interdit" energy without the eye-fatigue of a flash —
   important because blocked cells are typically numerous (50+ on
   a busy schedule). The 8.485px = 6 × √2 step matches one repeat
   of the 45° hatch gradient (base period 6px), so the pattern
   loops seamlessly. */
@keyframes t-tactical-blocked-hatch-march {
  from { background-position: 0 0; }
  to   { background-position: 8.485px 0; }
}

/* One-shot burst when `cycleForceViolations()` jumps to a cell.
   Quick scale-up + outer glow then settles. */
@keyframes t-tactical-violation-pulse-burst {
  0% {
    transform: scale(1);
    box-shadow: 0 0 0 0 var(--color-danger-icon);
  }
  30% {
    transform: scale(1.08);
    box-shadow: 0 0 0 6px rgba(220, 38, 38, 0.45);
  }
  100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(220, 38, 38, 0);
  }
}

/* ============================================================================
   BILLING & INSCRIPTION  (apps/billing)  — Phase 0
   ----------------------------------------------------------------------------
   Optional, per-school module. Every rule is scoped to `.themed` (R2) and uses
   tokens only (R3). Mobile breakpoints are mandatory (R6) and appear at the end
   of this block.

   Plan: todo-billing.md · Reference: docs/features/billing.md
   ========================================================================== */

/* --- Settings page: status panel ----------------------------------------- */

.themed .t-billing-status-panel {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.themed .t-billing-status-body {
  flex: 1 1 320px;
  min-width: 0;
}

.themed .t-billing-status-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

/* --- Status pill ---------------------------------------------------------- */

.themed .t-billing-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  font-size: 0.8125rem;
  font-weight: 600;
  white-space: nowrap;
  border: 1px solid transparent;
}

.themed .t-billing-pill-on {
  background: var(--color-success-bg);
  color: var(--color-success-text);
  border-color: var(--color-success-border);
}

.themed .t-billing-pill-off {
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
  border-color: var(--color-warning-border);
}

.themed .t-billing-pill-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--radius-full);
  flex-shrink: 0;
}

.themed .t-billing-pill-on .t-billing-pill-dot {
  background: var(--color-success-icon);
}

.themed .t-billing-pill-off .t-billing-pill-dot {
  background: var(--color-warning-icon);
}

/* --- Currency row --------------------------------------------------------- */

.themed .t-billing-currency-row {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.themed .t-billing-currency-input {
  width: 7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
}

.themed .t-billing-currency-locked {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.8125rem;
  color: var(--color-text-muted);
}

/* --- Informational note --------------------------------------------------- */

.themed .t-billing-note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-info-border);
  background: var(--color-info-bg);
  color: var(--color-info-text);
  font-size: 0.875rem;
}

.themed .t-billing-note-icon {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  margin-top: 0.125rem;
  color: var(--color-info-icon);
}

.themed .t-billing-note-title {
  font-weight: 600;
  margin-bottom: var(--space-1);
}

/* --- Mobile (R6) ---------------------------------------------------------- */

@media (max-width: 768px) {
  .themed .t-billing-status-panel {
    flex-direction: column;
    align-items: stretch;
  }

  .themed .t-billing-status-actions {
    justify-content: space-between;
    width: 100%;
  }

  .themed .t-billing-currency-row {
    align-items: stretch;
    flex-direction: column;
  }

  .themed .t-billing-currency-input {
    width: 100%;
  }
}

@media (max-width: 480px) {
  .themed .t-billing-pill {
    font-size: 0.75rem;
    padding: var(--space-0-5) var(--space-2);
  }

  .themed .t-billing-note {
    padding: var(--space-3);
    font-size: 0.8125rem;
  }

  .themed .t-billing-note-icon {
    display: none;
  }
}

/* ----------------------------------------------------------------------------
   BILLING — Inscription form (Phase 1)
   Same rules as the Phase 0 block above: `.themed`-scoped, tokens only, mobile
   breakpoints mandatory.
   -------------------------------------------------------------------------- */

.themed .t-billing-form-section {
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  margin-bottom: var(--space-5);
}

.themed .t-billing-form-legend {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
}

.themed .t-billing-form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
}

.themed .t-billing-form-grid-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
}

.themed .t-billing-form-full {
  grid-column: 1 / -1;
}

.themed .t-billing-required::after {
  content: " *";
  color: var(--color-danger-icon);
  font-weight: 700;
}

.themed .t-billing-field-hint {
  display: block;
  margin-top: var(--space-1);
  font-size: 0.75rem;
  color: var(--color-text-subtle);
  line-height: 1.4;
}

/* Provisional-code callout — amber, because it is a to-do, not an error. */
.themed .t-billing-prov-callout {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-warning-border);
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
  font-size: 0.8125rem;
}

.themed .t-billing-prov-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-0-5) var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
  border: 1px solid var(--color-warning-border);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

/* Occupancy chip on the class picker + the worklist table */
.themed .t-billing-occupancy {
  font-variant-numeric: tabular-nums;
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

.themed .t-billing-occupancy-full {
  color: var(--color-danger-text);
  font-weight: 600;
}

.themed .t-billing-worklist {
  width: 100%;
  border-collapse: collapse;
}

.themed .t-billing-worklist th {
  text-align: left;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-muted);
  border-bottom: 1px solid var(--color-border);
}

.themed .t-billing-worklist td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  font-size: 0.875rem;
  vertical-align: middle;
}

.themed .t-billing-worklist tr:hover td {
  background: var(--color-surface-hover);
}

.themed .t-billing-regularize-form {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.themed .t-billing-regularize-input {
  width: 11rem;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

.themed .t-billing-empty {
  padding: var(--space-8) var(--space-4);
  text-align: center;
  color: var(--color-text-muted);
  font-size: 0.875rem;
}

/* --- Mobile (R6) --- */

@media (max-width: 768px) {
  .themed .t-billing-form-grid,
  .themed .t-billing-form-grid-3 {
    grid-template-columns: minmax(0, 1fr);
  }

  .themed .t-billing-form-section {
    padding: var(--space-4);
  }

  .themed .t-billing-worklist thead {
    display: none;
  }

  .themed .t-billing-worklist tr {
    display: block;
    border-bottom: 2px solid var(--color-border);
    padding: var(--space-2) 0;
  }

  .themed .t-billing-worklist td {
    display: flex;
    justify-content: space-between;
    gap: var(--space-3);
    border-bottom: none;
    padding: var(--space-1-5) var(--space-3);
  }

  .themed .t-billing-worklist td::before {
    content: attr(data-label);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--color-text-muted);
  }

  .themed .t-billing-regularize-form {
    width: 100%;
  }

  .themed .t-billing-regularize-input {
    flex: 1 1 auto;
    width: auto;
  }
}

@media (max-width: 480px) {
  .themed .t-billing-form-section {
    padding: var(--space-3);
  }

  .themed .t-billing-prov-callout {
    flex-direction: column;
    gap: var(--space-2);
    font-size: 0.75rem;
  }

  .themed .t-billing-form-legend {
    font-size: 0.6875rem;
  }
}

/* ----------------------------------------------------------------------------
   BILLING — Fee plans & accounts (Phase 2)
   Same rules as the Phase 0/1 blocks: `.themed`-scoped, tokens only, both mobile
   breakpoints mandatory.
   -------------------------------------------------------------------------- */

.themed .t-billing-plan-card {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.themed .t-billing-plan-card:hover {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-sm);
}

.themed .t-billing-plan-name {
  font-weight: 600;
  color: var(--color-text-base);
}

.themed .t-billing-plan-scope {
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

.themed .t-billing-plan-total {
  font-variant-numeric: tabular-nums;
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--color-text-base);
  white-space: nowrap;
}

.themed .t-billing-plan-inactive {
  opacity: 0.6;
}

/* --- Money figures ------------------------------------------------------- */

.themed .t-billing-amount {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.themed .t-billing-amount-negative {
  color: var(--color-success-text);
}

.themed .t-billing-amount-positive {
  color: var(--color-danger-text);
}

/* --- Summary strip on the account page ----------------------------------- */

.themed .t-billing-summary {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3);
}

.themed .t-billing-summary-tile {
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.themed .t-billing-summary-label {
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-1);
}

.themed .t-billing-summary-value {
  font-size: 1.375rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-base);
}

.themed .t-billing-summary-tile-due .t-billing-summary-value {
  color: var(--color-warning-text);
}

.themed .t-billing-summary-tile-credit .t-billing-summary-value {
  color: var(--color-success-text);
}

/* --- Account status pill ------------------------------------------------- */

.themed .t-billing-acct-status {
  display: inline-flex;
  align-items: center;
  padding: var(--space-0-5) var(--space-2-5);
  border-radius: var(--radius-full);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  border: 1px solid transparent;
}

.themed .t-billing-acct-draft {
  background: var(--color-surface-muted);
  color: var(--color-text-muted);
  border-color: var(--color-border);
}

.themed .t-billing-acct-active {
  background: var(--color-success-bg);
  color: var(--color-success-text);
  border-color: var(--color-success-border);
}

.themed .t-billing-acct-closed {
  background: var(--color-surface-hover);
  color: var(--color-text-subtle);
  border-color: var(--color-border);
}

/* --- Obligation ledger (instalments + adjustments, merged) --------------- */

.themed .t-billing-ledger {
  width: 100%;
  border-collapse: collapse;
}

.themed .t-billing-ledger th {
  text-align: left;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  background: var(--color-surface-muted);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

.themed .t-billing-ledger td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  font-size: 0.875rem;
}

.themed .t-billing-ledger-adjustment td {
  background: var(--color-surface-muted);
  font-style: italic;
}

.themed .t-billing-row-status {
  display: inline-flex;
  align-items: center;
  padding: var(--space-0-5) var(--space-2);
  border-radius: var(--radius-full);
  font-size: 0.6875rem;
  font-weight: 600;
}

.themed .t-billing-row-paid {
  background: var(--color-success-bg);
  color: var(--color-success-text);
}

.themed .t-billing-row-partial {
  background: var(--color-info-bg);
  color: var(--color-info-text);
}

.themed .t-billing-row-overdue {
  background: var(--color-danger-bg);
  color: var(--color-danger-text);
}

.themed .t-billing-row-pending {
  background: var(--color-surface-muted);
  color: var(--color-text-muted);
}

/* --- Editable instalment rows (plan builder / draft editor) -------------- */

.themed .t-billing-rowset {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.themed .t-billing-row-edit {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr auto;
  gap: var(--space-2);
  align-items: end;
}

.themed .t-billing-row-remove {
  color: var(--color-danger-text);
  background: none;
  border: none;
  cursor: pointer;
  padding: var(--space-2);
  line-height: 1;
}

.themed .t-billing-frozen-note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-info-border);
  background: var(--color-info-bg);
  color: var(--color-info-text);
  font-size: 0.8125rem;
}

/* --- Mobile (R6) --------------------------------------------------------- */

@media (max-width: 768px) {
  .themed .t-billing-summary {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .themed .t-billing-plan-card {
    flex-direction: column;
    align-items: stretch;
  }

  .themed .t-billing-row-edit {
    grid-template-columns: minmax(0, 1fr);
  }

  .themed .t-billing-ledger thead {
    display: none;
  }

  .themed .t-billing-ledger tr {
    display: block;
    border-bottom: 2px solid var(--color-border);
    padding: var(--space-2) 0;
  }

  .themed .t-billing-ledger td {
    display: flex;
    justify-content: space-between;
    gap: var(--space-3);
    border-bottom: none;
    padding: var(--space-1-5) var(--space-3);
  }

  .themed .t-billing-ledger td::before {
    content: attr(data-label);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--color-text-muted);
  }
}

@media (max-width: 480px) {
  .themed .t-billing-summary {
    grid-template-columns: minmax(0, 1fr);
  }

  .themed .t-billing-summary-value {
    font-size: 1.125rem;
  }

  .themed .t-billing-frozen-note {
    padding: var(--space-2) var(--space-3);
    font-size: 0.75rem;
  }
}

.themed .t-billing-ledger-total td {
  font-weight: 700;
  background: var(--color-surface-muted);
  border-top: 2px solid var(--color-border-strong);
  border-bottom: none;
}

@media (max-width: 768px) {
  .themed .t-billing-ledger-total td {
    display: flex;
    justify-content: space-between;
  }
}

@media (max-width: 480px) {
  .themed .t-billing-ledger-total td {
    font-size: 0.8125rem;
  }
}

.themed .t-billing-generator {
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--color-surface-muted);
  padding: var(--space-4);
}

@media (max-width: 768px) {
  .themed .t-billing-generator { padding: var(--space-3); }
}

@media (max-width: 480px) {
  .themed .t-billing-generator { padding: var(--space-2); }
}

/* --- Workflow explainer strip (account pages) --- */

.themed .t-billing-workflow {
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-info-border);
  background: var(--color-info-bg);
  color: var(--color-info-text);
}

.themed .t-billing-workflow-active {
  border-color: var(--color-success-border);
  background: var(--color-success-bg);
  color: var(--color-success-text);
}

.themed .t-billing-workflow-closed {
  border-color: var(--color-border);
  background: var(--color-surface-muted);
  color: var(--color-text-muted);
}

.themed .t-billing-workflow-steps {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.themed .t-billing-workflow-step {
  padding: var(--space-0-5) var(--space-2-5);
  border-radius: var(--radius-full);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  color: var(--color-text-subtle);
}

.themed .t-billing-workflow-step-active {
  background: var(--color-primary-600);
  border-color: var(--color-primary-600);
  color: var(--color-text-inverse);
}

.themed .t-billing-workflow-step-done {
  background: var(--color-surface);
  border-color: var(--color-border-strong);
  color: var(--color-text-muted);
}

.themed .t-billing-workflow-arrow {
  color: var(--color-text-subtle);
  font-size: 0.75rem;
}

.themed .t-billing-workflow-text {
  font-size: 0.8125rem;
  line-height: 1.55;
  margin: 0;
}

@media (max-width: 768px) {
  .themed .t-billing-workflow { padding: var(--space-3); }
  .themed .t-billing-workflow-arrow { display: none; }
}

@media (max-width: 480px) {
  .themed .t-billing-workflow-text { font-size: 0.75rem; }
  .themed .t-billing-workflow-step { font-size: 0.625rem; }
}

.themed .t-billing-workflow-draft {
  border-color: var(--color-info-border);
  background: var(--color-info-bg);
  color: var(--color-info-text);
}

.themed .t-billing-row-waived {
  background: var(--color-surface-muted);
  color: var(--color-text-subtle);
  text-decoration: line-through;
}

@media (max-width: 768px) { .themed .t-billing-row-waived { text-decoration: none; } }
@media (max-width: 480px) { .themed .t-billing-row-waived { font-size: 0.625rem; } }

/* --- Adjustment mode switch (one-off vs per-instalment) --- */

.themed .t-billing-mode-switch {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}

.themed .t-billing-mode-option {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
  font-size: 0.8125rem;
}

.themed .t-billing-mode-option:hover {
  border-color: var(--color-border-strong);
  background: var(--color-surface-hover);
}

.themed .t-billing-mode-option span {
  display: block;
}

.themed .t-billing-recurring-badge {
  display: inline-block;
  margin-left: var(--space-2);
  padding: var(--space-0-5) var(--space-2);
  border-radius: var(--radius-full);
  background: var(--color-info-bg);
  color: var(--color-info-text);
  border: 1px solid var(--color-info-border);
  font-size: 0.6875rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

@media (max-width: 768px) {
  .themed .t-billing-mode-switch { grid-template-columns: minmax(0, 1fr); }
  .themed .t-billing-recurring-badge { display: block; margin: var(--space-1) 0 0 0; }
}

@media (max-width: 480px) {
  .themed .t-billing-mode-option { padding: var(--space-2); font-size: 0.75rem; }
  .themed .t-billing-recurring-badge { font-size: 0.625rem; }
}


/* =========================================================================
   BILLING — Money events (Phase 3)
   =========================================================================
   Payment capture, receipt history, reversal and refund.

   The visual grammar has to keep three things apart, because conflating them
   falsifies the ledger:
     · a received payment      (neutral)
     · a REVERSED payment      (struck through + ANNULE badge — the record was wrong)
     · a refund                (negative amount — money genuinely went back)
   ========================================================================= */

.themed .t-billing-pay-card {
  border-left: 4px solid var(--color-success-border);
}

.themed .t-billing-next-due {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1-5);
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-warning-border);
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
  font-size: 0.8125rem;
}

.themed .t-billing-next-due-clear {
  border-color: var(--color-success-border);
  background: var(--color-success-bg);
  color: var(--color-success-text);
}

.themed .t-billing-pay-form {
  margin-top: var(--space-2);
}

/* --- Receipt history ----------------------------------------------------- */

.themed .t-billing-payments,
.themed .t-billing-refunds {
  border-collapse: collapse;
  font-size: 0.8125rem;
}

.themed .t-billing-payments th,
.themed .t-billing-refunds th {
  text-align: left;
  padding: var(--space-2) var(--space-3);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  background: var(--color-surface-muted);
  border-bottom: 1px solid var(--color-border);
}

.themed .t-billing-payments td,
.themed .t-billing-refunds td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border);
  vertical-align: middle;
}

/* A reversed receipt stays in the table — the row is never deleted (rule N3) —
   but must not read as money the school holds. */
.themed .t-billing-payment-reversed td {
  color: var(--color-text-muted);
  background: var(--color-surface-muted);
}

.themed .t-billing-payment-reversed .t-billing-amount {
  text-decoration: line-through;
}

.themed .t-billing-reversed-badge {
  display: inline-block;
  margin-left: var(--space-1-5);
  padding: 0 var(--space-1-5);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-danger-border);
  background: var(--color-danger-bg);
  color: var(--color-danger-text);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.themed .t-billing-reversed-reason {
  font-size: 0.75rem;
  font-style: italic;
  color: var(--color-text-muted);
}

.themed .t-billing-reverse-form {
  display: flex;
  align-items: center;
  gap: var(--space-1-5);
}

.themed .t-billing-reverse-reason {
  min-width: 0;
  width: 11rem;
}

.themed .t-billing-reverse-btn {
  flex-shrink: 0;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-danger-border);
  background: var(--color-surface);
  color: var(--color-danger-text);
  font-weight: 600;
}

.themed .t-billing-reverse-btn:hover {
  background: var(--color-danger-bg);
}

.themed .t-billing-refund-card {
  border-left: 4px solid var(--color-warning-border);
}

/* --- Mobile (R6) --------------------------------------------------------- */

@media (max-width: 768px) {
  .themed .t-billing-payments thead,
  .themed .t-billing-refunds thead {
    display: none;
  }

  .themed .t-billing-payments tr,
  .themed .t-billing-refunds tr {
    display: block;
    border-bottom: 2px solid var(--color-border);
    padding: var(--space-2) 0;
  }

  .themed .t-billing-payments td,
  .themed .t-billing-refunds td {
    display: flex;
    justify-content: space-between;
    gap: var(--space-3);
    border-bottom: none;
    padding: var(--space-1-5) var(--space-3);
  }

  .themed .t-billing-payments td::before,
  .themed .t-billing-refunds td::before {
    content: attr(data-label);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--color-text-muted);
  }

  .themed .t-billing-reverse-form {
    flex-wrap: wrap;
    justify-content: flex-end;
  }

  .themed .t-billing-reverse-reason {
    width: 100%;
  }
}

@media (max-width: 480px) {
  .themed .t-billing-next-due {
    font-size: 0.75rem;
    padding: var(--space-1-5) var(--space-2);
  }

  .themed .t-billing-pay-card,
  .themed .t-billing-refund-card {
    border-left-width: 3px;
  }

  .themed .t-billing-payments,
  .themed .t-billing-refunds {
    font-size: 0.75rem;
  }
}


/* =========================================================================
   BILLING — Documents (Phase 4)
   =========================================================================
   The Carnet is the deliverable that replaces the school's paper card, so its
   action bar reads as a primary affordance rather than a footnote. WhatsApp
   gets its own colour because it leaves the application.
   ========================================================================= */

.themed .t-billing-doc-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-primary-600);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.themed .t-billing-doc-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
  flex: 1 1 20rem;
}

.themed .t-billing-doc-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* Leaving the app is a different kind of action from downloading a file, and the
   colour says so before the label is read. */
.themed .t-billing-wa-btn {
  border-color: var(--color-success-border);
  background: var(--color-success-bg);
  color: var(--color-success-text);
}

.themed .t-billing-wa-btn:hover {
  background: var(--color-surface);
}

.themed .t-billing-receipt-link {
  display: inline-block;
  margin-right: var(--space-2);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-primary-600);
  text-decoration: underline;
}

/* --- Mobile (R6) --------------------------------------------------------- */

@media (max-width: 768px) {
  .themed .t-billing-doc-actions {
    flex-direction: column;
    align-items: stretch;
  }

  .themed .t-billing-doc-buttons {
    flex-direction: column;
  }

  .themed .t-billing-doc-buttons > * {
    width: 100%;
    justify-content: center;
  }
}

@media (max-width: 480px) {
  .themed .t-billing-doc-actions {
    padding: var(--space-3);
    border-left-width: 3px;
  }

  .themed .t-billing-receipt-link {
    display: block;
    margin: 0 0 var(--space-1) 0;
  }
}


/* =========================================================================
   BILLING — Owner dashboard (Phase 5)
   =========================================================================
   The screen answers one question: who owes us money. Two visual jobs follow
   from that — make the totals readable at a glance, and make the students
   nobody configured impossible to skim past.
   ========================================================================= */

.themed .t-billing-kpi-grid { align-items: stretch; }

.themed .t-billing-kpi {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.themed .t-billing-kpi-label {
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.themed .t-billing-kpi-value {
  font-size: 1.375rem;
  font-weight: 700;
  color: var(--color-text);
}

.themed .t-billing-kpi-warning { border-color: var(--color-warning-border); }
.themed .t-billing-kpi-warning .t-billing-kpi-value { color: var(--color-warning-text); }
.themed .t-billing-kpi-danger { border-color: var(--color-danger-border); }
.themed .t-billing-kpi-danger .t-billing-kpi-value { color: var(--color-danger-text); }

/* The alarm. A count the admin cannot act on is just anxiety, so the whole
   panel is the link to the filtered view. */
.themed .t-billing-alarm {
  display: block;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-warning-border);
  border-left: 4px solid var(--color-warning-border);
  border-radius: var(--radius-md);
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
  font-size: 0.8125rem;
  text-decoration: none;
}

.themed .t-billing-alarm:hover { background: var(--color-surface); }

.themed .t-billing-filter-bar {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr auto;
  gap: var(--space-3);
  align-items: end;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.themed .t-billing-filter-actions {
  display: flex;
  gap: var(--space-2);
}

.themed .t-billing-roster { border-collapse: collapse; font-size: 0.8125rem; }

.themed .t-billing-roster th {
  text-align: left;
  padding: var(--space-2) var(--space-3);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  background: var(--color-surface-muted);
  border-bottom: 1px solid var(--color-border);
}

.themed .t-billing-roster td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

.themed .t-billing-col-num { text-align: right; }

.themed .t-billing-roster-link {
  font-weight: 600;
  color: var(--color-primary-600);
  text-decoration: none;
}

.themed .t-billing-roster-link:hover { text-decoration: underline; }

/* A student nobody configured is the point of the screen, so the row is tinted
   rather than left to blend into the others. */
.themed .t-billing-row-unconfigured { background: var(--color-warning-bg); }

.themed .t-billing-unconfigured-badge {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-warning-border);
  color: var(--color-warning-text);
  font-size: 0.6875rem;
  font-weight: 700;
  text-decoration: none;
}

.themed .t-billing-unconfigured-badge:hover { background: var(--color-surface); }

.themed .t-billing-leaver-badge {
  display: inline-block;
  margin-left: var(--space-1-5);
  padding: 0 var(--space-1-5);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text-muted);
  font-size: 0.625rem;
  font-weight: 600;
}

/* --- Mobile (R6) --------------------------------------------------------- */

@media (max-width: 768px) {
  .themed .t-billing-filter-bar { grid-template-columns: minmax(0, 1fr); }
  .themed .t-billing-filter-actions > * { flex: 1 1 auto; justify-content: center; }

  .themed .t-billing-roster thead { display: none; }

  .themed .t-billing-roster tr {
    display: block;
    border-bottom: 2px solid var(--color-border);
    padding: var(--space-2) 0;
  }

  .themed .t-billing-roster td {
    display: flex;
    justify-content: space-between;
    gap: var(--space-3);
    border-bottom: none;
    padding: var(--space-1-5) var(--space-3);
    text-align: left;
  }

  .themed .t-billing-roster td::before {
    content: attr(data-label);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--color-text-muted);
  }
}

@media (max-width: 480px) {
  .themed .t-billing-kpi { padding: var(--space-2) var(--space-3); }
  .themed .t-billing-kpi-value { font-size: 1.125rem; }
  .themed .t-billing-alarm { font-size: 0.75rem; border-left-width: 3px; }
  .themed .t-billing-roster { font-size: 0.75rem; }
}


/* =========================================================================
   BILLING — Owner dashboard, fixes from the browser pass (Phase 5)
   =========================================================================
   Two alignment bugs and three new components.
   ========================================================================= */

/* FIX — numeric headers were left-aligned while their cells were right-aligned.
   `.themed .t-billing-roster th` is (0,2,1) and out-specifies
   `.themed .t-billing-col-num` (0,2,0), so the generic header rule won and the
   header drifted left of its own column. Reordering would not help; the fix has
   to raise specificity. */
.themed .t-billing-roster th.t-billing-col-num {
  text-align: right;
}

/* FIX — Filtrer/Effacer sat 20px below their fields. `.t-form-group` carries
   `margin-bottom: var(--space-5)`, and the existing strip-the-margin convention
   matches `.flex` containers only; this filter bar is a GRID, so `align-items:
   end` was aligning margin boxes rather than controls. */
.themed .t-billing-filter-bar .t-form-group {
  margin-bottom: 0;
}

/* --- Credit attribution --------------------------------------------------- */

.themed .t-billing-credit-panel {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-success-border);
  border-left: 4px solid var(--color-success-border);
  border-radius: var(--radius-md);
  background: var(--color-success-bg);
  color: var(--color-success-text);
  font-size: 0.8125rem;
}

.themed .t-billing-credit-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.themed .t-billing-credit-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.themed .t-billing-credit-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
}

.themed .t-billing-credit-name {
  font-weight: 600;
  color: var(--color-success-text);
  text-decoration: underline;
}

.themed .t-billing-credit-class,
.themed .t-billing-credit-more {
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

/* --- Result bar: a filter matching nothing must not read as broken -------- */

.themed .t-billing-result-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 0 var(--space-1);
  font-size: 0.8125rem;
  color: var(--color-text-muted);
}

.themed .t-billing-result-count strong { color: var(--color-text); }

.themed .t-billing-filter-notice {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-info-border);
  background: var(--color-info-bg);
  color: var(--color-info-text);
  font-size: 0.75rem;
}

.themed .t-billing-filter-notice a {
  font-weight: 600;
  text-decoration: underline;
  color: var(--color-info-text);
}

/* --- Pager ---------------------------------------------------------------- */

.themed .t-billing-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-2);
  font-size: 0.8125rem;
}

.themed .t-billing-pager-link {
  padding: var(--space-1-5) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-primary-600);
  font-weight: 600;
  text-decoration: none;
}

.themed .t-billing-pager-link:hover { background: var(--color-surface-hover); }

.themed .t-billing-pager-state { color: var(--color-text-muted); }

/* --- Mobile (R6) --------------------------------------------------------- */

@media (max-width: 768px) {
  .themed .t-billing-result-bar { flex-direction: column; align-items: flex-start; }
  .themed .t-billing-credit-list li { gap: var(--space-1); }
  .themed .t-billing-pager { flex-wrap: wrap; }
}

@media (max-width: 480px) {
  .themed .t-billing-credit-panel { padding: var(--space-2) var(--space-3); }
  .themed .t-billing-pager-link { padding: var(--space-1) var(--space-2); }
  .themed .t-billing-result-bar { font-size: 0.75rem; }
}


/* =========================================================================
   BILLING — Hardening (Phase 6)
   =========================================================================
   The near-duplicate confirmation. Deliberately NOT a danger colour: this is a
   question, not a refusal, and two identical payments in one day are often
   entirely legitimate.
   ========================================================================= */

.themed .t-billing-dup-warning {
  padding: var(--space-4);
  border: 1px solid var(--color-warning-border);
  border-left: 4px solid var(--color-warning-border);
  border-radius: var(--radius-lg);
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
}

.themed .t-billing-dup-title {
  font-weight: 700;
  margin-bottom: var(--space-1);
}

.themed .t-billing-dup-body {
  font-size: 0.8125rem;
  margin-bottom: var(--space-3);
}

.themed .t-billing-dup-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

@media (max-width: 768px) {
  .themed .t-billing-dup-actions { flex-direction: column; }
  .themed .t-billing-dup-actions > * { width: 100%; justify-content: center; }
}

@media (max-width: 480px) {
  .themed .t-billing-dup-warning {
    padding: var(--space-3);
    border-left-width: 3px;
  }
  .themed .t-billing-dup-body { font-size: 0.75rem; }
}


/* =========================================================================
   BILLING — UX refinement (roster actions, collapsed rare actions, discounts)
   =========================================================================
   The organising idea: a secretary encaisse every day, adjusts occasionally,
   and refunds or closes a file twice a year. Visual weight now matches that,
   instead of giving all three the same card.
   ========================================================================= */

/* --- Row actions ---------------------------------------------------------- */

.themed .t-billing-row-action {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-primary-600);
  background: var(--color-primary-600);
  color: var(--color-surface);
  font-size: 0.75rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.themed .t-billing-row-action:hover { background: var(--color-primary-700); }

/* "Voir" is navigation, not money — it should not compete with "Encaisser". */
.themed .t-billing-row-action-muted {
  border-color: var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text-muted);
}

.themed .t-billing-row-action-muted:hover { background: var(--color-surface-hover); }

/* The fix for the reported "there is no Actions button": this used to be an
   anchor styled as a status pill, so it read as a label. */
.themed .t-billing-configure-btn {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-warning-border);
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
  font-size: 0.75rem;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}

.themed .t-billing-configure-btn:hover { background: var(--color-surface); }

.themed .t-billing-action-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

/* --- Collapsed rare actions ----------------------------------------------- */

.themed .t-billing-more-actions {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.themed .t-billing-more-summary {
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-text-muted);
  list-style: none;
}

.themed .t-billing-more-summary::-webkit-details-marker { display: none; }

.themed .t-billing-more-summary::before {
  content: '\25B8';
  display: inline-block;
  margin-right: var(--space-2);
  transition: transform var(--transition-fast);
}

.themed .t-billing-more-actions[open] .t-billing-more-summary::before {
  transform: rotate(90deg);
}

.themed .t-billing-more-summary:hover { color: var(--color-text); }

.themed .t-billing-more-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: 0 var(--space-4) var(--space-4);
  border-top: 1px solid var(--color-border);
  padding-top: var(--space-4);
}

/* --- Discounts, lifted out of the schedule -------------------------------- */

.themed .t-billing-discount-summary {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-success-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.themed .t-billing-discount-title {
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}

.themed .t-billing-discount-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0 0 var(--space-2) 0;
  padding: 0;
  list-style: none;
  font-size: 0.8125rem;
}

.themed .t-billing-discount-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}

/* The compact active-state note: explanation without the lifecycle diagram. */
.themed .t-billing-workflow-compact {
  padding: var(--space-2) var(--space-3);
  font-size: 0.8125rem;
}

/* --- Mobile (R6) ---------------------------------------------------------- */

@media (max-width: 768px) {
  .themed .t-billing-row-action,
  .themed .t-billing-configure-btn {
    width: 100%;
    justify-content: center;
  }
  .themed .t-billing-more-body { padding: var(--space-3); }
}

@media (max-width: 480px) {
  .themed .t-billing-more-summary { padding: var(--space-2) var(--space-3); }
  .themed .t-billing-discount-summary {
    padding: var(--space-2) var(--space-3);
    border-left-width: 3px;
  }
  .themed .t-billing-discount-list { font-size: 0.75rem; }
}


/* =========================================================================
   BILLING — Excel exports
   ========================================================================= */

.themed .t-billing-export-btn {
  border-color: var(--color-border-strong);
  background: var(--color-surface);
  color: var(--color-text);
  white-space: nowrap;
}

.themed .t-billing-export-btn:hover { background: var(--color-surface-hover); }

.themed .t-billing-journal-form {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.themed .t-billing-journal-label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.themed .t-billing-journal-input { width: 10rem; }

@media (max-width: 768px) {
  .themed .t-billing-journal-form {
    flex-wrap: wrap;
    width: 100%;
  }
  .themed .t-billing-journal-input { flex: 1 1 8rem; width: auto; }
  .themed .t-billing-export-btn { width: 100%; justify-content: center; }
}

@media (max-width: 480px) {
  .themed .t-billing-journal-label { width: 100%; }
}

/* =========================================================================
   ANNOUNCEMENTS (Annonces) — admin list, editor, parent feed
   -------------------------------------------------------------------------
   Scope: templates/dashboard/parents/announcements.html
          templates/dashboard/parents/announcement_form.html
          apps/parents/templates/parents/communications.html
          apps/parents/templates/parents/announcement_detail.html
   All rules .themed-scoped, token-only (R2/R3). Breakpoints at the end (R6).
   ========================================================================= */

/* -- Toolbar: search + status filter ------------------------------------ */
.themed .t-ann-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  box-shadow: var(--shadow-sm);
}

.themed .t-ann-toolbar-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.themed .t-ann-toolbar-search { flex: 1 1 16rem; }

.themed .t-ann-toolbar-label {
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-text-subtle);
}

.themed .t-ann-toolbar-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* -- List + card -------------------------------------------------------- */
.themed .t-ann-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.themed .t-ann-card {
  position: relative;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--transition-base), border-color var(--transition-base);
}

.themed .t-ann-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--color-border-strong);
}

.themed .t-ann-card-published { border-left-color: var(--color-success-icon); }
.themed .t-ann-card-draft     { border-left-color: var(--color-border-strong); }
.themed .t-ann-card-expired   { border-left-color: var(--color-warning-icon); }

.themed .t-ann-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
}

.themed .t-ann-card-badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1-5);
  margin-bottom: var(--space-2);
}

.themed .t-ann-card-title {
  font-size: var(--text-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
  line-height: var(--leading-tight);
}

.themed .t-ann-card-preview {
  margin-top: var(--space-1-5);
  font-size: var(--text-base);
  color: var(--color-text-muted);
  line-height: var(--leading-normal);
}

.themed .t-ann-card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  margin-top: var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-text-subtle);
}

.themed .t-ann-card-meta-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.themed .t-ann-card-meta-warning { color: var(--color-warning-text); }

.themed .t-ann-card-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* -- Status + audience pills -------------------------------------------- */
.themed .t-ann-status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-0-5) var(--space-2);
  border-radius: var(--radius-full);
  border: 1px solid transparent;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.themed .t-ann-status-published {
  background-color: var(--color-success-bg);
  border-color: var(--color-success-border);
  color: var(--color-success-text);
}

.themed .t-ann-status-draft {
  background-color: var(--color-surface-muted);
  border-color: var(--color-border);
  color: var(--color-text-muted);
}

.themed .t-ann-status-expired {
  background-color: var(--color-warning-bg);
  border-color: var(--color-warning-border);
  color: var(--color-warning-text);
}

.themed .t-ann-audience {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-0-5) var(--space-2);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  background-color: var(--color-surface-muted);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  max-width: 18rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.themed .t-ann-audience-targeted {
  background-color: var(--color-info-bg);
  border-color: var(--color-info-border);
  color: var(--color-info-text);
}

/* -- Empty states ------------------------------------------------------- */
.themed .t-ann-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-2);
  background-color: var(--color-surface);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-xl);
  padding: var(--space-12) var(--space-6);
}

.themed .t-ann-empty-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: var(--radius-full);
  background-color: var(--color-surface-active);
  color: var(--color-primary-600);
  margin-bottom: var(--space-1);
}

.themed .t-ann-empty-title {
  font-size: var(--text-xl);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
}

.themed .t-ann-empty-text {
  font-size: var(--text-base);
  color: var(--color-text-muted);
  max-width: 26rem;
  line-height: var(--leading-normal);
}

.themed .t-ann-empty-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

/* -- Editor layout ------------------------------------------------------ */
.themed .t-ann-editor {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 20rem;
  gap: var(--space-5);
  align-items: start;
}

.themed .t-ann-editor-main {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}

.themed .t-ann-editor-side {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}

/* -- Publication radio cards -------------------------------------------- */
.themed .t-ann-pub-option {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2-5);
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
  cursor: pointer;
  transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

.themed .t-ann-pub-option:hover { border-color: var(--color-primary-300); }

.themed .t-ann-pub-option-selected {
  border-color: var(--color-primary-500);
  background-color: var(--color-surface-active);
}

.themed .t-ann-pub-option-title {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
}

.themed .t-ann-pub-option-hint {
  display: block;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin-top: var(--space-0-5);
  line-height: var(--leading-normal);
}

/* -- Audience picker ---------------------------------------------------- */
.themed .t-ann-audience-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-info-border);
  background-color: var(--color-info-bg);
  border-radius: var(--radius-md);
}

.themed .t-ann-audience-summary-label {
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-info-text);
}

.themed .t-ann-audience-summary-value {
  font-size: var(--text-md);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
}

.themed .t-ann-audience-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1-5);
  padding: var(--space-1-5) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
  color: var(--color-text-base);
  font-size: var(--text-base);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.themed .t-ann-audience-toggle:hover {
  background-color: var(--color-surface-hover);
  border-color: var(--color-primary-400);
}

.themed .t-ann-target-group { margin-top: var(--space-4); }

.themed .t-ann-target-group-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.themed .t-ann-target-group-title {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
}

.themed .t-ann-target-count {
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-primary-700);
}

.themed .t-ann-target-count-empty { color: var(--color-text-subtle); }

.themed .t-ann-target-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: var(--space-2);
}

.themed .t-ann-target-grid-compact {
  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
}

.themed .t-ann-target-option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-2-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
  cursor: pointer;
  min-height: 2.5rem;
  transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

.themed .t-ann-target-option:hover { border-color: var(--color-primary-400); }

.themed .t-ann-target-option-selected {
  border-color: var(--color-primary-500);
  background-color: var(--color-surface-active);
  box-shadow: var(--shadow-inset);
}

.themed .t-ann-target-code {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
}

.themed .t-ann-target-name {
  font-size: var(--text-sm);
  color: var(--color-text-subtle);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.themed .t-ann-target-subgroup { margin-bottom: var(--space-3); }

.themed .t-ann-target-subgroup-label {
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-subtle);
  margin-bottom: var(--space-1-5);
}

.themed .t-ann-target-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.themed .t-ann-target-empty {
  font-size: var(--text-sm);
  color: var(--color-text-subtle);
  font-style: italic;
  padding: var(--space-2) 0;
}

/* -- Attachments -------------------------------------------------------- */
.themed .t-ann-attach-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}

.themed .t-ann-attach-count {
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
}

.themed .t-ann-attach-drop {
  display: block;
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
  background-color: var(--color-surface-muted);
  padding: var(--space-6) var(--space-4);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

.themed .t-ann-attach-drop:hover {
  border-color: var(--color-primary-400);
  background-color: var(--color-surface-active);
}

.themed .t-ann-attach-drop-title {
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
}

.themed .t-ann-attach-drop-hint {
  font-size: var(--text-sm);
  color: var(--color-text-subtle);
  margin-top: var(--space-1);
}

.themed .t-ann-attach-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1-5);
  margin-top: var(--space-3);
}

.themed .t-ann-attach-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
}

.themed .t-ann-attach-name {
  font-size: var(--text-base);
  color: var(--color-text-base);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.themed .t-ann-attach-size {
  font-size: var(--text-sm);
  color: var(--color-text-subtle);
  white-space: nowrap;
}

.themed .t-ann-attach-remove {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-danger-text);
  cursor: pointer;
  white-space: nowrap;
}

/* -- Form actions ------------------------------------------------------- */
.themed .t-ann-form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* Grouped at the end: a cancel link stranded at the opposite edge of a wide
     canvas reads as unrelated to the submit it belongs with. */
  justify-content: flex-end;
  gap: var(--space-2);
  padding-top: var(--space-2);
}

.themed .t-ann-form-actions-right {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* -- Parent-facing feed + reader ---------------------------------------- */
.themed .t-ann-feed {
  display: flex;
  flex-direction: column;
  gap: var(--space-2-5);
}

.themed .t-ann-feed-card {
  display: block;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-success-icon);
  border-radius: var(--radius-lg);
  padding: var(--space-3-5) var(--space-4);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--transition-base), border-color var(--transition-base);
}

.themed .t-ann-feed-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--color-success-border);
  border-left-color: var(--color-success-text);
}

.themed .t-ann-feed-title {
  font-size: var(--text-md);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
  line-height: var(--leading-tight);
}

.themed .t-ann-feed-preview {
  font-size: var(--text-base);
  color: var(--color-text-muted);
  margin-top: var(--space-1);
  line-height: var(--leading-normal);
}

.themed .t-ann-feed-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-subtle);
}

.themed .t-ann-feed-cta {
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-link);
  white-space: nowrap;
}

.themed .t-ann-read-body {
  font-size: var(--text-md);
  color: var(--color-text-base);
  line-height: var(--leading-relaxed);
  max-width: 42rem;
}

/* -- Mandatory responsive rules (R6) ------------------------------------ */
@media (max-width: 768px) {
  .themed .t-ann-toolbar {
    flex-direction: column;
    align-items: stretch;
    padding: var(--space-3);
  }
  .themed .t-ann-toolbar-search { flex: 1 1 auto; }
  .themed .t-ann-toolbar-actions { width: 100%; }
  .themed .t-ann-toolbar-actions > * { flex: 1 1 auto; text-align: center; }

  .themed .t-ann-card { padding: var(--space-3-5) var(--space-4); }
  .themed .t-ann-card-head { flex-direction: column; gap: var(--space-3); }
  .themed .t-ann-card-actions { width: 100%; }
  .themed .t-ann-card-title { font-size: var(--text-md); }
  .themed .t-ann-audience { max-width: 100%; }

  .themed .t-ann-empty { padding: var(--space-8) var(--space-4); }
  .themed .t-ann-empty-icon { width: 3rem; height: 3rem; }
  .themed .t-ann-empty-title { font-size: var(--text-lg); }

  .themed .t-ann-editor { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
  .themed .t-ann-editor-main { gap: var(--space-4); }

  .themed .t-ann-target-grid { grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); }
  .themed .t-ann-target-grid-compact { grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr)); }
  .themed .t-ann-target-option { min-height: 2.75rem; }

  .themed .t-ann-attach-drop { padding: var(--space-5) var(--space-3); }
  .themed .t-ann-form-actions { flex-direction: column-reverse; align-items: stretch; }
  .themed .t-ann-form-actions-right { flex-direction: column-reverse; align-items: stretch; }

  .themed .t-ann-read-body { font-size: var(--text-base); }
}

@media (max-width: 480px) {
  .themed .t-ann-card { padding: var(--space-3); }
  .themed .t-ann-card-meta { flex-direction: column; align-items: flex-start; gap: var(--space-1); }
  .themed .t-ann-card-actions > * { flex: 1 1 auto; text-align: center; }

  .themed .t-ann-empty { padding: var(--space-6) var(--space-3); }
  .themed .t-ann-empty-actions { width: 100%; flex-direction: column; }
  .themed .t-ann-empty-actions > * { width: 100%; text-align: center; }

  .themed .t-ann-target-grid,
  .themed .t-ann-target-grid-compact { grid-template-columns: repeat(auto-fill, minmax(5.5rem, 1fr)); }
  .themed .t-ann-target-name { display: none; }
  .themed .t-ann-target-actions > * { flex: 1 1 auto; text-align: center; }

  .themed .t-ann-audience-summary { flex-direction: column; align-items: stretch; }
  .themed .t-ann-audience-toggle { width: 100%; justify-content: center; }

  .themed .t-ann-attach-row { flex-wrap: wrap; gap: var(--space-1-5); }
  .themed .t-ann-attach-drop { padding: var(--space-4) var(--space-2-5); }

  .themed .t-ann-feed-card { padding: var(--space-3); }
  .themed .t-ann-feed-meta { flex-direction: column; align-items: flex-start; gap: var(--space-1); }
}

/* =========================================================================
   MESSAGING (Messagerie) — staff workspace, thread, composer, parent portal
   -------------------------------------------------------------------------
   Scope: templates/dashboard/parents/message_inbox.html
          templates/dashboard/parents/message_new.html
          templates/dashboard/parents/partials/conv_list.html
          templates/dashboard/parents/partials/conv_detail.html
          templates/dashboard/parents/partials/message_bubble.html
          apps/parents/templates/parents/conversation_inbox.html
          apps/parents/templates/parents/conversation_detail.html
          apps/parents/templates/parents/partials/message_bubble.html

   Extends the pre-existing t-msg-bubble / t-msg-sent / t-msg-received trio
   rather than replacing it. All rules .themed-scoped, token-only (R2/R3).
   Breakpoints at the end (R6).
   ========================================================================= */

/* -- Workspace shell ---------------------------------------------------- */
.themed .t-msg-workspace {
  display: flex;
  /* The template cancels <main>'s padding with -m-6, so the shell is exactly
     the viewport minus the sticky 4rem header. Anything taller pushes the
     composer below the fold. */
  height: calc(100dvh - 4rem);
  overflow: hidden;
  background-color: var(--color-canvas);
}

@supports not (height: 100dvh) {
  .themed .t-msg-workspace { height: calc(100vh - 4rem); }
}

.themed .t-msg-sidebar {
  display: flex;
  flex-direction: column;
  width: 23rem;
  flex-shrink: 0;
  background-color: var(--color-surface);
  border-right: 1px solid var(--color-border);
  /* Lifts the list above the canvas so the two panes read as separate surfaces. */
  box-shadow: var(--shadow-sm);
  z-index: var(--z-base);
}

.themed .t-msg-sidebar-header {
  padding: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.themed .t-msg-sidebar-title {
  font-size: var(--text-xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-text-base);
  line-height: var(--leading-tight);
}

.themed .t-msg-sidebar-subtitle {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin-top: var(--space-0-5);
}

.themed .t-msg-sidebar-tools {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
  gap: var(--space-2-5);
}

.themed .t-msg-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background-color: var(--color-canvas);
}

/* -- Filter pills ------------------------------------------------------- */
.themed .t-msg-filter-bar {
  display: flex;
  align-items: center;
  gap: var(--space-1-5);
}

.themed .t-msg-filter-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background-color: var(--color-surface);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}

.themed .t-msg-filter-pill:hover {
  background-color: var(--color-surface-hover);
  border-color: var(--color-border-strong);
}

.themed .t-msg-filter-pill-active {
  background-color: var(--color-primary-600);
  border-color: var(--color-primary-600);
  color: var(--color-text-inverse);
}

.themed .t-msg-filter-pill-active:hover {
  background-color: var(--color-primary-700);
  border-color: var(--color-primary-700);
}

.themed .t-msg-filter-count {
  font-size: var(--text-xs);
  font-weight: var(--font-weight-bold);
}

/* -- Conversation list -------------------------------------------------- */
.themed .t-msg-list {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

.themed .t-msg-thread-row {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border: 0;
  border-bottom: 1px solid var(--color-border);
  border-left: 3px solid transparent;
  background-color: var(--color-surface);
  cursor: pointer;
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.themed .t-msg-thread-row:hover {
  background-color: var(--color-surface-hover);
}

.themed .t-msg-thread-row-unread {
  background-color: var(--color-surface-active);
}

.themed .t-msg-thread-row-active {
  background-color: var(--color-surface-active);
  border-left-color: var(--color-primary-600);
}

.themed .t-msg-thread-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}

.themed .t-msg-thread-name {
  font-size: var(--text-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-base);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.themed .t-msg-thread-row-unread .t-msg-thread-name {
  font-weight: var(--font-weight-bold);
}

.themed .t-msg-thread-time {
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
  white-space: nowrap;
  flex-shrink: 0;
}

.themed .t-msg-thread-context {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-primary-700);
  margin-top: var(--space-0-5);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.themed .t-msg-thread-subject {
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-muted);
  margin-top: var(--space-0-5);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.themed .t-msg-thread-preview {
  font-size: var(--text-sm);
  color: var(--color-text-subtle);
  margin-top: var(--space-0-5);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.themed .t-msg-thread-preview-prefix {
  color: var(--color-text-muted);
  font-weight: var(--font-weight-medium);
}

.themed .t-msg-unread-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 var(--space-1);
  border-radius: var(--radius-full);
  background-color: var(--color-primary-600);
  color: var(--color-text-inverse);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-bold);
  flex-shrink: 0;
}

.themed .t-msg-load-more {
  padding: var(--space-3);
  text-align: center;
}

/* -- Empty states ------------------------------------------------------- */
.themed .t-msg-empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: var(--space-2);
  padding: var(--space-10) var(--space-6);
}

.themed .t-msg-empty-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: var(--radius-full);
  background-color: var(--color-surface-active);
  color: var(--color-primary-600);
  margin-bottom: var(--space-1);
}

.themed .t-msg-empty-title {
  font-size: var(--text-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
}

.themed .t-msg-empty-text {
  font-size: var(--text-base);
  color: var(--color-text-muted);
  max-width: 24rem;
  line-height: var(--leading-normal);
}

.themed .t-msg-empty-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

/* -- Thread header ------------------------------------------------------ */
.themed .t-msg-thread-header {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  background-color: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}

.themed .t-msg-thread-header-main {
  flex: 1;
  min-width: 0;
}

.themed .t-msg-thread-header-name {
  font-size: var(--text-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-base);
  line-height: var(--leading-tight);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.themed .t-msg-thread-header-context {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin-top: var(--space-0-5);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.themed .t-msg-thread-header-subject {
  display: inline-block;
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-primary-700);
  margin-top: var(--space-1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.themed .t-msg-back-btn {
  display: none;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  flex-shrink: 0;
  cursor: pointer;
}

.themed .t-msg-back-btn:hover {
  background-color: var(--color-surface-hover);
  color: var(--color-text-base);
}

/* -- Message stream ----------------------------------------------------- */
.themed .t-msg-stream {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.themed .t-msg-date-divider {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-2) 0;
}

.themed .t-msg-date-divider::before,
.themed .t-msg-date-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background-color: var(--color-border);
}

.themed .t-msg-date-divider-label {
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-subtle);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

/* Bubble width: a five-word message must not stretch across a 1400px pane. */
.themed .t-msg-bubble {
  max-width: min(78%, 34rem);
}

.themed .t-msg-body {
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.themed .t-msg-meta {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
  margin-top: var(--space-0-5);
}

.themed .t-msg-sender-name {
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-muted);
  margin-bottom: var(--space-0-5);
}

.themed .t-msg-empty-thread {
  text-align: center;
  color: var(--color-text-subtle);
  font-size: var(--text-base);
  padding: var(--space-10) var(--space-4);
}

/* -- Composer ----------------------------------------------------------- */
.themed .t-msg-composer {
  flex-shrink: 0;
  padding: var(--space-3) var(--space-5);
  background-color: var(--color-surface);
  border-top: 1px solid var(--color-border);
}

.themed .t-msg-composer-form {
  display: flex;
  align-items: flex-end;
  gap: var(--space-2);
}

.themed .t-msg-composer-input {
  flex: 1;
  min-height: 2.75rem;
  resize: none;
  line-height: var(--leading-normal);
}

.themed .t-msg-composer-send {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1-5);
  min-width: 2.75rem;
  height: 2.75rem;
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  background-color: var(--color-primary-600);
  color: var(--color-text-inverse);
  font-size: var(--text-base);
  font-weight: var(--font-weight-medium);
  flex-shrink: 0;
  cursor: pointer;
  transition: background-color var(--transition-fast);
}

.themed .t-msg-composer-send:hover { background-color: var(--color-primary-700); }

.themed .t-msg-composer-send:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.themed .t-msg-composer-hint {
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
  margin-top: var(--space-1-5);
}

/* -- New conversation form --------------------------------------------- */
.themed .t-msg-new-page {
  max-width: 52rem;
  margin-left: auto;
  margin-right: auto;
}

.themed .t-msg-recipient-list {
  max-height: 20rem;
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-surface);
}

.themed .t-msg-recipient-option {
  display: flex;
  align-items: center;
  gap: var(--space-2-5);
  padding: var(--space-2-5) var(--space-3);
  border-bottom: 1px solid var(--color-border);
  cursor: pointer;
  transition: background-color var(--transition-fast);
}

.themed .t-msg-recipient-option:last-child { border-bottom: 0; }
.themed .t-msg-recipient-option:hover { background-color: var(--color-surface-hover); }

.themed .t-msg-recipient-option-selected {
  background-color: var(--color-surface-active);
}

.themed .t-msg-recipient-name {
  font-size: var(--text-base);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-base);
}

.themed .t-msg-recipient-meta {
  font-size: var(--text-sm);
  color: var(--color-text-subtle);
}

.themed .t-msg-recipient-empty {
  padding: var(--space-6) var(--space-4);
  text-align: center;
  font-size: var(--text-sm);
  color: var(--color-text-subtle);
}

/* -- Parent portal thread shell ----------------------------------------- */
.themed .t-msg-parent-thread {
  height: calc(100dvh - 5.5rem);
  display: flex;
  flex-direction: column;
}

@supports not (height: 100dvh) {
  .themed .t-msg-parent-thread { height: calc(100vh - 5.5rem); }
}

/* -- Mandatory responsive rules (R6) ------------------------------------ */
@media (max-width: 768px) {
  /* Master/detail: one pane at a time, never two narrow columns. */
  .themed .t-msg-sidebar {
    width: 100%;
    border-right: 0;
  }
  .themed .t-msg-sidebar-header { padding: var(--space-3); }
  .themed .t-msg-sidebar-tools { padding: var(--space-2-5) var(--space-3); }

  .themed .t-msg-back-btn { display: inline-flex; }

  .themed .t-msg-thread-header { padding: var(--space-2-5) var(--space-3); }
  .themed .t-msg-thread-header-name { font-size: var(--text-md); }
  .themed .t-msg-stream { padding: var(--space-3); }
  .themed .t-msg-composer { padding: var(--space-2-5) var(--space-3); }

  /* Restore the pre-existing mobile bubble width (this block ships after the
     original t-msg-bubble media rule, so it must repeat it). */
  .themed .t-msg-bubble { max-width: 88%; }

  .themed .t-msg-filter-bar { flex-wrap: wrap; }
  .themed .t-msg-empty { padding: var(--space-8) var(--space-4); }
  .themed .t-msg-empty-icon { width: 3rem; height: 3rem; }

  .themed .t-msg-recipient-list { max-height: 16rem; }
}

@media (max-width: 480px) {
  .themed .t-msg-thread-row { padding: var(--space-2-5) var(--space-3); }
  .themed .t-msg-thread-name { font-size: var(--text-base); }

  .themed .t-msg-bubble { max-width: 92%; }
  .themed .t-msg-stream { padding: var(--space-2-5); gap: var(--space-1-5); }

  /* Icon-only send button — the label would crowd the textarea at this width,
     but the tap target stays 44px. */
  .themed .t-msg-composer-send {
    padding: 0;
    min-width: 2.75rem;
    width: 2.75rem;
  }
  .themed .t-msg-composer-send-label { display: none; }

  .themed .t-msg-empty { padding: var(--space-6) var(--space-3); }
  .themed .t-msg-empty-actions { width: 100%; flex-direction: column; }
  .themed .t-msg-empty-actions > * { width: 100%; text-align: center; }

  .themed .t-msg-filter-pill { padding: var(--space-1) var(--space-2-5); }
  .themed .t-msg-recipient-option { padding: var(--space-2) var(--space-2-5); }
}

/* -- Messaging depth pass (2026-08-17 review follow-up) ------------------ */
/* The two panes and the three bands of the thread were all flat white, so the
   header / stream / composer read as one undifferentiated column. These rules
   only add elevation and surface contrast — no layout changes. */

.themed .t-msg-form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
}

/* Sidebar bands */
.themed .t-msg-sidebar-header {
  background-color: var(--color-surface);
}

.themed .t-msg-sidebar-tools {
  background-color: var(--color-surface-muted);
}

.themed .t-msg-list {
  background-color: var(--color-surface);
}

/* Thread bands: header and composer are raised, the stream sits recessed
   between them so the eye reads three distinct zones. */
.themed .t-msg-thread-header {
  box-shadow: var(--shadow-sm);
  z-index: var(--z-base);
}

.themed .t-msg-stream {
  background-color: var(--color-canvas);
}

/* No custom shadow here: R3 forbids raw rgb() in a theme file and there is no
   upward-shadow token. The existing top border plus the recessed stream
   background already separate the composer from the messages. */
.themed .t-msg-composer {
  background-color: var(--color-surface);
  border-top-color: var(--color-border-strong);
  z-index: var(--z-base);
}

/* The composer input gets a slightly recessed field so the write area is
   findable at a glance inside an already-white band. */
.themed .t-msg-composer-input {
  background-color: var(--color-surface-muted);
}

.themed .t-msg-composer-input:focus {
  background-color: var(--color-surface);
}

/* New-conversation recipient list: same recessed treatment as the composer. */
.themed .t-msg-recipient-list {
  background-color: var(--color-surface);
  box-shadow: var(--shadow-inset);
}

@media (max-width: 768px) {
  .themed .t-msg-sidebar { box-shadow: none; }
  .themed .t-msg-form-actions > * { flex: 1 1 auto; text-align: center; }
}

@media (max-width: 480px) {
  .themed .t-msg-form-actions {
    flex-direction: column-reverse;
    align-items: stretch;
  }
  .themed .t-msg-form-actions > * { width: 100%; text-align: center; }
}
