/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 *
 * Design tokens and shared component classes live in
 * app/assets/tailwind/application.css (Tailwind v4's @theme/@utility/
 * @layer components) - see docs/design_system.md. This file holds only
 * overrides into the vendored Schedule-X calendar theme below, which stay
 * here rather than in the Tailwind entry file so the vendored
 * stylesheet's own hooks are the only thing touched, per Task 07's "not a
 * Schedule-X replacement" non-goal.
 */

/* Schedule-X's own "primary" color (today's date circle, the selected
   view/date-picker state, drag-and-drop affordances) defaults to a
   hardcoded Material violet (schedule_x_theme_default.css's own
   --sx-color-primary) unrelated to Catnap's brand token. Repointing it at
   --color-accent means every one of Schedule-X's built-in "this is the
   active/selected thing" states automatically reads as Catnap's own
   accent instead of a second, coincidentally-similar purple - with no
   per-button styling, keeping the toolbar itself otherwise neutral.
   !important: confirmed empirically (getComputedStyle on a real rendered
   calendar page) that schedule_x_theme_default.css's own :root block -
   which sets --sx-color-primary itself - gets re-inserted into the
   document a second time, after this stylesheet, once the calendar
   page's work-report Turbo Frame has loaded; without !important the
   vendored value silently wins the second time and this override is
   inert. Root cause not fully chased down (likely something about how
   the Turbo Frame's own full-page response re-triggers a link tag Turbo
   considers "new") - worth a closer look separately, since it likely
   affects any other unguarded override in this file too. */
:root {
  --sx-color-primary: var(--color-accent) !important;
  --sx-color-on-primary: #fff !important;
  --sx-color-primary-container: var(--color-accent-soft) !important;
  --sx-color-on-primary-container: var(--color-accent-hover) !important;
  /* Schedule-X's own --sx-color-neutral (used for the month grid's
     per-cell day-of-week label, e.g. "MON") defaults to --sx-color-outline
     (#79747e), which axe-core's color-contrast rule flags on both a plain
     white cell (4.15:1) and the muted weekend tint added below (worse) -
     both under the 4.5:1 floor for this 11px text. --color-muted already
     clears 4.5:1 with real margin on both backgrounds (see its own
     definition's contrast comment), so repointing this one token fixes
     both cases without touching Schedule-X's own selectors. */
  --sx-color-neutral: var(--color-muted) !important;
}

/* Click-and-drag/long-press date range selection on the calendar's month
   grid day cells and the week grid's per-day date headers - see
   app/javascript/calendar/range_selector.js. color-mix() (not a flat
   --color-accent-soft) to preserve the exact translucent-overlay
   compositing this had as a literal rgba(79, 70, 229, 0.14) - that
   hardcoded 79/70/229 is --color-accent's own #4f46e5, just not
   expressed as the token, which is what let it silently stop tracking
   accent the moment a non-default palette changed it.
   !important: the weekend-tint rule below is a compound two-class
   selector (.sx__month-grid-day.sx__saturday/.sx__sunday), specificity
   (0,2,0) against this rule's plain (0,1,0) - on a selected weekend
   cell (both classes present) the weekend rule always won regardless of
   which rule appears later in this file, so a drag-selected weekend day
   never visibly changed color even though range_selector.js toggles the
   same class on every cell type identically, weekend or not. Confirmed
   by inspecting computed specificity, not guessed. !important here
   matches this file's own precedent above for a Schedule-X cascade
   fight, and is more robust than chasing selector specificity/order,
   which a future edit to either rule could silently re-break. */
/* Long-press range selection cannot survive the browser's own long-press.
   range_selector.js arms a live drag roughly 400ms into a held touch, but
   at around 500ms a touch device raises its own text-selection callout
   (iOS) or context menu (Android) over the cell - which fires touchcancel,
   and an armed drag that's cancelled drops the selection it had just
   started painting. The finger lifts onto nothing. The gesture was
   summoning the very thing that cancelled it, on every real device, while
   passing in CI because a synthetic touch driver raises no callout.

   Scoped to the selectable day cells rather than applied app-wide: this
   suppresses selecting and copying text, which is a real loss anywhere the
   text is worth reading - an event title, a report total. A day cell is a
   control that happens to contain a number.

   touch-action is deliberately still untouched here. Suppressing the
   callout is not the same as claiming the gesture: scrolling, momentum and
   pinch-zoom over these cells stay entirely the browser's own for as long
   as a touch is only being judged, which is the property
   range_selector.js's own comment protects - it claims the gesture itself
   only once a hold has already proven it isn't a scroll. */
.sx__month-grid-day,
.sx__week-grid__date,
.sx__month-agenda-day {
  -webkit-touch-callout: none;
  user-select: none;
}

.sx__month-grid-day--range-selected {
  background: color-mix(in srgb, var(--color-accent) 14%, transparent) !important;
}

.sx__week-grid__date--range-selected {
  background: color-mix(in srgb, var(--color-accent) 14%, transparent);
}

/* Month Agenda's mini-calendar day cells and Week Agenda's day-strip cells
   (both the same Schedule-X component - see range_selector.js's own
   comment). !important for a different reason than the month grid rule
   above: unlike either grid cell type, these cells are real <button>
   elements carrying the vendored theme's own .sx__button class, whose
   background-color: inherit (schedule_x_theme_default.css) ties this
   rule's specificity (0,1,0 each) - and the tie is won by whichever
   comes later in the cascade, which per this file's own :root comment
   above is .sx__button's OWN copy every time, once the work-report Turbo
   Frame's own re-inserted <link> duplicates that stylesheet after this
   one. Confirmed empirically (getComputedStyle on a real long-pressed
   cell reading transparent without this) rather than assumed from the
   grid rule's own reasoning, since the two conflicts are genuinely
   different - week-grid__date--range-selected two rules below has
   neither and needs no !important of its own. */
.sx__month-agenda-day--range-selected {
  background: color-mix(in srgb, var(--color-accent) 14%, transparent) !important;
}

/* The calendar page's coverage/error notices (app/views/calendar/
   show.html.slim), pinned over the bottom of the calendar column instead
   of stacked above the grid.

   This row used to sit in the flow and collapse when empty, so that the
   calendar's fixed height still lined up with the work-report frame's
   matching height in the column beside it (see that view's own comment on
   the frame's h-[45rem]). It lined up right up until a notice appeared,
   and then everything below it moved 42px down - mid-interaction, because
   what un-hides these is a Turbo frame load rather than anything the user
   did. #314 was that: a next-period click computed against the old
   position and dispatched after the reflow, landing on the grid container
   instead of the button.

   Out of flow, both properties hold at once - the columns stay aligned
   whether or not a notice shows, and no notice can move a control. The
   two rules below are load-bearing rather than cosmetic:

   pointer-events: none - this lies across the bottom row of day cells,
   which are click and drag targets. Intercepting there would re-create the
   exact defect in a new place. Nothing in here is interactive, so refusing
   events costs nothing.

   z-index - it has to draw above the grid it overlays, or being out of
   flow would make it invisible rather than harmless. */
.calendar-notices {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  pointer-events: none;
}

/* Catnap's work classification (work/needs review/not work/not
   classified yet), shown two ways depending on how much room the event
   has. Timed events
   (month-grid/time-grid, excluding .all-day - see below) get a small
   colored dot before the title - replacing an earlier full-height edge
   tab that ate too much of an already-narrow month-grid day column's
   text width, and an earlier border, both dropped to match Google
   Calendar's own convention (a dot, no fill, no border, on the plain
   grid) rather than trying to carry a second "which calendar" color
   channel that real-world use showed wasn't worth the visual noise or
   the text space it cost. All-day/multi-day events get a solid
   classification-colored fill instead - the whole bar already reads as
   "this is the color," mirroring Google's own solid all-day bars, but
   (unlike Google's) still carries the same circle/hollow-circle/filled-
   diamond/hollow-diamond shape as the timed dot markers, in white
   against the fill - see the ::before rules further below - since color alone isn't a sufficient
   cue for sighted color-deficient users (WCAG 1.4.1). calendarId is
   added as a plain CSS
   class in schedule_x_adapter.js specifically so .work/.not_work/
   .unresolved/.unclassified can be selected here - Schedule-X itself
   only ever uses calendarId to drive inline styles (still set inline per event - see
   workStatusCalendars() below); every override below needs !important
   for the same reason: only an author-stylesheet !important outranks a
   plain inline style. */
.sx__month-grid-event:not(.all-day),
.sx__time-grid-event {
  /* !important because the calendar page's Turbo-Frame-loaded report
     widget causes schedule_x_theme_default.css to be re-inserted into
     the document a second time, after this stylesheet - see the
     load-order note below - so a plain (non-!important) override here
     loses to the vendored padding shorthand's re-declaration. */
  padding-inline-start: 14px !important;
  border-inline-start: none !important;
  background-color: transparent !important;
  color: var(--color-ink) !important;
}
/* Shape, not just color, carries the work/not-work/needs-review/not-
   classified-yet distinction for sighted color-deficient users (axe-core's color-contrast
   rule only checks text-vs-background, not a decorative marker like this
   one against its own grid background - this is a manual WCAG 1.4.1 Use
   of Color fix, not something the automated accessibility.feature
   scenarios catch on their own). box-sizing: border-box keeps all three
   markers the same 7x7px footprint regardless of border width (the
   rotated hollow diamond is sized separately to match - see below). */
.sx__month-grid-event:not(.all-day)::before,
.sx__time-grid-event::before {
  content: "";
  position: absolute;
  inset-inline-start: 3px;
  top: 50%;
  transform: translateY(-50%);
  width: 7px;
  height: 7px;
  box-sizing: border-box;
}
/* work: filled circle. */
.sx__month-grid-event:not(.all-day).work::before, .sx__time-grid-event.work::before {
  border-radius: 50%;
  background: var(--color-success);
}
/* not work: hollow circle - an outline, not a fill. */
.sx__month-grid-event:not(.all-day).not_work::before, .sx__time-grid-event.not_work::before {
  border-radius: 50%;
  border: 1.5px solid var(--color-muted);
  background: transparent;
}
/* needs review: filled diamond - the one shape distinct enough from a
   circle at 7px to read clearly, without needing the width a triangle's
   asymmetry would cost to stay legible at this size. */
.sx__month-grid-event:not(.all-day).unresolved::before, .sx__time-grid-event.unresolved::before {
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  background: var(--color-warning);
}
/* not classified yet: hollow diamond, in the same neutral grey as not
   work rather than the warning hue - nothing has looked at this event, so
   it isn't asking anything of the user and must not read as an alert
   (that's what the filled warning diamond above means). Diamond because
   it's classification-adjacent like "needs review"; hollow because, like
   not work's hollow circle, no claim is being asserted. A rotated square
   with a border rather than a clip-path outline (clip-path clips the
   border away too): 5x5 rotated 45 degrees has a ~7px diagonal, so its
   rendered footprint matches the other three markers'. */
.sx__month-grid-event:not(.all-day).unclassified::before, .sx__time-grid-event.unclassified::before {
  width: 5px;
  height: 5px;
  border: 1.5px solid var(--color-muted);
  background: transparent;
  transform: translateY(-50%) rotate(45deg);
}

/* Month view renders an all-day/multi-day event as a .sx__month-grid-event
   too (just wider, spanning the days it covers as one element -
   confirmed against the real rendered DOM, Schedule-X already handles
   the spanning natively) rather than the dedicated .sx__date-grid-event
   week/day view uses - "all-day" (added in schedule_x_adapter.js) is
   what lets both get the same solid-fill treatment here. */
.sx__month-grid-event.all-day,
.sx__date-grid-event {
  border-inline-start: none !important;
  color: #fff !important;
  position: relative;
  padding-inline-start: 16px !important;
}
/* --color-success/--color-warning (the dot colors above) are too light
   for white text at normal size - confirmed via axe-core
   (features/accessibility.feature): ~3.18:1 against the warning fill,
   under the 4.5:1 floor. Their darker -text counterparts (already used
   elsewhere for text-on-light-fill, e.g. badge-warning/-success) clear it
   with real margin. --color-muted's white-text contrast was not flagged,
   so it's unchanged. */
.sx__month-grid-event.all-day.work, .sx__date-grid-event.work { background-color: var(--color-success-text) !important; }
.sx__month-grid-event.all-day.not_work, .sx__date-grid-event.not_work { background-color: var(--color-muted) !important; }
.sx__month-grid-event.all-day.unresolved, .sx__date-grid-event.unresolved { background-color: var(--color-warning-text) !important; }
/* Deliberately the same verified-contrast grey as not work - see the
   hollow-diamond rule above for why "not classified yet" shares not
   work's neutral hue and is distinguished by shape instead. */
.sx__month-grid-event.all-day.unclassified, .sx__date-grid-event.unclassified { background-color: var(--color-muted) !important; }
/* The all-day states were solid fills distinguished only by hue -
   no non-color cue for sighted color-deficient users, unlike the timed
   dot markers above (WCAG 1.4.1 Use of Color). Repeats the same
   shape vocabulary as the timed markers, in
   white against each solid fill (every fill already carries verified
   white-text contrast, so the same white reads clearly as a shape here
   too) - same iconography as the timed treatment, not a second one to
   learn. */
.sx__month-grid-event.all-day::before,
.sx__date-grid-event::before {
  content: "";
  position: absolute;
  inset-inline-start: 5px;
  top: 50%;
  transform: translateY(-50%);
  width: 7px;
  height: 7px;
  box-sizing: border-box;
}
.sx__month-grid-event.all-day.work::before, .sx__date-grid-event.work::before {
  border-radius: 50%;
  background: #fff;
}
.sx__month-grid-event.all-day.not_work::before, .sx__date-grid-event.not_work::before {
  border-radius: 50%;
  border: 1.5px solid #fff;
  background: transparent;
}
.sx__month-grid-event.all-day.unresolved::before, .sx__date-grid-event.unresolved::before {
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  background: #fff;
}
.sx__month-grid-event.all-day.unclassified::before, .sx__date-grid-event.unclassified::before {
  width: 5px;
  height: 5px;
  border: 1.5px solid #fff;
  background: transparent;
  transform: translateY(-50%) rotate(45deg);
}

/* Schedule-X's own auto-generated time label (always "10:00 AM" - see
   compactTime() in schedule_x_adapter.js for why that can't be
   reconfigured) is hidden in favor of the compact "7am"/"7:30pm" this
   app embeds directly in the title instead. !important on the time-grid
   selector specifically: schedule_x_theme_default.css declares
   .sx__time-grid-event-time's display as part of a shared rule with
   -people/-location, and per the note on the :root block above, that
   rule can be re-inserted after this one on the calendar page - without
   !important the label would stay hidden in month view but reappear in
   week/day view. */
.sx__month-grid-event-time {
  display: none;
}
.sx__time-grid-event-time {
  display: none !important;
}

/* Very light contextual tinting for the month grid - today, weekends, and
   adjacent-month days - kept subtle deliberately (the grid itself should
   stay quiet; classification/identity color lives on the events, not the
   grid). .sx__monday..sx__sunday and .is-leading-or-trailing are classes
   Schedule-X's own month-grid-day component already applies per cell
   (confirmed in the vendored bundle); :has() reaches the whole day cell
   from its nested .sx__is-today date circle, which is the only element
   Schedule-X itself marks as "today". */
.sx__month-grid-day:has(.sx__is-today) {
  background: var(--color-accent-soft);
}
.sx__month-grid-day.sx__saturday,
.sx__month-grid-day.sx__sunday {
  background: var(--color-surface-muted);
}
/* Previously a blanket opacity:0.55 on the whole cell - but CSS opacity
   composites down the tree (a child can't opt back in to full contrast
   against an ancestor's opacity), so that dimmed the 11px day-of-week
   label ("MON"/"TUE"...) below WCAG's 4.5:1 floor on both a plain white
   cell (2.57:1) and the muted weekend tint below (worse) - confirmed via
   axe-core. The day-of-week label is identical text to every other cell
   in that column anyway (nothing meaningfully de-emphasized about fading
   it specifically), so it's left at full contrast entirely.
   The date number still needs *some* visual de-emphasis to read as
   "outside the current month" - --color-muted has real margin (7.58:1 on
   white, already verified project-wide) rather than opacity's
   razor-thin, environment-fragile margin: the first attempt at this
   (opacity applied to the date number specifically, not the whole cell)
   still measured 4.41:1 against the 4.5:1 floor - close enough to pass
   locally but fail in CI on a different font-rendering engine, exactly
   the kind of flake a real color choice with margin avoids. Spillover
   event pills (a multi-day event crossing into an adjacent month) keep
   their normal, already-verified classification coloring at full opacity
   rather than risking the same razor-thin-margin mistake twice. */
.sx__month-grid-day.is-leading-or-trailing .sx__month-grid-day__header-date {
  color: var(--color-muted);
}

/* Schedule-X's own date-picker chevron (the small dropdown affordance
   next to the "Date" field) renders at 16x16px - under axe-core's
   target-size rule's 24x24px floor. Widening the hit area via padding
   (not changing the visible chevron glyph's own size) keeps the same
   visual weight while giving it a large enough tap/click target. */
.sx__date-input-chevron-wrapper {
  box-sizing: content-box !important;
  padding: 4px !important;
}
