  /* ---------- Calendar module (#569): the canvas module frame ----------
     The Calendar is the first module to move onto the canvas module frame. `.ctx-calendar` hides the
     Mail rail; the Calendar renders its own context column (#ctxCalendar) and its own stage pane
     (#calStage), which replaces the shared Mail list pane. The plan.css `.pl-*` rules and the
     helm.css `.mod`, `.mh`, `.mini`, `.seg`, `.dlg`, `.sw`, `.ban` and `.empty` style the frame; the
     rules below wire it into the shell grid and keep the states the canvas does not define. */
  .shell2.ctx-calendar .rail{display:none}
  .calstage{grid-column:2;grid-row:1;position:relative;background:var(--canvas);min-width:0;min-height:0;overflow:hidden}
  .calmod-body{flex:1;min-height:0;display:flex;flex-direction:column}
  /* The kept event tones (owner direction, 7 October 2026): free and tentative keep their current
     look on the canvas event block; a private event keeps its inset bar. */
  .pl-ev.free{background:transparent;color:var(--ink);box-shadow:inset 0 0 0 1px var(--line)}
  .pl-ev.tentative{background:color-mix(in srgb,var(--c-amber) 22%,var(--canvas));color:var(--ink);box-shadow:inset 0 0 0 1px var(--c-amber)}
  .pl-ev.private{box-shadow:inset 2px 0 0 currentColor}
  /* Drag and resize kept from #313: the chip is grabbable, the two edges resize, pending dims it.
     The timed event block (.pl-ev) is already position:absolute from plan.css, which is the edges'
     positioning context; the all-day chip needs position:relative for the same. */
  .pl-ev[data-can-edit="1"],.pl-mev[data-can-edit="1"],.pl-adchip[data-can-edit="1"]{cursor:grab;touch-action:pan-y}
  .pl-adchip[data-can-edit="1"],.pl-mev[data-can-edit="1"]{position:relative}
  .pl-ev[data-can-edit="1"].dragging,.pl-mev[data-can-edit="1"].dragging,.pl-adchip[data-can-edit="1"].dragging{cursor:grabbing;opacity:.85}
  .pl-ev[data-can-edit="1"].cal-pending,.pl-mev[data-can-edit="1"].cal-pending,.pl-adchip[data-can-edit="1"].cal-pending{opacity:.55;cursor:progress}
  .cal-edge{position:absolute;left:0;right:0;height:8px;z-index:2;cursor:ns-resize}
  .cal-edge.start{top:0}
  .cal-edge.end{bottom:0}
  /* Bank holidays keep their current dashed pill (owner direction), placed in the all-day band. */
  .cal-holiday{display:inline-flex;align-items:center;padding:3px 8px;border-radius:999px;background:var(--raised);border:1px dashed var(--line);font-size:11.5px;color:var(--ink-2);cursor:default}
  /* The Calendar suggestion listbox and the invitee chips on the canvas use plan.css `.pl-suggest`,
     `.pl-sugg` and helm.css `.chipfield`/`.pchip`. The RSVP uses the canvas `.seg`/`.pl-rsvp`. The
     one app-only rule is the in-dialog write-failure line and the read-only meta spacing. */
  .cal-dlg-err{margin:0;font-size:12.5px;font-weight:500;line-height:1.4;color:var(--danger)}
  .cal-dlg-err[hidden]{display:none}
  .cal-dlg-meta{margin-top:6px}
  .cal-invitee-chips{display:contents}
  #calInviteeSuggest[hidden]{display:none}
  #cal-rsvp-field .hint[hidden]{display:none}
  /* The Calendar event dialog lays its fields out as the canvas dialog body does: one flex column
     with the 16px dialog-body gap (canvas `.dlg-b`). The app wraps the fields in `#cal-form`, so
     the gap goes on the form. Without it the gap fell only between adjacent `.f` fields through the
     app-wide `.f + .f` margin, so the Invitees field butted against the When block and the Reminder
     and Private options block butted against the Description box (#615). The `.f + .f` margin would
     double the gap for two stacked fields, so it is reset for the form's direct children; the
     two-up rows inside the form (`.f-row` in the When block, `.pl-opts`) keep their own grid gaps
     and are not touched, so the two-up field alignment holds (#580). */
  #cal-form{display:flex;flex-direction:column;gap:var(--sp-4)}
  #cal-form > .f + .f{margin-top:0}
