    /* ============================================================
   LearnHub v2 — advanced design system (part 1)
   Utility-scoped overrides keep every page's logic intact.
   ============================================================ */
    :root {
      --lh-grad: linear-gradient(135deg, #047857 0%, #059669 50%, #10b981 100%)
    }

    html {
      scroll-behavior: smooth
    }

    ::selection {
      background: #d1fae5;
      color: #064e3b
    }

    .folder-touch-handle {
      touch-action: none;
      -ms-touch-action: none;
      -webkit-user-select: none;
      user-select: none;
      -webkit-touch-callout: none;
      cursor: grab
    }

    .course-explorer {
      overflow: hidden;
      border: 1px solid #cbd5e1;
      border-radius: 1rem;
      background: #fff;
      box-shadow: 0 4px 16px -12px rgba(15, 23, 42, .3)
    }

    .course-explorer-window {
      display: grid;
      min-height: 34rem;
      grid-template-columns: 13rem minmax(0, 1fr)
    }

    .course-explorer-sidebar {
      display: flex;
      flex-direction: column;
      gap: .2rem;
      padding: .8rem .65rem;
      border-right: 1px solid #e2e8f0;
      background: #f8fafc
    }

    .course-explorer-folder-tree {
      display: flex;
      flex-direction: column;
      gap: .1rem
    }

    .course-explorer-sidebar-folder {
      min-width: 0
    }

    .course-explorer-sidebar-folder-line {
      display: flex;
      min-width: 0;
      align-items: center;
      gap: .2rem
    }

    .course-explorer-sidebar-grip {
      display: grid;
      width: 1.35rem;
      height: 1.8rem;
      flex: 0 0 auto;
      place-items: center;
      border-radius: .3rem;
      color: #94a3b8;
      font-size: .95rem
    }

    .course-explorer-subtree {
      display: flex;
      flex-direction: column;
      gap: .1rem;
      margin-left: .9rem;
      border-left: 1px solid #dbe3ed;
      padding-left: .25rem
    }

    .course-explorer-nav,
    .course-explorer-course-label {
      display: flex;
      min-width: 0;
      align-items: center;
      gap: .65rem;
      border: 0;
      border-radius: .45rem;
      padding: .55rem .65rem;
      background: transparent;
      color: #334155;
      text-align: left;
      font-size: .78rem;
      text-decoration: none;
      white-space: nowrap
    }

    .course-explorer-nav:hover,
    .course-explorer-nav.active {
      background: #e8eef7;
      color: #1e293b
    }

    .course-explorer-nav span,
    .course-explorer-course-label span {
      overflow: hidden;
      text-overflow: ellipsis
    }

    .course-explorer-sidebar-divider {
      height: 1px;
      margin: .55rem .35rem;
      background: #dbe3ed
    }

    .course-explorer-sidebar-label {
      padding: .2rem .65rem;
      color: #64748b;
      font-size: .62rem;
      font-weight: 800;
      letter-spacing: .08em
    }

    .course-explorer-course-label {
      font-weight: 700;
      color: #334155
    }

    .course-explorer-sidebar-new-folder {
      display: flex;
      min-height: 2.35rem;
      align-items: center;
      gap: .45rem;
      margin: .2rem .35rem .45rem;
      border: 1px solid #c7d2fe;
      border-radius: .45rem;
      padding: .45rem .6rem;
      background: #fff;
      color: #4338ca;
      font-size: .76rem;
      font-weight: 700;
      text-align: left;
      cursor: pointer
    }

    .course-explorer-sidebar-new-folder:hover {
      background: #eef2ff
    }

    .course-explorer-subfolder-button {
      display: inline-flex;
      min-height: 2rem;
      align-items: center;
      border: 1px solid #c7d2fe;
      border-radius: .4rem;
      padding: .35rem .65rem;
      background: #fff;
      color: #4338ca;
      font-size: .72rem;
      font-weight: 700;
      white-space: nowrap;
      cursor: pointer
    }

    .course-explorer-subfolder-button:hover {
      background: #eef2ff
    }

    .course-explorer-folder-shortcut {
      width: 100%;
      min-width: 0;
      cursor: pointer;
      padding-left: .5rem
    }

    .course-explorer-folder-shortcut.is-main-folder {
      font-weight: 700
    }

    .course-explorer-folder-shortcut small {
      margin-left: auto;
      color: #64748b;
      font-size: .62rem
    }

    .course-explorer-main {
      min-width: 0
    }

    .course-explorer-addressbar {
      display: flex;
      min-height: 3.6rem;
      align-items: center;
      gap: .6rem;
      padding: .6rem 1rem;
      border-bottom: 1px solid #e2e8f0;
      background: #fff
    }

    .course-explorer-crumb-control {
      display: grid;
      width: 1.8rem;
      height: 1.8rem;
      flex: 0 0 auto;
      place-items: center;
      border-radius: .35rem;
      color: #64748b;
      font-size: 1.3rem;
      text-decoration: none
    }

    a.course-explorer-crumb-control:hover {
      background: #f1f5f9
    }

    .course-explorer-breadcrumb {
      display: flex;
      min-width: 0;
      flex: 1 1 auto;
      align-items: center;
      gap: .65rem;
      overflow: hidden;
      border: 1px solid #e2e8f0;
      border-radius: .45rem;
      padding: .48rem .7rem;
      color: #475569;
      font-size: .78rem;
      white-space: nowrap
    }

    .course-explorer-search {
      display: flex;
      width: min(15rem, 32%);
      min-width: 8rem;
      align-items: center;
      gap: .4rem;
      border: 1px solid #e2e8f0;
      border-radius: .45rem;
      padding: .42rem .65rem;
      color: #64748b
    }

    .course-explorer-search input {
      width: 100%;
      min-width: 0;
      border: 0;
      outline: 0;
      background: transparent;
      color: #334155;
      font-size: .75rem
    }

    .course-explorer-commandbar {
      display: flex;
      min-height: 2.8rem;
      align-items: center;
      gap: .55rem;
      padding: .4rem 1rem;
      border-bottom: 1px solid #e2e8f0;
      background: #f8fafc
    }

    .course-explorer-command {
      display: inline-flex;
      min-height: 2rem;
      align-items: center;
      gap: .35rem;
      border: 1px solid transparent;
      border-radius: .4rem;
      padding: .35rem .6rem;
      background: transparent;
      color: #475569;
      font-size: .73rem;
      font-weight: 600
    }

    .course-explorer-command.primary {
      border-color: #c7d2fe;
      background: #fff;
      color: #4338ca;
      cursor: pointer
    }

    .course-explorer-command.primary:hover {
      background: #eef2ff
    }

    .course-explorer-command-divider {
      width: 1px;
      height: 1.4rem;
      margin: 0 .2rem;
      background: #dbe3ed
    }

    .course-explorer-command-label {
      padding: .35rem .45rem;
      color: #64748b;
      font-size: .68rem
    }

    .course-explorer-command-spacer {
      flex: 1 1 auto
    }

    .course-explorer-body {
      min-width: 0;
      padding: 1rem
    }

    .course-explorer-content {
      min-width: 0
    }

    .course-explorer-quick-access {
      margin-bottom: 1.25rem
    }

    .course-explorer-quick-access h2,
    .course-explorer-section-heading h2 {
      display: flex;
      align-items: center;
      gap: .55rem;
      margin-bottom: .65rem;
      color: #334155;
      font-size: .8rem;
      font-weight: 700
    }

    .course-explorer-quick-grid {
      display: grid;
      grid-template-columns: repeat(4, minmax(0, 1fr));
      gap: .55rem
    }

    .course-explorer-quick-card {
      display: flex;
      min-width: 0;
      min-height: 4.25rem;
      align-items: center;
      gap: .7rem;
      border: 1px solid transparent;
      border-radius: .55rem;
      padding: .6rem .7rem;
      background: #f8fafc;
      color: #334155;
      text-align: left;
      font-size: .75rem;
      cursor: pointer
    }

    .course-explorer-quick-card:hover {
      border-color: #cbd5e1;
      background: #f1f5f9
    }

    .course-explorer-folder-icon {
      display: grid;
      width: 2.2rem;
      height: 2.2rem;
      flex: 0 0 auto;
      place-items: center;
      border-radius: .4rem;
      background: #e0edff;
      font-size: 1.35rem
    }

    .course-explorer-empty {
      grid-column: 1 / -1;
      border: 1px dashed #cbd5e1;
      border-radius: .55rem;
      padding: .8rem;
      color: #64748b;
      font-size: .75rem
    }

    .course-explorer-folder-listing {
      overflow: hidden;
      border: 1px solid #e2e8f0;
      border-radius: .65rem
    }

    .course-explorer-source {
      display: none
    }

    .folder-explorer-mobile-open {
      display: none
    }

    .course-explorer-current {
      min-height: 10rem;
      background: #f8fafc
    }

    .course-explorer-current > .is-current-folder-content {
      display: block
    }

    .course-explorer-current .folder-explorer-item > .folder-explorer-content {
      display: none
    }

    .course-explorer-section-heading {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: .75rem;
      padding: .75rem .9rem .25rem;
      background: #fff
    }

    .course-explorer-section-heading h2 {
      margin: 0
    }

    .course-explorer-section-heading > span {
      color: #64748b;
      font-size: .68rem
    }

    .course-explorer-toolbar {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 1rem;
      padding: 1rem 1.25rem;
      border-bottom: 1px solid #e2e8f0;
      background: linear-gradient(180deg, #fff, #f8fafc)
    }

    .course-explorer-column-head,
    .folder-explorer-row {
      display: grid;
      grid-template-columns: minmax(0, 1fr) 190px 72px;
      align-items: center;
      column-gap: 1rem
    }

    .course-explorer-no-progress .course-explorer-column-head,
    .course-explorer-no-progress .folder-explorer-row {
      grid-template-columns: minmax(0, 1fr) 72px
    }

    .course-explorer-column-head {
      padding: .55rem 1.25rem;
      border-bottom: 1px solid #e2e8f0;
      background: #f8fafc;
      color: #64748b;
      font-size: .68rem;
      font-weight: 700;
      letter-spacing: .04em;
      text-transform: uppercase
    }

    .course-explorer-content {
      padding: 0
    }

    .course-explorer-list {
      overflow: hidden
    }

    .folder-explorer-item {
      background: #fff
    }

    .folder-explorer-item + .folder-explorer-item {
      border-top: 1px solid #e2e8f0
    }

    .folder-explorer-row {
      min-height: 4.25rem;
      transition: background-color .15s ease
    }

    .folder-explorer-name {
      display: flex;
      min-width: 0;
      align-items: center;
      gap: .75rem
    }

    .folder-explorer-row > [data-folder-progress-text] {
      color: #475569
    }

    .folder-explorer-open {
      justify-self: end;
      white-space: nowrap
    }

    .folder-explorer-item[open] > .folder-explorer-row {
      background: #f1f5f9
    }

    .folder-explorer-content {
      background: #f8fafc
    }

    .folder-explorer-children {
      overflow: hidden;
      border: 1px solid #dbe3ed;
      border-radius: .75rem;
      background: #fff
    }

    .folder-explorer-children > .folder-explorer-item + .folder-explorer-item {
      border-top: 1px solid #e2e8f0
    }

    .folder-explorer-subitem > .folder-explorer-row {
      padding-left: .75rem;
      padding-right: .75rem
    }

    @media (max-width: 640px) {
      .course-explorer-window {
        display: none
      }

      .course-explorer-source {
        display: block;
        padding: .75rem
      }

      .course-explorer-source .course-explorer-content {
        padding: 0
      }

      .course-explorer-source .course-explorer-list {
        display: flex;
        flex-direction: column;
        gap: .45rem;
        overflow: visible
      }

      .course-explorer-source .folder-explorer-item {
        overflow: hidden;
        border: 1px solid #cbd5e1;
        border-radius: .9rem;
        background: #fff;
        box-shadow: 0 1px 2px rgba(15, 23, 42, .06)
      }

      .course-explorer-source .folder-explorer-item + .folder-explorer-item {
        border-top: 1px solid #cbd5e1
      }

      .course-explorer-source .folder-explorer-row {
        display: flex;
        min-height: 3.25rem;
        flex-wrap: nowrap;
        gap: .65rem;
        padding: .65rem .8rem
      }

      .course-explorer-source .folder-explorer-name {
        flex: 1 1 auto;
        gap: .65rem
      }

      .course-explorer-source .folder-explorer-name > span:last-child {
        min-width: 0
      }

      .course-explorer-source .folder-explorer-name .block.text-\[11px\] {
        display: none
      }

      .course-explorer-source [data-folder-touch-handle],
      .course-explorer-source [data-folder-progress-text] {
        display: none
      }

      .course-explorer-source .folder-explorer-open {
        flex: 0 0 auto;
        margin-left: auto;
        white-space: nowrap;
        color: #4f46e5
      }

      .course-explorer-source .folder-explorer-desktop-open {
        display: none
      }

      .course-explorer-source .folder-explorer-mobile-open {
        display: inline
      }

      .course-explorer-source .folder-explorer-content {
        margin-top: 0;
        border-top: 1px solid #e2e8f0;
        background: #f8fafc;
        padding: .75rem
      }

      .course-explorer-source .folder-explorer-children {
        display: flex;
        flex-direction: column;
        gap: .45rem;
        overflow: visible;
        border: 0;
        background: transparent
      }

      .course-explorer-source .folder-explorer-subitem > .folder-explorer-row {
        padding: .65rem .8rem
      }

      .course-explorer-sidebar {
        display: block;
        order: 0;
        overflow: visible;
        border-right: 0;
        border-bottom: 1px solid #e2e8f0;
        padding: .55rem
      }

      .course-explorer-sidebar > .course-explorer-nav:not([data-folder-sidebar-item]),
      .course-explorer-sidebar-divider,
      .course-explorer-sidebar-label,
      .course-explorer-course-label {
        display: none
      }

      .course-explorer-sidebar-new-folder {
        width: 100%;
        min-height: 2.5rem;
        margin: 0 0 .45rem
      }

      .course-explorer-folder-tree {
        display: block;
        width: 100%;
        min-width: 0
      }

      .course-explorer-sidebar-folder {
        display: block;
        width: 100%
      }

      .course-explorer-sidebar-folder-line {
        width: 100%;
        margin-left: 0
      }

      .course-explorer-subtree {
        display: block;
        margin-left: .8rem;
        border-left: 1px solid #dbe3ed;
        padding-left: .3rem
      }

      .course-explorer-folder-shortcut {
        width: 100%;
        max-width: none;
        min-height: 2.5rem;
        border: 1px solid #dbe3ed;
        background: #fff;
        padding: .45rem .6rem
      }

      .course-explorer-folder-shortcut.active {
        border-color: #a5b4fc;
        background: #eef2ff;
        color: #3730a3
      }

      .course-explorer-sidebar-grip {
        width: 1rem;
        height: 2rem
      }

      .course-explorer-addressbar {
        order: 1;
        flex-wrap: wrap;
        padding: .55rem .65rem
      }

      .course-explorer-main {
        order: 1;
        min-width: 0
      }

      .course-explorer-breadcrumb {
        flex: 1 1 calc(100% - 5rem)
      }

      .course-explorer-search {
        width: 100%;
        min-width: 0;
        margin-left: 2.4rem
      }

      .course-explorer-commandbar {
        flex-wrap: wrap;
        padding: .35rem .65rem
      }

      .course-explorer-command-label:last-child {
        display: none
      }

      .course-explorer-body {
        padding: .7rem
      }

      .course-explorer-section-heading {
        flex-wrap: wrap;
        padding: .65rem
      }

      .course-explorer-subfolder-button {
        min-height: 2.25rem
      }

      .course-explorer-quick-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr))
      }

      .course-explorer-quick-card {
        min-height: 3.75rem;
        gap: .5rem;
        padding: .5rem
      }

      .course-explorer-toolbar {
        align-items: flex-start;
        padding: .9rem
      }

      .course-explorer-column-head {
        display: none
      }

      .folder-explorer-row {
        grid-template-columns: minmax(0, 1fr) auto;
        column-gap: .5rem;
        padding: .5rem .65rem
      }

      .folder-explorer-row > [data-folder-progress-text] {
        grid-column: 1 / -1;
        padding-left: 3.25rem
      }

      .folder-explorer-open {
        grid-column: 2;
        grid-row: 1;
        align-self: center
      }

      .folder-explorer-subitem > .folder-explorer-row {
        padding-left: .4rem;
        padding-right: .4rem
      }
    }

    @media (min-width: 641px) and (max-width: 900px) {
      .course-explorer-window {
        grid-template-columns: 10.5rem minmax(0, 1fr)
      }

      .course-explorer-quick-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr))
      }
    }

    /* aurora page background */
    body {
      background:
        radial-gradient(1100px 560px at 88% -8%, rgba(5, 150, 105, .16), transparent 60%),
        radial-gradient(950px 520px at -8% 18%, rgba(4, 120, 87, .13), transparent 55%),
        radial-gradient(900px 620px at 50% 112%, rgba(6, 182, 212, .10), transparent 60%),
        #f2f8f4
    }

    /* thin gradient scrollbars */
    * {
      scrollbar-width: thin;
      scrollbar-color: #6ee7b7 transparent
    }

    *::-webkit-scrollbar {
      height: 8px;
      width: 8px
    }

    *::-webkit-scrollbar-track {
      background: transparent
    }

    *::-webkit-scrollbar-thumb {
      background: linear-gradient(#34d399, #6ee7b7);
      border-radius: 99px
    }

    /* page enter animation — OPACITY ONLY on purpose: keyframing transform here
       keeps `main` a containing block for position:fixed modals (fill-mode: both)
       and knocks every modal off the center of the screen */
    main {
      animation: pageIn .45s cubic-bezier(.22, .61, .36, 1) both
    }

    @keyframes pageIn {
      from {
        opacity: 0
      }

      to {
        opacity: 1
      }
    }

    /* glass nav */
    nav.glass {
      background: rgba(255, 255, 255, .72);
      backdrop-filter: blur(16px) saturate(1.5);
      -webkit-backdrop-filter: blur(16px) saturate(1.5);
      box-shadow: 0 8px 28px -14px rgba(4, 120, 87, .22)
    }

    nav.glass::after {
      content: '';
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      height: 2px;
      background: var(--lh-grad);
      opacity: .45
    }

    /* scroll progress bar */
    #lh-progress {
      position: fixed;
      top: 0;
      left: 0;
      height: 3px;
      width: 0;
      background: var(--lh-grad);
      z-index: 60;
      box-shadow: 0 0 14px rgba(5, 150, 105, .55)
    }

    /* gradient logo with pulse glow */
    .lh-logo {
      background: var(--lh-grad);
      box-shadow: 0 8px 20px -8px rgba(5, 150, 105, .6);
      position: relative;
      transition: transform .25s
    }

    .lh-logo:hover {
      transform: scale(1.06) rotate(-3deg)
    }

    .lh-logo::before {
      content: '';
      position: absolute;
      inset: -5px;
      border-radius: inherit;
      background: var(--lh-grad);
      opacity: .35;
      filter: blur(12px);
      z-index: -1;
      animation: logoPulse 3.2s ease-in-out infinite
    }

    @keyframes logoPulse {

      0%,
      100% {
        opacity: .22
      }

      50% {
        opacity: .5
      }
    }

    /* desktop nav pills */
    .lh-pill {
      position: relative;
      border-radius: 12px;
      transition: color .2s, background-color .2s, box-shadow .2s, transform .2s
    }

    .lh-pill:hover {
      color: #047857 !important;
      background: #ecfdf5 !important
    }

    /* active state: original header colors preserved (no gradient) */

    /* mobile icon buttons */
    .lh-ico {
      position: relative;
      border-radius: 12px;
      transition: all .2s
    }

    .lh-ico:hover {
      transform: translateY(-1px);
      color: #047857 !important;
      background: #ecfdf5 !important
    }

    /* notification / chat badges: red circle pinned to the top-right of the icon */
    .lh-badge {
      position: absolute;
      top: -5px;
      right: -7px;
      min-width: 18px;
      height: 18px;
      padding: 0 5px;
      display: grid;
      place-items: center;
      border-radius: 9999px;
      background: #dc2626;
      color: #fff;
      font-size: 10px;
      font-weight: 800;
      line-height: 1;
      letter-spacing: .02em;
      box-shadow: 0 0 0 2px #fff;
      pointer-events: none;
      z-index: 5;
    }

    /* the bell is a torn-paper button — the badge must not be clipped by its tear */
    #lh-notif-btn {
      clip-path: none;
    }

    /* avatar with gradient ring + online dot */
    .lh-avatar {
      background: var(--lh-grad);
      box-shadow: 0 0 0 2px #fff, 0 0 0 4px rgba(5, 150, 105, .30);
      position: relative
    }

    .lh-avatar::after {
      content: '';
      position: absolute;
      right: -2px;
      bottom: -2px;
      width: 11px;
      height: 11px;
      border-radius: 99px;
      background: #10b981;
      border: 2px solid #fff
    }

    /* ── profile picture, and the initial that stands in for it ─────────────
       The compiled Tailwind build has no object-cover and no size larger than
       the circles already in use, so the shape lives here — same reason the
       roster avatar sizes were moved here long ago. Sizes still arrive from the
       h-*/w-* classes the caller passes; everything else is decided once. */
    .lh-avatar-img {
      display: block;
      flex: none;
      border-radius: 9999px;
      object-fit: cover;
      background: var(--lh-grad);        /* the brand circle shows while it loads */
      background-color: #059669
    }

    /* mirrors the utilities the markup carries, so the circle is never an
       unstyled letter even on a page that forgot to pass them */
    .lh-avatar-initial {
      flex: none;                        /* a long name must never squeeze the circle */
      color: #fff;
      background-color: #059669;
      font-weight: 700;
      font-size: .875rem
    }

    /* the big circle on My profile — 120 px in both axes, big type inside */
    .lh-avatar-hero {
      width: 120px;
      height: 120px;
      border-radius: 9999px
    }

    .lh-avatar-initial.lh-avatar-hero {
      display: grid;
      place-items: center;
      font-size: 2.75rem;
      line-height: 1
    }

    /* guest CTA */
    .lh-cta {
      background-image: var(--lh-grad);
      background-color: #047857;
      box-shadow: 0 10px 22px -10px rgba(5, 150, 105, .65);
      transition: all .25s
    }

    .lh-cta:hover {
      transform: translateY(-2px);
      filter: brightness(1.07)
    }

    /* ---------- nav components via existing utility classes (no markup change) ---------- */
    /* desktop pills */
    nav .sm\:flex a {
      position: relative;
      border-radius: 12px;
      transition: color .2s, background-color .2s, box-shadow .2s, transform .2s
    }

    nav .sm\:flex a:not(.bg-indigo-50):hover {
      color: #047857 !important;
      background: #ecfdf5 !important
    }

    /* active state: original header colors preserved (bg-indigo-50 text-indigo-700, no gradient) */
    /* mobile icon buttons */
    nav .sm\:hidden a {
      position: relative;
      border-radius: 12px;
      transition: color .2s, background-color .2s, box-shadow .2s, transform .2s
    }

    nav .sm\:hidden a:not(.bg-indigo-600):hover {
      color: #047857 !important;
      background: #ecfdf5 !important;
      transform: translateY(-1px)
    }

    /* active state: original header colors preserved (bg-indigo-600 text-white, no gradient) */
    /* gradient logo */
    nav a.grid.rounded-xl.bg-indigo-600 {
      background-image: var(--lh-grad);
      background-color: #047857;
      box-shadow: 0 8px 20px -8px rgba(5, 150, 105, .6);
      position: relative;
      transition: transform .25s
    }

    nav a.grid.rounded-xl.bg-indigo-600:hover {
      transform: scale(1.06) rotate(-3deg)
    }

    /* avatar: gradient ring + online dot */
    nav span.rounded-full.bg-indigo-600 {
      background-image: var(--lh-grad);
      background-color: #047857;
      box-shadow: 0 0 0 2px #fff, 0 0 0 4px rgba(5, 150, 105, .3);
      position: relative
    }

    nav span.rounded-full.bg-indigo-600::after {
      content: '';
      position: absolute;
      right: -2px;
      bottom: -2px;
      width: 11px;
      height: 11px;
      border-radius: 99px;
      background: #10b981;
      border: 2px solid #fff
    }

    /* guest CTA */
    nav a.px-4.bg-indigo-600 {
      background-image: var(--lh-grad);
      background-color: #047857;
      box-shadow: 0 10px 22px -10px rgba(5, 150, 105, .65);
      transition: all .25s
    }

    nav a.px-4.bg-indigo-600:hover {
      transform: translateY(-2px);
      filter: brightness(1.07)
    }

    /* ---------- site-wide card upgrade (glass + soft depth) ---------- */
    main .bg-white.ring-1 {
      background: rgba(255, 255, 255, .85);
      backdrop-filter: blur(10px);
      -webkit-backdrop-filter: blur(10px);
      box-shadow: 0 12px 32px -14px rgba(15, 23, 42, .14), inset 0 0 0 1px rgba(255, 255, 255, .65)
    }

    main .rounded-2xl.bg-white.ring-1,
    main .rounded-3xl.bg-white.ring-1 {
      transition: box-shadow .3s, transform .3s
    }

    main .rounded-2xl.bg-white.ring-1:hover,
    main .rounded-3xl.bg-white.ring-1:hover {
      box-shadow: 0 22px 44px -18px rgba(4, 120, 87, .26)
    }

    /* gradient primary buttons site-wide */
    main a.bg-indigo-600,
    main button.bg-indigo-600 {
      background-image: var(--lh-grad);
      background-color: #047857;
      box-shadow: 0 12px 24px -12px rgba(4, 120, 87, .7);
      transition: all .25s
    }

    main a.bg-indigo-600:hover,
    main button.bg-indigo-600:hover {
      transform: translateY(-2px);
      filter: brightness(1.08);
      box-shadow: 0 18px 30px -12px rgba(4, 120, 87, .75)
    }

    /* progress bars: gradient + shimmer */
    main .h-2>.h-full,
    main .h-2\.5>.h-full,
    main .h-3>.h-full {
      background-image: var(--lh-grad);
      background-color: #059669;
      position: relative;
      overflow: hidden
    }

    main .h-2>.h-full::after,
    main .h-2\.5>.h-full::after,
    main .h-3>.h-full::after {
      content: '';
      position: absolute;
      inset: 0;
      background: repeating-linear-gradient(45deg, rgba(255, 255, 255, .28) 0 8px, transparent 8px 18px);
      animation: shimmer 1.4s linear infinite
    }

    @keyframes shimmer {
      from {
        transform: translateX(-18px)
      }

      to {
        transform: translateX(18px)
      }
    }

    /* hero sections: animated aurora */
    main>section.bg-gradient-to-r {
      position: relative;
      isolation: isolate;
      background-size: 180% 180% !important;
      animation: heroShift 14s ease-in-out infinite
    }

    main>section.bg-gradient-to-r::before:;

      {
      content: '';
      position: absolute;
      inset: 0;
      z-index: -1;
      pointer-events: none;
      background: radial-gradient(420px 220px at 15% 15%, rgba(255, 255, 255, .4), transparent 60%), radial-gradient(520px 280px at 85% 85%, rgba(255, 255, 255, .25), transparent 60%);
      mix-blend-mode: overlay;
      animation: blobFloat 10s ease-in-out infinite alternate
    }

    @keyframes heroShift {

      0%,
      100% {
        background-position: 0% 50%
      }

      50% {
        background-position: 100% 50%
      }
    }

    @keyframes blobFloat {
      from {
        transform: translate(0, 0) scale(1)
      }

      to {
        transform: translate(34px, -22px) scale(1.1)
      }
    }

    /* forms */
    main input:focus,
    main select:focus,
    main textarea:focus {
      outline: none;
      border-color: #10b981;
      box-shadow: 0 0 0 4px rgba(5, 150, 105, .14)
    }

    /* password fields: the show/hide eye sits INSIDE the input box (login,
        register). The caller wraps the input in .lh-pw — that wrapper is what
        the button is centred against, and it also buys the input room on the
        right so text never runs under the eye (a padding-right here beats the
        input's own px-4: higher specificity, and shell.css loads after
        tailwind.min.css). The toggle itself is one delegated handler in
        footer.php, keyed off the button's aria-pressed, so the icon and the
        input's type can never disagree. */
    .lh-pw {
      position: relative
    }

    .lh-pw input {
      padding-right: 2.75rem
    }

    .lh-pw-btn {
      position: absolute;
      right: 4px;
      top: 50%;
      transform: translateY(-50%);
      display: grid;
      place-items: center;
      width: 34px;
      height: 34px;
      border: 0;
      border-radius: 9px;
      background: transparent;
      color: var(--lh-mut, #94a3b8);
      cursor: pointer
    }

    .lh-pw-btn:hover {
      color: var(--lh-ink, #334155)
    }

    .lh-pw-btn:focus-visible {
      outline: 2px solid #10b981;
      outline-offset: 1px
    }

    .lh-pw-btn svg {
      display: block;
      width: 18px;
      height: 18px
    }

    .lh-pw-btn .lh-pw-eye-off,
    .lh-pw-btn[aria-pressed="true"] .lh-pw-eye {
      display: none
    }

    .lh-pw-btn[aria-pressed="true"] .lh-pw-eye-off {
      display: block
    }

    /* floating back-to-top */
    #lh-top {
      position: fixed;
      right: 20px;
      bottom: 20px;
      z-index: 50;
      opacity: 0;
      pointer-events: none;
      transform: translateY(10px);
      transition: all .3s
    }

    #lh-top.show {
      opacity: 1;
      pointer-events: auto;
      transform: none
    }

    #lh-top:hover {
      filter: brightness(1.08)
    }

    /* ---------- preserved function styles (toast / reveal / swipe hint) ---------- */
    .toast-in {
      animation: toastIn .25s ease-out
    }

    @keyframes toastIn {
      from {
        opacity: 0;
        transform: translateY(-8px)
      }

      to {
        opacity: 1;
        transform: none
      }
    }

    .reveal {
      opacity: 0;
      transform: translateY(18px);
      transition: opacity .55s cubic-bezier(.22, .61, .36, 1), transform .55s cubic-bezier(.22, .61, .36, 1)
    }

    .reveal.in {
      opacity: 1;
      transform: none
    }

    .no-scrollbar::-webkit-scrollbar {
      display: none
    }

    .no-scrollbar {
      -ms-overflow-style: none;
      scrollbar-width: none
    }

    /* Mobile swipe hint: right-edge fade + nudge chevron; hidden on desktop or after first swipe */
    .swipe-hint::after {
      content: '';
      position: absolute;
      top: 0;
      bottom: 0;
      right: 0;
      width: 16px;
      pointer-events: none;
      background: linear-gradient(to left, rgba(255, 255, 255, .95), rgba(255, 255, 255, 0))
    }

    .swipe-hint .swipe-chevron {
      position: absolute;
      right: 3px;
      top: 50%;
      transform: translate(0, -50%);
      z-index: 10;
      display: grid;
      place-items: center;
      width: 26px;
      height: 26px;
      border-radius: 9999px;
      background: #1e293b;
      color: #fff;
      font-size: 14px;
      line-height: 1;
      box-shadow: 0 4px 10px rgba(15, 23, 42, .25);
      animation: nudge 1.4s ease-in-out infinite;
      cursor: pointer
    }

    .swipe-hint .swipe-chevron:active {
      background: #059669
    }

    @keyframes nudge {

      0%,
      100% {
        margin-right: 0
      }

      50% {
        margin-right: 4px
      }
    }

    .swipe-hint.hint-off::after {
      display: none
    }

    .swipe-hint.hint-off .swipe-chevron {
      display: none
    }

    @media (min-width:640px) {
      .swipe-hint::after {
        display: none
      }

      .swipe-hint .swipe-chevron {
        display: none
      }
    }

    @media (prefers-reduced-motion:reduce) {
      .reveal {
        opacity: 1;
        transform: none;
        transition: none
      }

      main {
        animation: none
      }

      nav a.grid.rounded-xl.bg-indigo-600::before {
        animation: none
      }

      main>section.bg-gradient-to-r {
        animation: none;
        background-size: 100% 100% !important
      }

      main>section.bg-gradient-to-r::before {
        animation: none
      }

      main .h-2>.h-full::after,
      main .h-2\.5>.h-full::after,
      main .h-3>.h-full::after {
        animation: none
      }

      .swipe-hint .swipe-chevron {
        animation: none
      }

      #lh-progress {
        transition: none
      }
    }


    /* ============================================================
   Redesign shell: fixed sidebar + top bar + notification panel
   ============================================================ */
    .lh-app {
      background: #eef3ee
    }

    .lh-sidebar {
      position: fixed;
      top: 0;
      left: 0;
      bottom: 0;
      width: 264px;
      z-index: 35;
      background: rgba(255, 255, 255, .97);
      border-right: 1px solid rgba(226, 232, 240, .92);
      box-shadow: 0 24px 48px -24px rgba(4, 120, 87, .18);
      transform: translateX(-280px);
      transition: transform .25s ease;
      display: flex;
      flex-direction: column
    }

    .lh-sidebar.open {
      transform: none
    }

    @media(min-width:1024px) {
      .lh-sidebar {
        transform: none;
        box-shadow: none
      }
    }

    .lh-backdrop {
      position: fixed;
      inset: 0;
      z-index: 34;
      background: rgba(15, 23, 42, .35);
      display: none
    }

    body.lh-side-open .lh-backdrop {
      display: block
    }

    @media(min-width:1024px) {
      .lh-backdrop {
        display: none !important
      }
    }

    body.lh-app {
      padding-left: 0
    }

    @media(min-width:1024px) {
      body.lh-app {
        padding-left: 264px
      }
    }

    .lh-main {
      transition: padding-left .25s ease
    }

    .lh-side-head {
      display: flex;
      align-items: center;
      gap: .6rem;
      padding: .9rem 1rem .8rem;
      border-bottom: 1px solid rgba(226, 232, 240, .9)
    }

    .lh-side-sec {
      padding: .9rem 1rem .35rem;
      font-size: 10px;
      font-weight: 800;
      letter-spacing: .12em;
      text-transform: uppercase;
      color: #94a3b8
    }

    .lh-side-nav {
      display: flex;
      flex-direction: column;
      gap: 2px;
      padding: 0 .65rem
    }

    .lh-side-link {
      display: flex;
      align-items: center;
      gap: .65rem;
      padding: .55rem .7rem;
      font-size: .875rem;
      font-weight: 600;
      color: #475569;
      border-radius: 12px;
      transition: all .15s;
      position: relative
    }

    .lh-side-link:hover {
      background: #ecfdf5;
      color: #047857
    }

    .lh-side-link.active {
      background: linear-gradient(135deg, rgba(4, 120, 87, .14), rgba(16, 185, 129, .10));
      color: #047857;
      box-shadow: inset 0 0 0 1.5px rgba(16, 185, 129, .28)
    }

    .lh-side-link.active::before {
      content: '';
      position: absolute;
      left: -.65rem;
      top: 20%;
      bottom: 20%;
      width: 3px;
      border-radius: 99px;
      background: linear-gradient(#047857, #10b981)
    }

    .lh-side-ico {
      width: 1.25rem;
      text-align: center;
      font-size: 15px;
      line-height: 1
    }

    .lh-side-label {
      flex: 1;
      min-width: 0
    }

    .lh-side-foot {
      margin-top: auto;
      display: flex;
      align-items: center;
      gap: .6rem;
      padding: 1rem;
      border-top: 1px solid rgba(226, 232, 240, .9)
    }

    .lh-topbar .lh-top-inner {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: .75rem;
      padding: 0 1rem;
      height: 60px
    }

    .lh-badge {
      position: absolute;
      top: -3px;
      right: -4px;
      min-width: 17px;
      height: 17px;
      padding: 0 3px;
      border-radius: 9999px;
      background: #dc2626;
      color: #fff;
      font-size: 10px;
      font-weight: 800;
      line-height: 17px;
      text-align: center;
      box-shadow: 0 0 0 2px #fff
    }

    /* ---- notifications panel: responsive on every screen ----------------------
   Phones  : full-width sheet pinned 8px inside the viewport (never overflows)
   Desktop : dropdown anchored under the bell
   Both    : dvh (not vh) so mobile URL bars can never push it off-screen,
             long words wrap, and the list scrolls with momentum containment.
   ------------------------------------------------------------------------- */
    .lh-panel {
      position: absolute;
      top: calc(100% + 10px);
      right: 0;
      z-index: 60;
      width: min(380px, calc(100vw - 2rem));
      max-height: min(480px, calc(100dvh - 84px));
      overflow: hidden;
      border-radius: 18px;
      border: 1px solid rgba(226, 232, 240, .9);
      background: #fff;
      box-shadow: 0 28px 60px -24px rgba(4, 120, 87, .28);
      display: flex;
      flex-direction: column;
      overscroll-behavior: contain
    }

    /* app.js pins the "closed" state of these components by toggling Tailwind's
   `.hidden` (a single class = 0-1-0 specificity). `.lh-panel` and `.lh-badge`
   both declare their own `display` (flex / grid) further up in THIS stylesheet,
   so they collide with `.hidden` at identical specificity — and the winning
   rule is simply the one that comes last. This inline <style> is emitted after
   the linked assets/tailwind.min.css, so without the combined-selector rules
   below the notification panel could never close and the badges stayed
   permanently visible showing an empty "0". Re-assert the closed state with a
   higher-specificity selector so the toggle always works, whatever the
   stylesheet order. */
    .lh-panel.hidden {
      display: none !important
    }

    .lh-badge.hidden {
      display: none !important
    }

    /* Mobile list "peek" — the dashboard panels (Live now / Attendance today /
   Needs attention / Recent activity) arrive with every row the server sent,
   which on a phone is a wall of text. app.js keeps the newest five rows
   visible and puts the rest behind a Show-all control: opening a panel caps
   it at five rows (the --lh-peek-h height app.js measures) and scrolling
   inside streams the next batch of rows in.
   `.lh-peek-btn` is hidden with the `hidden` attribute, so re-assert the
   closed state here — same reason as .lh-panel.hidden above. */
    .lh-peek-btn[hidden] {
      display: none !important
    }

    .lh-peek-caret {
      display: inline-block;
      margin-left: .3rem;
      line-height: 1;
      transition: transform .18s
    }

    .lh-peek-btn[aria-expanded="true"] .lh-peek-caret {
      transform: rotate(180deg)
    }

    @media (max-width: 1023.98px) {
      /* a row the reader has not "loaded" yet */
      .lh-peek-off {
        display: none !important
      }

      /* the opened panel: a five-row window whose remaining rows stream in
     as the list is scrolled (see app.js) */
      .lh-peek-box {
        max-height: var(--lh-peek-h, 15rem);
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
        padding-right: .25rem;
        scrollbar-width: thin
      }

      /* a row that just streamed in: a short rise, so it reads as "loaded" */
      .lh-peek-in {
        animation: lhPeekIn .22s ease-out both
      }
    }

    @keyframes lhPeekIn {
      from {
        opacity: 0;
        transform: translateY(4px)
      }

      to {
        opacity: 1;
        transform: none
      }
    }

    @media (prefers-reduced-motion: reduce) {
      .lh-peek-in {
        animation: none
      }
    }

    /* Rolling live stats: when the realtime poll changes a number (e.g. the
   "Total time" card on the attendance day page), the old value slides up and
   out while the new value slides in from the bottom. app.js adds .lh-rolling
   to the stat element only while the animation runs, so layout at rest is
   untouched. */
    .lh-rolling {
      position: relative;
      overflow: hidden;
      display: inline-block
    }

    .lh-roll-in {
      display: inline-block;
      animation: lhRollIn .42s cubic-bezier(.2, .7, .3, 1) both
    }

    .lh-roll-out {
      position: absolute;
      left: 0;
      top: 0;
      display: inline-block;
      pointer-events: none;
      animation: lhRollOut .42s cubic-bezier(.2, .7, .3, 1) both
    }

    @keyframes lhRollIn {
      from {
        transform: translateY(110%);
        opacity: 0
      }

      to {
        transform: translateY(0);
        opacity: 1
      }
    }

    @keyframes lhRollOut {
      from {
        transform: translateY(0);
        opacity: 1
      }

      to {
        transform: translateY(-110%);
        opacity: 0
      }
    }

    @media (prefers-reduced-motion: reduce) {

      .lh-roll-in,
      .lh-roll-out {
        animation: none
      }

      .lh-roll-out {
        display: none
      }
    }

    /* Dashboard graph hover: lib.php embeds each day's label + values on invisible
   strip rects; app.js moves the guide line / highlight dots and fills a shared
   tooltip. The hover layer stays hidden until a strip is under the cursor. */
    .lh-chart .js-chart-col {
      cursor: crosshair
    }

    .lh-chart .js-chart-hover {
      visibility: hidden
    }

    .lh-chart.lh-chart-on .js-chart-hover {
      visibility: visible
    }

    .lh-chart-tip {
      position: fixed;
      z-index: 70;
      pointer-events: none;
      min-width: 132px;
      padding: 8px 11px;
      border-radius: 10px;
      background: rgba(15, 23, 42, .95);
      color: #cbd5e1;
      font-size: 11px;
      line-height: 1.4;
      box-shadow: 0 10px 28px rgba(15, 23, 42, .28);
      opacity: 0;
      transform: translateY(3px);
      transition: opacity .12s ease, transform .12s ease
    }

    .lh-chart-tip.lh-chart-tip-on {
      opacity: 1;
      transform: translateY(0)
    }

    .lh-chart-tip-day {
      margin: 0 0 4px;
      font-weight: 700;
      color: #fff
    }

    .lh-chart-tip-row {
      margin: 2px 0 0;
      display: flex;
      align-items: center;
      gap: 6px
    }

    .lh-chart-tip-row i {
      flex: none;
      width: 8px;
      height: 8px;
      border-radius: 999px
    }

    .lh-chart-tip-row span {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap
    }

    .lh-chart-tip-row b {
      margin-left: auto;
      padding-left: 12px;
      font-weight: 700;
      color: #fff
    }

    /* ============================================================
   Live class room (class_room.php) + its course-page banner.
   WHY PLAIN CSS: assets/tailwind.min.css is a PRECOMPILED Tailwind
   subset — it contains min-h-[560px] / text-[10px] but NOT
   h-[calc(100vh-230px)] or min-h-[460px]. The room asked for exactly
   those, so #lr-meeting had no height at all (auto = 0), the Jitsi
   iframe inside it collapsed to nothing and the meeting looked broken
   with no mic/camera bar. These rules always exist.
   ============================================================ */
    .lh-stage {
      position: relative;
      width: 100%;
      /* 100dvh (not vh) so the bottom toolbar never hides behind mobile
     browser chrome; the extra 245px leaves room for the page header,
     the room toolbar and the help strip above/below. */
      height: calc(100dvh - 245px);
      min-height: 460px;
      overflow: hidden;
      border-radius: .75rem;
      background: #0f172a
    }

    @supports not (height: 100dvh) {
      .lh-stage {
        height: calc(100vh - 245px)
      }
    }

    @media (max-width: 900px) {
      .lh-stage {
        height: 64vh;
        min-height: 340px
      }
    }

    /* keep the embedded meeting filling its box no matter what Jitsi sets */
    .lh-stage>iframe {
      position: absolute;
      inset: 0;
      width: 100% !important;
      height: 100% !important;
      border: 0
    }

    /* "Own window" mode: meet.jit.si refuses to be embedded (it hangs the call up
   after 5 minutes), so the room shows this launch panel instead of an iframe
   and the video runs in its own browser window (a fresh hour per unsigned
   meeting — the teacher signing in lifts that cap). */
    .lh-launch {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 14px;
      width: 100%;
      min-height: 420px;
      padding: 30px 20px;
      border-radius: .75rem;
      background: linear-gradient(160deg, #0f172a, #1e293b);
      color: #e2e8f0;
      text-align: center
    }

    .lh-launch-icon {
      font-size: 38px;
      line-height: 1
    }

    .lh-launch h2 {
      margin: 0;
      max-width: 620px;
      font-size: 18px;
      font-weight: 700;
      color: #fff
    }

    .lh-launch p {
      max-width: 660px;
      margin: 0;
      font-size: 13px;
      line-height: 1.75;
      color: #cbd5e1
    }

    a.lh-launch-go {
      display: inline-flex;
      align-items: center;
      gap: 8px;
      min-height: 48px;
      padding: 12px 28px;
      border-radius: .75rem;
      background: #059669;
      color: #fff;
      font-size: 15px;
      font-weight: 700;
      text-decoration: none;
      box-shadow: 0 10px 24px rgba(5, 150, 105, .35)
    }

    a.lh-launch-go:hover {
      background: #047857
    }

    .lh-launch .lh-launch-alt {
      font-size: 11px;
      color: #94a3b8
    }

    .lh-launch .lh-launch-alt button {
      border: 0;
      padding: 0;
      background: none;
      color: #7dd3fc;
      font-size: 11px;
      font-weight: 600;
      text-decoration: underline;
      cursor: pointer
    }

    /* Shown when an embedded call drops (e.g. the 5-minute cut on meet.jit.si). */
    .lh-drop {
      margin-top: 12px;
      padding: 12px 16px;
      border-radius: .75rem;
      background: #fff7ed;
      box-shadow: 0 0 0 1px #fed7aa;
      font-size: 12px;
      line-height: 1.75;
      color: #9a3412
    }

    .lh-drop b {
      color: #7c2d12
    }

    .lh-drop a {
      color: #c2410c;
      font-weight: 700
    }

    /* Device notices (in-app-browser warning, phone "use the full page" hint). */
    .lh-inapp {
      margin-top: 12px;
      padding: 12px 16px;
      border-radius: .75rem;
      background: #fef2f2;
      box-shadow: 0 0 0 1px #fecaca;
      font-size: 12px;
      line-height: 1.75;
      color: #b91c1c
    }

    .lh-inapp b {
      color: #991b1b
    }

    .lh-inapp a,
    .lh-inapp button {
      border: 0;
      padding: 0;
      background: none;
      color: #dc2626;
      font-size: 12px;
      font-weight: 700;
      text-decoration: underline;
      cursor: pointer
    }

    /* Fingers need bigger targets than a mouse: bump every button in the room
   toolbar on touch devices (phones, tablets — not touch-screen laptops). */
    @media (pointer: coarse) {
      .lh-roombar>button {
        min-height: 40px;
        padding-top: 8px;
        padding-bottom: 8px
      }
    }

    @media (max-width: 900px) {
      .lh-launch {
        min-height: 340px;
        padding: 22px 14px
      }

      .lh-launch h2 {
        font-size: 16px
      }
    }

    /* pulsing red "live" dot (replaces bg-rose-500 + animate-ping, which are
   not in the compiled CSS either) */
    .lh-live-dot {
      position: relative;
      display: inline-flex;
      flex: none;
      height: .75rem;
      width: .75rem
    }

    .lh-live-dot>span:first-child {
      position: absolute;
      inset: 0;
      border-radius: 9999px;
      background: #fb7185;
      opacity: .75;
      animation: lh-ping 1.5s cubic-bezier(0, 0, .2, 1) infinite
    }

    .lh-live-dot>span:last-child {
      display: block;
      position: relative;
      height: .75rem;
      width: .75rem;
      border-radius: 9999px;
      background: #f43f5e
    }

    @keyframes lh-ping {

      75%,
      100% {
        transform: scale(2.1);
        opacity: 0
      }
    }

    /* roster avatar: `.h-6 .w-6` were missing from the compiled CSS, so the
   circles had no size and the initials rendered unstyled */
    .lh-avatar {
      display: grid;
      flex: none;
      place-items: center;
      height: 1.5rem;
      width: 1.5rem;
      border-radius: 9999px;
      background: #4f46e5;
      color: #fff;
      font-size: 10px;
      font-weight: 700
    }

    .lh-hand {
      margin-left: auto;
      color: #f59e0b
    }

    .lh-soft {
      font-weight: 400
    }

    .lh-chip-amber:hover {
      background: #fef3c7
    }

    /* browsers without dvh support keep the old viewport maths */
    @supports not (height: 100dvh) {
      .lh-panel {
        max-height: min(480px, calc(100vh - 84px))
      }

      .lx-panel-list {
        max-height: min(400px, calc(100vh - 148px))
      }
    }

    /* NOTE: the list/head classes really are `lx-…` in the markup (header.php and
   app.js) — the old rules said `.lh-panel-list`, which matched nothing, so the
   list had no overflow rule at all and long lists were simply clipped. */
    .lx-panel-list {
      flex: 1 1 auto;
      min-height: 0;
      max-height: min(400px, calc(100dvh - 148px));
      overflow-y: auto;
      overscroll-behavior: contain;
      -webkit-overflow-scrolling: touch
    }

    .lx-panel-head {
      flex: 0 0 auto
    }

    .lx-panel-item {
      display: flex;
      flex-direction: column;
      gap: 2px;
      padding: .65rem .85rem;
      border-bottom: 1px solid rgba(241, 245, 249, .8);
      cursor: pointer;
      text-decoration: none
    }

    .lx-panel-item:hover {
      background: #f6fbf8
    }

    /* An e-mail address or URL in a notification is one long unbreakable word —
       let it wrap instead of overflowing the sheet (the panel clips with
       overflow:hidden, so overflow would silently cut the text off). */
    .lx-panel-item,
    .lx-panel-item-title {
      min-width: 0;
      overflow-wrap: anywhere;
      word-break: break-word
    }

    /* ==== responsive rules BELOW every base panel rule ======================
       These must come last: a media query does not add specificity, so a base
       rule placed after the query would silently win by source order (that is
       why `.lx-panel-item`'s padding used to beat the phone override).
       Phones  : full-width sheet pinned 8px inside the viewport (never overflows)
       Desktop : dropdown anchored under the bell
       Both    : dvh (not vh) so mobile URL bars can never push it off-screen.
       ===================================================================== */

    @media (max-width: 639.98px) {

      /* `backdrop-filter` makes its element a containing block for position:fixed
     children, so drop the blur on phones — the sheet below then pins to the
     viewport itself instead of to the 60px topbar. Also cheaper to render.
     `!important` is required: `nav.glass` (line ~1161) and `.lh-topbar`
     (line ~1174) both set the background with `!important`, and an important
     declaration beats a non-important one no matter the specificity. */
      .lh-topbar.glass {
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        background: rgba(255, 255, 255, .97) !important
      }

      .lh-panel {
        position: fixed;
        top: 66px;
        left: 8px;
        right: 8px;
        width: auto;
        max-height: calc(100dvh - 82px);
        border-radius: 16px
      }

      .lx-panel-list {
        max-height: calc(100dvh - 170px);
        padding-bottom: calc(.5rem + env(safe-area-inset-bottom, 0px))
      }

      /* comfy touch targets, and the sheet spans edge to edge */
      .lx-panel-item {
        padding: .8rem 1rem;
        min-height: 44px
      }

      /* Ultra-narrow phones (iPhone SE portrait, 320-360px): "Notifications" and
     "Mark all as read" sit on one row and would push each other out of the
     sheet. Let them wrap only when they actually run out of room. */
      .lx-panel-head {
        flex-wrap: wrap;
        row-gap: .25rem
      }
    }

    /* Landscape phones / very short windows: reclaim vertical space.
   NOTE: no `top` here. On desktop the panel is `position: absolute` and hangs
   from `top: calc(100% + 10px)` under the bell — overriding that to a viewport
   value would drop it out of the topbar. Only the heights need shrinking. */
    @media (max-height: 480px) {
      .lh-panel {
        max-height: calc(100dvh - 84px)
      }

      .lx-panel-list {
        max-height: calc(100dvh - 132px)
      }

      .lx-panel-item {
        padding: .55rem .85rem
      }
    }

    /* big desktop / large fonts: keep it comfortable, still never off-screen */
    @media (min-width: 1280px) {
      .lh-panel {
        width: min(400px, calc(100vw - 4rem))
      }
    }


    .lh-notif-unread {
      background: #ecfdf5
    }

    .lh-notif-unread:hover {
      background: #d1fae5
    }

    .lh-notif-unread::before {
      content: '';
      align-self: flex-start;
      width: 7px;
      height: 7px;
      border-radius: 99px;
      background: #059669;
      margin-bottom: 3px
    }

    .lh-notif-item {
      display: flex;
      flex-direction: column;
      gap: 1px
    }



    /* ============================================================
   

/* ---------- collapsible sidebar (icon rail + hover labels) ---------- */
    #lh-side-collapse {
      margin-top: 0;
      display: grid;
      place-items: center;
      width: 36px;
      height: 36px;
      border-radius: 10px;
      border: 1px solid rgba(226, 232, 240, .9);
      color: #64748b;
      background: #fff;
      cursor: pointer;
      transition: all .2s
    }

    #lh-side-collapse:hover {
      color: #047857;
      background: #ecfdf5;
      border-color: #a7f3d0
    }

    .lh-side-collapse-wrap {
      display: flex;
      justify-content: center;
      padding: .8rem 0;
      border-top: 1px solid rgba(226, 232, 240, .9)
    }

    @media(min-width:1024px) {
      #lh-rail-toggle {
        display: grid;
        visibility: visible
      }
    }

    @media(max-width:1023.98px) {
      #lh-rail-toggle {
        display: none
      }
    }

    @media(max-width:1023.98px) {
      .lh-side-collapse-wrap {
        display: none
      }
    }

    /* collapsed rail on desktop only */
    @media(min-width:1024px) {

      /* `html … !important` so the fold outranks BOTH a theme's own width
         pins AND density-compact.css' `.lh-sidebar{width:232px!important}`.
         Without it the rail keeps the full panel width while the label rules
         below already hide the text — an icon-only, 232px-wide sidebar that
         looks like it never closed (Console/Bright/Calm/Minimal + Compact).
         Themes that really want another rail width (material: 64px/88px,
         paper: 76px) still win from their own later sheet. */
      html body.lh-rail .lh-sidebar {
        width: 76px !important;
        overflow: visible
      }

      html body.lh-rail {
        padding-left: 76px !important
      }

      body.lh-rail .lh-side-head {
        justify-content: center;
        padding: .9rem .5rem .8rem
      }

      body.lh-rail .lh-side-head>div {
        display: none
      }

      /* wordmark (learn.png) hides on the collapsed rail — icon only */
      body.lh-rail .lh-side-head .lh-side-wordmark {
        display: none
      }

      body.lh-rail .lh-side-sec {
        display: none
      }

      body.lh-rail .lh-side-nav {
        padding: 0 .55rem
      }

      body.lh-rail .lh-side-link {
        justify-content: center;
        padding: .62rem .4rem;
        gap: 0
      }

      body.lh-rail .lh-side-link .lh-side-label {
        display: none
      }

      body.lh-rail .lh-side-foot {
        justify-content: center;
        padding: .8rem .4rem
      }

      body.lh-rail .lh-side-foot>span:not(:first-child) {
        display: none
      }

      body.lh-rail .lh-side-foot>a {
        display: none
      }

      body.lh-rail .lh-side-collapse-wrap {
        padding: 0 .4rem .8rem
      }

      body.lh-rail .lh-side-link .lh-badge {
        position: absolute;
        top: -2px;
        right: 2px
      }
    }

    /* hover tooltip on collapsed rail */
    .lh-side-link::after {
      content: attr(data-tip);
      position: absolute;
      left: calc(100% + 10px);
      top: 50%;
      transform: translateY(-50%);
      white-space: nowrap;
      background: #0f172a;
      color: #fff;
      font-size: 11px;
      font-weight: 700;
      padding: 5px 9px;
      border-radius: 8px;
      opacity: 0;
      pointer-events: none;
      transition: opacity .15s;
      box-shadow: 0 8px 20px -8px rgba(15, 23, 42, .4);
      z-index: 80
    }

    @media(min-width:1024px) {
      body.lh-rail .lh-side-link:hover::after {
        opacity: 1
      }
    }

    /* ============================================================
       Styled hover chip for icon-only controls — the same chip the
       folded rail uses. Text lives in data-tip; native title is
       omitted on purpose so the two never stack.
       ============================================================ */
    .lh-tip,
    .lh-side-tip {
      position: relative
    }

    .lh-tip::after,
    .lh-side-tip::after {
      content: attr(data-tip);
      position: absolute;
      white-space: nowrap;
      background: #0f172a;
      color: #fff;
      font-size: 11px;
      font-weight: 700;
      padding: 5px 9px;
      border-radius: 8px;
      opacity: 0;
      pointer-events: none;
      transition: opacity .15s;
      box-shadow: 0 8px 20px -8px rgba(15, 23, 42, .4);
      z-index: 80
    }

    /* default: under the icon, centered (top bar / page controls) */
    .lh-tip::after {
      left: 50%;
      top: calc(100% + 8px);
      transform: translateX(-50%)
    }

    /* right-edge icons: keep the chip inside the viewport */
    .lh-tip-end::after {
      left: auto;
      right: 0;
      transform: none
    }

    /* bottom-fixed icons (back-to-top): open upward */
    .lh-tip-up::after {
      top: auto;
      bottom: calc(100% + 8px)
    }

    /* inside the sidebar: open to the right, like the folded rail */
    .lh-side-tip::after {
      left: calc(100% + 10px);
      top: 50%;
      transform: translateY(-50%)
    }

    .lh-tip:hover::after,
    .lh-side-tip:hover::after {
      opacity: 1
    }

/* ---------- schedule calendar (schedule.php): the month grid + hover card ---------- */
.folder-lesson-actions {
  position: relative;
  flex: 0 0 auto
}

.folder-lesson-actions > summary {
  list-style: none;
  -webkit-tap-highlight-color: transparent
}

.folder-lesson-actions > summary::-webkit-details-marker {
  display: none
}

.folder-lesson-actions-menu {
  display: none;
  position: absolute;
  top: calc(100% + .25rem);
  right: 0;
  z-index: 40;
  box-sizing: border-box;
  width: max-content;
  min-width: 11rem;
  max-width: calc(100vw - 2rem);
  padding: .25rem;
  border: 1px solid #e2e8f0;
  border-radius: .75rem;
  background: #fff;
  box-shadow: 0 12px 28px -12px rgba(15, 23, 42, .35)
}

.folder-lesson-actions[open] > .folder-lesson-actions-menu,
.folder-lesson-actions:hover > .folder-lesson-actions-menu,
.folder-lesson-actions:focus-within > .folder-lesson-actions-menu {
  display: block
}

.folder-lesson-actions-menu button {
  display: block;
  width: 100%;
  padding: .55rem .75rem;
  border: 0;
  border-radius: .5rem;
  background: transparent;
  color: #334155;
  font-size: .75rem;
  font-weight: 600;
  line-height: 1rem;
  text-align: left;
  white-space: nowrap
}

.folder-lesson-actions-menu button:hover,
.folder-lesson-actions-menu button:focus-visible {
  background: #eef2ff;
  color: #4338ca;
  outline: none
}

/* The grid is a real calendar: seven columns, whole weeks only, every day of the
   month present. A day that holds something shows compact chips on a wide screen
   and dots on a phone; pointing at it (or focusing it with the keyboard, or tapping
   it) fills #lh-cal-pop, one shared card the page script positions next to the day.
   One card instead of one per day means the details can never be clipped by the
   grid, and every cell keeps only a <template> copy of its own details. */
.lh-cal {
  border-radius: 1rem;
  background: #fff;
  box-shadow: 0 1px 2px rgba(17, 33, 26, .05);
  outline: 1px solid #e2e8f0;
  overflow: visible
}

.lh-cal-weekhead,
.lh-cal-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr))
}

.lh-cal-weekhead {
  border-bottom: 1px solid #f1f5f9;
  border-radius: 1rem 1rem 0 0;
  background: #f8fafc
}

.lh-cal-weekhead span {
  padding: .5rem .2rem;
  text-align: center;
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #94a3b8
}

.lh-cal-grid {
  gap: .375rem;
  padding: .5rem
}

.lh-cal-day {
  position: relative;
  min-height: 6.4rem;
  padding: .4rem .45rem;
  border: 1px solid #f1f5f9;
  border-radius: .75rem;
  background: #fff;
  transition: background .15s ease, border-color .15s ease, box-shadow .15s ease
}

.lh-cal-day:hover,
.lh-cal-day:focus-visible,
.lh-cal-day.is-open {
  border-color: #a7f3d0;
  background: #f0fdf9;
  box-shadow: 0 6px 18px -14px rgba(4, 120, 87, .55);
  outline: none
}

/* days of the neighbouring months: present, but clearly not the month in view */
.lh-cal-day.is-out {
  background: #fcfdfe
}

.lh-cal-day.is-out .lh-cal-num,
.lh-cal-day.is-out .lh-cal-chip {
  color: #cbd5e1
}

.lh-cal-day.is-today {
  border-color: #6ee7b7;
  background: #ecfdf5
}

/* One face per teacher with something on this day. Sits in the top corner,
   overlapped like a row of faces so three still fit a narrow cell. */
.lh-cal-faces {
  position: absolute;
  top: .3rem;
  right: .3rem;
  display: flex;
  flex-direction: row-reverse
}

.lh-cal-faces > * {
  margin-left: -.45rem;
  border: 1.5px solid #fff;
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .12)
}

.lh-cal-faces > *:last-child {
  margin-left: 0
}

/* once the count badge is on screen it owns the top corner, so drop below it */
.lh-cal-day:has(.lh-cal-badge) .lh-cal-faces {
  top: 1.5rem
}

/* On a phone the cells are only ~45px wide, so a two-digit date and a 20px
   picture cannot share one row: the date ends around x=20 and the face would
   begin at x=19. Rather than hide the faces on the smallest screens, they drop
   below the number and shrink — the teacher is still identifiable at 14px, and
   the date keeps the corner it has always owned. */
@media (max-width: 640px) {
  .lh-cal-faces {
    top: 1.3rem;
    right: .25rem
  }

  .lh-cal-faces > * {
    width: 14px;
    height: 14px;
    margin-left: -.35rem
  }

  .lh-cal-day:has(.lh-cal-badge) .lh-cal-faces {
    top: 2.5rem
  }
}

.lh-cal-num {
  display: block;
  font-size: .78rem;
  font-weight: 700;
  color: #475569
}

.lh-cal-day.is-today .lh-cal-num {
  color: #047857
}

.lh-cal-badge {
  position: absolute;
  top: .3rem;
  right: .4rem;
  display: grid;
  place-items: center;
  min-width: 1.15rem;
  height: 1.15rem;
  padding: 0 .25rem;
  border-radius: 999px;
  background: #047857;
  color: #fff;
  font-size: .6rem;
  font-weight: 800
}

.lh-cal-chips {
  display: flex;
  flex-direction: column;
  gap: .2rem;
  margin-top: .3rem
}

.lh-cal-chip {
  display: block;
  overflow: hidden;
  padding: .15rem .3rem;
  border-radius: .4rem;
  background: #f1f5f9;
  color: #334155;
  font-size: .63rem;
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis
}

.lh-cal-chip b {
  margin-right: .3rem;
  color: #0f172a;
  font-weight: 800
}

.lh-cal-chip[data-kind="exam"],
.lh-cal-dots i[data-kind="exam"] {
  background: #ffe4e6;
  color: #9f1239
}

.lh-cal-chip[data-kind="activity"],
.lh-cal-dots i[data-kind="activity"] {
  background: #fef3c7;
  color: #92400e
}

.lh-cal-chip[data-kind="deadline"],
.lh-cal-dots i[data-kind="deadline"] {
  background: #e2e8f0;
  color: #475569
}

.lh-cal-more {
  padding-left: .3rem;
  color: #94a3b8;
  font-size: .6rem;
  font-weight: 700
}

/* phones: chips would be unreadable in a ~46px cell — dots say "there is something
   here", and a tap opens the card with the whole day in it */
.lh-cal-dots {
  display: none;
  flex-wrap: wrap;
  gap: .2rem;
  margin-top: .35rem
}

.lh-cal-dots i {
  width: .4rem;
  height: .4rem;
  border-radius: 999px;
  background: #64748b
}

.lh-cal-dots i[data-kind="exam"] {
  background: #e11d48
}

.lh-cal-dots i[data-kind="activity"] {
  background: #d97706
}

.lh-cal-dots i[data-kind="deadline"] {
  background: #94a3b8
}

/* the shared hover card */
.lh-cal-pop {
  position: fixed;
  z-index: 60;
  width: min(21rem, calc(100vw - 1.5rem));
  padding: .7rem .8rem;
  border: 1px solid #e2e8f0;
  border-radius: .85rem;
  background: #fff;
  box-shadow: 0 18px 40px -22px rgba(15, 23, 42, .45), 0 2px 6px -2px rgba(15, 23, 42, .12);
  opacity: 0;
  transform: translateY(-.25rem);
  transition: opacity .12s ease, transform .12s ease;
  pointer-events: none
}

.lh-cal-pop.is-shown {
  opacity: 1;
  transform: none;
  pointer-events: auto
}

.lh-cal-pop-title {
  color: #047857;
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .05em;
  text-transform: uppercase
}

.lh-cal-pop-list {
  display: flex;
  flex-direction: column;
  gap: .45rem;
  margin-top: .5rem
}

.lh-cal-pop-list li {
  display: grid;
  gap: .1rem;
  padding-left: .5rem;
  border-left: 3px solid #10b981
}

.lh-cal-pop-list li.is-past {
  border-left-color: #cbd5e1;
  opacity: .55
}

.lh-cal-t {
  color: #0f172a;
  font-size: .68rem;
  font-weight: 800
}

.lh-cal-n {
  color: #1e293b;
  font-size: .8rem;
  font-weight: 600
}

.lh-cal-m {
  color: #64748b;
  font-size: .7rem
}

.lh-cal-x {
  color: #94a3b8;
  font-size: .7rem;
  font-style: italic
}

.lh-cal-live {
  justify-self: start;
  margin-top: .15rem;
  padding: .1rem .4rem;
  border-radius: .4rem;
  background: #047857;
  color: #fff;
  font-size: .63rem;
  font-weight: 800
}

.lh-cal-day-link {
  display: inline-block;
  margin-top: .55rem;
  color: #047857;
  font-size: .7rem;
  font-weight: 700
}

.lh-cal-day-link:hover {
  text-decoration: underline
}

@media (max-width: 640px) {
  .lh-cal-day {
    min-height: 3.4rem;
    padding: .3rem
  }

  .lh-cal-chips {
    display: none
  }

  .lh-cal-dots {
    display: flex
  }

  .lh-cal-weekhead span {
    font-size: .55rem
  }
}

@media (prefers-reduced-motion: reduce) {

  .lh-cal-day,
  .lh-cal-pop {
    transition: none
  }
}

@media print {
  .lh-cal-pop {
    display: none !important
  }

  .lh-cal-day {
    min-height: 0
  }

  .lh-cal-dots {
    display: none
  }
}

/* ============================================================
   PROFILE HOVER CARD — a name that tells you who it belongs to.
   lib.php (profile_hover_html) wraps the circle-and-name markup of any account
   the viewer is entitled to see, and puts the words on it as data attributes.
   app.js then fills ONE card element and moves it — the same arrangement the
   calendar card above uses, so hovering a 200-row roster costs nothing and a
   card is never clipped by the table or card it came out of.
   ============================================================ */
[data-hcard] {
  border-radius: .75rem;
  cursor: help;
  transition: background .15s ease, box-shadow .15s ease
}

/* the wrapper profile_hover_html() adds is an inline span, so the highlight
   hugs the name instead of breaking the line */
.lh-hcard {
  display: inline-block
}

/* where the name stands on its own line (a table cell, a roster row): the card
   wrapper is a <div>, so the highlighted area is the whole block of content */
.lh-hcard-block {
  display: block
}

/* the trigger itself is not a control, but a name inside one may still be a link */
[data-hcard] a {
  cursor: pointer
}

[data-hcard]:hover,
[data-hcard].is-open {
  background: #f0fdf4;
  box-shadow: 0 0 0 4px #f0fdf4
}

[data-hcard]:focus-visible {
  outline: none;
  background: #f0fdf4;
  box-shadow: 0 0 0 2px #fff, 0 0 0 4px rgba(5, 150, 105, .35)
}

.lh-hcard-pop {
  position: fixed;
  z-index: 70;
  display: flex;
  gap: .7rem;
  width: min(19rem, calc(100vw - 1.5rem));
  padding: .8rem .9rem;
  border: 1px solid #e2e8f0;
  border-radius: .9rem;
  background: #fff;
  box-shadow: 0 18px 40px -22px rgba(15, 23, 42, .45), 0 2px 6px -2px rgba(15, 23, 42, .12);
  opacity: 0;
  transform: translateY(-.25rem);
  transition: opacity .12s ease, transform .12s ease;
  pointer-events: none
}

.lh-hcard-pop.is-shown {
  opacity: 1;
  transform: none;
  pointer-events: auto
}

.lh-hcard-pic {
  flex: none;
  width: 3rem;
  height: 3rem;
  border-radius: 999px;
  object-fit: cover;
  box-shadow: 0 0 0 1px #e2e8f0
}

/* the same fallback the rest of the shell uses: no picture, first letter */
.lh-hcard-init {
  display: grid;
  flex: none;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 999px;
  background: #047857;
  color: #fff;
  font-size: 1.15rem;
  font-weight: 800
}

.lh-hcard-txt {
  min-width: 0
}

.lh-hcard-name {
  display: block;
  color: #0f172a;
  font-size: .9rem;
  font-weight: 800;
  line-height: 1.25;
  overflow-wrap: anywhere
}

.lh-hcard-role {
  display: inline-block;
  margin-top: .2rem;
  padding: .05rem .45rem;
  border-radius: 999px;
  background: #eef2ff;
  color: #4338ca;
  font-size: .6rem;
  font-weight: 800;
  letter-spacing: .05em;
  text-transform: uppercase
}

/* the about line is words the person chose: never markup, and long words must
   not push the card out of the viewport */
.lh-hcard-bio {
  margin-top: .3rem;
  color: #475569;
  font-size: .78rem;
  line-height: 1.45;
  white-space: pre-line;
  overflow-wrap: anywhere
}

.lh-hcard-join {
  margin-top: .35rem;
  color: #94a3b8;
  font-size: .68rem;
  font-weight: 600
}

.lh-hcard-address {
  margin: .35rem 0 0;
  color: #475569;
  font-size: .72rem;
  line-height: 1.45;
  white-space: pre-line;
  overflow-wrap: anywhere
}

/* a card that slides in on hover is decoration: it may stop, it may not distract
   somebody whose system asks for less movement */
@media (prefers-reduced-motion: reduce) {

  .lh-hcard-pop,
  [data-hcard] {
    transition: none
  }
}

@media print {

  .lh-hcard-pop {
    display: none !important
  }
}

/* ── the crop window on My profile ──────────────────────────────────────────
   A picture is framed before it is uploaded, and the framing window has to be
   drawn here rather than with utility classes: the compiled Tailwind build has
   no square aspect helper, no touch-action and no wide ring, and a class that is
   not already in it only starts existing after a rebuild.
   The window is a circle because a circle is the shape every avatar on this site
   is cut into (.lh-avatar-img) — frame to the circle and the face is where it
   will be seen. The stored file is still a square: the corners outside this
   circle are simply never shown anywhere. */
.lh-crop-stage {
  position: relative;
  width: min(72vw, 288px);
  aspect-ratio: 1 / 1;
  margin: 1rem auto 0;
  overflow: hidden;
  border-radius: 1rem;
  background: #e2e8f0;
  touch-action: none;              /* dragging on a phone pans the picture, not the page */
  -webkit-user-select: none;
  user-select: none;
  cursor: grab
}

.lh-crop-stage:active {
  cursor: grabbing
}

/* the arrows nudge the picture, so the window has to show that it is focused */
.lh-crop-stage:focus-visible {
  box-shadow: 0 0 0 3px rgba(79, 70, 229, .5)
}

/* the picked picture: the page script sets its size and left/top in stage px */
.lh-crop-img {
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  max-width: none;
  pointer-events: none             /* the drag belongs to the stage, never the image */
}

/* one huge ring is what dims the part of the picture the crop throws away */
.lh-crop-win {
  position: absolute;
  inset: 0;
  border-radius: 9999px;
  box-shadow: 0 0 0 300px rgba(15, 23, 42, .45), inset 0 0 0 2px rgba(255, 255, 255, .92);
  pointer-events: none
}

/* where a face usually sits — a hint drawn on the glass, nothing more */
.lh-crop-face {
  position: absolute;
  left: 50%;
  top: 26%;
  width: 32%;
  height: 40%;
  transform: translate(-50%, -50%);
  border: 1px dashed rgba(255, 255, 255, .75);
  border-radius: 9999px;
  pointer-events: none
}

.lh-reaction-menu {
  display: none;
  z-index: 90
}

.lh-reaction-control:hover .lh-reaction-menu,
.lh-reaction-control:focus-within .lh-reaction-menu {
  display: flex
}

.lh-reaction-menu::after {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: .4rem;
  content: ""
}

.lh-reaction-people-row {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  margin-left: .5rem
}

.lh-reaction-people {
  position: relative;
  display: inline-block;
  width: 4rem;
  height: 2rem;
  vertical-align: middle
}

.lh-reaction-face {
  position: absolute;
  display: block;
  width: 1.75rem;
  height: 1.75rem;
  border: 2px solid #fff;
  border-radius: 9999px;
  background: #fff
}

.lh-reaction-face-1 {
  left: 0;
  bottom: 0;
  z-index: 1
}

.lh-reaction-face-2 {
  left: 1.1rem;
  top: 0;
  z-index: 3
}

.lh-reaction-face-3 {
  right: 0;
  bottom: 0;
  z-index: 2
}

.lh-reaction-face > .lh-avatar-img,
.lh-reaction-face > .lh-avatar-initial {
  width: 100%;
  height: 100%
}

.lh-reaction-face-emoji {
  position: absolute;
  right: -3px;
  bottom: -3px;
  display: grid;
  width: 14px;
  height: 14px;
  place-items: center;
  border: 1px solid #fff;
  border-radius: 9999px;
  background: #fff;
  font-size: 9px;
  line-height: 1
}

/* Shared surfaces and accessible interaction affordances across the app. */
.lh-ui-card {
  border: 1px solid #e2e8f0;
  border-radius: 1rem;
  background: #fff;
  box-shadow: 0 1px 3px rgba(15, 23, 42, .06)
}

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid #4f46e5 !important;
  outline-offset: 3px !important
}

.lh-tap-target {
  min-height: 44px
}

@media (max-width: 640px) {
  .student-action-grid,
  .student-action-card,
  .student-action-card ul,
  .student-action-link,
  .student-action-copy {
    min-width: 0;
    max-width: 100%
  }

  .student-action-card {
    overflow: hidden
  }

  .student-action-link {
    flex-wrap: wrap;
    justify-content: flex-start;
    overflow-wrap: anywhere
  }

  .student-action-copy {
    flex: 1 1 100%
  }

  .student-action-meta {
    max-width: 100%;
    white-space: normal;
    overflow-wrap: anywhere
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto !important
  }

  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important
  }
}
