/* ============================================================
   CalendarKey — minimalist popover legend for the calendar
   Trigger lives in the calendar header between date-nav and
   view switcher. Popover anchors under the trigger.
   ============================================================ */

.calendar-key-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  margin: 0 6px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 50%;
  background: transparent;
  color: var(--slate-500, #64748b);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  flex: 0 0 auto;
}

.calendar-key-trigger:hover,
.calendar-key-trigger:focus-visible {
  color: var(--primary-600, #0d9488);
  background: rgba(13, 148, 136, 0.08);
  border-color: rgba(13, 148, 136, 0.25);
  outline: none;
}

.calendar-key-trigger[aria-expanded="true"] {
  color: var(--primary-700, #0f766e);
  background: rgba(13, 148, 136, 0.14);
  border-color: rgba(13, 148, 136, 0.35);
}

.calendar-key-popover {
  position: absolute;
  z-index: 50;
  min-width: 260px;
  max-width: 320px;
  padding: 12px 14px;
  background: var(--surface-primary, #ffffff);
  color: var(--slate-800, #1e293b);
  border: 1px solid var(--slate-200, #e2e8f0);
  border-radius: var(--radius-sm, 8px);
  box-shadow: 0 10px 30px rgba(15, 23, 42, 0.18);
  font-size: 12px;
  line-height: 1.35;
}

.calendar-key-popover[hidden] { display: none; }

.calendar-key-popover__section + .calendar-key-popover__section {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--slate-100, #f1f5f9);
}

.calendar-key-popover__title {
  margin: 0 0 6px 0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--slate-500, #64748b);
}

.calendar-key-popover__hint {
  margin: -2px 0 8px 0;
  font-size: 11px;
  line-height: 1.4;
  color: var(--slate-500, #64748b);
}

.calendar-key-popover__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.calendar-key-popover__list li {
  display: grid;
  grid-template-columns: 28px 1fr;
  align-items: center;
  gap: 8px;
}

.calendar-key-swatch {
  width: 4px;
  height: 14px;
  border-radius: 2px;
  justify-self: center;
}

/* The month's day bar in miniature (2026-10-08): the same colours as
   day-nav.css .cal-day-bar (grey day, green working hours, one event). */
.calendar-key-daybar {
  position: relative;
  justify-self: center;
  width: 26px;
  height: 6px;
  border-radius: 3px;
  background: #eef2f6;
  overflow: hidden;
}
.calendar-key-daybar i { position: absolute; top: 0; bottom: 0; }
.calendar-key-daybar__work { left: 33%; width: 38%; background: #bff0d3; }
.calendar-key-daybar__ev { left: 42%; width: 12%; background: #3b82f6; border-radius: 1px; }
body.dark-mode .calendar-key-daybar { background: #273449; }
body.dark-mode .calendar-key-daybar__work { background: #166534; }

.calendar-key-swatch--green { background: var(--cal-day-green-solid, #16a34a); }
.calendar-key-swatch--amber { background: var(--cal-day-amber-solid, #ca8a04); }
.calendar-key-swatch--red   { background: var(--cal-day-red-solid,   #dc2626); }

/* ⭐⭐⭐ THE BOARD LEGEND'S OWN SWATCHES (2026-08-16, vocabulary audit).
   buildBoardPopoverHTML() emits five swatch classes that had NO CSS anywhere in
   the repo: --daynight, --verdict, --teambar, --nowline and --busy. They fell
   back to the bare 4x14px `.calendar-key-swatch` (no background at all) and the
   empty `.calendar-key-marker`, so the board key rendered FIVE BLANK SWATCHES
   next to five perfectly good descriptions. A key that shows nothing is worse
   than no key: it teaches the user the mark is invisible.
   Each is painted from the SAME token the real surface uses, so the key cannot
   drift from the board. */
.calendar-key-swatch--daynight {
  /* The day/night wash, deep blue at night through to warm midday. */
  width: 18px;
  background: linear-gradient(180deg, #1e3a5f 0%, #93c5fd 55%, #fde68a 100%);
}
/* Work and sleep brackets (2026-10-08): the opening bracket the board's
   .work-start / .sleep-start cells paint, in the same tokens. */
.calendar-key-swatch--workframe,
.calendar-key-swatch--sleepedge {
  width: 18px;
  border-radius: 1px;
  background: #e0f2fe;
  box-shadow:
    inset 2.5px 0 0 0 var(--work-bracket, rgba(59, 130, 246, 0.85)),
    inset 0 2.5px 0 0 var(--work-bracket, rgba(59, 130, 246, 0.85)),
    inset 0 -2.5px 0 0 var(--work-bracket, rgba(59, 130, 246, 0.85));
}
.calendar-key-swatch--sleepedge {
  background: #1e293b;
  box-shadow:
    inset 2.5px 0 0 0 var(--sleep-bracket, #6d28d9),
    inset 0 2.5px 0 0 var(--sleep-bracket, #6d28d9),
    inset 0 -2.5px 0 0 var(--sleep-bracket, #6d28d9);
}
.calendar-key-swatch--verdict {
  /* The scanner's per-row grade strips: green fine, amber a stretch,
     red costly, violet asleep (2026-10-08). */
  width: 18px;
  background: linear-gradient(180deg,
    #22c55e 0 25%, #f59e0b 25% 50%, #ef4444 50% 75%, #8b5cf6 75% 100%);
}
.calendar-key-swatch--teambar {
  /* The bar above the scanner: grey where no one can make it, green where
     everyone can (2026-10-08). */
  width: 18px;
  height: 8px;
  background: linear-gradient(90deg,
    #cbd5e1 0 28%, #86efac 28% 44%, #22c55e 44% 76%, #cbd5e1 76% 100%);
}
.calendar-key-marker--nowline {
  /* Pink core + white ring, exactly as .timeline-comparison-bar paints it. */
  position: relative;
}
.calendar-key-marker--nowline::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 1.5px;
  transform: translateX(-50%);
  background: #ec4899;
  box-shadow: 0 0 0 0.75px rgba(255, 255, 255, 0.9);
}
.calendar-key-marker--busy {
  /* The -45deg slate hatch a masked busy block wears. */
  border-radius: 3px;
  background:
    repeating-linear-gradient(
      -45deg,
      rgba(120, 130, 150, 0.92) 0px,
      rgba(120, 130, 150, 0.92) 3px,
      rgba(148, 163, 184, 0.92) 3px,
      rgba(148, 163, 184, 0.92) 7px
    );
}

/* ⭐⭐⭐ EVENT BLOCKS (2026-08-16, owner: "compare actual and my block event
   guide, any inconsistencies between there and rendered").
   There were: the key documented NO event state at all, while the board paints
   four. These swatches mirror the real treatments token for token:
     confirmed = category fill + a 1px SOLID white ring
     tentative = the same, DASHED, plus the 135deg confirmation stripe
     busy      = slate + the -45deg hatch
     conflict  = red, reserved for clashes and danger only
   Border-STYLE is the confirmation channel on the board, so it is the
   confirmation channel in the key too. */
.calendar-key-block {
  justify-self: center;
  width: 20px;
  height: 12px;
  border-radius: 3px;
  box-sizing: border-box;
  color: #fff;
}
/* Slate body + the category edge on BOTH sides, like the real block
   (2026-09-08). These swatches teach the SETTLED channel, so they keep one
   sample category (work) and let the border carry the distinction. */
/* THREE CHANNELS (2026-09-13 ruling, key aligned 2026-09-14): the BODY is the
   category hue, the SIDES are visibility, the BORDER is confirmation. The
   swatches keep one sample category (work) so the other channels read. */
.calendar-key-block--confirmed {
  background: var(--event-work, #3b82f6);
  border: 1px solid rgba(255, 255, 255, 0.9);
  box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.55), inset -1px 0 0 rgba(255, 255, 255, 0.55), 0 1px 3px rgba(0, 0, 0, 0.25);
}
.calendar-key-block--tentative {
  background: var(--event-work, #3b82f6);
  border: 1.5px dashed rgba(255, 255, 255, 0.9);
  /* 2026-09-15: explicit red, matching the chips. Was color-mix(currentColor),
     which rendered this swatch WHITE while the board painted the same state
     red - a legend must show what the board shows. */
  background-image: repeating-linear-gradient(
    135deg,
    rgba(220, 38, 38, 0.85) 0px,
    rgba(220, 38, 38, 0.85) 5px,
    transparent 5px,
    transparent 10px
  );
  box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.55), inset -1px 0 0 rgba(255, 255, 255, 0.55), 0 1px 3px rgba(0, 0, 0, 0.25);
}
.calendar-key-block--busy {
  box-shadow: inset 3px 0 0 var(--visibility-blocked, rgb(120, 130, 150)), inset -3px 0 0 var(--visibility-blocked, rgb(120, 130, 150));
  background-color: var(--status-busy, #64748b);
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(120, 130, 150, 0.45) 0px,
    rgba(120, 130, 150, 0.45) 3px,
    rgba(148, 163, 184, 0.7) 3px,
    rgba(148, 163, 184, 0.7) 7px
  );
  border: 1px solid rgba(255, 255, 255, 0.9);
}
.calendar-key-block--conflict {
  background: var(--shading-busy, #dc2626);
  border: 1px solid rgba(255, 255, 255, 0.9);
}
/* VISIBILITY, ONE LANGUAGE (2026-09-14) — same treatments as the board marker,
   the compact strip, the day-panel chip and the picker:
     open    = category body + 3px GREEN  bars each side
     busy    = slate + hatch (above) + 3px SLATE bars each side
     private = category body + 3px VIOLET bars each side (own board only)
   ⭐RE-COLOURED 2026-09-18: the key teaches the language, so it moves with the
   board. See the note on the data-shared-as rules in style.css. */
.calendar-key-block--open {
  background: var(--event-work, #3b82f6);
  box-shadow: inset 3px 0 0 var(--visibility-shared, #059669), inset -3px 0 0 var(--visibility-shared, #059669), 0 1px 3px rgba(0, 0, 0, 0.25);
}
.calendar-key-block--private {
  background: var(--event-work, #3b82f6);
  box-shadow: inset 3px 0 0 var(--visibility-private, #8b5cf6), inset -3px 0 0 var(--visibility-private, #8b5cf6);
}
/* A shift: painted as a WORK event (2026-09-15, owner: "Shifts are treated like
   work events"), with the coverage type still on the top and bottom lines
   (sample type colour from the quota swatch set). The stripe was retired with
   the chips it described - a legend must not advertise a texture the board no
   longer paints. */
.calendar-key-block--shift {
  background-color: var(--event-work, #3b82f6);
  background-image: none;
  box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.55), inset -1px 0 0 rgba(255, 255, 255, 0.55), inset 0 2px 0 #a21caf, inset 0 -2px 0 #a21caf;
}

/* V3/V4: sample chips inside the popover.
   - V3 `.calendar-key-count-badge` retired; V4 uses `.calendar-key-busy-badge`
     for "Nh/Mh" personal busy preview and `.calendar-key-team-chip` for the
     bottom-right team-availability N/M preview. Share the same pill shape
     so the legend reads as a consistent "chip" vocabulary. */
.calendar-key-count-badge,
.calendar-key-busy-badge,
.calendar-key-team-chip {
  justify-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  padding: 1px 6px;
  border-radius: var(--radius-full, 9999px);
  background: var(--slate-100, #f1f5f9);
  color: var(--slate-700, #334155);
  font-size: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
}
/* Team chip is visually secondary — slightly dimmer + thin border to match
   the real cell chip so users recognise it at a glance. */
.calendar-key-team-chip {
  border: 1px solid var(--slate-200, #e2e8f0);
  opacity: 0.9;
}

.calendar-key-marker {
  justify-self: center;
  width: 14px;
  height: 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--cal-day-green-solid, #16a34a);
  font-size: 12px;
}

.calendar-key-marker--golden {
  color: var(--golden-day, #eab308);
  text-shadow: 0 0 6px rgba(234, 179, 8, 0.55);
}

/* TIME OFF = the away ORANGE the board now paints (2026-08-23).
   Was var(--event-timeoff, #f59e0b) — the flex/tentative amber — which after
   the 2026-08-22 recolour was a DIFFERENT token from the one the strip paints,
   and had no dark-mode variant so it could never reach --status-away-scan-dark.
   Reading --status-away-scan keeps the legend and the strip on one token. */
.calendar-key-marker--leave {
  width: 18px;
  height: 0;
  border-top: 2px solid var(--status-away-scan, #d97706);
}

/* PENDING = the SAME amber line, DASHED. 2026-09-08: this swatch drew a red
   135deg hatch, which the real ribbon has never had — .calendar-day-leave-ribbon
   (css/day-nav.css:517) is a 2px amber TOP BORDER on a transparent fill, and
   .is-pending only switches that border to `dashed`. The 2026-08-23 note below
   was right that pending needs a shared vocabulary, but it re-pointed the KEY at
   the tentative-event hatch without moving the ribbon, so the legend and the
   thing it explains disagreed. Mirror the ribbon instead. */
.calendar-key-marker--leave-pending {
  width: 18px;
  height: 0;
  border-top: 2px dashed var(--status-away-scan, #d97706);
}

body.dark-mode .calendar-key-marker--leave {
  border-top-color: var(--status-away-scan-dark, #ea580c);
}
/* Dark mode keeps the dashed line too (2026-10-08): the red hatch the light
   swatch dropped on 2026-09-08 had survived here, under a "dashed" label. */
body.dark-mode .calendar-key-marker--leave-pending {
  border-top-color: var(--status-away-scan-dark, #ea580c);
}

.calendar-key-icon {
  justify-self: center;
  font-size: 12px;
}
/* Event-type swatches (2026-08-05). The key explained the traffic light, leave
   strips, badges and privacy, but never what an event's COLOUR meant — the one
   question the board raises most. Hues are the canonical --event-* tokens. */
.calendar-key-popover__list--types { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.calendar-key-popover__list--types li { flex: 0 0 auto; }
.calendar-key-type {
  display: inline-block;
  width: 22px;
  height: 11px;
  border-radius: 3px;
  vertical-align: -1px;
  margin-right: 6px;
}
/* ⭐THE CATEGORY IS THE BODY, AT FULL STRENGTH (2026-09-13 "three channels, one
   meaning each"; style.css ~17143). These swatches taught the SUPERSEDED
   2026-09-08 rule — a slate body with the category down both sides — which the
   ruling reversed when it gave the side edges to VISIBILITY. Worse, they
   contradicted .calendar-key-block--open/--private ~120 lines above in this
   same file, which already draw visibility on the sides over a categorised
   body. A swatch that teaches the old rule is a legend lying about the board,
   so the category is a fill again and the sides are left free. */
.calendar-key-type--work     { background: var(--event-work, #3b82f6); }
.calendar-key-type--personal { background: var(--event-personal, #f472b6); }
.calendar-key-type--external { background: var(--event-external, #14b8a6); }
.calendar-key-type--timeoff  { background: var(--event-timeoff, #f59e0b); }
/* Busy carries the canonical -45deg hatch — the hatch is what says "busy"
   rather than "some uncategorised grey event", so a flat swatch would teach the
   wrong thing. Stops mirror .timeline-event-marker.busy-block. */
.calendar-key-type--busy {
  background: repeating-linear-gradient(
    -45deg,
    rgba(120, 130, 150, 0.92) 0px,
    rgba(120, 130, 150, 0.92) 3px,
    rgba(148, 163, 184, 0.92) 3px,
    rgba(148, 163, 184, 0.92) 7px
  );
}

.calendar-key-icon--private { color: var(--visibility-private, #8b5cf6); }
/* Fallback tracks --visibility-blocked, which moved amber -> canonical busy
   slate on 2026-08-05. A stale fallback only surfaces when the var fails to
   resolve, which is exactly when you cannot see it going wrong. */
.calendar-key-icon--busy    { color: var(--visibility-blocked, rgb(120, 130, 150)); }
.calendar-key-icon--shared  { color: var(--visibility-shared,  #059669); }

.calendar-key-label {
  color: var(--slate-700, #334155);
}

/* ---------- Dark mode ---------- */
body.dark-mode .calendar-key-trigger {
  color: var(--slate-400, #94a3b8);
}
body.dark-mode .calendar-key-trigger:hover,
body.dark-mode .calendar-key-trigger:focus-visible {
  color: var(--primary-300, #5eead4);
  background: rgba(94, 234, 212, 0.10);
  border-color: rgba(94, 234, 212, 0.25);
}

body.dark-mode .calendar-key-popover {
  background: var(--slate-800, #1e293b);
  color: var(--slate-100, #f1f5f9);
  border-color: var(--slate-700, #334155);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
}
body.dark-mode .calendar-key-popover__section + .calendar-key-popover__section {
  border-top-color: var(--slate-700, #334155);
}
body.dark-mode .calendar-key-popover__title { color: var(--slate-400, #94a3b8); }
body.dark-mode .calendar-key-popover__hint { color: var(--slate-400, #94a3b8); }
body.dark-mode .calendar-key-count-badge,
body.dark-mode .calendar-key-busy-badge,
body.dark-mode .calendar-key-team-chip {
  background: var(--slate-700, #334155);
  color: var(--slate-100, #f1f5f9);
}
body.dark-mode .calendar-key-team-chip {
  border-color: var(--slate-600, #475569);
}
body.dark-mode .calendar-key-label   { color: var(--slate-200, #e2e8f0); }

/* "More help" footer (2026-07-15 education-surfaces audit): bridges the colour
   legend popover to the full searchable Help Center. */
.calendar-key-popover__footer {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--slate-200, #e2e8f0);
}
.calendar-key-morehelp {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: none;
  padding: 4px 2px;
  font-size: 12px;
  font-weight: 600;
  color: var(--primary-600, #0d9488);
  cursor: pointer;
}
.calendar-key-morehelp:hover { text-decoration: underline; }
body.dark-mode .calendar-key-popover__footer { border-top-color: var(--slate-600, #475569); }
body.dark-mode .calendar-key-morehelp { color: var(--teal-300, #5eead4); }
