/* ============================================================================
   Calendar page — /Calendar
   ============================================================================
   Migrated out of a 425-line inline <style> block in Pages/Calendar/Index.cshtml.

   Fourth page with the now-familiar shape: a `calendar-` component vocabulary on
   a private token block with one hardcoded hue (--cal-blue #0369a1) plus its own
   copy of the neutral grey ramp. Everything is --ac-* now.

   THE FULLCALENDAR BRIDGE IS THE POINT OF THIS FILE
   -------------------------------------------------
   The original fought FullCalendar with ~40 `.fc ...` override rules, restating
   its borders, header cells, buttons, today highlight and list view one at a
   time. Unnecessary: FullCalendar 6 is itself CSS-variable driven and exposes 30
   `--fc-*` custom properties. Bridging those onto our tokens themes the whole
   widget — including the internals nobody had thought to override — and most of
   the old rules simply deleted.

   Order works in our favour, deliberately on FullCalendar's part: v6 injects its
   stylesheet at runtime with
       head.insertBefore(style, head.querySelector('script,link[rel=stylesheet],…'))
   so its `:root` defaults land FIRST in <head>, before every one of our
   stylesheets. Ours therefore win. Do not "fix" this by adding !important.

   ALSO FIXED: Pages/Calendar/Index.cshtml linked
       fullcalendar@6.1.8/index.global.min.css
   which is a 404 — that file does not exist in v6, because v6 ships its CSS
   inside the JS bundle. Every calendar page view was making a failing request.
   ============================================================================ */

:root {
    /* Pass-throughs to the theme brand. */
    --cal-accent: var(--ac-brand);
    --cal-accent-hover: var(--ac-brand-hover);
    --cal-accent-subtle: var(--ac-brand-soft);
    --cal-on-accent: var(--ac-brand-contrast);

    --cal-radius: var(--ac-radius-sm);
    --cal-radius-lg: var(--ac-radius-md);

    /* ---- FullCalendar bridge ---------------------------------------------
       These are FullCalendar's own variable names. Setting them here is what
       makes the widget follow the theme; see the note above. */
    --fc-page-bg-color: var(--ac-surface);
    --fc-border-color: var(--ac-border);
    --fc-neutral-bg-color: var(--ac-surface-sunken);
    --fc-neutral-text-color: var(--ac-text-muted);
    --fc-today-bg-color: var(--ac-brand-soft);
    --fc-highlight-color: var(--ac-brand-soft);
    --fc-non-business-color: var(--ac-surface-sunken);

    --fc-button-text-color: var(--ac-text);
    --fc-button-bg-color: var(--ac-surface);
    --fc-button-border-color: var(--ac-border-strong);
    --fc-button-hover-bg-color: var(--ac-surface-sunken);
    --fc-button-hover-border-color: var(--ac-brand);
    --fc-button-active-bg-color: var(--ac-brand);
    --fc-button-active-border-color: var(--ac-brand);

    --fc-event-bg-color: var(--ac-brand);
    --fc-event-border-color: var(--ac-brand);
    --fc-event-text-color: var(--ac-brand-contrast);
    --fc-event-selected-overlay-color: rgba(var(--ac-brand-rgb), 0.25);
    --fc-list-event-hover-bg-color: var(--ac-brand-soft);

    --fc-more-link-bg-color: var(--ac-surface-sunken);
    --fc-more-link-text-color: var(--ac-brand);

    /* "Now" is a status, not decoration — it stays red in every theme. */
    --fc-now-indicator-color: var(--ac-danger);

    --fc-small-font-size: var(--ac-text-sm);
}


/* ============================================================================
   Page chrome
   ============================================================================ */

.calendar-container {
    max-width: 1100px;
    margin: 0 auto;
    padding: 1rem;
}

/* Was a three-stop gradient composed inline, unreachable by any theme. */
.calendar-page-header {
    background: var(--ac-surface-sunken);
    padding: var(--ac-section-gap) 1rem;
    text-align: center;
    border-bottom: var(--ac-border-width) solid var(--ac-border);
    margin-bottom: var(--ac-section-gap);
}

.calendar-header-icon {
    width: 70px;
    height: 70px;
    background: var(--ac-gradient-brand);
    border-radius: var(--ac-radius-lg);
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 1.25rem;
    color: var(--cal-on-accent);
    font-size: 1.75rem;
    box-shadow: var(--ac-shadow-md);
}

.calendar-page-header h1 {
    color: var(--ac-text);
    font-weight: var(--ac-weight-heading);
    font-size: var(--ac-text-2xl);
    margin: 0 0 0.5rem;
}

.calendar-page-header p {
    color: var(--ac-text-muted);
    font-size: var(--ac-text-base);
    margin: 0;
}


/* ============================================================================
   Calendar card
   ============================================================================ */

.calendar-card {
    background: var(--ac-surface);
    border-radius: var(--cal-radius-lg);
    box-shadow: var(--ac-shadow-lg);
    overflow: hidden;
    border: var(--ac-border-width) solid var(--ac-border);
    margin-bottom: var(--ac-section-gap);
}

.calendar-card-header {
    background: var(--ac-gradient-inverse);
    color: var(--ac-text-on-inverse);
    padding: var(--ac-gap) 1.5rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ac-gap);
    flex-wrap: wrap;
}

.calendar-card-header h2,
.calendar-card-header h4 {
    margin: 0;
    color: var(--ac-text-on-inverse);
    font-weight: var(--ac-weight-semibold);
    font-size: var(--ac-text-base);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.calendar-legend {
    display: flex;
    gap: var(--ac-gap);
    font-size: var(--ac-text-xs);
    flex-wrap: wrap;
}

.calendar-legend-item {
    display: flex;
    align-items: center;
    gap: 0.375rem;
}

.calendar-legend-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--cal-accent);
    flex-shrink: 0;
}

.calendar-card-body { padding: 1.5rem; }


/* ============================================================================
   FullCalendar — only what the variables cannot express
   ============================================================================ */

.fc { font-family: inherit; }

.fc .fc-toolbar-title {
    font-size: var(--ac-text-xl);
    color: var(--ac-text);
    font-weight: var(--ac-weight-semibold);
}

.fc .fc-button {
    font-weight: var(--ac-weight-medium);
    border-radius: var(--cal-radius);
    text-transform: none;
    box-shadow: none;
}

.fc .fc-button:focus-visible {
    outline: none;
    box-shadow: var(--ac-focus-ring);
}

/* Button groups need their inner corners squared off — not a variable. */
.fc .fc-button-group > .fc-button { border-radius: 0; }
.fc .fc-button-group > .fc-button:first-child { border-radius: var(--cal-radius) 0 0 var(--cal-radius); }
.fc .fc-button-group > .fc-button:last-child { border-radius: 0 var(--cal-radius) var(--cal-radius) 0; }

.fc .fc-today-button {
    background: var(--ac-brand);
    border-color: var(--ac-brand);
    color: var(--ac-brand-contrast);
}

.fc .fc-today-button:hover:not(:disabled) {
    background: var(--ac-brand-hover);
    border-color: var(--ac-brand-hover);
}

.fc .fc-today-button:disabled {
    background: var(--ac-surface-sunken);
    border-color: var(--ac-border);
    color: var(--ac-text-subtle);
    opacity: 1;
}

.fc .fc-col-header-cell-cushion {
    color: var(--ac-text-muted);
    font-weight: var(--ac-weight-semibold);
    font-size: var(--ac-text-xs);
    letter-spacing: var(--ac-label-tracking);
    text-transform: var(--ac-label-transform);
    padding: 0.5rem;
}

.fc .fc-daygrid-day-number {
    color: var(--ac-text);
    font-weight: var(--ac-weight-medium);
}

/* Today's number as a filled disc — a shape, not a variable. */
.fc .fc-day-today .fc-daygrid-day-number {
    background: var(--ac-brand);
    color: var(--ac-brand-contrast);
    border-radius: 50%;
    width: 1.75rem;
    height: 1.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: var(--ac-weight-heading);
}

.fc .fc-day-other .fc-daygrid-day-number { color: var(--ac-text-subtle); }

/* The SELECTED view button (Month / Week / List) — ink, not just fill.
 *
 * FullCalendar has no --fc-button-active-text-color. It reuses
 * --fc-button-text-color for every state, and the bridge above sets that to
 * --ac-text (near-black body ink) because that is right for the RESTING button,
 * which sits on --ac-surface. The active button swaps its background to
 * --ac-brand and keeps that same near-black ink — so on any theme with a dark
 * brand you get dark-on-dark. Chapel's navy measured barely above 1:1.
 *
 * This is exactly the fill-vs-ink rule in CLAUDE.md: --ac-brand is a fill, and
 * a fill carries --ac-brand-contrast. Selector mirrors FullCalendar's own so it
 * matches on specificity and simply loads later — no !important needed. */
.fc .fc-button-primary:not(:disabled).fc-button-active,
.fc .fc-button-primary:not(:disabled):active {
    color: var(--ac-brand-contrast);
}

.fc-event {
    border-radius: var(--ac-radius-xs);
    cursor: pointer;
    transition: var(--ac-transition-fast);
}

/* Lift on hover, do NOT darken.
 *
 * This was `filter: brightness(0.92)`, which was safe only while every event
 * chip carried white text on a mid-to-dark fill. Event types can now choose
 * their own ink, so a light fill with dark ink is normal — and darkening THAT
 * reduces the contrast at the exact moment the pointer arrives, undoing the
 * pairing the admin verified on /EventAdmin/EventTypeList.
 *
 * This is the rule CLAUDE.md states for Harbor's teal accent: hover direction
 * follows the ink. CSS cannot branch on an inline colour to pick a direction,
 * so the honest answer is a hover treatment that does not touch the fill at
 * all. The shadow reads as interactive at every lightness, in both modes. */
.fc-event:hover {
    box-shadow: var(--ac-shadow-md);
    transform: translateY(-1px);
}

/* Stop the event time being clipped mid-glyph in Month view.
 *
 * FullCalendar 6.1.8 lays a horizontal event out as a flex row
 * (`.fc-h-event .fc-event-main-frame { display: flex }`) and gives the time
 * `max-width: 100%; overflow: hidden` WITHOUT a flex-shrink, so it inherits the
 * default `flex-shrink: 1`. A long title therefore squeezes the time and
 * `overflow: hidden` cuts it partway through a character — "10:30a" renders as
 * "10:3" and "6p" as "6". That is worse than truncation: it reads as a real but
 * different time. The vertical (Week) event already sets `flex-shrink: 0`, which
 * is why this only ever showed up in Month view.
 *
 * Pin the time to its natural width and let the title absorb the shortfall.
 * Matches FullCalendar's own selector specificity and simply loads later, so no
 * !important is needed. */
.fc-h-event .fc-event-time {
    flex-shrink: 0;
}

/* FullCalendar ships no `text-overflow` anywhere, so a clipped title ends on a
 * hard cut ("Youth Back to Schoo") that looks like a rendering fault. An ellipsis
 * makes the truncation legible as truncation. Works because
 * `.fc-daygrid-event` already sets `white-space: nowrap`. */
.fc-h-event .fc-event-title {
    text-overflow: ellipsis;
}

.fc .fc-list { border-radius: var(--cal-radius); }

.fc .fc-list-day-text,
.fc .fc-list-day-side-text {
    color: var(--ac-text);
    font-weight: var(--ac-weight-semibold);
    text-decoration: none;
}

.fc .fc-toolbar { flex-wrap: wrap; gap: 0.5rem; }

@media (max-width: 768px) {
    .fc .fc-toolbar { flex-direction: column; align-items: stretch; }
    .fc .fc-toolbar-chunk { display: flex; justify-content: center; }
    .fc .fc-toolbar-title { font-size: var(--ac-text-lg); text-align: center; }
    .calendar-card-header { flex-direction: column; align-items: flex-start; }
    .calendar-legend { gap: 0.75rem; }
}


/* ============================================================================
   Tip + subscribe panel
   ============================================================================ */

.calendar-tip {
    background: var(--ac-brand-soft);
    border: var(--ac-border-width) solid var(--ac-brand);
    border-radius: var(--cal-radius);
    padding: 0.75rem 1rem;
    color: var(--ac-brand-active);
    font-size: var(--ac-text-sm);
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin-bottom: var(--ac-gap);
}

.calendar-tip i {
    color: var(--ac-brand);
    flex-shrink: 0;
    margin-top: 0.125rem;
}

.subscribe-card {
    background: var(--ac-surface);
    border: var(--ac-border-width) solid var(--ac-border);
    border-radius: var(--cal-radius-lg);
    overflow: hidden;
    margin-bottom: var(--ac-section-gap);
}

.subscribe-card .card-header {
    background: var(--ac-surface-sunken);
    border-bottom: var(--ac-border-width) solid var(--ac-border);
    cursor: pointer;
    padding: var(--ac-gap) 1.25rem;
}

.subscribe-card .card-header:hover { background: var(--ac-neutral-soft); }

.subscribe-option {
    border: var(--ac-border-width) solid var(--ac-border);
    border-radius: var(--cal-radius);
    padding: var(--ac-gap);
    background: var(--ac-surface);
    transition: var(--ac-transition-fast);
    height: 100%;
}

.subscribe-option:hover {
    border-color: var(--ac-brand);
    box-shadow: var(--ac-shadow-sm);
}

.subscribe-option h6 {
    color: var(--ac-text);
    font-weight: var(--ac-weight-semibold);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.subscribe-option ol {
    margin: 0;
    padding-left: 1.25rem;
    font-size: var(--ac-text-sm);
    color: var(--ac-text-muted);
}

.subscribe-option ol li { margin-bottom: 0.25rem; }

.subscribe-icon {
    width: 2rem;
    height: 2rem;
    border-radius: var(--ac-radius-sm);
    background: var(--ac-brand-soft);
    color: var(--ac-brand);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

#icsUrlInput {
    font-family: var(--ac-font-mono);
    font-size: var(--ac-text-sm);
    background: var(--ac-surface-sunken);
    color: var(--ac-text);
}

/* Copy confirmation — a real success signal. */
.copy-success { color: var(--ac-success-text) !important; }


/* ============================================================================
   Print
   ============================================================================ */

@media print {
    .calendar-page-header,
    .subscribe-card,
    .calendar-tip,
    .fc .fc-toolbar { display: none !important; }

    .calendar-card { box-shadow: none; border: 1px solid #cccccc; }
}


/* ============================================================================
   Third-party service marks — a DELIBERATE exception to the token rule
   ============================================================================
   Google blue, Apple's near-black and Microsoft's blue are identity marks for
   named external services. Keeping them is how a user recognises "Google
   Calendar" at a glance, so unlike every other colour on the site these do NOT
   follow the theme — a Google icon rendered in the church's brand hue would be
   worse, not more consistent.

   This is narrow and it is not a loophole. The test is whether the colour
   IDENTIFIES a third party. The Facebook blue that was on the home page's RSVP
   buttons failed that test — it was a generic "Going" control that happened to
   have been copied from Facebook — and it became --ac-brand.

   Values were inline styles on the markup; they are classes now so they read as
   intentional rather than as drift, and so the audit can see them.
   ============================================================================ */

.subscribe-icon--google  { background: #4285f4; color: #ffffff; }
.subscribe-icon--apple   { background: #333333; color: #ffffff; }
.subscribe-icon--outlook { background: #0078d4; color: #ffffff; }
/* iOS device instructions — not a brand mark, so this one follows the theme. */
.subscribe-icon--device  { background: var(--ac-brand); color: var(--ac-brand-contrast); }


/* ============================================================================
   Per-occurrence cancel control (event admins only)
   ============================================================================
   The × that removes ONE date from a repeating event. It is appended to
   FullCalendar's own event element by eventDidMount, so it has to position
   itself against that element without disturbing the layout FullCalendar
   computed — hence absolute positioning and a padding-right on the host rather
   than anything that changes the event's own box.

   It is rendered server-side for Admin/SA/EventAdmin only. Hiding it in CSS
   would leave a live delete button in the DOM of a page every member reads, and
   still tabbable — the same mistake CLAUDE.md documents for Give links in
   embedded mode. This block styles a control that is either present or absent,
   never merely invisible.

   Opacity, not display, on hover: a control that appears from nothing shifts
   the eye and is unreachable on touch, where there is no hover at all. It stays
   at rest visible enough to find and fades to full strength on hover/focus, and
   :focus-visible gets the same treatment so keyboard users are not chasing an
   invisible target.
   ============================================================================ */

.fc-event:has(> .calendar-occ-cancel) {
    position: relative;
    padding-right: 1.35em;
}

.calendar-occ-cancel {
    position: absolute;
    top: 50%;
    right: .15em;
    transform: translateY(-50%);

    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.15em;
    height: 1.15em;
    padding: 0;

    border: 0;
    border-radius: var(--ac-radius-xs);
    background: transparent;
    /* currentColor, so the × follows whatever ink FullCalendar chose for this
       event type's colour instead of assuming a dark or a light one. */
    color: currentColor;
    opacity: .55;
    font-size: .85em;
    line-height: 1;
    cursor: pointer;
    transition: var(--ac-transition-fast);
}

/* The soft fill + -text ink pair, not the --ac-danger FILL. The × sits on top of
   an event chip whose colour is the church's own EventType colour, so the ink
   here cannot assume a background — and -text is the half that inverts for dark
   mode, which the fill deliberately does not. */
.calendar-occ-cancel:hover,
.calendar-occ-cancel:focus-visible {
    opacity: 1;
    background: var(--ac-danger-soft);
    color: var(--ac-danger-text);
}

.calendar-occ-cancel:focus-visible {
    outline: none;
    box-shadow: var(--ac-focus-ring);
}

/* The list view lays events out as table rows, so the button is appended to the
   title CELL (see eventDidMount) rather than the row. In a table cell there is
   nothing sensible to absolutely position against, so there it simply trails the
   title inline. */
.fc-list-event-title .calendar-occ-cancel {
    position: static;
    transform: none;
    margin-left: .5rem;
    vertical-align: middle;
    font-size: 1em;
}


/* ============================================================================
   Expanded / full-screen calendar
   ============================================================================
   The page is a 1100px centred column, which is right for reading but wastes
   most of a 2500px monitor — and the cost is not just whitespace. At 1100px a
   day cell is ~150px wide, so nearly every event title truncates
   ("Wednesday S...", "Pre-Servic..."), and dayMaxEvents hides the rest behind
   "+2 more". On a wide screen there is room to show all of it.

   TWO MECHANISMS, ONE BUTTON. Browser full-screen is the good version: it
   reclaims the vertical space too (browser chrome, site nav, page header,
   footer), which is what makes every event fit without a "+N more". But
   requestFullscreen can be refused outright — iOS Safari has never supported it
   on a non-video element, and a permissions policy can block it in an iframe —
   and a button that silently does nothing is worse than no button. So the
   fallback is an in-page wide mode that needs no permission at all.

   Both land on the same two classes so there is one set of styles to keep
   right, not two.
   ============================================================================ */

/* In-page wide mode: the column constraint lifts, nothing else moves. */
.calendar-container--wide {
    max-width: none;
}

/* True full-screen. :fullscreen matches the element passed to
   requestFullscreen() — the card, not the page, so the browser paints its own
   backdrop behind it and the site's nav and footer are simply gone.

   The card normally has a radius and a shadow; against the screen edge both
   read as a rendering fault, so they come off. */
.calendar-card:fullscreen {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    margin: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: var(--ac-surface);
}

/* The body has to be the flex child that grows, and it must be allowed to
   SHRINK below its content — without min-height: 0 a flex item's automatic
   minimum size is its content, so a tall month would push the grid past the
   bottom of the screen instead of fitting inside it. */
.calendar-card:fullscreen .calendar-card-body {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.calendar-card:fullscreen #calendar {
    flex: 1 1 auto;
    min-height: 0;
}

/* Day cells get the reclaimed height. FullCalendar caps an event's own height,
   so this is what turns "+2 more" into two more visible rows. */
.calendar-card:fullscreen .fc .fc-daygrid-day-frame {
    min-height: 0;
}

/* Wider cells mean titles no longer need to be clipped to one line. Two lines
   fit comfortably at full-screen row heights and read far better than an
   ellipsis. */
.calendar-card--expanded .fc-h-event .fc-event-title {
    white-space: normal;
    overflow-wrap: anywhere;
}

.calendar-card--expanded .fc-daygrid-event {
    white-space: normal;
}

/* The toggle itself. It sits on .calendar-card-header, which is the inverse
   gradient — so its ink is --ac-text-on-inverse, NOT --ac-text, and the resting
   border is a tint of that same ink rather than --ac-border (which is tuned for
   a light surface and vanishes here). */
.calendar-expand-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 0.625rem;
    border-radius: var(--ac-radius-xs);
    border: var(--ac-border-width) solid currentColor;
    background: transparent;
    color: var(--ac-text-on-inverse);
    font-size: var(--ac-text-xs);
    font-weight: var(--ac-weight-semibold);
    line-height: 1.5;
    cursor: pointer;
    transition: var(--ac-transition-fast);
}

/* Inverting to the header's own ink is the only hover that is guaranteed to
   work here: --ac-text-on-inverse is readable on the gradient by definition, so
   the reverse pairing is readable too, in both modes and every theme. */
.calendar-expand-btn:hover,
.calendar-expand-btn:focus-visible {
    background: var(--ac-text-on-inverse);
    color: var(--ac-brand);
}

.calendar-expand-btn:focus-visible {
    outline: none;
    box-shadow: var(--ac-focus-ring);
}

/* Hidden below the width where expanding would achieve nothing — a phone is
   already edge to edge, so the control would promise something it cannot give.
   1200px is just above the 1100px column, i.e. the first point at which there
   is real space to reclaim. */
@media (max-width: 1200px) {
    .calendar-expand-btn { display: none; }
}


/* ============================================================================
   Jump-to-month controls
   ============================================================================
   Two selects injected into FullCalendar's left toolbar chunk beside
   prev/next/today. They are native <select> elements on purpose — a custom
   listbox here would have to reimplement type-ahead, keyboard navigation and
   the mobile picker, all of which the platform already does better.

   Sized against --fc-button-* rather than our own button tokens so they sit
   level with the buttons they stand next to, whatever the theme does to
   control height.
   ============================================================================ */

.calendar-jump {
    display: inline-flex;
    align-items: stretch;
    gap: .375rem;
    margin-left: .75rem;
}

.calendar-jump__select {
    appearance: none;
    -webkit-appearance: none;
    padding: .375rem 1.75rem .375rem .625rem;
    border: var(--ac-border-width) solid var(--ac-border-strong);
    border-radius: var(--cal-radius);
    background-color: var(--ac-surface);
    color: var(--ac-text);
    font-family: inherit;
    font-size: var(--ac-text-sm);
    font-weight: var(--ac-weight-medium);
    line-height: 1.5;
    cursor: pointer;
    transition: var(--ac-transition-fast);

    /* The chevron is drawn rather than shipped as an asset so it follows the
       theme's ink. Encoded currentColor is not possible in a url(), so the
       stroke is the one place this file names a colour — kept in sync with
       --ac-text by the two blocks below. */
    background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                      linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position: calc(100% - 1.05rem) 55%, calc(100% - .7rem) 55%;
    background-size: .35rem .35rem, .35rem .35rem;
    background-repeat: no-repeat;
}

.calendar-jump__select:hover {
    border-color: var(--ac-brand);
}

.calendar-jump__select:focus-visible {
    outline: none;
    border-color: var(--ac-brand);
    box-shadow: var(--ac-focus-ring);
}

/* The month name is much wider than the year, and letting both size to content
   makes the pair jump every time the month changes. */
.calendar-jump__select:first-child { min-width: 8.5rem; }

/* On a narrow screen the toolbar already wraps; give the jump controls their
   own full-width row rather than letting them crowd prev/next. */
@media (max-width: 640px) {
    .calendar-jump {
        margin-left: 0;
        margin-top: .5rem;
        width: 100%;
    }
    .calendar-jump__select { flex: 1 1 auto; }
}


/* ============================================================================
   Admin day-number shortcut
   ============================================================================
   For SA / Admin / EventAdmin the day number becomes "add an event on this
   day". It has to stay LOOKING like a day number — a calendar grid where every
   date is visibly a link reads as noise — so it inherits the number's type and
   only declares itself on hover and focus.

   Rendered server-side for those roles only; a member never receives the anchor
   at all, so this is styling, not the gate.
   ============================================================================ */

/* The admin "add an event on this day" affordance.
 *
 * Targeted at an ATTRIBUTE on FullCalendar's own day-number <a>, not at a class
 * on an anchor of ours. Two reasons, both learned the hard way:
 *
 *  - There is no anchor of ours any more. Wrapping the number in one meant
 *    replacing a text node that FullCalendar's Preact tree still owned, and a
 *    re-render put the original number back beside the copy: "27" became "2727".
 *  - `className` is a prop Preact writes; a data-attribute is not. A class added
 *    from JS is dropped the moment FullCalendar recomputes the element's classes
 *    (fc-day-today, fc-daygrid-month-start). The attribute survives.
 *
 * No `color` here on purpose - the rules above already colour the number, and
 * `color: inherit` would undo the muted treatment on other-month days. */
.fc .fc-daygrid-day-number[data-ac-add] {
    text-decoration: none;
    border-radius: var(--ac-radius-xs);
    transition: var(--ac-transition-fast);
}

.fc .fc-daygrid-day-number[data-ac-add]:hover,
.fc .fc-daygrid-day-number[data-ac-add]:focus-visible {
    background: var(--ac-brand);
    color: var(--ac-brand-contrast);
    text-decoration: none;
}

.fc .fc-daygrid-day-number[data-ac-add]:focus-visible {
    outline: none;
    box-shadow: var(--ac-focus-ring);
}

/* The printable-year link shares the header-button treatment but must NOT take
   the expand button's 1200px hide — a printable calendar is just as useful on a
   phone, where expanding is not. */
a.calendar-expand-btn { text-decoration: none; }

@media (max-width: 1200px) {
    a.calendar-expand-btn { display: inline-flex; }
}

/* ---------------------------------------------------------------------------
   A date cancelled but left visible

   The point of this state is that the entry STAYS on the calendar and reads as
   called off, so it must be unmistakable at a glance and still legible. Struck
   through and faded, with a CANCELLED prefix — never colour alone (WCAG 1.4.1),
   which is also why eventDidMount puts the word in the accessible name.

   Selected off a data attribute, not a class: FullCalendar 6 is Preact
   underneath and owns className on the nodes it renders, so a JS-added class is
   wiped on the next re-render (events arriving, "+N more" remeasuring, a
   resize). data-* attributes are invisible to its prop diff and survive. Same
   reason the day-number "add an event" link is styled off [data-ac-add].
   --------------------------------------------------------------------------- */
.fc-event[data-ac-cancelled] {
    /* Muted, not hidden — the whole feature is that people can still see it. */
    opacity: .75;
    background-color: var(--ac-neutral-soft) !important;
    border-color: var(--ac-border) !important;
}

/* The ink has to be forced WITH the fill, and it has to be forced on the
   DESCENDANTS, not just on .fc-event.

   FullCalendar writes the event's category textColor as an INLINE style on
   .fc-event-main — a child — so colouring only the .fc-event container does
   nothing: the inline colour on the child wins for every piece of text inside
   it. That shipped. The category colour here is a dark brown carrying white
   text, so the cancelled entry rendered white on the light neutral wash at
   about 1.1:1 — invisible, which is the exact outcome this feature exists to
   prevent.

   It was reported as passing because the check measured .fc-event's computed
   colour. That element renders no text. Measure .fc-event-title.

   The universal descendant selector is deliberate over naming each node:
   FullCalendar's internal tree differs per view (dayGrid nests
   main > main-frame > title-container > title, list view does not) and is not
   a public contract. !important in a stylesheet beats a non-important inline
   style, which is what makes this reach the child at all. */
.fc-event[data-ac-cancelled],
.fc-event[data-ac-cancelled] * {
    color: var(--ac-text) !important;
}

.fc-event[data-ac-cancelled] .fc-event-title,
.fc-event[data-ac-cancelled] .fc-list-event-title a {
    text-decoration: line-through;
    text-decoration-thickness: 2px;
}

.fc-event[data-ac-cancelled] .fc-event-title::before,
.fc-event[data-ac-cancelled] .fc-list-event-title a::before {
    content: "CANCELLED ";
    /* The badge is the part that must NOT be struck through, or the one word
       carrying the meaning becomes the hardest thing on the row to read. */
    text-decoration: none;
    display: inline-block;
    font-size: .7em;
    font-weight: 700;
    letter-spacing: .04em;
    padding: 0 .35em;
    margin-right: .3em;
    border-radius: var(--ac-radius-sm);
    /* The .ac-badge--danger pairing: a soft tint carrying the INK token, not
       the solid fill carrying white. --ac-danger is a FILL and is not inverted
       for dark mode, so white-on-fill here would be a contrast failure in one
       of the two modes; --ac-danger-text is the half that inverts. */
    background: var(--ac-danger-soft);
    /* !important so the blanket ink rule above cannot flatten the badge to
       body text. A pseudo-element is not matched by `*`, but it DOES inherit,
       and an inherited !important value would beat a plain declaration here. */
    color: var(--ac-danger-text) !important;
    vertical-align: baseline;
}

/* Time and dot are decoration here; the strike and badge carry the meaning. */
.fc-event[data-ac-cancelled] .fc-event-time,
.fc-event[data-ac-cancelled] .fc-list-event-time {
    text-decoration: line-through;
    opacity: .8;
}

/* ---------------------------------------------------------------------------
   The "+N more" popover's close button

   FullCalendar ships it as an 18x18 span — below the ~24px a pointer can
   reliably hit and well below the 44px touch guideline. Clicking a few pixels
   off lands on the popover HEADER, which does not close it, so the button
   reads as broken rather than as missed. It was reported that way.

   The glyph keeps its size; only the hit area grows. The negative margin
   absorbs that growth so the header does not get taller and the X does not
   visibly move.

   Note this is a different control from .calendar-occ-cancel, the per-event
   cancel X on each row inside the same popover. They sat at the same size and
   in the same corner region, which is its own reason to make this one bigger
   and give it a hover state: an admin should never have to wonder which X
   closes the popover and which one cancels a service.
   --------------------------------------------------------------------------- */
.fc-popover-close {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    margin: -0.45rem -0.35rem -0.45rem 0;
    border-radius: var(--ac-radius-sm);
    cursor: pointer;
    opacity: .8;
}

.fc-popover-close:hover {
    background: var(--ac-neutral-soft);
    opacity: 1;
}

.fc-popover-close:focus-visible {
    outline: none;
    box-shadow: var(--ac-focus-ring);
    opacity: 1;
}
