/*
 * attend. -- the lecturer's screens: the Today panel, the live session (round
 * strip, live card, roster) and the presenter (docs/design/visual-design.md,
 * boards A-lecturer-desktop, A-lecturer-phone, A3-lecturer-desktop, A-presenter).
 *
 * Linked after app.css and components.css (templates/base.html), so these rules
 * win over the shared components at equal specificity. Same rules as app.css
 * (tests/test_css_rules.py): colours only as var(--attend-*) tokens, no
 * gradients, blur or filters, shadows only as the light theme's elevation
 * tokens (each is `none` in the dark themes).
 */
@layer components {
  /* --- The lecture's meta line ("CE-301 · Lecture | Groups | Room | 08:30–10:00") */

  /* A thin rule before every segment; the line is pulled left by one rule and
     its gap and clipped there, so a wrapped line never starts with a rule. */
  .lecture-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1) var(--space-3);
    margin-top: var(--space-3);
    margin-left: calc(-1 * var(--space-3) - 1px);
    clip-path: inset(0 0 0 calc(var(--space-3) + 1px));
    color: var(--attend-text);
    font-size: var(--text-small);
    line-height: var(--leading-small);
  }

  .lecture-meta span {
    padding-left: var(--space-3);
    border-left: 1px solid var(--attend-border);
  }

  /* --- Live page header: breadcrumbs, the course in display type, the meta line */

  .live-header h1 {
    margin-top: var(--space-2);
    font-size: var(--text-display);
    line-height: var(--leading-display);
    font-weight: var(--weight-display);
    letter-spacing: var(--tracking-display);
    overflow-wrap: anywhere;
  }

  .page-header:has(.live-header) {
    align-items: flex-start;
  }

  .live-present:empty {
    display: none;
  }

  /* --- Today: CurrentLecturePanel */

  .lecture-panel {
    display: flex;
    flex-direction: column;
  }

  .lecture-panel__eyebrow {
    margin-bottom: var(--space-1);
    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;
  }

  .lecture-panel__title {
    color: var(--attend-text-strong);
    font-family: var(--font-display);
    font-optical-sizing: auto;
    font-size: var(--text-h1);
    line-height: var(--leading-h1);
    font-weight: var(--weight-h1);
    letter-spacing: var(--tracking-h1);
    overflow-wrap: anywhere;
  }

  .lecture-panel__note {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    color: var(--attend-text-muted);
    font-size: var(--text-small);
  }

  .lecture-panel__note .icon {
    flex: none;
    margin-top: 2px;
  }

  /* --- Round strip: a brand-tint pill, "Round N · started … · N-minute window" */

  .round-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    min-height: 52px;
    margin: var(--space-6) 0 var(--space-4);
    padding: var(--space-2) var(--space-2) var(--space-2) var(--space-5);
    border: 0;
    border-radius: var(--r-lg);
    background: var(--attend-brand-tint);
    color: var(--attend-text);
    font-size: var(--text-small);
    line-height: var(--leading-small);
  }

  .lecture-panel__about + .round-strip {
    margin-top: var(--space-5);
  }

  .round-strip__icon {
    flex: none;
    inline-size: 18px;
    block-size: 18px;
    color: var(--attend-brand-text);
  }

  .round-strip__label {
    color: var(--attend-text-strong);
    font-family: var(--font-body);
    font-size: var(--text-small);
    line-height: var(--leading-small);
    font-weight: var(--weight-label);
    letter-spacing: 0;
  }

  .round-strip__when {
    flex: 1 1 12rem;
    color: var(--attend-text);
    text-align: left;
  }

  /* New attendance round: a surface pill on the tint. */
  .round-strip .btn {
    padding-inline: var(--space-4);
    background: var(--attend-surface);
    color: var(--attend-brand-text);
    font-size: var(--text-small);
  }

  @media (min-width: 768px) {
    .round-strip {
      border-radius: var(--r-pill);
    }
  }

  /* Compact for a mouse only; on a touch screen the button keeps 44px+. */
  @media (min-width: 768px) and (pointer: fine) {
    .round-strip .btn {
      min-height: 40px;
    }
  }

  /* --- Live card: the count and its bar beside the round's actions */

  .round-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    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);
  }

  .lecture-panel__about + .round-card {
    margin-top: var(--space-4);
  }

  .round-card__main {
    display: grid;
    gap: var(--space-5);
  }

  .round-card__head {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    min-width: 0;
  }

  .round-card__state {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1) 0;
  }

  /* Countdowns keep their width, so the line never jitters. */
  .round-card__countdown {
    display: inline-block;
    min-inline-size: 4ch;
  }

  /* "41 / 57": the figure in display numerals, "/ 57" muted at the same size. */
  .round-panel__count {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
    margin-top: var(--space-4);
  }

  .round-card__tally {
    color: var(--attend-text-strong);
    font-size: var(--text-num-xl);
    line-height: var(--leading-num-xl);
    font-weight: var(--weight-num-xl);
    letter-spacing: var(--tracking-num-xl);
    font-variant-numeric: tabular-nums;
  }

  .round-card__tally small {
    color: var(--attend-text-muted);
    font-size: inherit;
    font-weight: var(--weight-h2);
    letter-spacing: inherit;
  }

  .round-card__caption {
    color: var(--attend-text);
    font-family: var(--font-body);
    font-size: var(--text-body);
    line-height: var(--leading-body);
  }

  /* Progress bars (the live card, the presenter's code lifetime): a pill track
     in brand tint, the fill in --attend-accent (brand in light, brand-text in
     dark, where brand on tint would be 2.96:1). Each engine's pseudo-element
     has its own rule: an unknown one would drop a whole selector list. */
  .round-progress,
  .presenter__progress {
    display: block;
    inline-size: 100%;
    block-size: 8px;
    border: 0;
    border-radius: var(--r-pill);
    background: var(--attend-brand-tint);
    color: var(--attend-accent);
    overflow: hidden;
    appearance: none;
  }

  .round-progress {
    max-inline-size: 440px;
    margin-top: var(--space-4);
  }

  .round-progress::-webkit-progress-bar,
  .presenter__progress::-webkit-progress-bar {
    border-radius: var(--r-pill);
    background: var(--attend-brand-tint);
  }

  .round-progress::-webkit-progress-value,
  .presenter__progress::-webkit-progress-value {
    border-radius: var(--r-pill);
    background: var(--attend-accent);
  }

  .round-progress::-moz-progress-bar,
  .presenter__progress::-moz-progress-bar {
    border-radius: var(--r-pill);
    background: var(--attend-accent);
  }

  /* Close check-in (the one primary) full width; Extend and Add manually share
     the row under it. */
  .round-card__actions {
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    gap: var(--space-2);
  }

  .round-card__actions > * {
    flex: 1 1 0;
  }

  .round-card__actions > .btn--primary,
  .round-card__actions > form {
    flex-basis: 100%;
  }

  .round-card__actions .btn {
    width: 100%;
  }

  .round-card__note {
    color: var(--attend-text-muted);
    font-size: var(--text-small);
    line-height: var(--leading-small);
  }

  /* The round's details and the quiet tools row, under a rule. */
  .round-card__foot {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding-top: var(--space-4);
    border-top: 1px solid var(--attend-border);
  }

  .round-card__details {
    gap: var(--space-1) var(--space-6);
    color: var(--attend-text-muted);
    font-size: var(--text-small);
  }

  .round-card__details dt {
    font-size: var(--text-small);
  }

  .round-card__more {
    gap: var(--space-1);
  }

  .round-card__more .btn {
    padding-inline: var(--space-3) var(--space-4);
    font-size: var(--text-small);
  }

  .round-card__more .btn .icon {
    color: var(--attend-text-muted);
  }

  @media (min-width: 768px) {
    .round-card {
      padding: var(--space-6) 28px;
    }

    .round-card__main {
      grid-template-columns: minmax(0, 1fr) minmax(200px, 240px);
      align-items: center;
      gap: var(--space-6) var(--space-10);
    }

    .round-card__actions > * {
      flex-basis: 100%;
    }

    .round-card__actions .btn--primary {
      min-height: 48px;
    }
  }

  @media (min-width: 768px) and (pointer: fine) {
    .round-card__actions .btn {
      min-height: 40px;
    }

    .round-card__actions .btn--primary {
      min-height: 48px;
    }

    .round-card__more .btn {
      min-height: 36px;
    }
  }

  /* --- Roster: a card with the count tabs, the pill search and compact rows */

  .roster-card {
    padding: var(--space-5) var(--space-4) var(--space-4);
    border: 1px solid var(--attend-border);
    border-radius: var(--r-lg);
    background: var(--attend-surface);
    box-shadow: var(--attend-shadow-card);
  }

  .roster-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3) var(--space-4);
    margin-bottom: var(--space-4);
  }

  .roster-tools__title {
    font-size: var(--text-h2);
    line-height: var(--leading-h2);
  }

  /* The tabs: the segmented track; the selected tab a surface pill. */
  .roster-tabs {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 2px;
    padding: 3px;
    border: 1px solid var(--attend-border);
    border-radius: var(--r-pill);
    background: var(--attend-ground);
  }

  .roster-tabs .btn--plain {
    gap: var(--space-2);
    min-height: var(--touch);
    padding: 0 var(--space-2) 0 var(--space-4);
    color: var(--attend-text-muted);
    font-size: var(--text-small);
    font-weight: var(--weight-bold);
  }

  .roster-tabs .btn--plain:hover {
    background: transparent;
    color: var(--attend-text-strong);
  }

  .roster-tabs .btn--plain[aria-current="true"] {
    background: var(--attend-surface);
    color: var(--attend-text-strong);
    font-weight: var(--weight-strong);
    box-shadow: var(--attend-shadow-card);
    /* A 3:1 edge in every theme (dark has no shadows); a border, so the focus
       ring (an outline) stays the 2px one. */
    border-color: var(--attend-border-strong);
  }

  .roster-search {
    flex: 1 1 280px;
    max-width: 420px;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    margin-bottom: 0;
  }

  .roster-search .field--search {
    flex: 1 1 220px;
    margin: 0;
  }

  .roster-search__submit {
    flex: none;
  }

  .roster-compare {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    margin: var(--space-3) 0;
    font-size: var(--text-small);
  }

  .roster-person {
    display: flex;
    align-items: center;
    gap: 10px;
  }

  .roster-student {
    display: block;
    color: var(--attend-text-strong);
    font-weight: var(--weight-bold);
  }

  .roster-student__id {
    color: var(--attend-text-muted);
    font-size: var(--text-small);
    font-variant-numeric: tabular-nums;
  }

  /* Needs review: a thin plum marker on the row's left edge and the chip's
     review icon -- never a tinted row (owner, 2026-10-31). */
  .roster-row--review > td:first-child {
    position: relative;
  }

  .roster-row--review > td:first-child::before {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    inline-size: 3px;
    background: var(--attend-warning-text);
  }

  .roster-actions {
    white-space: nowrap;
  }

  .roster-action {
    min-height: var(--touch);
    padding-inline: var(--space-3);
    font-size: var(--text-small);
  }

  @media (min-width: 768px) {
    .roster-card {
      padding: var(--space-5) var(--space-6) var(--space-6);
    }

    .roster-table td {
      block-size: 48px;
    }

    .roster-actions {
      text-align: right;
    }
  }

  /* Compact for a mouse only (tests/test_css_touch.py): count tabs 36px as
     the design's segmented control (§7), row actions 36px ghost buttons. */
  @media (min-width: 768px) and (pointer: fine) {
    .roster-tabs .btn--plain {
      min-height: 36px;
    }

    .roster-action {
      min-height: 36px;
    }
  }

  /* Phone: the rows are cards (table--cards); the marker runs along the card. */
  @media (max-width: 767px) {
    .roster-card {
      padding-inline: 0;
      padding-bottom: 0;
      overflow: hidden;
    }

    .roster-tools,
    .roster-card > .region > :not(.table-wrap) {
      padding-inline: var(--space-4);
    }

    .roster-tabs {
      flex: 1 1 100%;
    }

    .roster-tabs .btn--plain {
      flex: 1 1 0;
      padding-inline: var(--space-2);
    }

    .roster-search {
      max-width: none;
    }

    .roster-row--review {
      border-inline-start: 3px solid var(--attend-warning-text);
    }

    .roster-row--review > td:first-child::before {
      content: none;
    }

    .roster-person .initials {
      inline-size: 40px;
      block-size: 40px;
      font-size: var(--text-small);
    }

    .roster-actions {
      justify-content: flex-end;
    }

    /* A row with no action shows no empty "Actions" line. */
    .roster-actions:empty {
      display: none;
    }
  }

  /* --- Presenter (§11): the page follows the theme; the code's tile is always
     white with black modules (the canvas paints its own quiet zone). The tile
     takes most of the height beside the course, "Code k", its bar, the hint,
     the countdown and the checked-in count (below it on a narrow screen). */

  html:has(body.presenter-page) {
    background: var(--attend-ground);
    color-scheme: revert-layer;
  }

  .presenter-page {
    background: var(--attend-ground);
    color: var(--attend-text);
  }

  /* Stacked (a narrow, portrait or nearly square screen): the page is the
     window's height; the tile takes the room the words leave (a size
     container, so the square follows the smaller side), never under 240px.
     Content that still does not fit scrolls; nothing is clipped. */
  .presenter {
    position: relative;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    gap: var(--space-4);
    min-height: 100vh;
    min-height: 100dvh;
    padding: var(--space-3) var(--space-4);
    padding-bottom: max(var(--space-4), env(safe-area-inset-bottom));
    overflow-x: clip;
    background: var(--attend-ground);
    color: var(--attend-text);
  }

  .presenter__tools {
    position: relative;
    z-index: 1;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-2);
  }

  .presenter .btn {
    border-color: transparent;
    background: var(--attend-brand-tint);
    color: var(--attend-brand-text);
  }

  .presenter .btn--plain {
    background: transparent;
    color: var(--attend-text);
  }

  /* Full screen and the way back stay 44px targets at every width. */
  .presenter .presenter__btn {
    min-height: var(--touch);
  }

  .presenter__layout {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(240px, 1fr) auto;
    gap: var(--space-6) clamp(32px, 5vw, 80px);
    min-height: 0;
  }

  .presenter__frame {
    display: grid;
    place-items: center;
    min-height: 240px;
    container-type: size;
  }

  /* The white tile: rounded, with 16px of white padding so its corners never
     cut into the code (a 28px corner reaches 8.2px in). */
  .presenter__tile {
    box-sizing: border-box;
    inline-size: max(240px, min(100cqi, 100cqb));
    block-size: max(240px, min(100cqi, 100cqb));
    padding: var(--space-4);
    border-radius: var(--r-xl);
    background: var(--attend-projection-bg);
    box-shadow: var(--attend-shadow-raised);
  }

  .presenter__stage {
    display: grid;
    place-items: center;
    inline-size: 100%;
    block-size: 100%;
    overflow: hidden;
    background: var(--attend-projection-bg);
    color: var(--attend-projection-fg);
  }

  .presenter__code {
    display: block;
    image-rendering: pixelated;
  }

  .presenter__message {
    max-width: 36rem;
    padding: var(--space-6);
    color: var(--attend-projection-fg);
    font-size: var(--text-h2);
    line-height: var(--leading-h2);
    text-align: center;
  }

  .presenter__info {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-self: center;
    min-width: 0;
    max-width: 46rem;
  }

  .presenter__brand {
    font-size: 28px;
    line-height: 1;
  }

  .presenter__brand .wordmark {
    font-size: inherit;
  }

  .presenter__label {
    margin-top: clamp(16px, 2vw, 30px);
    color: var(--attend-text-strong);
    font-size: clamp(28px, 3.5vw, 56px);
    line-height: 1.1;
    font-weight: var(--weight-display);
    letter-spacing: var(--tracking-display);
    overflow-wrap: anywhere;
  }

  .presenter__sep {
    color: var(--attend-text-muted);
    font-weight: var(--weight-h2);
  }

  .presenter__code-number {
    margin-top: clamp(16px, 2.5vw, 40px);
    color: var(--attend-brand-text);
    font-family: var(--font-display);
    font-optical-sizing: auto;
    font-size: clamp(56px, 7.5vw, 120px);
    line-height: 0.92;
    font-weight: var(--weight-display);
    letter-spacing: var(--tracking-num-xl);
    font-variant-numeric: tabular-nums;
  }

  .presenter__progress {
    max-inline-size: 520px;
    block-size: 10px;
    margin-top: clamp(16px, 2vw, 30px);
  }

  .presenter__hint {
    margin-top: clamp(24px, 3.25vw, 52px);
    color: var(--attend-text);
    font-size: clamp(20px, 2.5vw, 40px);
    line-height: 1.2;
    font-weight: var(--weight-button);
  }

  .presenter__hint strong {
    color: var(--attend-text-strong);
    font-weight: var(--weight-h2);
  }

  .presenter__app {
    color: var(--attend-text-strong);
    font-family: var(--font-display);
    font-optical-sizing: auto;
    font-weight: var(--weight-display);
    letter-spacing: -0.03em;
  }

  .presenter__status {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3) 28px;
    margin-top: clamp(20px, 2.5vw, 40px);
  }

  .presenter__countdown {
    color: var(--attend-text-strong);
    font-size: clamp(22px, 2.25vw, 36px);
    line-height: 1.2;
    font-weight: var(--weight-h2);
    font-variant-numeric: tabular-nums;
  }

  .presenter__checked-in {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    color: var(--attend-text-muted);
    font-size: clamp(16px, 1.5vw, 24px);
    font-weight: var(--weight-bold);
    font-variant-numeric: tabular-nums;
  }

  .presenter__checked-in .icon {
    inline-size: 1em;
    block-size: 1em;
    color: var(--attend-positive-text);
  }

  .presenter__note {
    margin-top: var(--space-4);
    color: var(--attend-text-muted);
    font-size: var(--text-small);
  }

  /* A landscape screen (a projector): the tile left, the words beside it, and
     the one decorative shape, a brand-tint circle off the bottom-right corner,
     far from the tile. */
  @media (min-width: 900px) and (min-aspect-ratio: 1/1) {
    .presenter__layout {
      grid-template-columns: auto minmax(0, 40rem);
      grid-template-rows: none;
      align-content: center;
      align-items: center;
      justify-content: center;
    }

    .presenter__frame {
      display: block;
      min-height: 0;
      container-type: normal;
    }

    /* 560-640px on a 1600x900 projector (§11), centred with the words. */
    .presenter__tile {
      inline-size: min(40vw, calc(100dvh - 160px), 640px);
      block-size: min(40vw, calc(100dvh - 160px), 640px);
    }

    .presenter__info {
      justify-self: start;
    }

    .presenter::after {
      content: "";
      position: absolute;
      inset-inline-end: -84px;
      inset-block-end: -96px;
      inline-size: 240px;
      block-size: 240px;
      border-radius: 50%;
      background: var(--attend-brand-tint);
      opacity: 0.6;
      pointer-events: none;
    }
  }

  /* Full screen (ATTENDANCE_PROTOCOL §8): the navigation link and the notes go;
     the expanded fallback (no or refused Fullscreen API) fills the window.
     Separate rules per selector: an unknown prefixed pseudo-class would drop a
     whole selector list. */
  .presenter[data-expanded="true"] {
    position: fixed;
    inset: 0;
    z-index: 10;
    overflow-y: auto;
  }

  .presenter[data-expanded="true"] .presenter__back,
  .presenter[data-expanded="true"] .presenter__note {
    display: none;
  }

  :root:fullscreen .presenter__back,
  :root:fullscreen .presenter__note {
    display: none;
  }

  :root:-webkit-full-screen .presenter__back,
  :root:-webkit-full-screen .presenter__note {
    display: none;
  }
}
