/* ==========================================================================
   course.thu.edu.tw — institutional theme layer
   Loaded after Tabler and stylesheets/style.css; owns the site's identity.

   One ink family carries all chrome and all text hierarchy. The brand cyan
   survives as an accent on dark grounds and its deepened form on light ones,
   never as body text (raw #0ad1e5 is 1.86:1 on white).
   ========================================================================== */

:root {
  /* ── Ground ─────────────────────────────────────────────────────────── */
  --course-ground:        #f4f7f8;
  --course-surface:       #ffffff;
  --course-surface-2:     #eef3f4;
  --course-surface-3:     #e4ecee;
  --course-line:          #dbe4e6;
  --course-line-strong:   #c3d2d5;

  /* ── Ink ────────────────────────────────────────────────────────────── */
  --course-ink:           #1a2428;  /* 15.8:1 on white */
  --course-ink-soft:      #3d4b50;
  --course-ink-mute:      #5b6b70;  /*  5.6:1 on white */

  /* ── Identity ───────────────────────────────────────────────────────── */
  --course-primary:       #1d5c6b;  /*  7.5:1 on white */
  --course-primary-strong:#164a56;
  --course-primary-rgb:   29, 92, 107;
  --course-primary-on:    #ffffff;
  --course-accent:        #0b6e79;  /*  6.0:1 — marks + text accents */
  --course-accent-quiet:  rgba(11, 110, 121, .10);

  /* ── Text on a filled surface ───────────────────────────────────────────
     Which ink a fill takes is measured per fill, never pinned to white. The
     identity status fills are deep here and pale on the dark ground, so their
     text flips with the theme; the bright accent fills (azure/lime/cyan/
     orange and the legacy coloured buttons) want the dark ink in both. */
  --course-on-status:     #ffffff;  /* on primary / success / warning / danger */
  --course-on-bright:     #06202a;  /* on the bright fills, both themes */

  /* ── Status ─────────────────────────────────────────────────────────── */
  --course-ok:            #1c7c3f;
  --course-ok-rgb:        28, 124, 63;
  --course-ok-quiet:      rgba(28, 124, 63, .10);
  --course-warn:          #e0a94a;  /* the warning fill, on both grounds */
  --course-warn-rgb:      224, 169, 74;
  --course-warn-text:     #8a5200;  /* the same warning as ink: 6.4:1 on white */
  --course-warn-quiet:    rgba(224, 169, 74, .16);
  --course-danger:        #b4232a;
  --course-danger-rgb:    180, 35, 42;
  --course-danger-quiet:  rgba(180, 35, 42, .09);
  --course-info:          #1f5fa8;  /* distinct from primary, 6.4:1 on white */
  --course-info-rgb:      31, 95, 168;

  /* ── Scheduled-course hues ──────────────────────────────────────────────
     Ten hues for the schedule grid, one triplet per hue. Held at one
     lightness so no course shouts louder than another; every pair is at
     least ΔE76 18 apart as a rule (measured). The theme blocks below swap
     the triplets, so the blocks stay theme-aware without re-rendering. */
  --course-hue-0:  11, 110, 121;   /* teal — the identity */
  --course-hue-1:  49, 127, 216;   /* blue */
  --course-hue-2:  75, 65, 210;    /* indigo */
  --course-hue-3:  131, 62, 177;   /* violet */
  --course-hue-4:  161, 58, 123;   /* plum */
  --course-hue-5:  168, 56, 64;    /* crimson */
  --course-hue-6:  163, 97, 46;    /* rust */
  --course-hue-7:  138, 104, 21;   /* amber */
  --course-hue-8:  103, 127, 26;   /* olive */
  --course-hue-9:  48, 120, 72;    /* green */

  /* ── Type scale (floor 12px) ────────────────────────────────────────── */
  --course-fs-xs:   .75rem;
  --course-fs-sm:   .8125rem;
  --course-fs-base: .875rem;
  --course-fs-md:   .9375rem;
  --course-fs-lg:   1.0625rem;
  --course-fs-xl:   1.25rem;
  --course-fs-2xl:  1.5rem;
  --course-fs-3xl:  1.875rem;

  --course-font: "PingFang TC", "Noto Sans TC", "Microsoft JhengHei",
                 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
                 "Helvetica Neue", Arial, sans-serif;
  --course-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* ── Remap Tabler onto the identity ─────────────────────────────────── */
  --tblr-font-sans-serif: var(--course-font);
  --tblr-body-bg:         var(--course-ground);
  --tblr-body-color:      var(--course-ink);
  --tblr-bg-surface:      var(--course-surface);
  --tblr-bg-surface-secondary: var(--course-surface-2);
  --tblr-border-color:    var(--course-line);
  --tblr-border-color-translucent: var(--course-line);
  --tblr-secondary:       var(--course-ink-mute);
  --tblr-muted:           var(--course-ink-mute);
  --tblr-primary:         var(--course-primary);
  --tblr-primary-rgb:     var(--course-primary-rgb);
  --tblr-primary-fg:      var(--course-primary-on);
  /* Status fills come from the same ink family, so a badge never introduces a
     hue the palette does not own. Without this the shell still ships Tabler's
     own red/green/amber next to the token ones. */
  --tblr-success:         var(--course-ok);
  --tblr-success-rgb:     var(--course-ok-rgb);
  --tblr-warning:         var(--course-warn);
  --tblr-warning-rgb:     var(--course-warn-rgb);
  --tblr-danger:          var(--course-danger);
  --tblr-danger-rgb:      var(--course-danger-rgb);
  --tblr-info:            var(--course-info);
  --tblr-info-rgb:        var(--course-info-rgb);
  --tblr-link-color:      var(--course-primary);
  --tblr-link-color-rgb:  var(--course-primary-rgb);
  --tblr-link-hover-color: var(--course-primary-strong);
  --tblr-active-bg:       var(--course-accent-quiet);
  --tblr-focus-ring-color: rgba(var(--course-primary-rgb), .35);
}

[data-bs-theme="dark"] {
  --course-ground:        #0b1a20;
  --course-surface:       #0d2027;
  --course-surface-2:     #12303a;
  --course-surface-3:     #173b47;
  --course-line:          #22454f;
  --course-line-strong:   #2f5a66;

  --course-ink:           #e6eef0;  /* 14.3:1 on ground */
  --course-ink-soft:      #c6d6da;
  --course-ink-mute:      #a4b8bd;  /*  8.1:1 on ground */

  --course-primary:       #3fa8b8;
  --course-primary-strong:#57c0cf;
  --course-primary-rgb:   63, 168, 184;
  --course-primary-on:    #06202a;  /*  6.0:1 on primary */
  --course-accent:        #0ad1e5;  /*  9.0:1 on ground — brand cyan, dark only */
  --course-accent-quiet:  rgba(10, 209, 229, .14);
  --course-on-status:     #06202a;
  --course-on-bright:     #06202a;

  --course-ok:            #5fd47a;
  --course-ok-rgb:        95, 212, 122;
  --course-ok-quiet:      rgba(95, 212, 122, .14);
  --course-warn:          #e0a94a;
  --course-warn-rgb:      224, 169, 74;
  --course-warn-text:     #e0a94a;
  --course-warn-quiet:    rgba(224, 169, 74, .14);
  --course-danger:        #f08a8a;
  --course-danger-rgb:    240, 138, 138;
  --course-danger-quiet:  rgba(240, 138, 138, .14);
  --course-info:          #6aa6e0;
  --course-info-rgb:      106, 166, 224;

  /* Hue triplets lifted to hold >=3:1 as a rule on the dark ground; hue 0 is
     the brand cyan, which is only legible here (9.0:1) and unreadable on white. */
  --course-hue-0:  10, 209, 229;
  --course-hue-1:  49, 127, 216;
  --course-hue-2:  102, 94, 217;
  --course-hue-3:  147, 78, 193;
  --course-hue-4:  180, 65, 138;
  --course-hue-5:  191, 64, 72;
  --course-hue-6:  163, 97, 46;
  --course-hue-7:  138, 104, 21;
  --course-hue-8:  103, 127, 26;
  --course-hue-9:  49, 124, 74;
}

/* ==========================================================================
   Base
   ========================================================================== */

body {
  font-family: var(--course-font);
  background-color: var(--course-ground);
  color: var(--course-ink);
  -webkit-font-smoothing: antialiased;
}

a:not(.badge):not(.btn) { color: var(--course-primary); text-underline-offset: .18em; }
a:not(.badge):not(.btn):hover { color: var(--course-primary-strong); }

/* Counts, times and credits line up only when the numerals are tabular. */
.tabular-nums,
#course-table td,
.course-times,
.cell-time,
.cell-credits,
.sim-grid,
.sim-period,
#enrollment-hero .course-figure {
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   Browser surfaces — selection, caret, scrollbar, focus.
   The cheapest place to show a page was designed rather than assembled.
   ========================================================================== */

::selection { background: var(--course-accent-quiet); color: var(--course-ink); }
:root { caret-color: var(--course-primary); }

* { scrollbar-width: thin; scrollbar-color: var(--course-line-strong) transparent; }
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--course-line-strong);
  border: 3px solid var(--course-ground);
  border-radius: 99px;
}
::-webkit-scrollbar-thumb:hover { background: var(--course-ink-mute); }

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

/* ==========================================================================
   Chrome: navbar + nav menu
   ========================================================================== */

.navbar {
  background-color: var(--course-surface);
  border-bottom: 1px solid var(--course-line);
}
#nav-menu-header {
  background-color: var(--course-surface);
  border-bottom: 1px solid var(--course-line);
}
/* Nav links sit on the ink scale; the active page is marked, not shouted. */
#navbar-menu .nav-link {
  color: var(--course-ink-soft);
  font-size: var(--course-fs-base);
  font-weight: 500;
  border-bottom: 2px solid transparent;
}
#navbar-menu .nav-link:hover { color: var(--course-primary); }
#navbar-menu .nav-link.active,
#navbar-menu .nav-item.active .nav-link {
  color: var(--course-primary);
  border-bottom-color: var(--course-accent);
}

/* The term is the page's own datum — set in ink, not as a decorative pill. */
#termSwitcher {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: .01em;
  font-size: var(--course-fs-base) !important;
}

/* ==========================================================================
   Controls
   ========================================================================== */

.btn { font-size: var(--course-fs-base); }
.btn-sm { font-size: var(--course-fs-sm); }
.btn-primary { --tblr-btn-color: var(--course-primary-on); }

/* An outline button paints its label in the fill's colour, so a fill that is too
   light to read as ink (the warning amber) needs the ink value here. */
.btn-outline-warning {
  --tblr-btn-color: var(--course-warn-text);
  --tblr-btn-border-color: var(--course-warn-text);
  --tblr-btn-hover-bg: var(--course-warn);
  --tblr-btn-hover-color: var(--course-on-bright);
  --tblr-btn-hover-border-color: var(--course-warn-text);
}

.btn-outline-primary {
  --tblr-btn-color: var(--course-primary);
  --tblr-btn-border-color: var(--course-line-strong);
  --tblr-btn-hover-bg: var(--course-primary);
  --tblr-btn-hover-color: var(--course-primary-on);
}

/* Touch: pointer targets reach 44px where a finger is the input device. */
@media (pointer: coarse), (max-width: 767.98px) {
  .btn, .button, .btn-group > .btn { min-height: 44px; min-width: 44px; }
  .btn-sm, .button_hilite { min-height: 44px; padding-inline: .75rem; }
  .navbar .nav-link { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; justify-content: center; }
  .form-control, .form-select { min-height: 44px; }
  .btn-close { min-width: 44px; min-height: 44px; }
  .list-group-item { min-height: 44px; }
}

/* ==========================================================================
   Surfaces
   ========================================================================== */

.card {
  background-color: var(--course-surface);
  border: 1px solid var(--course-line);
  --tblr-card-cap-bg: var(--course-surface-2);
}
.card-header {
  background-color: var(--course-surface-2);
  border-bottom: 1px solid var(--course-line);
}
.card-title { font-weight: 600; color: var(--course-ink); }

/* ==========================================================================
   Term status — the season's state in one line.
   Was a 4px coloured left stripe over a diagonal gradient; both are decoration
   standing in for hierarchy, so the state now carries its own surface and ink.
   ========================================================================== */

#hero-status-card {
  border: 1px solid var(--course-line);
  border-radius: var(--tblr-border-radius-lg, .5rem);
  background: var(--course-surface);
  overflow: hidden;
}
/* The state is carried by the wash and by the words themselves; the rule above
   stays 1px like every other rule on the page. */
#hero-status-card .card-body { border-top: 1px solid var(--course-line-strong); }
#hero-status-card.hero-active .card-body   { border-top-color: var(--course-ok);     background: var(--course-ok-quiet); }
#hero-status-card.hero-upcoming .card-body { border-top-color: var(--course-primary); background: var(--course-accent-quiet); }
#hero-status-card.hero-ended .card-body    { border-top-color: var(--course-line-strong); background: var(--course-surface-2); }
.hero-active, .hero-upcoming, .hero-ended { background: none; }

/* One line: term · phase · state, with the countdown trailing. The countdown is
   a reading in the ink scale, not a second headline competing with the phase. */
.hero-status-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .5rem;
}
.hero-status-term {
  font-size: var(--course-fs-sm);
  color: var(--course-ink-mute);
  font-variant-numeric: tabular-nums;
}
.hero-status-sep { color: var(--course-ink-mute); }
.hero-status-phase {
  font-size: var(--course-fs-xl);
  font-weight: 600;
  color: var(--course-ink);
  letter-spacing: -.01em;
}
.hero-status-count {
  margin-left: auto;
  font-size: var(--course-fs-sm);
  color: var(--course-ink-soft);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.hero-status-count #hero-countdown-label { color: var(--course-ink-mute); margin-right: .375rem; }
.hero-status-count #hero-countdown-value { font-weight: 600; color: var(--course-ink); }

#hero-countdown-label { color: var(--course-ink-mute); font-size: var(--course-fs-sm); }

/* ==========================================================================
   Course detail — enrolment reads as a data row, not as hero metrics.
   ========================================================================== */

#enrollment-hero {
  border: 1px solid var(--course-line);
  border-radius: var(--tblr-border-radius-lg, .5rem);
  background: var(--course-surface);
}
/* Enrolment reads as a labelled data row, not as three oversized numerals:
   label above value, hairlines between, one ink for all three. */
.enrollment-row { display: grid; grid-template-columns: repeat(3, 1fr); }
.enrollment-item {
  display: flex;
  flex-direction: column;
  gap: .125rem;
  padding: .25rem .75rem;
  border-left: 1px solid var(--course-line);
  min-width: 0;
}
.enrollment-item:first-child { border-left: 0; padding-left: 0; }
.enrollment-label {
  font-size: var(--course-fs-xs);
  font-weight: 500;
  color: var(--course-ink-mute);
  letter-spacing: .02em;
}
.enrollment-value {
  font-size: var(--course-fs-xl);
  font-weight: 600;
  line-height: 1.2;
  color: var(--course-ink);
  font-variant-numeric: tabular-nums;
}
.enrollment-value--danger { color: var(--course-danger); }
.enrollment-foot {
  margin-top: .75rem;
  padding-top: .75rem;
  border-top: 1px solid var(--course-line);
  font-size: var(--course-fs-sm);
  color: var(--course-ink-mute);
}
@media (max-width: 420px) {
  .enrollment-item { padding-inline: .5rem; }
  .enrollment-value { font-size: var(--course-fs-lg); }
}

#course-hero { border-bottom: 1px solid var(--course-line); padding-bottom: 1rem; }
#course-hero #course-title { font-size: var(--course-fs-3xl); font-weight: 700; letter-spacing: -.02em; }
#hero-countdown-label { color: var(--course-ink-mute); font-size: var(--course-fs-sm); }

/* ==========================================================================
   Tables — the course listings are the product; give them a reading rhythm.
   ========================================================================== */

.table { --tblr-table-color: var(--course-ink); }
.table > thead th {
  font-size: var(--course-fs-xs);
  font-weight: 600;
  letter-spacing: .03em;
  color: var(--course-ink-mute);
  border-bottom-color: var(--course-line-strong);
  white-space: nowrap;
}
.table > tbody td { font-size: var(--course-fs-base); }
.table-hover > tbody > tr:hover > * { --tblr-table-bg-state: var(--course-accent-quiet); }

/* ==========================================================================
   Simulated schedule — the grid is the star; the sidebar is its control.
   ========================================================================== */

/* Type floor: the grid used to shrink teacher and room to 0.6rem (9.6px) and
   the period ruler to 0.7rem. Hierarchy now comes from weight and ink, and
   nothing carrying data sits below 12px. */
.sim-grid-container { font-size: var(--course-fs-sm); }
.sim-grid-header { font-size: var(--course-fs-xs); color: var(--course-ink); }
.sim-grid-period { font-size: var(--course-fs-xs); color: var(--course-ink-mute); }
.sim-cell { font-size: var(--course-fs-sm); }

/* Course blocks carry their hue in the rule and in a 34% wash of the same hue.
   Below ~30% the ten hues composite to within ΔE 5 of each other and stop
   being distinguishable at all; 34% holds every pair at ΔE 7+ while the block
   text still sits above 9:1 in both themes. */
[data-hue="0"] { --hue: var(--course-hue-0); }
[data-hue="1"] { --hue: var(--course-hue-1); }
[data-hue="2"] { --hue: var(--course-hue-2); }
[data-hue="3"] { --hue: var(--course-hue-3); }
[data-hue="4"] { --hue: var(--course-hue-4); }
[data-hue="5"] { --hue: var(--course-hue-5); }
[data-hue="6"] { --hue: var(--course-hue-6); }
[data-hue="7"] { --hue: var(--course-hue-7); }
[data-hue="8"] { --hue: var(--course-hue-8); }
[data-hue="9"] { --hue: var(--course-hue-9); }
.sim-cell {
  background: rgba(var(--hue), .34);
  border: 1px solid rgb(var(--hue));
}
.sim-hue-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  margin-right: 4px;
  vertical-align: middle;
}
.sim-cell .sim-cell-name { font-size: var(--course-fs-sm); font-weight: 600; color: var(--course-ink); }
.sim-cell .sim-cell-teacher { font-size: var(--course-fs-xs); font-weight: 500; color: var(--course-ink-soft); }
/* On a 34% course wash the muted ink falls to ~3.0:1 and the soft ink holds at
   >=5.1:1 across all ten hues in both themes, so room and teacher share the soft
   ink and separate on weight instead. */
.sim-cell .sim-cell-room { font-size: var(--course-fs-xs); font-weight: 400; color: var(--course-ink-soft); }
.sim-empty-state { color: var(--course-ink-mute); }
.sim-sidebar, .sim-main-header { background: var(--course-surface); border-color: var(--course-line); }

/* A week does not compress into 374px. Six day columns at phone width leave
   ~56px each, which truncates most course names; hold a readable column and let
   the grid scroll sideways instead. */
@media (max-width: 767.98px) {
  .sim-grid-container, #sim-grid-body { min-width: 680px; }
  .sim-sidebar { max-height: 34vh; }
}

/* Section heading. The old sheet set these as tracked small caps in the muted
   ink — an eyebrow doing a heading's job. Set in ink, at a heading's size, and
   the hairline does the separating. */
.title {
  font-family: var(--course-font);
  font-size: var(--course-fs-lg);
  font-weight: 600;
  text-transform: none;
  letter-spacing: normal;
  color: var(--course-ink);
  margin: 1.5rem 0 .75rem;
  padding-bottom: .5rem;
  border-bottom: 1px solid var(--course-line);
}
.title i { opacity: 1; color: var(--course-ink-mute); }

/* ==========================================================================
   Legacy surfaces carried by the old sheet (course-profile, ta pages…)
   ========================================================================== */

.aqua_table th {
  background: var(--course-surface-2);
  color: var(--course-ink);
  border-color: var(--course-line);
}
.aqua_table td { border-color: var(--course-line); color: var(--course-ink); }
.aqua_table tr.odd td { background: var(--course-surface-2); }
.aqua_table tr:hover td { background: var(--course-accent-quiet); }

/* Page heading: the old sheet stacked a decorative stripe image behind a
   flush-left title. Flat surface, ink title, one hairline. */
.page_heading { background: none; margin: 1.25rem 0; }
.page_heading h1 {
  display: block;
  background: none;
  color: var(--course-ink);
  font-family: var(--course-font);
  font-size: var(--course-fs-2xl);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -.01em;
}
.page_heading h1 span { background: none; }
[data-bs-theme="dark"] .page_heading { background-image: none; }

/* Breadcrumb: legacy pager strip on a gradient image, set at 11px. */
.breadcrumb { background: transparent; height: auto; margin: .75rem 0 0; }
.breadcrumb a,
.breadcrumb a.first_bc,
.breadcrumb a.last_bc {
  float: none;
  display: inline-block;
  background: none;
  border-radius: 0;
  color: var(--course-ink-mute);
  font-size: var(--course-fs-xs);
  line-height: 1.6;
  text-shadow: none;
}
.breadcrumb a:hover { color: var(--course-primary); }
.breadcrumb a span,
.breadcrumb a.last_bc span { background: none; padding: 0 .5rem; line-height: 1.6; }
.breadcrumb a span::after { content: "›"; color: var(--course-line-strong); padding-left: .5rem; }
.breadcrumb a.last_bc span::after { content: ""; padding: 0; }

/* Legacy status blocks */
.success     { background: var(--course-ok-quiet);     border: 1px solid var(--course-ok);     }
.warning     { background: var(--course-danger-quiet); border: 1px solid var(--course-danger); }
.attention   { background: var(--course-warn-quiet);   border: 1px solid var(--course-warn-text);   }
.information { background: var(--course-accent-quiet); border: 1px solid var(--course-primary); }
.success, .warning, .attention, .information { color: var(--course-ink); border-radius: var(--tblr-border-radius, .25rem); }
.success a, .warning a, .attention a, .information a { color: var(--course-primary); }
.required, .error { color: var(--course-danger); }

/* ==========================================================================
   Footer. Tabler ships footer headings at 10px in a fixed grey that does not
   flip with the theme (3.7:1 on the dark ground). Set them in ink at the floor.
   ========================================================================== */

.footer { border-top: 1px solid var(--course-line); color: var(--course-ink-mute); }
.footer h6 {
  font-size: var(--course-fs-base);
  font-weight: 600;
  color: var(--course-ink);
  margin-bottom: .5rem;
}
.footer p, .footer li { font-size: var(--course-fs-sm); line-height: 1.7; }
.footer .text-muted { color: var(--course-ink-mute); }
.footer a { color: var(--course-primary); }
.footer a:hover { color: var(--course-primary-strong); }

/* ==========================================================================
   Selection notice — course selection happens on the Student Information
   System, not here. Flat tinted surface, 1px rule, ink text.
   ========================================================================== */

.selection-notice {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem;
  padding: .75rem 1rem;
  margin-bottom: 1rem;
  background: var(--course-accent-quiet);
  border: 1px solid var(--course-line);
  border-radius: var(--tblr-border-radius, .25rem);
}
.selection-notice-text {
  flex: 1 1 20rem;
  margin: 0;
  font-size: var(--course-fs-base);
  line-height: 1.6;
  color: var(--course-ink);
}
.selection-notice-text i { color: var(--course-primary); }
.selection-notice .btn { white-space: nowrap; }

/* ==========================================================================
   Print — the schedule and course tables get printed every registration week.
   ========================================================================== */

@media print {
  body { background: #fff; color: #000; }
  .navbar, #nav-menu-header, .footer, .d-print-none { display: none !important; }
  .card, #enrollment-hero, #hero-status-card { border-color: #999; box-shadow: none; }
  a:not(.badge):not(.btn) { color: #000; }
}
