/* ============================================================
   LearnHub v2 — the dark scheme (assets/dark.css)

   An opt-in *scheme*, not a seventh design. It answers one question —
   "what happens to the colours when the room is dark?" — and leaves every
   theme (bright/console/emerald/material/minimal/paper), every density and
   every layout intact on top of it.

   Two rules shape this file, and both exist for the same reason:

   1. every selector is prefixed `html.dark`. header.php prints this sheet
      LAST, but the theme sheets already promote their own surfaces with
      `!important`, so the only reliable trump card is specificity: `html.dark`
      + the very selector a theme used is always one step above it. It is also
      what makes the scheme free to undo — remove the class, the whole file
      stops applying, and a page that never got the class is byte-for-byte the
      light page it always was.
   2. the palette lives in custom properties at the top and every rule below
      reads one. That is what lets `@media print` hand the light values back in
      a single place: a certificate printed from a dark session still comes out
      on white paper.

   The tokens double as the interface with the rest of the design system —
   shell.css, hero.css, curtain.css and the theme sheets all consume
   var(--lh-ink / --lh-body --lh-mut / --lh-line / --lh-paper / --lh-deep …)
   with light fallbacks, so re-declaring them on html.dark re-skins every rule
   that reads them without touching a single one of those files.
   ============================================================ */

/* ---------- 1. the palette ---------- */
html.dark {
  color-scheme: dark;

  /* the token surface the rest of the design system already reads */
  --lh-ink: #eaf4ef;
  --lh-body: #c1d4ca;
  --lh-mut: #8ea89c;
  --lh-line: #1f3a30;
  --lh-line-2: #27473b;
  --lh-paper: #111d19;
  --lh-tint: #16241f;
  --lh-mint: #34d399;
  --lh-teal: #2dd4bf;
  --lh-brand: #10b981;

  /* --lh-deep does double duty in the theme sheets — some rules paint with it
     (a CTA the theme expects white text on), others write text in it. A value
     that survives both jobs is the app's own brand green: white-on-emerald-600
     is the contrast the light app already ships for every primary button, and
     emerald-600 text on a dark canvas stays readable. */
  --lh-deep: #059669;

  /* shadows have to do more work on a dark canvas: the light sheet's soft grey
     lift is simply invisible here, so they lean on depth instead */
  --lh-shadow: 0 1px 2px rgba(0, 0, 0, .55), 0 20px 44px -26px rgba(0, 0, 0, .85);
  --lh-shadow-hover: 0 2px 4px rgba(0, 0, 0, .55), 0 28px 52px -24px rgba(0, 0, 0, .9);

  /* the loading curtain (curtain.css reads both with light fallbacks) */
  --lh-curtain: #0b1512;
  --lh-curtain-hi: rgba(255, 255, 255, .05);

  /* the surfaces this file paints with */
  --lh-dark-canvas: #0b1512;
  --lh-dark-panel: #111d19;
  --lh-dark-raise: #16241f;
  --lh-dark-sink: #0e1814;
  --lh-dark-edge: #1f3a30;
  --lh-dark-edge-2: #2b4a3e;
  --lh-dark-hover: #182a23;
  --lh-dark-glass: rgba(13, 25, 21, .82);
  --lh-dark-wash: rgba(52, 211, 153, .12);
}

/* ---------- 2. the canvas ---------- */
/* the same three aurora pools as the light shell, dimmed to embers over a
   near-black green instead of a mint white */
html.dark body {
  background:
    radial-gradient(1100px 560px at 88% -8%, rgba(5, 150, 105, .17), transparent 60%),
    radial-gradient(950px 520px at -8% 18%, rgba(4, 120, 87, .14), transparent 55%),
    radial-gradient(900px 620px at 50% 112%, rgba(6, 182, 212, .08), transparent 60%),
    var(--lh-dark-canvas);
  color: var(--lh-body);
}

html.dark body.lh-app {
  background: var(--lh-dark-canvas)
}

html.dark ::selection {
  background: #065f46;
  color: #d1fae5
}

/* the emerald scrollbar is already a dark-canvas colour — keep the thumb,
   darken the trough it runs in */
html.dark *::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, .04)
}

/* ---------- 3. the shell: bar, sidebar, panels ---------- */
html.dark nav.glass,
html.dark .lh-topbar.glass,
html.dark body.lh-app .lh-topbar {
  background: var(--lh-dark-glass) !important;
  border-color: var(--lh-dark-edge) !important;
  box-shadow: 0 8px 28px -14px rgba(0, 0, 0, .8) !important;
}

html.dark nav a:hover,
html.dark nav .sm\:flex a:not(.bg-indigo-50):hover,
html.dark nav .sm\:hidden a:not(.bg-indigo-600):hover,
html.dark .lh-pill:hover,
html.dark .lh-ico:hover,
html.dark .lh-side-link:hover,
html.dark .lx-panel-item:hover,
html.dark .lh-notif-unread,
html.dark .lh-side-collapse:hover,
html.dark #lh-side-collapse:hover {
  background: var(--lh-dark-hover) !important;
}

/* the avatar and the unread badge wear a white ring in the light shell so they
   read against a white bar — here the ring has to match the bar instead */
html.dark .lh-badge,
html.dark .lh-avatar,
html.dark nav span.rounded-full.bg-indigo-600 {
  box-shadow: 0 0 0 2px var(--lh-dark-panel), 0 0 0 4px rgba(16, 185, 129, .3) !important;
}

html.dark .lh-avatar::after,
html.dark nav span.rounded-full.bg-indigo-600::after {
  border-color: var(--lh-dark-panel) !important;
  background: var(--lh-dark-panel) !important;
}

/* A profile picture is a photograph, not a surface: it keeps its own colours in
   either scheme — nothing here should tint a person's face. It only needs an
   edge, because the dark bar and the dark card it sits on are the same tone as
   the shadows at the rim of a photo. */
html.dark .lh-avatar-img {
  box-shadow: 0 0 0 1px var(--lh-dark-edge-2) !important;
}

html.dark .lh-sidebar,
html.dark body.lh-app .lh-sidebar {
  background: var(--lh-dark-panel) !important;
  border-right-color: var(--lh-dark-edge) !important;
}

html.dark .lh-side-sec,
html.dark .lh-side-collapse-wrap,
html.dark .lh-side-foot {
  border-color: var(--lh-dark-edge) !important
}

html.dark #lh-side-collapse {
  background: var(--lh-dark-raise) !important;
  border-color: var(--lh-dark-edge) !important;
  color: var(--lh-mut) !important
}

html.dark #lh-side-collapse:hover {
  color: var(--lh-mint) !important;
  border-color: var(--lh-dark-edge-2) !important
}

/* the notifications panel, the calendar, every floating sheet */
html.dark .lh-panel,
html.dark .lh-cal,
html.dark .lh-cal-pop {
  background: var(--lh-dark-panel) !important;
  border-color: var(--lh-dark-edge) !important;
  outline-color: var(--lh-dark-edge) !important;
  box-shadow: var(--lh-shadow) !important;
}

/* the swipe fade that hints at more columns: a white veil over a white card */
html.dark .swipe-hint::after {
  background: linear-gradient(to left, var(--lh-dark-panel), rgba(17, 29, 25, 0)) !important
}

/* the drag-and-drop and in-app-browser notices: warm light alerts */
html.dark .lh-drop {
  background: rgba(245, 158, 11, .12) !important;
  box-shadow: inset 0 0 0 1px rgba(245, 158, 11, .38) !important;
  color: #fcd34d !important
}

html.dark .lh-inapp {
  background: rgba(244, 63, 94, .12) !important;
  box-shadow: inset 0 0 0 1px rgba(244, 63, 94, .38) !important;
  color: #fda4af !important
}

html.dark .lh-chip-amber:hover {
  background: rgba(245, 158, 11, .18) !important
}

/* the calendar widget: sheet, week head, day cells, chips, popover */
html.dark .lh-cal-weekhead {
  background: var(--lh-dark-raise) !important;
  border-bottom-color: var(--lh-dark-edge) !important;
  color: var(--lh-mut) !important
}

html.dark .lh-cal-day {
  background: var(--lh-dark-panel) !important;
  border-color: var(--lh-dark-edge) !important;
  color: var(--lh-body) !important
}

html.dark .lh-cal-day.is-open {
  background: var(--lh-dark-raise) !important
}

html.dark .lh-cal-day.is-out {
  background: var(--lh-dark-sink) !important;
  color: var(--lh-mut) !important
}

html.dark .lh-cal-day.is-today {
  background: var(--lh-dark-wash) !important
}

html.dark .lh-cal-day.is-today .lh-cal-num {
  background: var(--lh-brand) !important;
  color: #052e22 !important
}

html.dark .lh-cal-chip {
  background: var(--lh-dark-raise) !important;
  color: var(--lh-body) !important
}

html.dark .lh-cal-dots i[data-kind="exam"] {
  background: #fb7185 !important
}

html.dark .lh-cal-dots i[data-kind="activity"] {
  background: #fbbf24 !important
}

html.dark .lh-cal-dots i[data-kind="deadline"] {
  background: #94a3b8 !important
}

/* ---------- 4. the theme layer ---------- */
/* Each design sheet pins its own surfaces with !important, and a keyframe or a
   long selector cannot be outranked by cascade order alone — so the scheme
   mirrors the exact selector each theme used, one step above it. Nothing here
   invents a look: it only re-lightens what those rules lightened. */

/* material + paper both paint the sidebar, the icons, the inputs and the table
   heads white; minimal paints the bar translucent white */
html.dark .lh-ico,
html.dark body.lh-app .lh-ico,
html.dark .glass.lh-topbar .lh-ico,
html.dark body.lh-app .glass.lh-topbar .lh-ico {
  background: var(--lh-dark-raise) !important;
  border-color: var(--lh-dark-edge) !important;
  color: var(--lh-body) !important;
}

html.dark body.lh-app .glass.lh-topbar {
  background: var(--lh-dark-glass) !important;
  border-bottom-color: var(--lh-dark-edge) !important
}

/* material: the white card, the white table head, the white form field, and the
   "secondary button" it paints white from a border utility */
html.dark body.lh-app main .rounded-2xl.bg-white,
html.dark body.lh-app main .rounded-3xl.bg-white {
  background: var(--lh-dark-panel) !important;
  border-color: var(--lh-dark-edge) !important;
  box-shadow: var(--lh-shadow) !important
}

html.dark main input,
html.dark main select,
html.dark main textarea,
html.dark body.lh-app main input,
html.dark body.lh-app main select,
html.dark body.lh-app main textarea {
  background: var(--lh-dark-sink) !important;
  border-color: var(--lh-dark-edge-2) !important;
  color: var(--lh-ink) !important
}

html.dark main input::placeholder,
html.dark main textarea::placeholder {
  color: var(--lh-mut) !important;
  opacity: 1
}

/* a selected <option> is drawn by the OS over the field's own box;
   color-scheme: dark above gets most browsers to paint that box dark */
html.dark main select option {
  background: var(--lh-dark-panel);
  color: var(--lh-ink)
}

html.dark main table thead th,
html.dark body.lh-app main table thead th {
  background: var(--lh-dark-raise) !important;
  color: var(--lh-mut) !important;
  border-color: var(--lh-dark-edge) !important
}

html.dark main table tbody tr,
html.dark main table tbody td {
  border-color: var(--lh-dark-edge) !important
}

html.dark body.lh-app main button[class*="border-slate-200"],
html.dark body.lh-app main a[class*="border-slate-300"],
html.dark body.lh-app main button[class*="bg-white"] {
  background: var(--lh-dark-raise) !important;
  border-color: var(--lh-dark-edge-2) !important;
  color: var(--lh-body) !important
}

/* paper: the cream "wall", the ruled sheet of the hero band */
html.dark .lh-hero,
html.dark body.lh-app .lh-hero {
  background:
    radial-gradient(130% 100% at 18% 0%, rgba(52, 211, 153, .10), transparent 55%),
    linear-gradient(180deg, var(--lh-dark-raise) 0%, var(--lh-dark-panel) 100%) !important;
  border-color: var(--lh-dark-edge) !important;
  box-shadow: var(--lh-shadow) !important;
  color: var(--lh-body) !important
}

/* ---------- 4b. the pieces a design paints with its own hand ----------
   A theme is not only tokens. Several sheets put hexadecimal straight onto a
   class — material flattens the canvas behind the content to #f5f6f8 and squares
   the hero sheet away, console squares it to #fff and paints its "plain" wells
   white, paper rules a cream border under the sidebar head and prints a footer in
   near-black. Those declarations beat a token change, so each is answered
   selector-for-selector, and always in the same shape: the theme's own selector
   with html.dark in front of it. One more class in a rule that is otherwise the
   same is what wins, so the scheme never has to out-shout a sheet with
   !important it did not already use — and a design's *structure* (material wants
   no hero card at all) survives the change of light untouched. */

/* material: the canvas, and the footer bar that slides up off the bottom of the
   screen and has to be the same colour as the canvas to be invisible in peace */
html.dark body.lh-app,
html.dark body.lh-app main.lh-main {
  background: var(--lh-dark-canvas) !important
}

html.dark body.lh-app .lh-footer,
html.dark body.lh-app .lh-footer.lh-footer-inline,
html.dark body.lh-app .lh-footer-inline {
  background: var(--lh-dark-canvas) !important;
  border-top-color: var(--lh-dark-edge) !important;
  color: var(--lh-body) !important
}

/* the ruled sheet the hero is printed on: cream and tilted for paper, flat white
   for console and bright, a faint gradient for emerald — one dark version of it
   with the ruling kept, because re-inking a texture is a scheme's job and
   deleting it is not */
html.dark .lh-hero-paper {
  background:
    linear-gradient(rgba(255, 255, 255, .035) 1px, transparent 1px) 0 0 / 100% 30px,
    linear-gradient(180deg, var(--lh-dark-raise) 0%, var(--lh-dark-panel) 100%) !important;
  border-color: var(--lh-dark-edge) !important;
  box-shadow: var(--lh-shadow) !important;
  color: var(--lh-body) !important
}

/* material took that sheet away altogether — transparent, no border, no padding.
   The scheme keeps that decision: a dark card standing where the design drew no
   card is the scheme designing, which is the one thing this file may not do. */
html.dark[data-theme="material"] .lh-hero-paper {
  background: none !important;
  border: 0 !important;
  box-shadow: none !important;
  padding: 0 !important
}

/* material's dark call-to-action is a near-black tile with white ink on it, which
   stays perfectly readable here — what it loses is the edge, since the canvas it
   now sits on is nearly as dark as it is. Only a border-colour, so the designs
   that draw no border keep drawing no border. */
html.dark .lh-hero-cta,
html.dark body.lh-app main .lh-hero-cta {
  border-color: var(--lh-dark-edge-2) !important
}

/* console's "plain" wells — the flat, hairline-bordered fields it lays tables on */
html.dark .lh-plain {
  background: var(--lh-dark-panel) !important;
  border-color: var(--lh-dark-edge) !important;
  color: var(--lh-body) !important
}

/* paper and material both redraw the seam under the wordmark, in cream and in
   near-white respectively */
html.dark .lh-sidebar .lh-side-head,
html.dark .lh-sidebar .lh-side-foot {
  border-color: var(--lh-dark-edge) !important
}

/* the small all-caps line above a headline. Grey-on-cream at 11px is the first
   thing to disappear on a dark canvas, and it is set !important in two designs */
html.dark .lh-kicker,
html.dark .lh-hero .lh-kicker,
html.dark body.lh-app main .lh-kicker {
  color: var(--lh-mint) !important
}


/* minimal animates the bar to (near) opaque white once the page is scrolled —
   a keyframe ignores specificity entirely, so it has to be redefined wholesale.
   Re-declaring the name later in the cascade is what wins here. */
@keyframes m-scrolled {
  to {
    background: rgba(13, 25, 21, .92)
  }
}

/* ---------- 5. the utilities the pages are written with ---------- */
/* The pages are markup-first: their colour comes from Tailwind utilities
   (bg-white 128 times, text-slate-500 191, border-slate-300 91 …), so the
   scheme has to answer the utilities too or every card stays white on a black
   canvas. This list is not a guess — it is the vocabulary the markup actually
   uses, counted across every .php file and app.js, with the hover/focus/
   aria-selected variants written out because a variant is a *different* class
   name and a base-class rule never reaches it.

   Brand colours are deliberately absent: emerald-600 buttons, their white
   labels and the indigo form accents read exactly as well on a dark canvas as
   they do on a light one, and a scheme that recolours brand green has stopped
   being a scheme and become a theme. */

/* the neutrals: paper, insets, hairlines, ink */
html.dark .bg-white {
  background-color: var(--lh-dark-panel) !important
}

html.dark .bg-slate-50,
html.dark .bg-slate-100 {
  background-color: var(--lh-dark-raise) !important
}

html.dark .bg-slate-200 {
  background-color: var(--lh-dark-edge) !important
}

/* the one utility that really means "dark thing": a tooltip bubble or a chip.
   bg-slate-900/90 — the modal scrim — is a different class name and stays
   exactly as dark as it was, which is what a scrim is for. */
html.dark .bg-slate-900 {
  background-color: var(--lh-dark-edge-2) !important
}

/* the same surfaces at an opacity — mostly sticky table heads and toolbars
   that scroll content underneath themselves. Their translucency is the point, so
   they get the dark equivalent at the same weight rather than a solid panel.
   bg-slate-900/50, /60, /90 and bg-black/70 are deliberately not here: those are
   scrims behind modals, already the right colour in either scheme. */
html.dark .bg-slate-50\/60,
html.dark .bg-slate-50\/70,
html.dark .bg-slate-50\/80,
html.dark .bg-white\/90 {
  background-color: rgba(17, 29, 25, .86) !important
}

html.dark .border-white\/60 {
  border-color: var(--lh-dark-edge) !important
}

html.dark .hover\:bg-white:hover,
html.dark .hover\:bg-slate-50:hover,
html.dark .hover\:bg-slate-100:hover,
html.dark .aria-selected\:bg-white[aria-selected="true"] {
  background-color: var(--lh-dark-hover) !important
}

html.dark .border-slate-100,
html.dark .border-slate-200,
html.dark .border-slate-300,
html.dark .border-slate-400 {
  border-color: var(--lh-dark-edge) !important
}

html.dark .hover\:border-slate-300:hover {
  border-color: var(--lh-dark-edge-2) !important
}

/* a divider paints border-color on the siblings, so it needs the sibling
   selector the utility itself uses */
html.dark .divide-slate-100>:not([hidden])~:not([hidden]),
html.dark .divide-slate-200>:not([hidden])~:not([hidden]) {
  border-color: var(--lh-dark-edge) !important
}

/* a ring is a box-shadow built from --tw-ring-color, so the colour token is
   the one thing worth overriding — the shadow itself is left alone */
html.dark .ring-slate-200,
html.dark .ring-slate-100,
html.dark .ring-slate-300 {
  --tw-ring-color: rgba(43, 74, 62, .9) !important
}

html.dark .text-slate-900,
html.dark .text-slate-800 {
  color: var(--lh-ink) !important
}

html.dark .text-slate-700,
html.dark .text-slate-600 {
  color: var(--lh-body) !important
}

html.dark .text-slate-500,
html.dark .text-slate-400 {
  color: var(--lh-mut) !important
}

/* slate-300 and lighter are already used as light-on-dark text (inside the
   emerald hero, on top of coloured chips), so they stay as they are */

/* the tints: a 50-level wash is a *light* surface in every one of these hues,
   so each becomes the same hue at low alpha, and its dark text goes a couple of
   steps up the same ramp to keep the contrast it had on white */
html.dark .bg-emerald-50,
html.dark .bg-emerald-100,
html.dark .hover\:bg-emerald-50:hover,
html.dark .has-\[\:checked\]\:bg-emerald-50:has(:checked) {
  background-color: rgba(16, 185, 129, .14) !important
}

html.dark .bg-rose-50,
html.dark .bg-rose-100,
html.dark .hover\:bg-rose-50:hover {
  background-color: rgba(244, 63, 94, .13) !important
}

html.dark .bg-amber-50,
html.dark .bg-amber-100 {
  background-color: rgba(245, 158, 11, .14) !important
}

html.dark .bg-sky-50,
html.dark .bg-sky-100,
html.dark .bg-teal-50,
html.dark .bg-cyan-50 {
  background-color: rgba(56, 189, 248, .13) !important
}

html.dark .bg-indigo-50,
html.dark .bg-indigo-100,
html.dark .has-\[\:checked\]\:bg-indigo-50:has(:checked) {
  background-color: rgba(99, 102, 241, .16) !important
}

html.dark .text-emerald-700,
html.dark .text-emerald-800,
html.dark .text-emerald-600,
html.dark .hover\:text-emerald-700:hover,
html.dark .aria-selected\:text-emerald-700[aria-selected="true"] {
  color: #6ee7b7 !important
}

html.dark .text-rose-600,
html.dark .text-rose-700,
html.dark .hover\:text-rose-600:hover,
html.dark .hover\:text-rose-700:hover {
  color: #fda4af !important
}

html.dark .text-amber-700,
html.dark .text-amber-800,
html.dark .hover\:text-amber-700:hover {
  color: #fcd34d !important
}

html.dark .text-sky-700,
html.dark .text-sky-800,
html.dark .hover\:text-sky-700:hover {
  color: #7dd3fc !important
}

html.dark .text-indigo-600,
html.dark .text-indigo-700,
html.dark .text-indigo-800,
html.dark .hover\:text-indigo-600:hover,
html.dark .hover\:text-indigo-700:hover,
html.dark .aria-selected\:text-indigo-700[aria-selected="true"] {
  color: #a5b4fc !important
}

html.dark .ring-emerald-200,
html.dark .ring-emerald-100 {
  --tw-ring-color: rgba(16, 185, 129, .35) !important
}

html.dark .ring-amber-100,
html.dark .ring-rose-100,
html.dark .ring-sky-100,
html.dark .ring-indigo-100 {
  --tw-ring-color: rgba(148, 163, 184, .28) !important
}

/* ---------- 6. the toggle ---------- */
/* Which half of the icon you see is decided here rather than in script, so the
   button always agrees with the canvas it sits on — including on a first paint
   where the head bootstrap already knew the answer and no script has run yet. */
.lh-scheme-sun {
  display: none
}

html.dark .lh-scheme-moon {
  display: none
}

html.dark .lh-scheme-sun {
  display: block
}

/* ---------- 7. the circular reveal ---------- */
/* Where the circle starts and how far it has to grow: dark.js writes these
   three from the button's own position, which sits in the top-right corner of
   the bar, so the page opens from that corner and the radius is exactly the
   distance to the farthest pixel of the viewport — no corner is ever left
   mid-change. The fallback values need no script at all. */
html {
  --lh-wipe-x: 100%;
  --lh-wipe-y: 0;
  --lh-wipe-r: 150%;
}

/* The good version: a real view transition, where the incoming page is
   genuinely unrolled over the outgoing one through a widening circle.
   The cross-fade the user agent would rather do is switched off, so the only
   thing moving is the clip. */
html.lh-reveal::view-transition-old(root),
html.lh-reveal::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}

html.lh-reveal::view-transition-old(root) {
  z-index: 0
}

html.lh-reveal::view-transition-new(root) {
  z-index: 1;
  clip-path: circle(0 at var(--lh-wipe-x) var(--lh-wipe-y));
  animation: lh-scheme-reveal .62s cubic-bezier(.22, .61, .36, 1) both;
}

@keyframes lh-scheme-reveal {
  from {
    clip-path: circle(0 at var(--lh-wipe-x) var(--lh-wipe-y))
  }

  to {
    clip-path: circle(var(--lh-wipe-r) at var(--lh-wipe-x) var(--lh-wipe-y))
  }
}

/* The fallback, for a browser without startViewTransition: the same circle, cut
   out of one flat sheet of the incoming canvas colour, which the script swaps
   for the real page the moment it covers everything. Less information, same
   gesture — and it is gone entirely under prefers-reduced-motion, where the
   scheme simply changes. */
.lh-wipe {
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  pointer-events: none;
  background: var(--lh-wipe-bg, #0b1512);
  opacity: 1;
  clip-path: circle(0 at var(--lh-wipe-x) var(--lh-wipe-y));
}

.lh-wipe.is-going {
  clip-path: circle(var(--lh-wipe-r) at var(--lh-wipe-x) var(--lh-wipe-y));
  transition: clip-path .62s cubic-bezier(.22, .61, .36, 1);
}

.lh-wipe.is-out {
  opacity: 0;
  transition: opacity .22s ease
}

@media (prefers-reduced-motion: reduce) {

  html.lh-reveal::view-transition-new(root),
  html.lh-reveal::view-transition-old(root) {
    animation: none !important;
    clip-path: none !important
  }

  .lh-wipe.is-going {
    clip-path: circle(var(--lh-wipe-r) at var(--lh-wipe-x) var(--lh-wipe-y));
    transition: none
  }
}

/* ---------- 8. print ---------- */
/* A dark *screen* must not become a dark *page*. Everything above reads a
   token, so handing the light values back here is the whole fix: a student
   printing a certificate, a transcript or an enrolment table from a dark
   session gets the same white paper as everyone else, and the tints come back
   as the light washes they were drawn to be. */
@media print {
  html.dark {
    color-scheme: light;
    --lh-ink: #0f172a;
    --lh-body: #334155;
    --lh-mut: #64748b;
    --lh-line: #e2e8f0;
    --lh-line-2: #cbd5e1;
    --lh-paper: #ffffff;
    --lh-tint: #f8fafc;
    --lh-shadow: 0 1px 2px rgba(15, 23, 42, .08);
    --lh-shadow-hover: 0 1px 2px rgba(15, 23, 42, .08);
    --lh-curtain: #ffffff;
    --lh-dark-canvas: #ffffff;
    --lh-dark-panel: #ffffff;
    --lh-dark-raise: #f8fafc;
    --lh-dark-sink: #ffffff;
    --lh-dark-edge: #e2e8f0;
    --lh-dark-edge-2: #cbd5e1;
    --lh-dark-hover: #f1f5f9;
    --lh-dark-glass: #ffffff;
  }

  html.dark body {
    background: #ffffff !important;
    color: #0f172a !important
  }

  html.dark .text-emerald-700,
  html.dark .text-emerald-600,
  html.dark .text-emerald-800 {
    color: #047857 !important
  }

  html.dark .text-rose-600,
  html.dark .text-rose-700 {
    color: #be123c !important
  }

  html.dark .text-amber-700,
  html.dark .text-amber-800 {
    color: #b45309 !important
  }

  html.dark .text-sky-700,
  html.dark .text-sky-800 {
    color: #0369a1 !important
  }

  html.dark .text-indigo-600,
  html.dark .text-indigo-700,
  html.dark .text-indigo-800 {
    color: #4338ca !important
  }

  html.dark .bg-emerald-50,
  html.dark .bg-emerald-100 {
    background-color: #ecfdf5 !important
  }

  html.dark .bg-rose-50,
  html.dark .bg-rose-100 {
    background-color: #fff1f2 !important
  }

  html.dark .bg-amber-50,
  html.dark .bg-amber-100 {
    background-color: #fffbeb !important
  }

  html.dark .bg-sky-50,
  html.dark .bg-sky-100,
  html.dark .bg-teal-50,
  html.dark .bg-cyan-50 {
    background-color: #f0f9ff !important
  }

  html.dark .bg-indigo-50,
  html.dark .bg-indigo-100 {
    background-color: #eef2ff !important
  }

  /* the hand-painted pieces from §4b, back to the paper they were drawn on */
  html.dark body.lh-app .lh-hero-paper,
  html.dark .lh-hero-paper,
  html.dark .lh-plain,
  html.dark body.lh-app .lh-footer,
  html.dark body.lh-app .lh-footer.lh-footer-inline {
    background: #ffffff !important;
    border-color: #e2e8f0 !important;
    box-shadow: none !important;
    color: #0f172a !important
  }

  html.dark .lh-kicker {
    color: #047857 !important
  }

  /* never print a wipe or a half-torn view transition */
  .lh-wipe {
    display: none !important
  }

  html.lh-reveal::view-transition-old(root),
  html.lh-reveal::view-transition-new(root) {
    animation: none !important;
    clip-path: none !important
  }
}






/* ---------- profile hover card ---------- */
/* The card floats over everything, so it is the one surface that has to match
   the bar it may sit on rather than the page behind it. */
html.dark .lh-hcard-pop {
  background: var(--lh-dark-panel);
  border-color: var(--lh-dark-edge-2)
}

html.dark [data-hcard]:hover,
html.dark [data-hcard].is-open,
html.dark [data-hcard]:focus-visible {
  background: var(--lh-dark-hover);
  box-shadow: 0 0 0 4px var(--lh-dark-hover)
}

html.dark [data-hcard]:focus-visible {
  box-shadow: 0 0 0 2px var(--lh-dark-panel), 0 0 0 4px rgba(16, 185, 185, .35)
}

html.dark .lh-hcard-name {
  color: #f1f5f9
}

html.dark .lh-hcard-bio {
  color: #c3d3cb
}

html.dark .lh-hcard-role {
  background: rgba(99, 102, 241, .2);
  color: #a5b4fc
}

html.dark .lh-hcard-join {
  color: #8aa296
}

html.dark .lh-hcard-pic {
  box-shadow: 0 0 0 1px var(--lh-dark-edge-2)
}

html.dark .lh-hcard-init {
  box-shadow: 0 0 0 1px var(--lh-dark-edge)
}

