/*
 * attend. -- the student screens in the Indigo design (docs/design/visual-design.md;
 * boards Main, A-student-desktop, A-checkin-scan, A-checkin-receipt, colours A3):
 * Today, the attendance page, the scanner and its receipt.
 *
 * Linked after components.css (templates/base.html) and added to
 * `@layer components`, so it overrides the shared rules at equal specificity
 * while app.css's reset ([hidden], reduced motion) and utilities still win.
 * Colours are var(--attend-*) tokens only; shadows only the light theme's
 * elevation tokens (none in dark); no gradients, blur or filters
 * (tests/test_css_rules.py). Decoration -- the hero's two faint blobs (light
 * theme only), the scan sweep, the receipt's pop and confetti -- never sits in
 * tables or near status chips, and moves only without prefers-reduced-motion.
 */
@layer components {
  /* ------------------------------------------------------------ Today */
  .student-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-6);
  }

  @media (min-width: 1024px) {
    .student-grid {
      grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
      gap: var(--space-4);
      align-items: start;
    }
  }

  .student-now {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
  }

  .student-day {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
  }

  .student-now .section-label,
  .student-day .section-label,
  .student-recent .section-label {
    margin: 0 0 var(--space-3);
  }

  /* The current-class hero: a soft tinted card, dark text, no glow. */
  .course-card {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    padding: var(--space-6);
    border: 1px solid var(--attend-hero-border);
    border-radius: var(--r-xl);
    background: var(--attend-hero);
    color: var(--attend-text-strong);
  }

  .course-card > :not(.course-card__blob) {
    position: relative;
  }

  /* Two faint circles clipped by the card's top-right corner, clear of the text lines. */
  .course-card__blob {
    position: absolute;
    z-index: -1;
    top: -96px;
    right: -92px;
    inline-size: 180px;
    block-size: 180px;
    border-radius: 50%;
    background: var(--attend-brand);
    opacity: 0.06;
    pointer-events: none;
  }

  .course-card__blob--small {
    top: -30px;
    right: -46px;
    inline-size: 96px;
    block-size: 96px;
    opacity: 0.05;
  }

  :root[data-theme="dark"] .course-card__blob {
    display: none;
  }

  @media (prefers-color-scheme: dark) {
    :root[data-theme="system"] .course-card__blob {
      display: none;
    }
  }

  .course-card__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
  }

  .course-card__eyebrow {
    display: none;
    color: var(--attend-text-muted);
    font-size: var(--text-label);
    font-weight: var(--weight-label);
    letter-spacing: var(--tracking-label);
    line-height: var(--leading-label);
    text-transform: uppercase;
  }

  /* "Check-in open": a pill on the hero with the live dot (the motif). */
  .course-card__live {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 32px;
    padding: 0 14px 0 var(--space-3);
    border-radius: var(--r-pill);
    /* Raised: white on the light hero, a step above it in dark (14.27:1). */
    background: var(--attend-raised);
    color: var(--attend-text-strong);
    font-size: var(--text-small);
    font-weight: var(--weight-strong);
    line-height: var(--leading-small);
  }

  .course-card__live::before {
    content: "";
    flex-shrink: 0;
    inline-size: 8px;
    block-size: 8px;
    border-radius: 50%;
    background: var(--attend-accent);
    outline: 3px solid var(--attend-brand-tint);
  }

  .course-card__state {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    min-height: 32px;
    color: var(--attend-text);
    font-size: var(--text-small);
    font-weight: var(--weight-strong);
  }

  .course-card__code {
    margin-top: var(--space-5);
    color: var(--attend-text-muted);
    font-size: var(--text-small);
    font-weight: var(--weight-bold);
    letter-spacing: 0;
    line-height: var(--leading-small);
    text-transform: none;
  }

  .course-card__title {
    margin: var(--space-1) 0 0;
    color: var(--attend-text-strong);
    font-family: var(--font-display);
    font-size: var(--text-display);
    font-weight: var(--weight-display);
    letter-spacing: var(--tracking-display);
    line-height: var(--leading-display);
    overflow-wrap: anywhere;
  }

  .course-card__facts {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    margin-top: var(--space-3);
  }

  .course-card__meta,
  .course-card__teacher {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0;
    color: var(--attend-text);
    font-size: var(--text-body);
    line-height: var(--leading-body);
  }

  .course-card__meta span + span {
    padding-left: 0;
    border-left: 0;
  }

  .course-card__actions {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-top: var(--space-6);
  }

  .course-card__actions .btn {
    min-height: 56px;
  }

  /* A secondary button ("View receipt") on the tinted hero: a surface pill,
     since the brand tint would vanish into the hero's own tint. */
  .course-card__actions .btn:not(.btn--primary) {
    background: var(--attend-surface);
  }

  .course-card__hint {
    color: var(--attend-text-muted);
    font-size: var(--text-small);
    line-height: var(--leading-small);
    text-align: center;
  }

  @media (min-width: 1024px) {
    .course-card {
      min-height: 100%;
      padding: var(--space-8);
    }

    .course-card__eyebrow {
      display: block;
    }

    .course-card__facts {
      flex-direction: row;
      flex-wrap: wrap;
      gap: var(--space-2) var(--space-6);
    }

    .course-card__actions {
      flex-direction: row;
      flex-wrap: wrap;
      align-items: center;
      gap: var(--space-3) var(--space-5);
      margin-top: auto;
      padding-top: var(--space-8);
    }

    .course-card__actions .btn--block {
      width: auto;
      padding-inline: var(--space-8);
    }

    .course-card__hint {
      max-width: 300px;
      text-align: left;
    }
  }

  /* "Later today" / "Earlier today": rows with time tiles, inside a card. */
  .day-list,
  .recent-list {
    list-style: none;
    margin: 0;
    padding: 0;
    overflow: hidden;
    border: 1px solid var(--attend-border);
    border-radius: var(--r-lg);
    background: var(--attend-surface);
    box-shadow: var(--attend-shadow-card);
  }

  .day-row {
    position: relative;
    display: grid;
    grid-template-columns: 48px minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-3);
    min-height: 64px;
    padding: var(--space-3) var(--space-4);
    border-bottom: 0;
    font-size: var(--text-small);
  }

  .day-row:first-child {
    padding-top: var(--space-3);
  }

  /* Dividers inset past the time tile. */
  .day-row + .day-row::before,
  .recent-row + .recent-row::before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    left: 76px;
    border-top: 1px solid var(--attend-border);
  }

  .recent-row + .recent-row::before {
    left: var(--space-4);
  }

  .day-row__time {
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 48px;
    block-size: 44px;
    border-radius: var(--r-sm);
    background: var(--attend-brand-tint);
    color: var(--attend-brand-text);
    font-size: var(--text-small);
    font-weight: var(--weight-num-m);
  }

  .day-list--past .day-row__time {
    background: var(--attend-ground);
    color: var(--attend-text);
  }

  .day-row__title,
  .recent-row__title {
    color: var(--attend-text-strong);
    font-size: var(--text-body);
    font-weight: var(--weight-strong);
    line-height: var(--leading-body);
    overflow-wrap: anywhere;
  }

  .day-row__meta,
  .recent-row__meta {
    margin-top: var(--space-05);
    color: var(--attend-text-muted);
    font-size: var(--text-small);
    line-height: var(--leading-small);
  }

  .day-none {
    padding: var(--space-4) var(--space-5);
    border: 1px solid var(--attend-border);
    border-radius: var(--r-lg);
    background: var(--attend-surface);
    color: var(--attend-text-muted);
    font-size: var(--text-small);
  }

  /* Recent attendance: course and date, its status chip at the end. */
  .student-recent {
    margin-top: var(--space-8);
  }

  /* Wraps under enlarged text (200%) rather than pushing the link off screen. */
  .student-recent__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-2);
  }

  .student-recent__head .section-label {
    margin: 0;
  }

  .day-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-05);
    min-height: var(--touch);
    color: var(--attend-brand-text);
    font-size: var(--text-small);
    font-weight: var(--weight-strong);
    text-decoration: none;
  }

  .day-link:hover,
  .day-link:focus-visible {
    color: var(--attend-link-hover);
    text-decoration: underline;
    text-underline-offset: 3px;
  }

  .recent-row {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "title status"
      "meta status";
    align-items: center;
    column-gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
  }

  .recent-row__title {
    grid-area: title;
  }

  .recent-row__meta {
    grid-area: meta;
  }

  .recent-row__status {
    grid-area: status;
  }

  @media (min-width: 1024px) {
    .recent-row {
      grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) auto;
      grid-template-areas: "title meta status";
      min-height: 52px;
      padding-block: var(--space-2);
    }

    .recent-row__meta {
      margin-top: 0;
    }
  }

  /* The attendance page: the lecture list as one card. */
  .student-history {
    padding: 0 var(--space-4);
    border: 1px solid var(--attend-border);
    border-radius: var(--r-lg);
    background: var(--attend-surface);
    box-shadow: var(--attend-shadow-card);
  }

  .student-history > .row:last-child {
    border-bottom: 0;
  }

  /* --------------------------------------------------------- Scanner */
  /* The viewfinder is ink in both themes (the sidebar's colours, whose
     text pairs are checked in tests/test_contrast.py). */
  .scanner--indigo .scanner__viewport {
    border: 0;
    border-radius: var(--r-xl);
    background: var(--attend-sidebar);
  }

  .scanner--indigo .scanner__frame {
    inset: auto;
    top: 50%;
    left: 50%;
    inline-size: min(240px, 68%);
    aspect-ratio: 1;
    border: 0;
    border-radius: 0;
    transform: translate(-50%, -50%);
  }

  .scanner__corner {
    position: absolute;
    inline-size: 44px;
    block-size: 44px;
    border: 0 solid var(--attend-sidebar-strong);
  }

  .scanner__corner--tl {
    top: 0;
    left: 0;
    border-top-width: 6px;
    border-left-width: 6px;
    border-top-left-radius: var(--r-md);
  }

  .scanner__corner--tr {
    top: 0;
    right: 0;
    border-top-width: 6px;
    border-right-width: 6px;
    border-top-right-radius: var(--r-md);
  }

  .scanner__corner--br {
    right: 0;
    bottom: 0;
    border-right-width: 6px;
    border-bottom-width: 6px;
    border-bottom-right-radius: var(--r-md);
  }

  .scanner__corner--bl {
    bottom: 0;
    left: 0;
    border-bottom-width: 6px;
    border-left-width: 6px;
    border-bottom-left-radius: var(--r-md);
  }

  .scanner__sweep {
    position: absolute;
    top: 50%;
    right: var(--space-3);
    left: var(--space-3);
    block-size: 2px;
    border-radius: var(--r-pill);
    background: var(--attend-sidebar-accent);
  }

  /* The guidance line, repeated over the camera (presentation.js). */
  .scanner__chip {
    position: absolute;
    right: var(--space-4);
    bottom: var(--space-6);
    left: var(--space-4);
    width: fit-content;
    max-width: calc(100% - var(--space-8));
    margin-inline: auto;
    padding: var(--space-2) var(--space-4);
    border-radius: var(--r-pill);
    background: var(--attend-sidebar-active);
    color: var(--attend-sidebar-strong);
    font-size: var(--text-small);
    font-weight: var(--weight-bold);
    line-height: var(--leading-small);
    text-align: center;
  }

  /* While the chip says it over the camera, the line under the camera is
     hidden from sight only: screen readers still read it (the chip is
     aria-hidden). */
  .scanner--indigo:has([data-camera]:not([hidden]) .scanner__chip:not([hidden]))
    .scanner__guidance {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .scanner__stop {
    min-height: 48px;
  }

  /* Stop sits after the progress card (the board's order) and only while the
     camera runs. */
  .scanner:has([data-camera][hidden]) .scanner__stop {
    display: none;
  }

  /* Progress card: "k of N codes confirmed", the step dots, bar and window. */
  .scanner--indigo .verified-progress {
    gap: var(--space-3);
    padding: var(--space-5);
    border: 1px solid var(--attend-border);
    border-radius: var(--r-lg);
    background: var(--attend-surface);
    box-shadow: var(--attend-shadow-card);
  }

  .scanner--indigo .verified-progress[hidden] {
    display: none;
  }

  .verified-progress__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
  }

  .scanner--indigo .verified-progress__text {
    font-weight: var(--weight-strong);
  }

  .steps {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
  }

  .steps__dot {
    position: relative;
    inline-size: 14px;
    block-size: 14px;
    border: 2px solid var(--attend-border-strong);
    border-radius: 50%;
  }

  .steps__dot--done {
    border-color: var(--attend-accent);
    background: var(--attend-accent);
  }

  /* A small check inside a done dot. */
  .steps__dot--done::after {
    content: "";
    position: absolute;
    top: 1px;
    left: 3px;
    inline-size: 3px;
    block-size: 6px;
    border: solid var(--attend-surface);
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
  }

  .steps__dot--current {
    border-color: var(--attend-accent);
    outline: 4px solid var(--attend-brand-tint);
  }

  .scanner--indigo .verified-progress__bar {
    block-size: 8px;
    border: 0;
    border-radius: var(--r-pill);
    background: var(--attend-brand-tint);
  }

  /* One rule per engine: a selector list with an unknown pseudo-element is dropped. */
  .scanner--indigo .verified-progress__bar::-webkit-progress-bar {
    border-radius: var(--r-pill);
  }

  .scanner--indigo .verified-progress__bar::-webkit-progress-value {
    border-radius: var(--r-pill);
  }

  .scanner--indigo .verified-progress__bar::-moz-progress-bar {
    border-radius: var(--r-pill);
  }

  .scanner__window {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2) var(--space-3);
    margin-top: var(--space-1);
    padding-top: var(--space-4);
    border-top: 1px solid var(--attend-border);
  }

  .scanner__window-label {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--attend-text-muted);
    font-size: var(--text-small);
  }

  .scanner__closes {
    color: var(--attend-text-strong);
    font-size: var(--text-num-m);
    font-weight: var(--weight-num-m);
    line-height: var(--leading-num-m);
  }

  .scanner__countdown {
    display: inline-block;
    min-width: 4ch;
    text-align: right;
  }

  /* --------------------------------------------------------- Receipt */
  .scanner--indigo .receipt {
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-6) var(--space-5);
    border: 1px solid var(--attend-border);
    border-radius: var(--r-xl);
    background: var(--attend-surface);
    box-shadow: var(--attend-shadow-card);
    text-align: center;
  }

  .scanner--indigo .receipt[hidden] {
    display: none;
  }

  .receipt__burst {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 100%;
    block-size: 168px;
  }

  .receipt__disc {
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: 120px;
    block-size: 120px;
    border-radius: 50%;
    background: var(--attend-positive-solid);
    color: var(--attend-on-brand);
  }

  .receipt__disc .icon {
    inline-size: 56px;
    block-size: 56px;
    stroke-width: 3.5;
  }

  /* Confetti: circles, short pills and rounded squares, settled around the disc. */
  .receipt__bit {
    --bit-x: 0px;
    --bit-y: 0px;
    --bit-r: 0deg;
    position: absolute;
    top: 50%;
    left: 50%;
    inline-size: 8px;
    block-size: 8px;
    border-radius: 50%;
    background: var(--attend-brand);
    transform: translate(-50%, -50%) translate(var(--bit-x), var(--bit-y)) rotate(var(--bit-r));
  }

  .receipt__bit:nth-child(3n) {
    inline-size: 4px;
    block-size: 14px;
    border-radius: var(--r-pill);
  }

  .receipt__bit:nth-child(3n + 1) {
    inline-size: 12px;
    block-size: 12px;
    border-radius: var(--r-xs);
  }

  .receipt__bit:nth-child(4n + 1) {
    background: var(--attend-brand-tint);
  }

  .receipt__bit:nth-child(4n + 2) {
    background: var(--attend-positive-bg);
  }

  .receipt__bit:nth-child(4n + 3) {
    border: 1.5px solid var(--attend-brand-text);
    background: transparent;
  }

  .receipt__bit:nth-child(2) { --bit-x: -96px; --bit-y: -52px; --bit-r: 20deg; }
  .receipt__bit:nth-child(3) { --bit-x: -78px; --bit-y: 18px; --bit-r: -30deg; }
  .receipt__bit:nth-child(4) { --bit-x: -110px; --bit-y: 4px; --bit-r: 35deg; }
  .receipt__bit:nth-child(5) { --bit-x: -64px; --bit-y: -74px; --bit-r: 0deg; }
  .receipt__bit:nth-child(6) { --bit-x: -86px; --bit-y: 60px; --bit-r: 25deg; }
  .receipt__bit:nth-child(7) { --bit-x: -30px; --bit-y: -82px; --bit-r: 45deg; }
  .receipt__bit:nth-child(8) { --bit-x: 34px; --bit-y: -80px; --bit-r: -20deg; }
  .receipt__bit:nth-child(9) { --bit-x: 70px; --bit-y: -66px; --bit-r: 30deg; }
  .receipt__bit:nth-child(10) { --bit-x: 100px; --bit-y: -30px; --bit-r: 0deg; }
  .receipt__bit:nth-child(11) { --bit-x: 112px; --bit-y: 12px; --bit-r: -40deg; }
  .receipt__bit:nth-child(12) { --bit-x: 82px; --bit-y: 50px; --bit-r: 20deg; }
  .receipt__bit:nth-child(13) { --bit-x: 58px; --bit-y: 74px; --bit-r: 45deg; }
  .receipt__bit:nth-child(14) { --bit-x: -50px; --bit-y: 76px; --bit-r: -25deg; }
  .receipt__bit:nth-child(15) { --bit-x: 0px; --bit-y: 80px; --bit-r: 30deg; }

  .scanner--indigo .receipt__title {
    justify-content: center;
    margin-top: var(--space-2);
    color: var(--attend-text-strong);
    font-family: var(--font-display);
    font-optical-sizing: auto;
    font-size: var(--text-h1);
    font-weight: var(--weight-display);
    letter-spacing: var(--tracking-h1);
    line-height: var(--leading-h1);
  }

  .receipt__lead {
    color: var(--attend-text-strong);
    font-weight: var(--weight-strong);
    overflow-wrap: anywhere;
  }

  .receipt__meta,
  .receipt__note {
    color: var(--attend-text-muted);
    font-size: var(--text-small);
    line-height: var(--leading-small);
  }

  .receipt__ref {
    display: inline-flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-1) var(--space-2);
    max-width: 100%;
    margin-block: var(--space-3) var(--space-1);
    padding: var(--space-2) var(--space-4);
    border: 1.5px dashed var(--attend-border-strong);
    border-radius: var(--r-pill);
    color: var(--attend-text);
    font-size: var(--text-small);
  }

  .receipt__ref-id {
    color: var(--attend-text-strong);
    font-weight: var(--weight-num-m);
    overflow-wrap: anywhere;
    user-select: all;
  }

  .receipt__actions {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    inline-size: 100%;
    margin-top: var(--space-4);
  }

  .receipt__details {
    display: inline-flex;
    align-items: center;
    min-height: var(--touch);
    color: var(--attend-brand-text);
    font-weight: var(--weight-strong);
  }

  @media (min-width: 768px) {
    .scanner--indigo .receipt {
      padding: var(--space-8);
    }

    .receipt__actions .btn--block {
      width: auto;
      min-width: 240px;
    }
  }

  /* ---------------------------------------------------------- Motion
     Only when the device allows it; otherwise everything above is the
     settled, static picture (the confetti stays where it landed). */
  @media (prefers-reduced-motion: no-preference) {
    .course-card__live::before,
    .steps__dot--current {
      animation: attend-student-pulse 1.6s ease-in-out infinite alternate;
    }

    .scanner__sweep {
      animation: attend-student-sweep 2s ease-in-out infinite alternate;
    }

    .receipt:not([hidden]) .receipt__disc {
      animation: attend-student-pop 420ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
    }

    .receipt:not([hidden]) .receipt__bit {
      animation: attend-student-burst 900ms cubic-bezier(0.22, 1, 0.36, 1) both;
    }
  }

  @keyframes attend-student-pulse {
    to {
      opacity: 0.35;
    }
  }

  @keyframes attend-student-sweep {
    from {
      top: 12%;
    }

    to {
      top: 88%;
    }
  }

  @keyframes attend-student-pop {
    0% {
      opacity: 0;
      transform: scale(0.6);
    }

    60% {
      opacity: 1;
      transform: scale(1.08);
    }

    100% {
      transform: scale(1);
    }
  }

  @keyframes attend-student-burst {
    from {
      opacity: 0;
      transform: translate(-50%, -50%) scale(0.4);
    }
  }
}
