/* ==========================================================================
   GRUMLAW — CALENDAR
   Page stylesheet for calendar.html. Loads after components.css and uses the
   same tokens as everything else, so light and dark come for free.

   Two views, one row component. The month grid and the list are different
   ways of arranging the SAME .calrow, which is why selecting a day can drop
   real event rows under the grid without a second card design existing.
   ========================================================================== */

.cal {
  /* Kind is carried as a colour on a dot and a chip edge, never as a filled
     background: three filled colours in a 42-cell grid reads as a heat map of
     something, and there is nothing here to be hot about. */
  --cal-service: var(--gl-sage-600);
  --cal-prayer:  #A87C3D;
  --cal-event:   var(--gl-stone-600);
  --cal-hair:    var(--border-subtle);
}
[data-theme="dark"] .cal {
  --cal-service: var(--gl-sage-400);
  --cal-prayer:  #D6A863;
  --cal-event:   var(--gl-stone-400);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) .cal {
    --cal-service: var(--gl-sage-400);
    --cal-prayer:  #D6A863;
    --cal-event:   var(--gl-stone-400);
  }
}

.cal__panel[hidden] { display: none; }

/* --------------------------------------------------------------------------
   WIDTH — the two views want different ones
   -------------------------------------------------------------------------- */
/* --container is 2200px, which is right for a page of photographs and wrong
   for both of these. A seven-column grid stretched to 2136px gives 300px
   cells carrying a 60px chip, and a list row stretched to the same width puts
   the date on one side of the screen and the Add buttons on the other.

   The narrow cap is the DEFAULT rather than the list-view override, because
   with scripting off there is no [data-view] at all and the list is what
   renders. Month view then opts into the wider one. */
/* The hero already introduced the page a moment ago, so the calendar does not
   need a full section gap above it as well — between the two paddings the
   first row of dates was starting a screen and a half down on a phone. */
.cal { padding-top: var(--section-y-tight); }

.cal > .container { max-width: calc(var(--measure-list) + var(--gutter) * 2); }
.cal[data-view="month"] > .container { max-width: 84rem; }


/* --------------------------------------------------------------------------
   THE HEADER, SOLID — calendar.html only
   -------------------------------------------------------------------------- */
/* The site header is glass: a scrim that starts at 0.86 alpha and fades to
   nothing by its bottom edge, over a progressive blur whose tail runs 2.5rem
   PAST it. Everywhere else that reads as depth, because what slides underneath
   is photography and long copy.

   It does not survive a second sticky bar. The month heading parks at the
   header's bottom edge and is opaque, so the two meet as a half-transparent
   gradient with rows visibly sliding through it, cut off by a hard edge — and
   the blur's tail, which is supposed to land on nothing, lands on the month
   bar instead. Rows appear to swim under the chrome and then vanish.

   So on this page the header goes solid — but only once there is something
   underneath it to hide. At rest the glass is exactly right and nothing is
   passing beneath it anyway, so [data-scrolled] is the whole condition.
   `.header` already transitions background-color over --dur-normal, so the
   two states cross-fade rather than snap.

   Two things this must NOT do, both learned the hard way:

   - It must not paint while the mobile menu is open. The drawer reveals itself
     by fading .header__blur and .header__scrim to zero, and relies on the
     header having no background of its own — an unconditional background sits
     on top of the open menu. Hence the :not().
   - It must not hide the blur and the scrim. Both sit at `z-index: -1`, behind
     the header's own background, so an opaque background already covers them.
     `display: none` bought nothing and took away the only lever the drawer has.

   This stylesheet loads on calendar.html and nowhere else, which is what keeps
   the override page-local. The [data-scrolled] hairline is left alone — against
   a solid header it is the divider the glass used to imply. */
.header[data-scrolled="true"]:not([data-drawer-open="true"]) {
  background-color: var(--surface-page);
}

/* --------------------------------------------------------------------------
   HERO — smaller than the standard page hero
   -------------------------------------------------------------------------- */
/* The shared .page-hero is built for a landing page: a display line at up to
   3.5rem with 4rem of air above it. On a page whose whole job is a dense grid
   of dates, that pushed the first row of the calendar below the fold and made
   the title the loudest thing on a screen it is not the subject of. The rise
   treatment stays — it is the site's hero signature and every other page has
   it — it just runs at about two thirds the size, over tighter padding. The
   GL watermark is sized as a fraction of the hero, so it shrinks along with
   this rather than needing its own rule. */
.cal-hero { padding-block: var(--space-xl) var(--space-md); }
.cal-hero__title { font-size: clamp(1.75rem, 1.1rem + 2.2vw, 2.5rem); }
.cal-hero__lead { font-size: var(--text-base); }

/* --------------------------------------------------------------------------
   BAR — month stepper on the left, view toggle on the right
   -------------------------------------------------------------------------- */
.cal__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm) var(--space-md);
  margin-bottom: var(--space-md);
}

/* The stepper is meaningless in list view and is hidden there rather than
   disabled: a control that cannot do anything is better absent than greyed. */
.cal__nav { display: flex; align-items: center; gap: var(--space-3xs); }
.cal[data-view="list"] .cal__nav { display: none; }

.cal__step {
  display: inline-grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  color: var(--text-secondary);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.cal__step:hover {
  background: var(--surface-hover);
  color: var(--text-primary);
  border-color: var(--border-default);
}
.cal__step:focus-visible {
  outline: var(--border-width-thick) solid var(--focus-ring);
  outline-offset: 2px;
}
.cal__stepicon { width: 1.125rem; height: 1.125rem; }

/* Tabular figures so the label does not change width between "1" and "11",
   which otherwise nudges both arrows sideways as you page through months. */
.cal__month {
  min-width: 11ch;
  margin: 0;
  text-align: center;
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-ui);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

.cal__today {
  margin-left: var(--space-2xs);
  padding: 0.4rem 0.85rem;
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.cal__today:hover { background: var(--surface-hover); color: var(--text-primary); }
.cal__today:focus-visible {
  outline: var(--border-width-thick) solid var(--focus-ring);
  outline-offset: 2px;
}

/* Both views exist in the markup and the toggle is the only way to reach the
   grid, so with scripting off the toggle would be a control that lies. It is
   revealed by the same attribute that reveals the grid. */
.cal__views { display: none; }
.cal[data-cal-ready] .cal__views { display: inline-flex; }

/* On a phone the row does not fit side by side, and wrapping left the toggle
   hanging off the left edge under a stepper that had already used the width.
   Stacked instead: the view toggle centred on its own line, the month stepper
   and Today below it as two groups pushed to opposite edges.

   `order` moves the toggle up rather than the markup, so the DOM keeps the
   reading order the desktop layout has — stepper, then toggle. The two are
   adjacent, individually labelled controls, which is where a visual/DOM order
   difference costs least; reordering the markup would only move the same
   mismatch onto the desktop layout instead. */
@media (max-width: 47.99rem) {
  .cal__bar {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-sm);
  }
  .cal__views {
    order: -1;
    align-self: center;
  }
  .cal__nav { gap: var(--space-2xs); }
  /* Today to the far edge. `space-between` on the row would have spread the
     stepper's own three parts apart with it, which is the opposite of the
     grouping being asked for. */
  .cal__today { margin-left: auto; }

  /* margin-left:auto can only hand over the width that is left, and at 375px
     the stepper was using 231 of 311 — which left 12px between the next arrow
     and Today, close enough to read as one control. The gap has to come from
     the stepper itself: a size down on the label and 4px off each button free
     about 33px, which is the difference between two groups and one row of
     buttons. The month is still comfortably the largest thing in the bar. */
  .cal__month { font-size: 1.25rem; }
  .cal__step { width: 2.25rem; height: 2.25rem; }
  .cal__stepicon { width: 1rem; height: 1rem; }
}

/* --------------------------------------------------------------------------
   MONTH GRID
   -------------------------------------------------------------------------- */
.cal__dows,
.cal__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 1px;
}
.cal__dows {
  margin: 0 0 var(--space-2xs);
  padding: 0;
  list-style: none;
}
.cal__dow {
  padding-bottom: var(--space-3xs);
  text-align: center;
  font-family: var(--font-condensed);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
}
.cal__dow abbr { text-decoration: none; border: 0; }

/* The hairlines are the 1px grid gap with the card's colour showing through,
   and the outer edge is a ring rather than a border — a border would make the
   grid 2px wider than the weekday row above it and the two would not line up.
   */
.cal__grid {
  background: var(--cal-hair);
  border-radius: var(--radius-md);
  box-shadow: 0 0 0 1px var(--cal-hair);
  overflow: hidden;
}

.cal__cell {
  display: flex;
  flex-direction: column;
  /* The number is a filled pill on today and on the selected day, and the
     first chip has a fill of its own, so 2px between them read as the two
     shapes touching. The gap is set by what the cell looks like at its
     busiest, not by what it looks like empty. */
  gap: 6px;
  min-height: 6.75rem;
  padding: var(--space-3xs);
  border: 0;
  border-radius: 0;
  background: var(--surface-page);
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.cal__cell:hover { background: var(--surface-hover); }
.cal__cell:focus-visible {
  outline: var(--border-width-thick) solid var(--focus-ring);
  outline-offset: -3px;
  z-index: 1;
}
/* Days belonging to the neighbouring months. Present, because a week that
   stops mid-row is harder to read than one that runs on, but recessive. */
.cal__cell[data-out] { background: var(--surface-sunken); }
.cal__cell[data-out] .cal__num { color: var(--text-muted); }
.cal__cell[data-out]:hover { background: var(--surface-active); }

.cal__num {
  display: inline-grid;
  place-items: center;
  /* A flex child in a column stretches to the cell's full width by default,
     which centres the numeral under it. The number belongs in the corner on
     desktop and under the dots on a phone, so it is pinned in both places
     rather than left to the container's alignment. */
  align-self: flex-start;
  min-width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}
.cal__cell[data-today] .cal__num {
  background: var(--surface-accent);
  color: var(--text-on-accent);
  font-weight: var(--weight-bold);
}
.cal__cell[aria-pressed="true"] {
  background: var(--surface-accent-subtle);
}
.cal__cell[aria-pressed="true"] .cal__num {
  box-shadow: 0 0 0 2px var(--border-accent);
}
.cal__cell[data-today][aria-pressed="true"] .cal__num { box-shadow: none; }

/* --- chips (desktop) ---------------------------------------------------- */
.cal__chips {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
  min-width: 0;
}
.cal__chip {
  display: flex;
  align-items: baseline;
  gap: 5px;
  padding: 3px 6px;
  border-radius: var(--radius-xs);
  background: var(--surface-sunken);
  border-left: 2px solid var(--chip, var(--cal-event));
  font-size: var(--text-2xs);
  line-height: 1.35;
  color: var(--text-secondary);
  overflow: hidden;
}
.cal__chip[data-kind="service"] { --chip: var(--cal-service); }
.cal__chip[data-kind="prayer"]  { --chip: var(--cal-prayer); }
.cal__chip[data-kind="event"]   { --chip: var(--cal-event); }

.cal__chiptime {
  flex: none;
  font-family: var(--font-condensed);
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}
.cal__chiptitle {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: var(--weight-medium);
  color: var(--text-primary);
}
.cal__more {
  padding: 1px 6px;
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  color: var(--text-muted);
}

/* --- dots (mobile) ------------------------------------------------------- */
.cal__dots { display: none; gap: 3px; min-height: 5px; }
.cal__dot {
  width: 5px;
  height: 5px;
  border-radius: var(--radius-pill);
  background: var(--dot, var(--cal-event));
}
.cal__dot[data-kind="service"] { --dot: var(--cal-service); }
.cal__dot[data-kind="prayer"]  { --dot: var(--cal-prayer); }
.cal__dot[data-kind="event"]   { --dot: var(--cal-event); }

/* Under 40rem the cell is roughly a thumb wide, which is not enough for a
   title at any size that is still readable. So the grid stops trying to say
   WHAT is on and only says THAT something is — the day panel below carries
   the detail, one tap away. This is the phone calendar pattern because it is
   the only one that fits. */
@media (max-width: 47.99rem) {
  /* --gutter is a constant 32px at every breakpoint, which is right for text
     and wrong for a seven-column grid on a 375px screen: it leaves 311px, and
     a 44px cell needs 314. Rather than move the gutter for the whole site,
     the grid steps out of it and keeps a 16px edge — the margin a phone
     calendar has anyway. Both rows move together or they stop lining up. */
  .cal__dows,
  .cal__grid {
    margin-inline: calc(var(--space-sm) - var(--gutter));
  }
  .cal__cell {
    min-height: 0;
    aspect-ratio: 1;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 2px;
  }
  .cal__chips, .cal__more { display: none; }
  .cal__dots { display: flex; }
  .cal__num { align-self: center; font-size: var(--text-base); }
}

/* --------------------------------------------------------------------------
   DAY PANEL — what the selected cell is showing
   -------------------------------------------------------------------------- */
.cal__detail {
  margin-top: var(--space-md);
  padding-top: var(--space-md);
  border-top: var(--border-width) solid var(--border-subtle);
}
.cal__detail[hidden] { display: none; }

/* Below the sidebar breakpoint an unselected day has nothing to say, so the
   panel is simply not there. Above it the column is permanent and this is the
   state that fills it. */
.cal[data-detail="empty"] .cal__detail { display: none; }

.cal__prompt {
  margin: 0;
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  color: var(--text-muted);
}

/* The panel's heading already names the day, so the per-row date rail is
   repeating it — in a 17rem column that is a third of the width spent saying
   the same thing twice. The row collapses to one column here. */
.cal__detail .calrow__rail { display: none; }
.cal__detail .calrow {
  grid-template-columns: minmax(0, 1fr);
  padding: var(--space-md) 0;
}
.cal__detail .calrow:first-child { padding-top: 0; }
.cal__detail .calrow__add { grid-column: 1; }
/* Everything in a narrow column competes for the same eye, so the title steps
   down to body size — the day numeral above is doing the leading now — and the
   "Add to" eyebrow goes. Two buttons labelled Google and Apple / Outlook do
   not need a caption telling you they add things. */
.cal__detail .calrow__title { font-size: var(--text-base); }
.cal__detail .calrow__addlabel { display: none; }
/* The panel is already about one named day, and the grid beside it marks today
   with a sage pill on the date itself. A third TODAY, in the heaviest colour
   on the page, sitting next to the only title in a 17rem column, was the
   loudest thing in the panel and the least informative. */
.cal__detail .calrow__now { display: none; }
.cal__detail .calrow__add { margin-top: var(--space-xs); }
/* Weekday over day number, with Close held on the weekday's line so the
   numeral has the column to itself. */
.cal__detailtop {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--space-2xs);
  margin-bottom: var(--space-md);
}
.cal__detailhead { margin: 0; }
/* Set exactly like .cal__dow, because on a wide screen it sits on that row and
   the two should read as the same kind of label. */
.cal__detaildow {
  display: block;
  padding-bottom: var(--space-3xs);
  font-family: var(--font-condensed);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
}
.cal__detailnum {
  display: block;
  font-family: var(--font-condensed);
  font-size: 2.75rem;
  font-weight: var(--weight-bold);
  line-height: 0.9;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}
.cal__detailclose {
  flex: none;
  padding: 0.25rem 0.6rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  cursor: pointer;
}
.cal__detailclose:hover { color: var(--text-primary); background: var(--surface-hover); }
.cal__detailclose:focus-visible {
  outline: var(--border-width-thick) solid var(--focus-ring);
  outline-offset: 2px;
}
.cal__detail .calgroup__rows { border-top: 0; }
.cal__detail .calrow:first-child { border-top: 0; }

.cal__more-note {
  margin: var(--space-xl) 0 0;
  padding-top: var(--space-md);
  border-top: var(--border-width) solid var(--border-subtle);
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.cal__jump {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--text-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.cal__jump:focus-visible {
  outline: var(--border-width-thick) solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

.cal__empty, .cal__none {
  margin: 0;
  padding: var(--space-md) 0;
  color: var(--text-secondary);
}

/* --------------------------------------------------------------------------
   DAY PANEL AS A SIDEBAR — wide screens only
   -------------------------------------------------------------------------- */
/* Below the grid, the selected day sits under six rows of dates and is off the
   bottom of the screen on the click that opened it. Beside the grid it is in
   view the whole time, which is the point of selecting a day at all.

   80rem rather than the 64rem the rest of the site uses for "desktop": the
   column costs 17rem, and taking that from a 1024px layout leaves cells too
   narrow for a chip to say anything. Between 48rem and 80rem the panel stays
   where it was, underneath. */
@media (min-width: 80rem) {
  .cal__panel[data-cal-panel="month"] {
    display: grid;
    grid-template-columns: 17rem minmax(0, 1fr);
    grid-template-areas:
      "detail dows"
      "detail grid";
    column-gap: var(--space-lg);
    /* Or the column stretches to the grid's height and the sticky offset
       inside it has nothing to travel against. */
    align-items: start;
  }
  .cal__dows   { grid-area: dows; }
  .cal__grid   { grid-area: grid; }
  .cal__detail {
    grid-area: detail;
    /* The rule and the space above it belonged to the stacked layout — here
       the column edge is the separation. */
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
    position: sticky;
    top: calc(var(--header-h) + var(--space-md));
  }
  /* Permanent: see .cal__prompt. */
  .cal[data-detail="empty"] .cal__detail { display: block; }

  /* A permanent column has nothing to close back to, and a Close button on a
     panel that is always there is a control that only ever makes the page
     worse. Selecting another day is the way out. It stays on narrow screens,
     where the panel really is a disclosure below the grid. */
  .cal__detailclose { display: none; }
}

/* --------------------------------------------------------------------------
   LIST
   -------------------------------------------------------------------------- */
.calgroup + .calgroup { margin-top: var(--space-xl); }

/* Sticky, because the month is the one piece of context you lose as soon as
   you start scrolling a list of bare day numbers. Offset by the header so it
   parks under it rather than behind it. */
.calgroup__head {
  position: sticky;
  top: calc(var(--header-h) - 1px);
  z-index: 2;
  display: flex;
  align-items: baseline;
  gap: 0.4em;
  margin: 0;
  padding: var(--space-2xs) 0;
  background: var(--surface-page);
  border-bottom: var(--border-width) solid var(--border-subtle);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-ui);
  color: var(--text-primary);
}
.calgroup__year {
  font-family: var(--font-condensed);
  font-size: var(--text-base);
  font-weight: var(--weight-normal);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.calgroup__rows { margin: 0; padding: 0; list-style: none; }

.calrow {
  display: grid;
  grid-template-columns: 3.25rem minmax(0, 1fr);
  gap: var(--space-3xs) var(--space-sm);
  padding: var(--space-sm) 0;
  border-bottom: var(--border-width) solid var(--border-subtle);
}
.calrow:last-child { border-bottom: 0; }

/* The rail is the date, set in the condensed face and sized like a number
   rather than like text — it is the thing the eye jumps between when scanning
   a month, so it gets to be the biggest thing in the row after the title. */
.calrow__rail {
  grid-row: span 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 2px;
  font-family: var(--font-condensed);
  line-height: 1;
}
.calrow__dow {
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
}
.calrow__day {
  font-size: 1.75rem;
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

.calrow__body { min-width: 0; }
.calrow__title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin: 0 0 2px;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-ui);
  line-height: var(--leading-snug);
}
.calrow__link { color: var(--text-primary); text-decoration: none; }
.calrow__link:hover { text-decoration: underline; text-underline-offset: 3px; }
.calrow__link:focus-visible {
  outline: var(--border-width-thick) solid var(--focus-ring);
  outline-offset: 3px;
  border-radius: var(--radius-xs);
}
.calrow__now {
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--surface-accent);
  color: var(--text-on-accent);
  font-family: var(--font-condensed);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}
.calrow__meta {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.calrow__blurb {
  margin: var(--space-3xs) 0 0;
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  color: var(--text-muted);
}

/* --- add to calendar ----------------------------------------------------- */
.calrow__add {
  grid-column: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs);
  margin-top: var(--space-2xs);
}
.calrow__addlabel {
  font-family: var(--font-condensed);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
}
.calbtn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.3rem 0.7rem;
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  color: var(--text-secondary);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.calbtn:hover {
  background: var(--surface-hover);
  color: var(--text-primary);
  border-color: var(--border-default);
}
.calbtn:focus-visible {
  outline: var(--border-width-thick) solid var(--focus-ring);
  outline-offset: 2px;
}
.calbtn__icon { width: 0.875rem; height: 0.875rem; }

/* Downloading a generated file is the one control on this page that cannot
   work without scripting, so it stays out of the document until it can. */
.calbtn--ics { display: none; }
[data-cal-ready] .calbtn--ics { display: inline-flex; }

@media (max-width: 39.99rem) {
  .calrow { grid-template-columns: 2.75rem minmax(0, 1fr); }
  .calrow__day { font-size: 1.5rem; }
  .calrow__title { font-size: var(--text-base); }
}

/* --------------------------------------------------------------------------
   SUBSCRIBE
   -------------------------------------------------------------------------- */
/* .section-head--center caps its children at 20ch so a two-line display
   heading breaks where it was written to break. That cap is meant for the
   heading; inherited by a paragraph it produces a column of five words. The
   heading keeps the cap, the lead gets a reading measure. */
[data-cal-sync] .section-head--center > .lead { max-width: 46ch; }

.syncs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--space-sm);
  margin: var(--space-lg) 0 0;
  padding: 0;
  list-style: none;
}
.sync {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding: var(--space-md);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
}
.sync__title {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-ui);
  color: var(--text-primary);
}
.sync__body {
  margin: 0;
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  color: var(--text-secondary);
}
.sync__btn { margin-top: auto; align-self: flex-start; }

.sync__url { margin-top: var(--space-lg); }
.sync__urllabel {
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-condensed);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
}
.copyfield {
  display: flex;
  align-items: stretch;
  gap: var(--space-2xs);
  padding: var(--space-3xs) var(--space-3xs) var(--space-3xs) var(--space-xs);
  border: var(--border-width) solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
}
/* The URL is the point of the field, so it never truncates to an ellipsis on
   a phone — it scrolls, and the whole thing can still be selected by hand if
   the copy button is not what somebody wants to use. */
.copyfield__value {
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  align-self: center;
  white-space: nowrap;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  scrollbar-width: none;
}
.copyfield__value::-webkit-scrollbar { display: none; }
.copyfield__btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.45rem 0.9rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--surface-sunken);
  color: var(--text-primary);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.copyfield__btn:hover { background: var(--surface-active); }
.copyfield__btn:focus-visible {
  outline: var(--border-width-thick) solid var(--focus-ring);
  outline-offset: 2px;
}
.copyfield__btn[data-copied] { background: var(--surface-accent); color: var(--text-on-accent); }
.copyfield__icon { width: 0.9375rem; height: 0.9375rem; }

.sync__note {
  margin: var(--space-sm) 0 0;
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  color: var(--text-muted);
}
.sync__note a { color: inherit; }

@media (prefers-reduced-motion: reduce) {
  .cal__cell, .cal__step, .cal__today, .calbtn, .copyfield__btn { transition: none; }
}
