/* The strip is the scrolling list's own index; the four-week grid is its own. Hiding it
   needs a rule because display: flex above outranks the hidden attribute. */
.agenda-strip[hidden] {
  display: none;
}

/* The phone strip's own shape (agenda.js toggles this class; the tablet keeps the flat
   ribbon above): not a row of buttons but week-sized pages -- the selected week with a
   swipeable week either side -- moved a whole week per swipe. column-gap equals the strip's
   own 0.6rem inline padding, so consecutive pages sit exactly one strip-width apart: a
   neighbouring page never peeks in at an edge, and the last page is reachable exactly.
   scroll-snap-stop: always is what makes one swipe one week rather than a run of them, and
   the scrollbar is hidden because the pages themselves are the affordance. */
.agenda-strip-paged {
  column-gap: 0.6rem;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: 0.6rem;
  scrollbar-width: none;
}

.agenda-strip-paged::-webkit-scrollbar {
  display: none;
}

.agenda-strip-week {
  display: flex;
  flex: 0 0 100%;
  gap: 0.3rem;
  min-width: 0;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

/* The strip's own .agenda-date rule sets min-width: 2.6rem, which seven buttons across one
   page cannot always afford; a page's buttons share the width the page has instead. */
.agenda-strip-week .agenda-date {
  min-width: 0;
}

/* Large text, or under 360px: a date never squeezes below 2.75rem (a 44px target); the week
   scrolls sideways instead. Paging between weeks is unchanged. */
:root[data-text-size="large"] .agenda-strip-week {
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

:root[data-text-size="large"] .agenda-strip-week .agenda-date {
  min-width: 2.75rem;
}

@media (max-width: 374px) {
  .agenda-strip-week {
    overflow-x: auto;
    overscroll-behavior-x: contain;
  }

  .agenda-strip-week .agenda-date {
    min-width: 2.75rem;
  }
}

/* Directly on the wallpaper now, not a card -- white ink and the shared soft shadow, the
   same on-wall pair the header text above it already reads through. */
.agenda-date {
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
  min-width: 2.75rem;
  min-height: var(--touch-min);
  padding: 0.35rem 0.2rem;
  color: var(--ink-heading);
  text-shadow: var(--text-shadow-on-wall);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  font: inherit;
}

.agenda-strip-scrollable .agenda-date {
  flex: 0 0 3.25rem;
  scroll-snap-align: center;
}

.agenda-date:hover,
.agenda-date:focus-visible {
  border-color: var(--line);
}

.agenda-date-weekday {
  color: var(--ink-on-wall-muted);
  font-size: var(--text-caption);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.agenda-date-day {
  font-size: var(--text-detail-title);
  font-weight: var(--w-title);
  font-variant-numeric: tabular-nums;
}

/* Not the accent -- a pip is a mark, not a datum, and the strip already has one accent
   (the selected/today state below). */
.agenda-date-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--faint);
}

.agenda-date-dot[hidden] {
  visibility: hidden;
}

/* Ink, and the two children below it, on the accent fill -- not the page ground. All
   three used to read --page, which happened to work only because --page was white. The
   on-wall text-shadow every other date in the strip carries would only muddy dark ink on a
   light gold fill, so the selected pill drops it. */
.agenda-date-today {
  color: var(--on-accent);
  text-shadow: none;
  background: var(--accent);
  border-color: var(--accent);
}

.agenda-date-today .agenda-date-weekday {
  color: color-mix(in srgb, var(--on-accent) 80%, transparent);
}

.agenda-date-today .agenda-date-dot {
  background: var(--on-accent);
}

/* No rule here on purpose. A weekend day used to carry a few-percent tint of its own, which
   a screenshot review read as a boxed/dim cell sitting beside plain ones -- only the
   selected/today day is meant to carry any ground at all (the gold pill above); every other
   day, weekend or not, stays directly on the wallpaper and is told apart by its dot and its
   weekday label alone. */

/* Marks the date the strip is following at the top of the list -- a border ring, not a
   text-colour change, so it reads over the weekend tint and never touches contrast in the
   light theme. Excluded when it is also today so the filled accent state always wins. */
.agenda-date[aria-current="date"]:not(.agenda-date-today) {
  border-color: var(--accent);
}

/* The strip always draws a whole Sunday-to-Saturday week, so in the current week it draws
   days that are already gone. They stay drawn -- the week's shape is what the strip is for,
   and a week that grew from three columns on Wednesday to seven on Sunday would be a
   stranger thing than a greyed day. They are `disabled` in the markup, which is what
   actually stops the navigation; this only makes them look the way they now behave. Both
   spans are dimmed rather than the button, so the weekday caption keeps its own relationship
   to the number above it, and the today/weekend/current states below can still be read. */
.agenda-date[data-agenda-past] .agenda-date-weekday,
.agenda-date[data-agenda-past] .agenda-date-day {
  color: color-mix(in srgb, var(--muted) 55%, var(--page));
}

.agenda-date[data-agenda-past]:hover,
.agenda-date[data-agenda-past]:focus-visible {
  border-color: transparent;
}

.agenda-status {
  margin: 0 var(--list-gutter) 0.3rem;
  font-size: var(--text-detail-body);
  text-shadow: var(--text-shadow-on-wall);
}

.agenda-status {
  color: var(--ink-on-wall-muted);
}

.agenda-status.app-status-failure {
  color: var(--error);
}

/* The shared scroller, with no vertical padding of its own: the agenda's own full-bleed
   inset used to carry both, and now that .agenda lives inside .chat's own padded box
   (see .chat above) that inset would double up. */
.agenda-days {
  flex: 1 1 0;
  padding-block: 0;
  touch-action: pan-y;
}

/* Scroll-trigger markers for the top/bottom IntersectionObserver, not day content: never
   display: none (the observer would stop firing), and normally show nothing. On a failed
   range request at that end, the retry button inside becomes visible with a quiet,
   retryable message (clicking it retries that end's request). */
.agenda-edge {
  display: block;
  width: 100%;
  min-height: 1px;
  margin: 0;
  padding: 0;
}

.agenda-edge-retry {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  color: var(--ink-on-wall-muted);
  text-align: center;
  text-shadow: var(--text-shadow-on-wall);
  background: transparent;
  border: 0;
  font: inherit;
  font-size: var(--text-detail-body);
}

.agenda-edge-retry:not([hidden]) {
  padding: var(--space-r2) 0;
}

/* The hidden attribute's UA display: none was being overridden by the block rule above,
   which left both sentinels rendering as a 44px-tall empty button. */
.agenda-edge-retry[hidden] {
  display: none;
}

/* A group of cards, not a filled slab: the day itself carries no border or background of its
   own, and 20px of its bottom padding is the gap between one day's group and the next. The
   6px inline inset is on EVERY day, not only the tinted ones, so a weekend's band can be a
   little wider than its cards without a weekend day box being a different shape from a weekday
   one -- which is what made a geometry check report a 6px offset that never existed. */
.agenda-day {
  padding: var(--space-r3) var(--space-sm) 20px;
  margin-inline: -6px;
}

.agenda-day[data-weekend="true"] {
  background: color-mix(in srgb, var(--accent) 4%, transparent);
  border-radius: var(--card-radius);
}

/* Directly on the wallpaper, not a card -- two pieces (see renderAgendaDay's own
   headingLabel/headingDate spans), the label on the left and the full date pushed to the
   far right, the reference's own gp-day-heading shape. */
.agenda-day-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
  margin: 0 0 var(--space-xl);
  padding-top: var(--space-md);
  color: var(--ink-on-wallpaper);
  text-shadow: var(--text-shadow-on-wall);
  font-size: var(--text-detail-title);
  font-weight: var(--w-display);
}

.agenda-day-heading-date {
  flex: none;
  color: var(--muted-on-wallpaper);
  font-size: var(--text-detail-meta);
  font-weight: var(--w-body);
}

/* Today's heading is NOT the accent, and that is rule 01 doing its job: the scrolling agenda
   is one region and it already spends its single accent on the Now line, which is the thing a
   person is actually looking for. Three accent marks for "today" in one viewport -- this
   heading, the week strip's today ring, and the Now line -- is what the restyle was called to
   fix.

   Nothing is lost by making it neutral, because the state was never carried by colour alone
   (rule 07): the heading's own text begins with the word "Today", the strip highlights the
   day, and the Now line sits inside this group. A reader eight feet away who cannot tell the
   accent from any other dark colour still reads the word. */
.agenda-day[data-agenda-today="true"] .agenda-day-heading {
  color: var(--ink-on-wallpaper);
}

/* Focused programmatically after a strip tap or Today, unlike .agenda-title this is a
   useful landing cue, so keep a quiet ring rather than suppressing it outright. */
.agenda-day-heading:focus {
  outline: none;
}

.agenda-day-heading:focus-visible {
  outline: 2px solid var(--muted-on-wallpaper);
  outline-offset: 2px;
}

.agenda-allday-group {
  margin-bottom: var(--card-gap);
}

/* Compact label in the row's own rail, not a section banner: an all-day title now aligns
   on the same x as every other row's title. The word itself is .app-key text now (see
   renderAgendaEventRow in agenda.js, and .agenda-event-time.agenda-allday-label .app-key's
   own size below) -- this rule only carries what the wrapper still owns. */
.agenda-allday-label {
  letter-spacing: 0.02em;
  white-space: normal;
}

/* Directly on the wallpaper, not a card -- these three quiet buttons (this one, the
   earlier-today disclosure below, and .agenda-completed-toggle further down) sit as
   siblings of the day's own cards rather than inside one, so the shared .app-quiet-button
   ink (tuned for a card ground) needs the on-wall pair instead. */
.agenda-allday-more {
  align-self: flex-start;
  color: var(--ink-on-wall-muted);
  text-shadow: var(--text-shadow-on-wall);
}

.agenda-earlier {
  display: flex;
  flex-direction: column;
  margin-bottom: var(--card-gap);
}

/* A collapsed Earlier today that ends the day must not leave a blank band before the next
   heading: the group's own bottom margin goes away whenever it is the day's last content,
   and the day's 20px of bottom padding goes away too -- but only while the disclosure is
   collapsed, because only then is there nothing under the toggle to separate from what
   follows. The next day's own 0.75rem top padding plus its heading's 8px padding-top still
   leave a 20px gap between the toggle and that heading, the same section gap a day with no
   earlier group already has before it. Expanded, the list is the day's real content again
   and the day keeps its bottom padding (only the group margin stays dropped, since the
   padding itself now provides that separation). */
.agenda-earlier:last-child {
  margin-bottom: 0;
}

.agenda-day:has(> .agenda-earlier:last-child > .agenda-earlier-toggle[aria-expanded="false"]) {
  padding-bottom: 0;
}

/* The reference's own <summary> reads at 12px with a native disclosure triangle beside it
   (see .gp-earlier); a plain button draws neither on its own, so both are stated here --
   --text-caption for the size, and .agenda-earlier-chevron below for the shape a screenshot
   review found missing entirely. --touch-min, not the shared quiet-button's own 32px floor:
   a disclosure that hides or reveals a whole group of events is worth the app's full resting
   target, the same call .app-primary-button's own comment makes for an "intentional action". */
.agenda-earlier-toggle {
  display: inline-flex;
  align-self: flex-end;
  align-items: center;
  gap: 0.3rem;
  min-height: var(--touch-min);
  color: var(--ink-on-wall-muted);
  text-shadow: var(--text-shadow-on-wall);
  font-size: var(--text-caption);
}

.agenda-earlier-chevron {
  display: flex;
  flex: none;
  align-items: center;
}

.agenda-earlier-chevron svg {
  width: 12px;
  height: 12px;
  stroke-width: 2.5;
}

/* The one place in the pane the accent earns a label rather than just a rule: "now" is a
   fact about the whole day, not a datum inside one row, so it reads at the same
   var(--w-display) the ladder wires everywhere else -- the W4 slice that wired up
   the ladder points this at the token like every other weight in the file. Sentence case,
   not the tracked all-caps a shorter word could afford -- agenda.js's own label already
   spells the time out in full ("Now · 11:37 AM"), and forcing that upper-case read as a
   clipped "11:37 AM" missing its trailing M in a screenshot review. */
.agenda-now-marker {
  display: flex;
  align-items: center;
  min-height: var(--label-row-min);
  gap: 0.4rem;
  margin: var(--space-md) 0;
  color: var(--ink-on-wallpaper);
  font-size: var(--text-detail-meta);
  font-weight: var(--w-display);
  text-shadow: var(--text-shadow-on-wall);
}

.agenda-now-marker::before {
  content: '';
  flex: 1 1 auto;
  height: 1px;
  background: var(--now-ink);
}

/* Earlier, expanded: one plain list of what is done or passed -- a single card
   (.app-card) of single-line rows split by hairlines (.app-divider-list), never the gaps or
   spacing of the timeline. */
.agenda-earlier-list[hidden] {
  display: none;
}

.agenda-earlier-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-r2);
  padding: var(--space-r1) 0;
  font-size: var(--text-detail-body);
}

.agenda-earlier-time {
  flex: none;
  color: var(--muted);
  font-size: var(--text-detail-meta);
  font-variant-numeric: tabular-nums;
}

.agenda-earlier-title {
  flex: 1 1 0;
  min-width: 0;
  margin: 0;
  overflow-wrap: break-word;
  white-space: normal;
}

.agenda-earlier-check {
  display: flex;
  flex: none;
  color: var(--muted);
}

.agenda-earlier-list > .agenda-now-marker {
  /* The Earlier list is an .app-divider-list; the now-marker is a line, not an entry, so it
     takes no hairline of its own. */
  border-top: 0;
  margin: var(--space-md) 0;
}

.agenda-timed-list {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.agenda-timed-list[hidden] {
  display: none;
}

/* Adjacent-sibling only: a row that instead follows a gap or the now-marker keeps that
   element's own computed spacing and gains nothing extra here. */
.agenda-timed-list > .agenda-event + .agenda-event,
.agenda-timed-list > .agenda-task + .agenda-event,
.agenda-timed-list > .agenda-event + .agenda-task,
.agenda-timed-list > .agenda-task + .agenda-task {
  margin-top: var(--card-gap);
}

/* A card belonging to exactly one person carries an ACCENT of that person's own saved
   colour, never a tinted or translucent background: the card is the one opaque surface
   between its content and the wallpaper (see .app-card's own comment above), and a wash
   mixed on top of it -- even at a calibrated few percent -- reads close enough to the
   wallpaper's own blue to look like the card had gone translucent, which is what a
   screenshot review actually caught here. The accent instead is a keyline on the card's
   own leading edge -- --keyline wide, solid --person-color -- with the card's own
   --card-pad-x reduced by that same width so the line adds no extra inset of its own.
   agenda.js decides *when* -- one person, and a colour that is actually saved -- and hands
   the colour over as --person-color; multi-person and unassigned cards match neither
   selector and stay exactly as they were, since a card has one keyline and choosing one of
   two people's colours would say something untrue -- their .person-dot chips still carry a
   colour each. The four-week grid's own compact chip keeps the calibrated wash this rule
   used to draw (see .agenda-chip[data-person-tint] below for those ΔE figures) -- a chip has
   no leading edge roomy enough for a keyline to read, and it is not the surface a screenshot
   review flagged. */
.agenda-event[data-person-tint] {
  border-left: var(--keyline) solid var(--person-color);
  padding-left: calc(var(--card-pad-x) - var(--keyline));
}

.agenda-event[data-person-tint]:hover {
  border-left-color: color-mix(in srgb, var(--person-color) 70%, var(--card-line));
}

.agenda-gap {
  /* Label rows between cards never drop below one line of their own text. */
  height: max(var(--agenda-gap-px, 0px), var(--label-row-min));
  display: flex;
  align-items: flex-end;
  padding-left: calc(var(--list-gutter) + var(--list-lead) + var(--list-lead-gap));
  overflow: hidden;
  color: var(--muted-on-wallpaper);
  text-shadow: var(--text-shadow-on-wall);
  font-size: var(--text-detail-meta);
}

.agenda-gap[hidden] {
  display: none;
}

/* Placement only: the card now supplies the padding, so the toggle's own copy of it
   would double up. */
.agenda-event-toggle,
.agenda-task-toggle {
  min-height: var(--touch-min);
  align-items: center;
  padding: 0;
  gap: var(--list-lead-gap);
  border-radius: 0;
}

/* A hover wash inside a card that already has its own bounded edge reads as a defect,
   not a cue -- the card itself takes the focus ring instead. */
.agenda-event-toggle:hover,
.agenda-event-toggle:focus-visible,
.agenda-task-toggle:hover,
.agenda-task-toggle:focus-visible {
  background: transparent;
}

.agenda-event-toggle:focus-visible,
.agenda-task-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

/* The rail: start time over its own AM/PM, never side by side -- a column is what keeps the
   rail at its fixed width instead of letting "7:30 PM" run wider than the time itself needs.
   An event's end time no longer lives here at all (see .agenda-event-meta's own "Until" text
   in agenda.js) -- two numbers stacked in one rail read as "2p over 3p", a pair of data
   points rather than one time and its unit. 58px, not --list-lead (76px): that token is sized
   for a single-line rail like "10:00 PM" written whole, but this one stacks the time over its
   own period on two lines, the same shape Today's own lead column uses at the same 58px
   -- wide enough for "12:30" on its own line without clipping, with nothing riding beside it
   that needs the extra 18px. A timed task carries no rail of its own any more (see
   .agenda-task-time-meta above): it takes the same checkbox-led shape the Tasks card gives
   every task, so only an event still reads this rule. */
/* Never the accent -- a time is a datum, not a selection, and this app has no other clock
   on a card to compete with (rule 02: times/dates/counts/durations are --muted,
   tabular-nums -- the platform face now, not a monospace one: see the styles.css header
   comment, "household labels read in the platform font"). */
.agenda-event-time {
  display: flex;
  flex: 0 0 58px;
  flex-direction: column;
  color: var(--muted);
  font-size: var(--text-detail-body);
  line-height: var(--leading-detail-tight);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* The same hierarchy as Today's lead column: the start time reads larger than the row's own body text
   (still .app-key's accent-tinted ink, not the full solid accent -- rule 02 reserves that for
   a press/selection), with its AM/PM beneath it a size down and quieter still. An all-day
   event's own "All day" word is this same .app-key span with no second line beneath it, so it
   takes the smaller size on its own -- the chained selector beats the plain one above on
   specificity, not on source order, so it holds regardless of where either rule is edited. */
.agenda-event-time .app-key {
  font-size: var(--text-section);
}

.agenda-event-time.agenda-allday-label .app-key {
  font-size: var(--text-caption);
}

.agenda-event-time-period {
  color: var(--muted);
  font-size: var(--text-caption);
  font-weight: var(--w-body);
}

.agenda-event-main {
  flex: 1 1 0;
  min-width: 0;
}

/* At Large on a phone the 58px rail cannot hold the time without clipping, and widening it
   would take the width the title needs. The row becomes one column instead: the time (with
   its period beside it) on top, the title and meta below at the card's full width. */
@media (max-width: 47.99rem) {
  :root[data-text-size="large"] .agenda-event-toggle {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.15rem;
  }

  :root[data-text-size="large"] .agenda-event-time {
    flex: none;
    flex-direction: row;
    align-items: baseline;
    gap: 0.3rem;
  }

  :root[data-text-size="large"] .agenda-event-main {
    flex: none;
    width: 100%;
  }
}

.agenda-event-detail {
  margin-top: var(--space-md);
}

.agenda-event-detail[hidden] {
  display: none;
}

.agenda-event-detail p {
  margin: 0 0 0.3rem;
}

.agenda-event-detail p:last-child {
  margin-bottom: 0;
}

/* The four-week grid: the wide-screen Calendar. The phone keeps the scrolling list of day
   sections above; #agenda-grid stands the same 28 dates a week strip used to index in seven
   weekday columns by four week rows, so a month of the household's plans is read at a glance
   instead of scrolled through. It stays hidden until agenda.js makes it the active layout,
   and everything below is the grid's own geometry -- the cells and chips inside it are built
   there and carry no measures of their own beyond these. */

.agenda-grid {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  gap: 0.2rem;
  padding-top: var(--space-r1);
}

/* For the same reason .agenda[hidden] needs one: display: flex above would otherwise beat
   the hidden attribute's own display: none. */
.agenda-grid[hidden] {
  display: none;
}

/* Today reads as a secondary action beside the title (see .app-top-button), pushed to the
   header's far edge the same way .app-page-header's own flex row already pushes a second
   title-line item -- margin-left: auto rather than a wrapper div, since the header's other
   panes already lay a title and a subtitle out as direct flex children of one row. */
#agenda-today {
  margin-left: auto;
}

#agenda-today[hidden] {
  display: none;
}

#agenda-view-toggle[hidden] {
  display: none;
}

/* The month label and the week-step chevrons that flank it, sharing the header's own
   subtitle row (an .app-page-header-subtitle composed onto a wrapping div, the same idiom
   a pane's own two-line subtitle uses) rather than the grid-only toolbar they used to sit
   in. The month label is reachable on every layout now; the chevrons show in the four-week
   grid and, in the narrow list layout, only for a fine pointer (see agenda.js's
   applyAgendaLayout) -- a mouse or keyboard has no swipe, where a touch phone pages the
   strip itself and keeps its header clear. The button sits in flow so it never shares pixels
   with #agenda-status. */
.agenda-subtitle-line {
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.5rem;
  line-height: 1.3;
}

.agenda-month-label {
  flex: 0 1 auto;
  min-width: 0;
  margin: 0;
  font-size: var(--text-caption);
}

/* The button sits in flow so it never shares pixels with #agenda-status. */
.agenda-week-step {
  display: grid;
  flex: none;
  place-items: center;
  width: var(--touch-min);
  min-height: var(--touch-min);
  padding: 0;
  color: inherit;
  background: transparent;
  border: 0;
  border-radius: var(--radius-control);
}

.agenda-week-step[hidden] {
  display: none;
}

.agenda-week-step svg {
  width: 17px;
  height: 17px;
  stroke-width: 1.8;
}

.agenda-week-step:hover,
.agenda-week-step:focus-visible {
  background: var(--top-button-ground);
}

.agenda-grid-weekdays {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  column-gap: var(--space-r1);
}

.agenda-grid-weekday {
  margin: 0;
  color: var(--muted);
  font-size: var(--text-detail-meta);
  font-weight: var(--w-title);
  letter-spacing: 0.05em;
  text-align: center;
  text-transform: uppercase;
}

.agenda-grid-weeks {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  grid-auto-rows: minmax(0, 1fr);
  gap: var(--space-r1);
  flex: 1;
  min-height: 0;
}

/* A week row is the role="row" wrapper accessibility needs, not a box the grid should see:
   display: contents leaves its seven cells as the grid's real items, one to a column. */
.agenda-week {
  display: contents;
}

.agenda-cell {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  padding: var(--space-sm);
  background: var(--panel-subtle);
  border: 1px solid var(--card-line);
  border-radius: var(--card-radius);
  text-align: left;
  cursor: pointer;
  transition: transform var(--motion-press) ease;
}

/* The one pressable card in the grid gets the same brief press feedback every other control
   does -- a past cell is excluded, the same guard its hover wash above uses, since it is
   inert and nothing should suggest a tap does anything. */
.agenda-cell:not([data-agenda-past]):active {
  transform: scale(0.98);
}

@media (prefers-reduced-motion: reduce) {
  .agenda-cell:active {
    transform: none;
  }
}

/* Every cell in the grid is the same opaque surface (--panel-subtle, the base rule above) --
   cards are equal, and a weekend column is not a second surface. This used to mix the accent
   4% into `transparent` rather than into the cell's own panel colour, which read as a
   translucent wash showing the wallpaper through it while the weekday cells beside it stayed
   solid. Nothing distinguishes a weekend cell now beyond what the date itself already says. */

/* Today's cell takes the accent the day heading takes in the list: the border says which
   box is today, and its date number says it again in the colour the heading uses. A soft
   accent ground, the same tint the tab bar's current display takes, says it a third way
   without turning the cell into a solid accent block. */
.agenda-cell[data-agenda-today="true"] {
  background: var(--accent-soft);
  border-color: var(--accent);
}

.agenda-cell[data-agenda-today="true"] .agenda-cell-day {
  color: var(--accent);
}

/* A date before today is inert rather than broken: the same dimmed date colour the strip's
   past days use, on the same --panel-subtle surface every other cell carries (the base rule
   above) -- a past cell used to sit on --panel instead, a different, lighter surface that
   read as a translucent wash beside the weekday cells around it. Muted text is the only cue
   a past day gets now; there is no pointer to invite a tap that does nothing. */
.agenda-cell[data-agenda-past="true"] {
  cursor: default;
}

.agenda-cell[data-agenda-past="true"] .agenda-cell-day {
  color: color-mix(in srgb, var(--muted) 55%, var(--page));
}

/* A quiet hover wash so a cell reads as the target it is: the same wash
   .agenda-event-toggle:hover gives a row in the base rule (var(--panel)), not the
   transparent override the agenda's own card rows take below -- a cell is the bounded box
   itself, not a row inside one. A past cell is excluded: it is inert, and a hover wash on
   it would invite a tap that does nothing. */
.agenda-cell:not([data-agenda-past]):hover {
  background: var(--panel);
}

/* The quiet ring the day heading keeps, drawn inside the cell: a positive offset would run
   into the grid gap and be clipped by the neighbours. */
.agenda-cell:focus {
  outline: none;
}

.agenda-cell:focus-visible {
  outline: 2px solid var(--muted);
  outline-offset: -2px;
}

/* A ring is a colour, and the date number underlining is the part of focus that is not:
   it names the day the keyboard is on even where the ring is thin. */
.agenda-cell:focus .agenda-cell-day {
  text-decoration: underline;
  text-underline-offset: 2px;
}

.agenda-cell-date {
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  flex: none;
}

.agenda-cell-day {
  font-size: var(--text-detail-body);
  font-weight: var(--w-title);
}

.agenda-cell-month {
  font-size: var(--text-detail-meta);
  font-weight: var(--w-title);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.agenda-cell-chips {
  /* The chip fit is measured against this box's clientHeight, so it has to *be* the space the date line leaves (flex: 1), not its own content's height. */
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.agenda-chip {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.3rem;
  min-width: 0;
  /* A touch more room than the 1px 4px this used to carry, so a two-line label breathes
     inside its clamp -- bought inside the existing +N more counting mechanism (a slightly
     taller chip means one fewer fits a cell, and the count says so), never by cutting a
     day's content quietly. */
  padding: var(--space-2xs) 5px;
  border-radius: var(--radius-control);
  background: var(--panel);
  font-size: var(--text-detail-meta);
  line-height: var(--leading-detail-tight);
}

/* fitAgendaGridChips (agenda.js) trims an overflowing chip by hiding it; display: flex
   above would otherwise beat the hidden attribute, the same trap .agenda-grid[hidden]
   exists for. */
.agenda-chip[hidden] {
  display: none;
}

.agenda-text {
  min-width: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  white-space: normal;
  word-break: normal;
  overflow-wrap: normal;
  text-overflow: ellipsis;
}

/* Single-line calendar cell text (the +N count) never clips: it shortens in agenda-3-grid.js
   instead of using an ellipsis. */
.agenda-cell-text {
  min-width: 0;
  white-space: nowrap;
  overflow: visible;
}

.agenda-chip-title {
  flex: 1 1 0;
  min-width: min(100%, 8ch);
  color: var(--ink);
}

/* A narrow grid's cell -- forced by AGENDA_FORCE_GRID or shown in landscape -- is too short for
   a two-line clamp to fit without the chip box clipping it; one line with an ellipsis is the
   same truncate-cleanly pattern the agenda cell's empty line uses. agenda.js sets
   body.agenda-grid-narrow for any grid narrower than the desktop width (see applyAgendaLayout). */
body.agenda-grid-narrow .agenda-text {
  -webkit-line-clamp: 1;
  line-clamp: 1;
}

/* Never the accent -- same rule the scrolling list's own rail keeps (rule 02). */
.agenda-chip-time {
  flex: none;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.agenda-chip-mark {
  flex: none;
  color: var(--muted);
}

/* The one place in the app that still washes a single person's colour across a whole
   surface rather than drawing a keyline: a compact grid chip has no leading edge roomy
   enough for a keyline to read at a glance, so it keeps the tint the scrolling list's own
   .agenda-event[data-person-tint] carried before that rule moved to a keyline (see its own
   comment).

   12% is calibrated, not guessed -- measured as the CIELAB ΔE of the mix against the base
   surface (weakest hue ΔE 7.0, strongest ΔE 9.7, resulting L* 94). The percentage rose from
   an old 8% because the palette's own chroma dropped: an old, highly saturated red read as
   a clear tint at 8%, but these hues are deliberately less saturated, so the same 8% reads
   weaker and needs a larger mix to hold the same perceived tint. The chip is still a
   white/near-white chip with a tint, not a coloured one -- L* holds at 94, so the title
   still stays --ink on a surface that reads as white at a glance. 16% (ΔE 9.5-12.6, L*
   91-92) was rejected for crossing into a coloured chip. Two or more people take no wash at
   all (see .agenda-chip[data-person-edge] below) -- a card/chip has one background, and
   blending several owners' colours into one tint would say something untrue about whose the
   event is. */
.agenda-chip[data-person-tint] {
  background: color-mix(in srgb, var(--person-color) 12%, var(--panel-subtle));
}

/* Two or more people: no per-person dot, no shared wash (blending several owners' colours
   into one tint would say something untrue about whose the event is -- the same reasoning
   the single-person wash rule above states). --person-edge is a hard-banded linear-gradient
   built in JS, one band per named colour; painted only 3px wide so it costs the chip no
   width a row of dots would have taken. */
.agenda-chip[data-person-edge] {
  background-image: var(--person-edge);
  background-repeat: no-repeat;
  background-position: left center;
  background-size: 3px 100%;
  padding-left: var(--space-md);
}

.agenda-chip-done .agenda-chip-title {
  text-decoration: line-through;
  color: var(--muted);
}

/* The count line is a <p>: without this reset its default margin pushes the count out of
   the cell it is counting for. */
.agenda-cell-more {
  margin: 0;
  flex: none;
  color: var(--muted);
  font-size: var(--text-detail-meta);
  font-weight: var(--w-title);
}

/* The ordinary (non-wall) grid layout's own Today panel: not body.wall's own
   #agenda-wall-today below, which has its own geometry, its own width variable and its own
   tightened type -- this one is a plain flex column of the grid's own ordinary
   --text-detail-* type by default (the forced-narrow kiosk's stacked shape), and only
   becomes a side column at the desktop breakpoint (see the body:not(.wall) rule inside the
   desktop media block further down, scoped away from the wall so its own #agenda
   grid-template-columns is never touched by this). */
/* flex: none, not the default auto: .agenda-grid-weeks beside this takes flex: 1 and would
   otherwise claim the panel's own space too under any height pressure, shrinking it toward
   zero while its un-clipped content kept painting at full size -- a real headless-Chromium
   screenshot at 390x844 (?agendaGrid=1) caught exactly that: the Tasks heading rendered on
   top of the Events list instead of below it. flex: none keeps this box at the height its
   own content (bounded below) actually asks for, so the two never compete for the same
   pixels again. */
.agenda-today-panel {
  display: flex;
  flex-direction: column;
  flex: none;
  min-height: 0;
  gap: 0.4rem;
}

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

/* The stacked Today panel would take the short landscape viewport's height from the weeks. */
body.agenda-grid-landscape .agenda-today-panel {
  display: none;
}

/* Stacked below the weeks (the default, and the forced-narrow kiosk's own shape): bounded
   rather than left to grow with however many entries today holds, so a dense today cannot
   push the grid itself out of the viewport the way an uncapped panel would. Scrolls its own
   overflow instead of clipping it silently. vh, not a parent-relative %: this box's own
   parent (.agenda-today-panel) sizes to its content (flex: none, no explicit height), and a
   percentage height against a parent with no definite height of its own computes to none per
   the CSS spec -- the max-height silently did nothing at all until this changed, which is
   what let the overflow above happen in the first place. Reset to a full column's height at
   the desktop breakpoint below, where the panel sits beside the grid instead of under it. */
.agenda-today-panel-body {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  max-height: 35vh;
  min-height: 0;
  overflow-y: auto;
}

.agenda-today-panel-title {
  flex: none;
  margin: 0;
  color: var(--ink-heading);
  text-shadow: var(--text-shadow-on-wall);
  font-size: var(--text-detail-title);
  font-weight: var(--w-title);
}

/* A shrunk section paints over its neighbour while the body scrolls. */
.agenda-today-panel-section {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-height: 0;
}

.agenda-today-panel-list {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-height: 0;
}

/* The day dialog reuses a whole day section, whose 20px of bottom padding is the gap
   between one day and the next in the scrolling list; here there is no next day, and
   .app-dialog-body already carries the scroll. */
.agenda-day-body .agenda-day {
  padding-bottom: 0;
}

/* A short viewport leaves the day list a sliver between the header and the dock, so the
   whole Calendar pane scrolls as one column instead and the day list keeps a readable height.
   The landscape month grid is exempt because it fills the pane height itself and the pane must not scroll under the composer. */
@media (max-height: 36rem) {
  body:not(.wall):not(.agenda-grid-landscape) .agenda {
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  body:not(.wall):not(.agenda-grid-landscape) .agenda > * {
    flex-shrink: 0;
  }

  body:not(.wall):not(.agenda-grid-landscape) .agenda-days {
    flex: none;
    height: 16rem;
  }
}

/* The landscape month grid fits the pane height: the header is one row (title, month nav, buttons)
   so the week rows keep the space, and fitAgendaGridChips trims what a short row cannot hold.
   Cells trade padding and line height for the room one chip needs. */
body.agenda-grid-landscape .agenda .app-page-header { flex-wrap: nowrap; padding-block: 0.5rem; }
body.agenda-grid-landscape .agenda-title { flex: 0 0 auto; }
body.agenda-grid-landscape .agenda-subtitle-line { flex: 1 1 auto; margin-top: 0; margin-right: auto; }
body.agenda-grid-landscape .agenda .app-page-header > :is(button, select) { order: 2; }
body.agenda-grid-landscape #agenda-today { margin-left: 0; }
body.agenda-grid-landscape .agenda-grid { padding-top: 0; }
body.agenda-grid-landscape .agenda-cell { padding: var(--space-2xs); gap: 0; }
body.agenda-grid-landscape .agenda-chip { padding-inline: 3px; gap: 0.15rem; font-size: var(--text-caption); }
body.agenda-grid-landscape .agenda-cell-day { line-height: var(--leading-detail-tight); }
