/* calendar.css — this app's own components.
 *
 * Prefix: cal-. Never rst- (rastrillo's namespace, and a future release
 * may claim a name we took) and never estilo- (the suite's, and these
 * are not suite components until a second app copies one).
 *
 * Grammar: the attribute spelling, matching rastrillo v3 — the KIND is
 * a bare attribute, a VARIANT is a token in its value matched with ~=,
 * and a PART is its own flat attribute. Adopted per screen, never per
 * element.
 *
 * Every colour here is a --rst-* token or derived from one with
 * color-mix. Nothing is a literal hex: the theme's own contrast table
 * is measured, and a hex dropped in beside it is a value nobody has
 * measured against anything.
 */

/* ── The view switcher ─────────────────────────────────────────── */

[cal-bar] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--rst-sp-3);
  margin-block-end: var(--rst-sp-4);
}

[cal-bar-spacer] { flex: 1 1 auto; }

/* The day's sentence. It is the page's opening line, so it reads at
 * body size rather than as a caption — a summary set in small grey
 * type is a summary people learn to skip. */
[cal-sentence] {
  color: var(--rst-text);
  margin: 0 0 var(--rst-sp-4);
  max-width: 52rem;
}

/* ── Month ─────────────────────────────────────────────────────── */

/* A real table: a month IS tabular data, so the row and column headers
 * come free for a screen reader and a scriptless page keeps working
 * semantics a div grid would have to rebuild with ARIA. */
[cal-month] {
  border-collapse: collapse;
  table-layout: fixed;
  width: 100%;
}

[cal-month] th {
  color: var(--rst-text-muted);
  font-size: var(--rst-fs-sm);
  font-weight: 600;
  padding: var(--rst-sp-2);
  text-align: start;
}

[cal-month] td {
  border: 1px solid var(--rst-line);
  height: 7.5rem;
  padding: 0;
  vertical-align: top;
}

[cal-day-cell] {
  display: flex;
  flex-direction: column;
  gap: 2px;
  height: 100%;
  padding: var(--rst-sp-1);
}

/* Outside the month: dimmed, but never hidden. A month grid whose
 * leading and trailing days are blank makes the first week look
 * broken. */
[cal-day-cell~="outside"] { opacity: 0.55; }

[cal-day-cell~="weekend"] { background: var(--rst-surface-2); }

[cal-day-num] {
  color: var(--rst-text-muted);
  display: block;
  font-size: var(--rst-fs-sm);
  padding: 2px;
  text-decoration: none;
}

[cal-day-num]:hover { text-decoration: underline; }

/* Today. Three signals, never colour alone: a filled marker, bold
 * weight, and the visually-hidden word "today" in the link's
 * accessible name. */
[cal-day-num~="today"] {
  background: var(--rst-accent);
  border-radius: var(--rst-radius-pill);
  color: var(--rst-on-accent);
  font-weight: 700;
  inline-size: 1.6rem;
  text-align: center;
}

[cal-more] {
  color: var(--rst-text-muted);
  font-size: var(--rst-fs-xs);
  padding-inline-start: 2px;
}

/* ── Chips ─────────────────────────────────────────────────────── */

/* One event, wherever it appears. The hue is set inline per calendar
 * as --cal-hue, and every colour below is mixed from it against a
 * theme token — so a chip stays legible in both schemes without the
 * calendar's colour being a measured value of its own. */
[cal-chip] {
  align-items: baseline;
  background: color-mix(in oklab, hsl(var(--cal-hue, 220) 60% 50%) 14%, var(--rst-surface));
  border-inline-start: 3px solid hsl(var(--cal-hue, 220) 55% 45%);
  border-radius: var(--rst-radius-sm);
  color: var(--rst-text);
  display: flex;
  font-size: var(--rst-fs-sm);
  gap: var(--rst-sp-1);
  overflow: hidden;
  padding: 2px var(--rst-sp-1);
  text-decoration: none;
  white-space: nowrap;
}

[cal-chip]:hover { text-decoration: underline; }

[cal-chip-time] {
  color: var(--rst-text-muted);
  flex: none;
  font-variant-numeric: tabular-nums;
}

[cal-chip-title] {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The past is dimmed AND written in the past tense — the tense is in
 * the markup, so the meaning survives greyscale and a stylesheet that
 * failed to load. */
[cal-chip~="past"] { opacity: 0.6; }

/* A cancelled event is struck through and says "Cancelled" in its own
 * text. Never the line alone. */
[cal-chip~="cancelled"] [cal-chip-title] { text-decoration: line-through; }

/* A note is a thing that is true of a day without occupying it, so it
 * is drawn as an outline rather than a filled block. */
[cal-chip~="note"] {
  background: transparent;
  border: 1px dashed color-mix(in oklab, hsl(var(--cal-hue, 220) 55% 45%) 60%, var(--rst-line));
  border-inline-start-width: 3px;
}

/* A commitment is yours rather than shared: a quieter fill than a
 * meeting, so a day of your own work does not read as a day of
 * meetings. */
[cal-chip~="commitment"] {
  background: color-mix(in oklab, hsl(var(--cal-hue, 220) 60% 50%) 7%, var(--rst-surface));
}

[cal-chip~="tentative"] {
  border-inline-start-style: dotted;
}

/* ── Day and week columns ──────────────────────────────────────── */

[cal-grid] {
  display: grid;
  gap: 0;
  grid-template-columns: 3.5rem 1fr;
}

[cal-week-grid] {
  display: grid;
  gap: 0;
  grid-template-columns: 3.5rem repeat(7, minmax(6rem, 1fr));
}

[cal-hours] {
  border-inline-end: 1px solid var(--rst-line);
  position: relative;
}

[cal-hour] {
  block-size: 3rem;
  color: var(--rst-text-faint);
  font-size: var(--rst-fs-xs);
  font-variant-numeric: tabular-nums;
  padding-inline-end: var(--rst-sp-2);
  text-align: end;
  /* The label sits at the line it names, not in the box below it. */
  transform: translateY(-0.5em);
}

/* The day column. 72rem is 24 hours at 3rem each, so an hour label and
 * the grid line beside it stay in step. */
[cal-column] {
  block-size: 72rem;
  border-inline-end: 1px solid var(--rst-line);
  position: relative;
}

[cal-column-head] {
  border-block-end: 1px solid var(--rst-line);
  padding: var(--rst-sp-2);
  position: sticky;
  text-align: center;
  top: 0;
  z-index: 2;
  background: var(--rst-bg);
}

[cal-column-head~="today"] { font-weight: 700; }

/* The hour rules, drawn as a repeating background so 24 of them cost
 * one declaration rather than 24 elements. */
[cal-column-rules] {
  background-image: repeating-linear-gradient(
    to bottom,
    var(--rst-line) 0,
    var(--rst-line) 1px,
    transparent 1px,
    transparent 3rem
  );
  inset: 0;
  position: absolute;
}

/* An empty half hour, as a link. This is what makes "click a time to
 * create an event" work with no JavaScript: 48 ordinary links per day,
 * each with a screen-reader label naming its time. */
[cal-slot] {
  display: block;
  inset-inline: 0;
  position: absolute;
}

[cal-slot]:hover {
  background: color-mix(in oklab, var(--rst-accent) 10%, transparent);
}

[cal-slot]:focus-visible {
  outline: 2px solid var(--rst-accent);
  outline-offset: -2px;
}

/* A placed event. top/height/left/width arrive as inline style from
 * the server's own packer — rastrillo's CSP allows inline styles, so
 * this needs no exception. */
[cal-placed] {
  position: absolute;
  z-index: 1;
}

[cal-placed] [cal-chip] {
  block-size: 100%;
  align-items: flex-start;
  flex-direction: column;
  gap: 0;
  white-space: normal;
}

/* The all-day strip above the timed grid. All-day events are not
 * packed into the column: giving a birthday a height would make it
 * look like a 24-hour meeting. */
[cal-allday] {
  border-block-end: 1px solid var(--rst-line);
  display: flex;
  flex-wrap: wrap;
  gap: var(--rst-sp-1);
  padding: var(--rst-sp-2);
}

/* ── The whisper ───────────────────────────────────────────────── */

/* An event authored in another zone. The primary time is always the
 * reader's own; this is a note beside it, never the headline. */
[cal-elsewhere] {
  color: var(--rst-text-faint);
  font-size: var(--rst-fs-xs);
}

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

/* At 320px the month reflows to a stacked list of days. A seven-column
 * grid at that width is seven columns of nothing.
 *
 * Week keeps its two dimensions and scrolls sideways: a week view IS a
 * two-dimensional comparison, and flattening it to a list makes it the
 * agenda, which already exists. */
@media (max-width: 40rem) {
  [cal-month], [cal-month] thead { display: block; }
  [cal-month] thead { display: none; }
  [cal-month] tbody, [cal-month] tr { display: block; }
  [cal-month] td { display: block; height: auto; min-height: 2.5rem; }
  /* A day with nothing in it is not worth a row of its own on a
   * phone. */
  [cal-month] td:not(:has([cal-chip])):not(:has([cal-day-num~="today"])) { display: none; }
  [cal-day-cell] { flex-direction: row; align-items: baseline; gap: var(--rst-sp-2); }

  [cal-week-scroll] { overflow-x: auto; }
  [cal-week-grid] { min-inline-size: 48rem; }
}

/* ── Motion ────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  [cal-slot], [cal-chip] { transition: none; }
}

/* ── Quick add ─────────────────────────────────────────────────── */

/* The header's action group. Quick add sits beside New event rather
 * than replacing it: one is the fast path, the other is the one that
 * shows every field. */
[cal-header-actions] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--rst-sp-2);
}

/* The disclosure is a <details>, so it opens with no script at all.
 * Everything below is appearance; none of it is behaviour. */
[cal-quick] { position: relative; }

/* The closed state reads as a small text input, because that is what it
 * behaves like — click it and type. The marker is removed in both
 * spellings: Safari still wants the -webkit- pseudo-element and leaving
 * it in puts a disclosure triangle inside what looks like a field. */
[cal-quick] > summary {
  align-items: center;
  background: var(--rst-surface);
  border: 1px solid var(--rst-line);
  border-radius: var(--rst-radius-sm);
  color: var(--rst-text-muted);
  cursor: text;
  display: flex;
  font-size: var(--rst-fs-sm);
  gap: var(--rst-sp-1);
  list-style: none;
  min-width: 12rem;
  padding: var(--rst-sp-2) var(--rst-sp-3);
}

[cal-quick] > summary::-webkit-details-marker { display: none; }

[cal-quick] > summary:hover { border-color: var(--rst-accent); }

[cal-quick][open] > summary {
  border-color: var(--rst-accent);
  color: var(--rst-text);
}

/* The popover. Absolute so opening it does not push the calendar down
 * the page — the grid behind stays exactly where it was, which is what
 * makes this feel like a panel rather than a page change. */
[cal-quick-form] {
  background: var(--rst-surface);
  border: 1px solid var(--rst-line);
  border-radius: var(--rst-radius-sm);
  box-shadow: 0 8px 24px color-mix(in oklab, var(--rst-text) 18%, transparent);
  /* Anchored to the END edge, so the panel opens back across the page
   * instead of off the side of it. The box sits at the far right of the
   * header, beside New event: anchored at the start edge a 30rem panel
   * hangs ~28px past a 1280px viewport, which every string assertion in
   * the Go suite happily passes. The browser gate measured it. */
  inset-inline-end: 0;
  margin-block-start: var(--rst-sp-1);
  padding: var(--rst-sp-3);
  position: absolute;
  top: 100%;
  width: min(30rem, 88vw);
  z-index: 30;
}

[cal-quick-text] {
  background: var(--rst-bg);
  border: 1px solid var(--rst-line);
  border-radius: var(--rst-radius-sm);
  color: var(--rst-text);
  display: block;
  font: inherit;
  padding: var(--rst-sp-2);
  resize: vertical;
  width: 100%;
}

[cal-quick-pane] {
  background: var(--rst-surface-2);
  border-radius: var(--rst-radius-sm);
  font-size: var(--rst-fs-sm);
  margin-block: var(--rst-sp-2);
  padding: var(--rst-sp-2) var(--rst-sp-3);
}

[cal-quick-blank] { color: var(--rst-text-muted); margin: 0; }

[cal-quick-detail] { margin: 0; }

[cal-quick-row] {
  display: grid;
  gap: var(--rst-sp-2);
  grid-template-columns: 8rem 1fr;
  padding-block: var(--rst-sp-1);
}

[cal-quick-row] dt { color: var(--rst-text-muted); margin: 0; }
[cal-quick-row] dd { margin: 0; }

/* The caveat rides in the LABEL. Somebody who reads only the left
 * column still learns that nothing was emailed. */
[cal-quick-caveat] { color: var(--rst-text-faint); font-size: var(--rst-fs-xs); }

[cal-quick-people] { list-style: none; margin: 0; padding: 0; }

[cal-quick-notes] {
  color: var(--rst-text-muted);
  font-size: var(--rst-fs-xs);
  margin: var(--rst-sp-2) 0 0;
  padding-inline-start: var(--rst-sp-4);
}

[cal-quick-actions] {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--rst-sp-2);
}

[cal-quick-hint] {
  color: var(--rst-text-faint);
  font-size: var(--rst-fs-xs);
  flex: 1 1 12rem;
}

/* Narrow: the popover stops floating and becomes part of the page. A
 * 30rem panel pinned to a header on a 320px screen is off the side of
 * it. */
@media (max-width: 40rem) {
  [cal-header-actions] { width: 100%; }
  [cal-quick] { flex: 1 1 100%; }
  [cal-quick] > summary { min-width: 0; }
  [cal-quick-form] {
    box-shadow: none;
    position: static;
    width: 100%;
  }
  [cal-quick-row] { grid-template-columns: 1fr; gap: 0; }
}

/* The keyboard hint. Revealed by quickadd.js, never by the template:
 * with no script Enter is just a newline, and advertising a shortcut
 * the page cannot honour is worse than staying quiet. */
[cal-quick-key] {
  color: var(--rst-text-faint);
  font-size: var(--rst-fs-xs);
}
