/* ============================================================
   AGENDA.CSS — the notification flag, its panel, and the forms
   ------------------------------------------------------------
   The flag hangs from the top edge of the page like a bookmark: a ribbon with
   a notch cut out of its bottom. Resting it is short and shows only its icon
   and a count. Hovering drops it lower and brings in a chevron, so the thing
   that says "pull me down" only appears once the pointer is on it and the
   affordance is actually available.
   ============================================================ */

.ag-root {
  position: fixed;
  top: 0;
  right: 26px;
  z-index: 940;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

/* The attempt screens are their own world — no app chrome over an editor. */
body.route-focused .ag-root { display: none; }

/* -- The flag ---------------------------------------------- */

/* The wrapper exists only to carry the shadow. clip-path clips a box-shadow
   away along with everything else outside the shape -- checked side by side:
   this exact notched ribbon with `box-shadow: 0 6px 18px` paints no shadow at
   all, while the same shape inside a wrapper with drop-shadow paints one that
   follows the notch. So the flag had been flat since it was written.

   Three layers rather than one: a tight contact shadow that pins it to the
   page, a mid one for the body, and a wide soft one for ambient depth. A
   single large blur on its own reads as a smudge under the shape. */
.ag-flag-wrap {
  filter:
    drop-shadow(0 1px 1px rgba(0, 0, 0, 0.32))
    drop-shadow(0 4px 7px rgba(0, 0, 0, 0.30))
    drop-shadow(0 12px 20px rgba(0, 0, 0, 0.26));
  transition: filter 0.24s ease;
}
.ag-flag-wrap:hover,
.ag-root.is-open .ag-flag-wrap {
  filter:
    drop-shadow(0 2px 2px rgba(0, 0, 0, 0.36))
    drop-shadow(0 8px 14px rgba(0, 0, 0, 0.34))
    drop-shadow(0 20px 32px rgba(0, 0, 0, 0.32));
}

.ag-flag {
  position: relative;
  /* flex-start, explicitly: a button centres its content vertically whatever
     its display is, which put the icon at 15.5px in a flag whose notch starts
     at 31px -- the glyph sat in the cut. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  width: 46px;
  height: 42px;
  padding: 7px 0 0;
  border: none;
  cursor: pointer;
  color: var(--text-on-dark);
  /* A sheen over the body colour rather than a flat ramp: the top edge catches
     light, the bottom falls away into the notch. */
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.20) 0%, rgba(255, 255, 255, 0) 58%),
    linear-gradient(180deg, var(--color-primary) 0%, var(--color-primary-dark) 100%);
  /* The notch. Cut from the bottom edge, which is what makes it read as a
     bookmark rather than a tab. */
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% calc(100% - 11px), 0 100%);
  /* Inset only. An outer shadow here would be clipped away with the corners --
     that is what the wrapper is for. These are the lit top edge, the two side
     bevels, and a wash that stops the notch reading as flat paper. */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.32),
    inset 1px 0 0 rgba(255, 255, 255, 0.10),
    inset -1px 0 0 rgba(0, 0, 0, 0.18),
    inset 0 -18px 20px -14px rgba(0, 0, 0, 0.42);
  transition: height 0.26s cubic-bezier(0.34, 1.4, 0.64, 1),
              filter 0.2s ease;
}

/* Driven from the wrapper so the drop and the shadow move together. The button
   is clipped, so its notch triangle is not hit-testable; the wrapper is not,
   and hovering there would otherwise deepen the shadow under a flag that had
   not dropped. */
.ag-flag-wrap:hover .ag-flag,
.ag-flag:focus-visible,
.ag-root.is-open .ag-flag {
  height: 70px;
  filter: brightness(1.06);
}

.ag-flag:focus-visible {
  outline: 2px solid var(--color-accent-hover);
  outline-offset: 3px;
}

/* Red once something is actually late - the count alone does not say which. */
.ag-flag.has-overdue {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.20) 0%, rgba(255, 255, 255, 0) 58%),
    linear-gradient(180deg, var(--color-danger) 0%, var(--color-danger-hover) 100%);
}

.ag-flag-icon {
  display: block;
  margin: 0 auto;
  width: 18px;
  height: 18px;
}

/* At rest the flag says THAT something is waiting, not how many. The count used
   to sit in the resting stack, where the notch cut through it: 7.4px of an
   11px digit was drawn inside the V, so what showed was a sliced glyph that
   read as a rendering fault rather than a number. A dot cannot be half-cut. */
.ag-flag-dot {
  position: absolute;
  top: 8px;
  right: 10px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  /* Blue on every flag colour it can sit on: danger red when something is
     late, and whatever --color-primary is in the current theme (indigo,
     purple or green). A lighter blue than any of them, kept off the body by
     the dark ring, with a faint glow so it reads as live rather than as a
     speck of dust. */
  background: #38bdf8;
  box-shadow:
    0 0 0 2px rgba(0, 0, 0, 0.28),
    0 0 6px rgba(56, 189, 248, 0.75);
  opacity: 0;
  transform: scale(0.5);
  transition: opacity 0.18s ease, transform 0.22s cubic-bezier(0.34, 1.4, 0.64, 1);
}
.ag-flag.has-items .ag-flag-dot { opacity: 1; transform: scale(1); }

/* All three are absolutely placed so that appearing costs no layout: the icon
   stays exactly where it is and the flag grows downward past it. */
.ag-flag-count {
  position: absolute;
  left: 0;
  right: 0;
  top: 29px;
  text-align: center;
  font-size: 0.68rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.02em;
  font-family: var(--font-sans);
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.16s ease, transform 0.22s cubic-bezier(0.34, 1.4, 0.64, 1);
}
.ag-flag-count[hidden] { display: none; }

.ag-flag-pull {
  position: absolute;
  left: 50%;
  top: 44px;
  margin-left: -7px;
  width: 14px;
  height: 14px;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.18s ease, transform 0.24s cubic-bezier(0.34, 1.4, 0.64, 1);
}

/* The number replaces the dot once there is room to read it, and the chevron
   that says "pull me down" only turns up once the flag is already down. */
.ag-flag-wrap:hover .ag-flag-dot,
.ag-flag:focus-visible .ag-flag-dot,
.ag-root.is-open .ag-flag-dot { opacity: 0; transform: scale(0.5); }

.ag-flag-wrap:hover .ag-flag-count,
.ag-flag:focus-visible .ag-flag-count,
.ag-root.is-open .ag-flag-count { opacity: 1; transform: translateY(0); }

.ag-flag-wrap:hover .ag-flag-pull,
.ag-flag:focus-visible .ag-flag-pull,
.ag-root.is-open .ag-flag-pull { opacity: 0.95; transform: translateY(0); }

.ag-root.is-open .ag-flag-pull { transform: translateY(0) rotate(180deg); }

@media (prefers-reduced-motion: reduce) {
  .ag-flag,
  .ag-flag-wrap,
  .ag-flag-dot,
  .ag-flag-count,
  .ag-flag-pull { transition: none; }
}

/* ── The panel ────────────────────────────────────────────── */

.ag-panel {
  width: min(390px, calc(100vw - 40px));
  margin-top: 8px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 90px);
  animation: agDrop 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}

.ag-panel[hidden] { display: none; }

@keyframes agDrop {
  from { opacity: 0; transform: translateY(-10px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .ag-panel { animation: none; }
  .ag-flag, .ag-flag-pull { transition: none; }
}

.ag-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 0.9rem;
  border-bottom: 1px solid var(--border-color);
  background: var(--bg-surface);
}

.ag-head-title {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--text-primary);
}

.ag-head-title i, .ag-head-title svg {
  width: 17px;
  height: 17px;
  color: var(--color-primary);
}

.ag-head-sub {
  margin-left: auto;
  font-size: 0.72rem;
  color: var(--text-tertiary);
  font-weight: 600;
}

.ag-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  flex-shrink: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-tertiary);
  cursor: pointer;
  transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

.ag-icon-btn i, .ag-icon-btn svg { width: 15px; height: 15px; }

.ag-icon-btn:hover {
  color: var(--text-primary);
  background: var(--bg-surface-hover);
  border-color: var(--border-color);
}

/* ── Quick actions ────────────────────────────────────────── */

.ag-quick {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.55rem 0.7rem;
  border-bottom: 1px solid var(--border-color);
}

.ag-quick-spacer { flex: 1; }

.ag-quick-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 0.4rem 0.45rem;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  font-family: var(--font-sans);
  transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

.ag-quick-btn i, .ag-quick-btn svg { width: 16px; height: 16px; }

.ag-quick-btn:hover {
  color: var(--color-primary);
  background: var(--color-primary-subtle);
  border-color: var(--border-color);
}

.ag-quick-stat {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 0.2rem 0.42rem;
  border-radius: var(--radius-full);
  background: var(--bg-surface-hover);
  color: var(--text-tertiary);
  font-size: 0.7rem;
  font-weight: 800;
}

.ag-quick-stat i, .ag-quick-stat svg { width: 12px; height: 12px; }
.ag-quick-stat.is-bad { background: var(--color-danger-bg); color: var(--color-danger); }
.ag-quick-stat.is-warn { background: var(--color-warning-bg); color: var(--color-warning); }

/* ── Calendar ─────────────────────────────────────────────── */

.ag-cal { padding: 0.6rem 0.7rem 0.7rem; border-bottom: 1px solid var(--border-color); }

.ag-cal-head {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  margin-bottom: 0.45rem;
}

.ag-cal-month {
  font-weight: 700;
  font-size: 0.82rem;
  color: var(--text-primary);
  min-width: 118px;
  text-align: center;
}

.ag-today-btn {
  margin-left: auto;
  padding: 0.22rem 0.55rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--text-secondary);
  font-size: 0.68rem;
  font-weight: 700;
  cursor: pointer;
  font-family: var(--font-sans);
  transition: color 0.15s ease, border-color 0.15s ease;
}

.ag-today-btn:hover { color: var(--color-primary); border-color: var(--color-primary); }

.ag-cal-dow, .ag-cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}

.ag-cal-dow span {
  text-align: center;
  font-size: 0.62rem;
  font-weight: 800;
  color: var(--text-tertiary);
  padding-bottom: 3px;
}

.ag-cell {
  position: relative;
  height: 34px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  font-family: var(--font-sans);
  transition: background 0.14s ease, color 0.14s ease, border-color 0.14s ease;
}

.ag-cell.is-blank { cursor: default; pointer-events: none; }
.ag-cell:hover { background: var(--bg-surface-hover); color: var(--text-primary); }

.ag-cell-num { font-size: 0.72rem; font-weight: 600; line-height: 1; }
.ag-cell.has-items .ag-cell-num { font-weight: 800; color: var(--text-primary); }

.ag-cell.is-today {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.ag-cell.is-selected {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--text-on-primary);
}

.ag-cell.is-selected .ag-cell-num { color: var(--text-on-primary); }

/* Dots sit in their own fixed-height strip so a day with items and a day
   without are exactly the same size and the grid never jitters. */
.ag-cell-dots {
  display: flex;
  gap: 2px;
  height: 4px;
  align-items: center;
}

.ag-dot { width: 4px; height: 4px; border-radius: 50%; background: var(--text-tertiary); }
.ag-dot-deadline { background: var(--color-warning); }
.ag-dot-event    { background: var(--color-primary); }
.ag-dot-exam     { background: #a855f7; }
.ag-dot-reminder { background: var(--color-accent); }
.ag-dot-review   { background: var(--color-success); }
.ag-dot-overdue  { background: var(--color-danger); }
.ag-cell.is-selected .ag-dot { background: var(--text-on-primary); }

/* ── The list ─────────────────────────────────────────────── */

.ag-list-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 0.85rem 0.35rem;
}

.ag-list-title {
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.ag-link-btn {
  border: none;
  background: transparent;
  color: var(--color-primary);
  font-size: 0.7rem;
  font-weight: 700;
  cursor: pointer;
  padding: 0;
  font-family: var(--font-sans);
}

.ag-link-btn:hover { text-decoration: underline; }

.ag-list-count {
  margin-left: auto;
  font-size: 0.68rem;
  font-weight: 800;
  color: var(--text-tertiary);
  background: var(--bg-surface-hover);
  border-radius: var(--radius-full);
  padding: 0.1rem 0.4rem;
}

.ag-list {
  flex: 1;
  overflow-y: auto;
  padding: 0 0.55rem 0.4rem;
  min-height: 0;
}

.ag-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.3rem;
  border-radius: var(--radius-sm);
  transition: background 0.14s ease;
}

.ag-row:hover { background: var(--bg-surface-hover); }

.ag-row-kind {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: var(--radius-sm);
  background: var(--bg-surface-hover);
  color: var(--text-tertiary);
}

.ag-row-kind i, .ag-row-kind svg { width: 14px; height: 14px; }

.ag-k-deadline { background: var(--color-warning-bg); color: var(--color-warning); }
.ag-k-event    { background: var(--color-primary-subtle); color: var(--color-primary); }
.ag-k-exam     { background: rgba(168, 85, 247, 0.14); color: #a855f7; }
.ag-k-reminder { background: rgba(6, 182, 212, 0.14); color: var(--color-accent); }
.ag-k-review   { background: var(--color-success-bg); color: var(--color-success); }

.ag-row.is-overdue .ag-row-kind { background: var(--color-danger-bg); color: var(--color-danger); }

.ag-row-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  text-align: left;
  border: none;
  background: transparent;
  padding: 0;
  cursor: pointer;
  font-family: var(--font-sans);
}

.ag-row-title {
  font-size: 0.8rem;
  font-weight: 650;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ag-row-main:hover .ag-row-title { color: var(--color-primary); }

.ag-row-when {
  font-size: 0.68rem;
  color: var(--text-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ag-row-left {
  flex-shrink: 0;
  font-size: 0.66rem;
  font-weight: 800;
  color: var(--text-secondary);
  background: var(--bg-surface-hover);
  border-radius: var(--radius-full);
  padding: 0.14rem 0.45rem;
  white-space: nowrap;
}

.ag-row-left.is-overdue { background: var(--color-danger-bg); color: var(--color-danger); }

/* Revealed on hover: a delete on every row all the time is a row of hazards. */
.ag-row-del { opacity: 0; }
.ag-row:hover .ag-row-del, .ag-row-del:focus-visible { opacity: 1; }
.ag-row-del:hover { color: var(--color-danger); }

.ag-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 1.6rem 1rem;
  text-align: center;
  color: var(--text-tertiary);
  font-size: 0.78rem;
}

.ag-empty i, .ag-empty svg { width: 26px; height: 26px; opacity: 0.5; }

.ag-foot {
  padding: 0.55rem 0.7rem 0.7rem;
  border-top: 1px solid var(--border-color);
}

.ag-foot .btn { width: 100%; justify-content: center; }

/* ── Forms ────────────────────────────────────────────────── */

/* .modal-content caps every dialog at 420px, so both dimensions are lifted —
   setting width alone leaves the cap in charge. */
.ag-modal-content {
  width: min(440px, 92vw);
  max-width: min(440px, 92vw);
  text-align: left;
}

.ag-modal-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.9rem;
}

.ag-modal-title {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0;
  font-size: 1.05rem;
}

.ag-modal-title i, .ag-modal-title svg {
  width: 18px;
  height: 18px;
  color: var(--color-primary);
}

.ag-modal-head .ag-icon-btn { margin-left: auto; }

.ag-form { display: flex; flex-direction: column; gap: 0.75rem; }

.ag-form-lead {
  margin: 0;
  padding: 0.5rem 0.65rem;
  border-radius: var(--radius-sm);
  background: var(--bg-surface-hover);
  border-left: 3px solid var(--color-primary);
  font-size: 0.82rem;
  font-weight: 650;
  color: var(--text-primary);
}

.ag-form-row { display: flex; flex-direction: column; gap: 0.3rem; }
.ag-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }

.ag-form-row .form-label { margin: 0; }

.ag-optional {
  font-weight: 600;
  font-size: 0.68rem;
  color: var(--text-tertiary);
  text-transform: none;
  letter-spacing: 0;
}

.ag-form-hint { font-size: 0.7rem; color: var(--text-tertiary); }

.ag-quickdates { display: flex; flex-wrap: wrap; gap: 0.35rem; }

.ag-chip {
  padding: 0.25rem 0.6rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--text-secondary);
  font-size: 0.72rem;
  font-weight: 650;
  cursor: pointer;
  font-family: var(--font-sans);
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.ag-chip:hover {
  color: var(--color-primary);
  border-color: var(--color-primary);
  background: var(--color-primary-subtle);
}

.ag-modal-actions { margin-top: 1.1rem; }
.ag-danger-btn { margin-right: auto; color: var(--color-danger); }
.ag-danger-btn:hover { background: var(--color-danger-bg); }

/* The browser's own date/time pickers are near-invisible on a dark surface. */
[data-theme="dark"] .ag-form input[type="date"]::-webkit-calendar-picker-indicator,
[data-theme="dark"] .ag-form input[type="time"]::-webkit-calendar-picker-indicator {
  filter: invert(1) brightness(1.6);
  cursor: pointer;
}

/* ── The due date on an item's own page ───────────────────── */

/* Plain text in the corner, no pill: it sits beside a large title and a badge
   there would fight it. Only the countdown is coloured, because that is the
   part that means something. */
.ag-deadline-text {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-tertiary);
  white-space: nowrap;
  cursor: default;
}

.ag-deadline-text em {
  font-style: normal;
  font-weight: 800;
  color: var(--color-warning);
}

.ag-deadline-text.is-overdue em { color: var(--color-danger); }

/* ── Narrow screens ───────────────────────────────────────── */

@media (max-width: 640px) {
  .ag-root { right: 12px; }
  .ag-panel { width: calc(100vw - 24px); }
  .ag-quick-btn span { display: none; }
}

/* Top right of an item's page, level with the title. Out of the stats strip
   on purpose: a due date is a commitment, not a statistic, and it should not
   be scanned past with "Versions" and "Attempts". */
.prog-detail-due {
  flex-shrink: 0;
  padding-top: 0.5rem;
  text-align: right;
}

@media (max-width: 720px) {
  .prog-detail-due { padding-top: 0; }
}

/* The Visualize topbar runs all the way to the right edge of the page, and its
   last two controls sat directly under the flag — the flag would have eaten
   the clicks. Reserving the flag's footprint (44px wide + its 26px offset,
   plus a gap) is better than moving the flag on one route: it is supposed to
   be in the same place on every page. */
body[data-route="visualization"] .viz-topbar {
  padding-right: 80px;
}

/* ── Done ─────────────────────────────────────────────────────
   Ticked off, not deleted: the row stays legible and stays on the calendar,
   it just stops asking for attention. */

.ag-row-done { opacity: 1; }
.ag-row-done.is-on { color: var(--color-success); }
.ag-row-done:hover { color: var(--color-success); }

.ag-row.is-done .ag-row-title {
  text-decoration: line-through;
  color: var(--text-tertiary);
}

.ag-row.is-done .ag-row-kind { opacity: 0.5; }

.ag-row-left.is-done {
  background: var(--color-success-bg);
  color: var(--color-success);
}

.ag-dot-done { background: var(--color-success); opacity: 0.5; }

.ag-done-note {
  padding: 0.5rem 0.35rem 0.2rem;
  font-size: 0.68rem;
  color: var(--text-tertiary);
  text-align: center;
}

.ag-deadline-text.is-done em { color: var(--color-success); }
