/*
 * Americon Bid Calendar component styles.
 *
 * Every colour below comes from the theme's design tokens (themes/americon-bid/
 * style.css). This file used to hardcode #FFFFFF, #333333, #555555 and #e5e7eb
 * directly, and defensively wrote `var(--americon-blue, #272E7E)` because it
 * could not be sure the theme stylesheet had loaded. Both problems are gone:
 * the tokens are the single source, and they carry dark-mode values, so the
 * calendar follows the rest of the site instead of staying white.
 *
 * The fallbacks in var() are kept for the case where this plugin is used with
 * a theme that does not define the tokens at all.
 */

/* =========================
   Empty-state note
   =========================

   Sits above the grid rather than replacing it. It is deliberately a slim
   band and not the theme's large .am-empty block: the calendar below is
   still the main content, and an empty month is a normal state -- most
   weeks of most years have no bid closing on them. */
.am-cal-note {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .75rem 1rem;
  margin-bottom: 1rem;
  padding: .75rem 1rem;
  background: var(--am-surface-sunk, #F7F8FA);
  border: 1px solid var(--am-border, #E2E5EA);
  border-radius: var(--am-radius, .75rem);
  color: var(--am-text-muted, #5E6673);
  font-size: var(--am-text-sm, .9rem);
}

.am-cal-note strong {
  color: var(--am-text, #1F2530);
}

/* =========================
   Subscribe band
   =========================

   Sits under the grid, not above it: the calendar is what people came for,
   and this is an offer rather than an instruction. Muted on purpose so it
   reads as a footnote to a contractor who already has the feed. */
.am-cal-subscribe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .75rem 1.25rem;
  margin-top: 1rem;
  padding: .9rem 1.1rem;
  background: var(--am-surface-sunk, #F7F8FA);
  border: 1px solid var(--am-border, #E2E5EA);
  border-radius: var(--am-radius, .75rem);
}

.am-cal-subscribe-text {
  display: flex;
  flex-direction: column;
  gap: .15rem;
  /* Keeps the copy from squeezing the buttons onto a second line at tablet
     widths while still allowing it to wrap on a phone. */
  flex: 1 1 22ch;
}

.am-cal-subscribe-text strong {
  color: var(--am-text, #1F2530);
  font-size: var(--am-text-sm, .9rem);
}

.am-cal-subscribe-text span {
  color: var(--am-text-muted, #5E6673);
  font-size: var(--am-text-xs, .8rem);
}

.am-cal-subscribe-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}

/* =========================
   Calendar container
   ========================= */

/* The card chrome lives here rather than on the theme's .americon-calendar-card
   wrapper, so the [bid_calendar] shortcode looks finished on any page it is
   dropped onto, not only on the dashboard template.

   It also lives here rather than on .fc, where it used to be: FullCalendar
   owns that element and re-renders it, and a max-width on it fought the
   wrapper's own width. */
.am-bid-calendar {
  container-type: inline-size;
  padding: clamp(.75rem, .4rem + 1.4vw, 1.5rem);
  background: var(--am-surface, #fff);
  border: 1px solid var(--am-border, #E2E5EA);
  border-radius: var(--am-radius-lg, 1rem);
  box-shadow: var(--am-shadow, 0 1px 3px rgb(16 24 40 / .08), 0 8px 24px rgb(16 24 40 / .06));

  /* The floor under a day cell, as a token rather than a literal, because
     three different situations want three different answers: a desktop grid
     that sizes itself (below), a phone (container query further down) and a
     grid told to fit a fixed height (fit mode). */
  --am-cal-day-min: 5.75rem;
}

/* =========================
   Fit mode
   =========================

   [bid_calendar fit="viewport"] asks the whole month to be visible at once,
   under the title and the tiles, without a scrollbar in the middle of the
   grid.

   The first attempt did this by giving FullCalendar a definite height
   (height:'100%' + expandRows) and letting it divide that height among its
   rows. That was wrong in a way worth recording: FullCalendar responds to a
   height it cannot honour by putting the week rows in their OWN scroller. So
   on a short window the page stopped scrolling and the calendar started --
   the month got clipped mid-grid at, say, the 15th, with a scrollbar inside a
   card. Trading a page scrollbar for a scrollbar inside the thing you are
   trying to read is a straight loss.

   The height is therefore never fixed. FullCalendar stays on height:'auto',
   where it has no scroller to create, and the only lever is how tall a day
   cell is -- cal.js measures the overflow and shrinks the cells (down to a
   readable floor) until the page fits. Past that floor the PAGE scrolls,
   which is the correct thing to give up.

   So there is nothing here that constrains height. That is the point. */
.am-bid-calendar.is-fit {
  /* Tighter chrome buys roughly a row's worth of height back from padding
     that is decorative, before any of it comes out of the cells. */
  padding: .85rem;
}

.am-bid-calendar.is-fit .fc .fc-toolbar.fc-header-toolbar {
  margin-bottom: .75rem;
}

/* The day number is the other thing setting a cell's natural height: at rest
   it is 34px, most of which is padding around a 22px numeral. Tightened here
   only, where the height is being fought over. */
.am-bid-calendar.is-fit .fc .fc-daygrid-day-number {
  padding: .1rem .45rem;
}

.am-bid-calendar.is-fit .fc .fc-day-today .fc-daygrid-day-number {
  margin: .1rem;
}

/* Back to one line per chip in fit mode.
   Names are clamped to two lines at rest, which is what makes them readable --
   but fit mode exists to get the whole month into the window without scrolling,
   and a second line on every chip is the largest single thing standing in the
   way of that. The full name is still on the chip's title, and the day modal
   lists them in full. */
.am-bid-calendar.is-fit .am-marker-name {
  -webkit-line-clamp: 1;
}

/* The subscribe band, on one line.

   Its heading and its explanation are stacked, which makes a 89px block out of
   two short sentences sitting under the thing people actually came for. Side
   by side they are one line and about 45px, with no words removed -- and they
   still wrap back to two lines when the window is too narrow to hold them,
   because the flex row is allowed to wrap. */
/* --am-cal-slack is whatever height the day cells could not use: cal.js grows
   the rows first and writes the remainder onto the page container, which this
   inherits (the band is the calendar's sibling, so it cannot come off the
   calendar itself). Zero on a window the grid fills, which is most of them --
   the fallback is what makes this an ordinary margin the rest of the time.

   The effect is that the band rides down to the bottom of the page instead of
   leaving a strip of dead space between itself and the footer. Nothing here
   pins it: if the month is tall enough to need every pixel, the band sits
   directly under the grid exactly as before. */
.am-bid-calendar.is-fit ~ .am-cal-subscribe {
  margin-top: calc(.65rem + var(--am-cal-slack, 0px));
  padding-block: .5rem;
}

.am-bid-calendar.is-fit ~ .am-cal-subscribe .am-cal-subscribe-text {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .15rem .6rem;
}

/* =========================
   FullCalendar surface & toolbar
   ========================= */

.am-bid-calendar .fc {
  /* Grid lines are blended toward the card they sit on rather than taking the
     card's own border colour. Six rows by seven columns is 60-odd lines; at
     full border weight that net is the loudest thing in the card, and in an
     empty month it is the ONLY thing in it. Mixing against the surface keeps
     the structure legible and stops it competing with the dates. */
  --fc-border-color: color-mix(in oklab, var(--am-border, #E2E5EA) 68%, var(--am-surface, #fff));
  --fc-page-bg-color: transparent;
  --fc-neutral-bg-color: var(--am-surface-sunk, #F7F8FA);
  --fc-today-bg-color: transparent; /* replaced by our own treatment below */

  font-size: var(--am-text-sm, .9rem);
  color: var(--am-text, #1F2530);
}

/* Month title */
.am-bid-calendar .fc .fc-toolbar-title {
  font-size: var(--am-text-xl, 1.4rem);
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--am-text, #1F2530);
}

.am-bid-calendar .fc .fc-toolbar.fc-header-toolbar {
  margin-bottom: 1.25rem;
  gap: .5rem;
  flex-wrap: wrap;
}

/* One left-aligned group: today, pager, month.

   These chunks used to be given `flex: 1 1 0` so that a centred title would
   land on the exact centre line whatever sat either side of it. cal.js no
   longer centres the title, and equal-thirds is actively wrong for the layout
   it does ask for: the two empty chunks would claim two thirds of the toolbar
   and push the controls off the left. Natural widths leave the one populated
   chunk exactly as wide as its contents, at the start of the row. */
.am-bid-calendar .fc .fc-toolbar.fc-header-toolbar > .fc-toolbar-chunk {
  display: flex;
  align-items: center;
  gap: .5rem;
}

/* The month is a heading, not a fourth button: the extra space before it is
   what separates "controls" from "what you are looking at", so the pager reads
   as a pair rather than as three things in a row. */
.am-bid-calendar .fc .fc-toolbar-chunk .fc-toolbar-title {
  margin-inline-start: .5rem;
}

/* Today / prev / next */
.am-bid-calendar .fc .fc-button-primary {
  background-color: transparent;
  border-color: var(--am-border-strong, #C9CED7);
  color: var(--am-text, #1F2530);
  border-radius: var(--am-radius-sm, 6px);
  padding: .35rem .8rem;
  font-size: var(--am-text-sm, .875rem);
  font-weight: 550;
  text-transform: capitalize;
  box-shadow: none;
  transition: background-color 160ms, border-color 160ms, color 160ms;
}

.am-bid-calendar .fc .fc-button-primary:hover {
  background-color: var(--am-surface-sunk, #F7F8FA);
  border-color: var(--am-border-strong, #C9CED7);
  color: var(--am-red, #ED1C24);
}

.am-bid-calendar .fc .fc-button-primary:disabled {
  background-color: transparent;
  border-color: var(--am-border, #E2E5EA);
  color: var(--am-text-subtle, #646D79);
  opacity: 1;
}

/* Keyboard focus. FullCalendar ships its own focus shadow on .fc-button; this
   replaces it with the site's ring and, critically, keeps it visible. */
.am-bid-calendar .fc .fc-button-primary:focus,
.am-bid-calendar .fc .fc-button-primary:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--am-surface, #fff), 0 0 0 4px var(--am-accent, #272E7E);
}

.am-bid-calendar .fc .fc-button-active {
  background-color: var(--am-red, #ED1C24);
  border-color: var(--am-red, #ED1C24);
  color: #fff;
}

/* Weekday header row */
.am-bid-calendar .fc .fc-col-header-cell {
  background: var(--am-surface-sunk, #F7F8FA);
}

.am-bid-calendar .fc-col-header-cell-cushion {
  display: block;
  padding: .6rem .25rem;
  color: var(--am-text-muted, #5E6673);
  font-weight: 700;
  font-size: var(--am-text-xs, .78rem);
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
}

/* Day cells. Only days with something due are interactive, so only those get
   the pointer and the hover wash -- the old rule invited a click on all 35
   cells and 33 of them did nothing. */
.am-bid-calendar .fc .fc-daygrid-day {
  transition: background-color 160ms;
}

/* A day with work on it, at rest.
   Previously indistinguishable from the 33 empty cells around it until you
   hovered -- which is no use at all for the question this grid exists to answer,
   "where is the work this month". The cell now carries a faint wash, so a month
   with five live bids shows five lit cells the moment it paints. Faint on
   purpose: the chips inside are the content, and a cell fill strong enough to
   compete with them would make the grid loud without making it clearer. */
.am-bid-calendar .fc .fc-daygrid-day.am-has-events {
  cursor: pointer;
  background-color: color-mix(in oklab, var(--am-accent, #272E7E) 9%, transparent);
}

.am-bid-calendar .fc .fc-daygrid-day.am-has-events:hover {
  background-color: color-mix(in oklab, var(--am-accent, #272E7E) 16%, transparent);
}

/* The date numeral is the other half of the scanning cue, and it costs nothing:
   a day with something due states its number at full contrast and weight, an
   empty day steps back. Reading down a column, the bold numbers are the days
   that matter.

   The two exclusions are load-bearing, not defensive. This selector carries five
   classes, which beats both `.fc-day-today .fc-daygrid-day-number` (four) and
   `.fc-day-other .fc-daygrid-day-number` (four) on specificity regardless of
   source order -- so without them an eventless today would have had its white
   numeral repainted grey on top of its red pill, and out-of-month dates would
   have been LIFTED from subtle to muted, i.e. made more prominent by a rule
   whose whole purpose is to recede. */
.am-bid-calendar .fc .fc-daygrid-day:not(.am-has-events):not(.fc-day-today):not(.fc-day-other) .fc-daygrid-day-number {
  color: var(--am-text-muted, #5E6673);
}

.am-bid-calendar .fc .fc-daygrid-day.am-has-events .fc-daygrid-day-number {
  font-weight: 700;
}

.am-bid-calendar .fc .fc-daygrid-day.am-has-events:focus-visible {
  outline: 2px solid var(--am-accent, #272E7E);
  outline-offset: -2px;
  background-color: var(--am-surface-sunk, #F7F8FA);
}

.am-bid-calendar .fc .fc-daygrid-day-number {
  padding: .4rem .5rem;
  color: var(--am-text, #1F2530);
  font-size: var(--am-text-sm, .875rem);
  font-variant-numeric: tabular-nums;
  text-decoration: none;
}

.am-bid-calendar .fc .fc-day-other .fc-daygrid-day-number {
  color: var(--am-text-subtle, #646D79);
}

/* Today: a filled chip on the date itself rather than a wash across the whole
   cell, which used to fight with the hover state. */
.am-bid-calendar .fc .fc-day-today .fc-daygrid-day-number {
  background: var(--am-red, #ED1C24);
  color: #fff;
  font-weight: 700;
  border-radius: var(--am-radius-pill, 999px);
  padding-inline: .55rem;
  margin: .25rem;
}

/* The marker sits in normal flow at the bottom of the cell, so the frame is a
   column with the day number at the top and whatever space is left below. */
.am-bid-calendar .fc .fc-daygrid-day-frame {
  display: flex;
  flex-direction: column;
  min-height: var(--am-cal-day-min, 5.75rem);
  padding-bottom: .3rem;
}

/* Hide FullCalendar's built-in event rows in month view -- we draw our own
   per-day count markers instead. */
.am-bid-calendar .fc-daygrid-event-harness,
.am-bid-calendar .fc-daygrid-event,
.am-bid-calendar .fc-daygrid-dot-event {
  display: none;
}

/* ...and reclaim the space FullCalendar reserves for them.

   .fc-daygrid-day-events carries a 2em (28px) min-height so an empty day still
   leaves room for an event row to appear in. Every event inside it is display:
   none here and our markers are appended to the day frame instead, so that
   28px was 28px of nothing -- in every cell, of every week, of every month.
   Six rows of it came to 168px, which is why a day cell would not go below
   82px however low the floor was set.

   Deliberately not scoped to fit mode: the reservation is equally pointless at
   full size. It simply was not visible there, because --am-cal-day-min holds
   an ordinary cell at 5.75rem and that is taller than the content either way.
   Removing it changes nothing about how the calendar looks at rest, and makes
   the floor mean what it says when something lowers it. */
.am-bid-calendar .fc .fc-daygrid-day-events {
  min-height: 0;
}

/* =========================
   Americon day markers
   ========================= */

/* --- Marker colours ------------------------------------------------------
   WHY THESE EXIST RATHER THAN USING --am-blue DIRECTLY
   ----------------------------------------------------
   --am-blue is a BRAND CONSTANT: #272E7E in both themes, by design, because a
   logo does not change colour with an OS setting. Every other semantic token in
   the theme wraps it -- --am-accent is light-dark(--am-blue, --am-blue-bright)
   for exactly this reason.

   The public marker used the raw constant, and in dark mode that made it
   invisible. #272E7E is DARKER than the #1A1F26 cell it sits on, so a 14% tint
   of it was a near-black smear on near-black, and the 3px left border meant to
   carry the public/private distinction was near-black too. Two live bids on a
   day looked like an empty day until you hovered it.

   Private never had the bug: --am-teal is already light-dark(). So the fix is
   not "make the markers louder", it is "give public the same treatment private
   already had" -- and then both get the weight below. */
.am-bid-calendar {
  --am-cal-public: #272E7E;
  --am-cal-public: light-dark(#272E7E, #8A93F0);
  --am-cal-private: var(--am-teal, #0F7A57);

  /* How much of that hue goes into the chip fill. High enough to read as a
     filled chip at a glance across a 7x6 grid, low enough that the project name
     on top of it still clears AA. */
  --am-cal-tint: 26%;
}

.am-bid-calendar .am-marker {
  /* Directly under the day number, not pinned to the bottom of the cell.
     It used `margin-top: auto`, which pushed the chips to the floor of a 92px
     cell -- so the number and the work due on that number sat an inch apart
     with nothing between them, and the eye had to pair them up. Every calendar
     application puts the entries under the date because that is what reads as
     "on this day". Growth still pushes the row taller rather than overlapping,
     which is all the auto margin was protecting. */
  margin-top: .15rem;
  padding-inline: .3rem;
  min-width: 0;               /* lets the ellipsis below actually engage */
  pointer-events: none;       /* clicks belong to the cell */
}

/* --- Names (the default at any width that can read them) ----------------- */

.am-bid-calendar .am-marker-names {
  display: flex;
  flex-direction: column;
  gap: .15rem;
  min-width: 0;
}

.am-bid-calendar .am-marker-name {
  /* Two lines, then ellipsis.
     It was one line, and one line of a 185px cell is about 22 characters -- so
     every real project name ended in "..." and the chips were legible without
     being readable. "Baraboo Fire Station 2 Re-Roof" fits in two.

     The clamp does the same job the old nowrap did: it caps the height and hides
     the rest, so a long name still cannot set the width of a grid column (the
     parent's min-width:0 is what guarantees that). Deliberately not three --
     past two lines a busy day starts pushing its week taller than its
     neighbours. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;

  /* Takes the pointer back from .am-marker, which sets pointer-events:none for
     the whole group. cal.js has always set `chip.title = chip.textContent`, and
     that tooltip could never appear because nothing in the marker could be
     hovered -- an accessible name written and then made unreachable. Clicks
     still bubble to the cell, so the day modal is unaffected. */
  pointer-events: auto;

  /* Sized to be seen. At --am-text-xs with 1.6px of vertical padding these were
     11px of 600-weight text on a barely-tinted ground: technically present,
     practically missed. A calendar entry is the payload of this whole screen and
     it was the quietest thing on it. */
  padding: .2rem .4rem;
  border-radius: var(--am-radius-sm, .3rem);
  font-size: var(--am-text-sm, .8125rem);
  font-weight: 600;
  line-height: 1.25;

  /* Colour is a secondary cue only -- the left border carries the same
     public/private distinction for anyone who cannot separate the hues, and the
     1px inset ring gives the chip a definite edge so it reads as an object
     rather than as a patch of slightly different background. */
  border-left: 4px solid transparent;
  background: var(--am-surface-sunk, #F7F8FA);
  color: var(--am-text, #1F2530);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--am-text-muted, #5E6673) 22%, transparent);
}

/* Public blue, private teal.

   Private was red, which collided with the urgency scale the moment red was
   reserved for "closing today" -- the same hue naming a category here and a
   deadline three cells over. Teal was measured against the rest of the set
   rather than picked: see the --am-teal note in the theme's token block for
   the pairs that ruled out violet and magenta.

   The tint is a fill now, not only a 3px edge. A left border alone is about
   nine pixels of colour in a cell that may be 40px tall in fit mode, which is
   not enough to sort public from private while scanning a month. */
.am-bid-calendar .am-marker-name.am-public {
  border-left-color: var(--am-cal-public);
  background: color-mix(in oklab, var(--am-cal-public) var(--am-cal-tint), var(--am-surface-sunk, #F7F8FA));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--am-cal-public) 45%, transparent);
}

.am-bid-calendar .am-marker-name.am-private {
  border-left-color: var(--am-cal-private);
  background: color-mix(in oklab, var(--am-cal-private) var(--am-cal-tint), var(--am-surface-sunk, #F7F8FA));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--am-cal-private) 45%, transparent);
}

/* --- The overflow row ----------------------------------------------------
   "+2 more" is the only thing on the grid that distinguishes a day holding four
   bids from a day holding two, and it was plain muted text sitting under two
   weighted chips: the least prominent element in the cell carrying the fact
   most likely to be missed. Once the chips gained weight it became the weakest
   thing in a populated cell by a distance.

   It now borrows the chips' geometry and takes an accent tint, so it reads as
   the continuation of the list rather than as a caption about it. It hugs its
   own content instead of stretching, which is what keeps it subordinate to the
   full-width chips above -- it is a pointer to more, not another entry.

   TEXT COLOUR IS --am-text, NOT --am-accent
   -----------------------------------------
   The obvious move is accent-coloured text to say "interactive". In dark mode
   --am-accent resolves to --am-blue-bright (#5964D3), which measures about
   3.4:1 against the cell -- under AA for text this size, and this is 11px. The
   tint and the ring carry the affordance instead, exactly as the name chips do,
   and the label stays at full contrast. */
.am-bid-calendar .am-marker-more {
  align-self: flex-start;   /* .am-marker-names is a flex column: don't stretch */
  margin-top: .05rem;
  padding: .1rem .4rem;
  border-radius: var(--am-radius-sm, .3rem);
  font-size: var(--am-text-xs, .7rem);
  font-weight: 700;
  color: var(--am-text, #1F2530);
  background: color-mix(in oklab, var(--am-accent, #272E7E) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--am-accent, #272E7E) 35%, transparent);

  /* Takes the pointer back from .am-marker for a cursor and a hover state only.
     It is not a button: the whole cell opens the day modal that lists every
     item in full, and a click here bubbles to that cell exactly as before. */
  pointer-events: auto;
  cursor: pointer;
}

/* Responds to the cell, not to itself, so hovering anywhere in the day lights
   the thing that will answer "what else is in here". */
.am-bid-calendar .fc-daygrid-day.am-has-events:hover .am-marker-more {
  background: color-mix(in oklab, var(--am-accent, #272E7E) 22%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--am-accent, #272E7E) 60%, transparent);
}

/* Count pills are the narrow-width fallback; hidden while names are shown. */
.am-bid-calendar .am-marker-counts {
  display: none;
  gap: .3rem;
  justify-content: center;
}

.am-bid-calendar .am-count {
  min-width: 1.35rem;
  height: 1.35rem;
  padding: 0 .4rem;
  border-radius: var(--am-radius-pill, 999px);
  font-size: var(--am-text-xs, .7rem);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.am-bid-calendar .am-count.am-public {
  background-color: var(--am-blue, #272E7E);
}

.am-bid-calendar .am-count.am-private {
  /* Teal, not red -- same reservation as the name chips above. */
  background-color: var(--am-teal, #0F7A57);
}

/* --- Urgency -------------------------------------------------------------
   cal.js already works out, per day, whether anything closes soon, whether
   the day is past, or neither, and writes that onto the marker:

       marker.className = "am-marker " + (rec.status || "upcoming");

   Nothing has ever styled those classes, so the single most decision-relevant
   fact on this screen -- "something closes imminently" -- was computed and
   then thrown away. A coordinator had to open each day to find out.

   Colour is not the only carrier here: "soon" also gets a ring and a pulse,
   because red-vs-blue pills alone are invisible to a red-green colourblind
   viewer, and roughly 1 in 12 men are. */

.am-bid-calendar .am-marker.soon .am-count {
  box-shadow:
    0 0 0 2px var(--am-surface, #fff),
    0 0 0 4px var(--am-amber, #F59E0B);
}

/* On a name chip the same fact is carried by a tinted background and a ring,
   because a pulsing rectangle the width of the cell is agitating rather than
   informative. */
.am-bid-calendar .am-marker.soon .am-marker-name {
  /* Blended against transparent rather than hardcoded, matching the theme's
     own tinted-surface pattern: the same rule then works in dark mode, where
     a fixed #FEF3C7 would be a bright slab. Text colour is left alone for the
     same reason. */
  background: color-mix(in oklab, var(--am-amber, #F59E0B) 22%, transparent);
  box-shadow: inset 0 0 0 1px var(--am-amber, #F59E0B);
}

/* Draws the eye to the imminent deadline without animating the whole grid. */
@media (prefers-reduced-motion: no-preference) {
  .am-bid-calendar .am-marker.soon .am-count {
    animation: am-pulse 2.4s var(--am-ease, ease-in-out) infinite;
  }
}

@keyframes am-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.09); }
}

/* --- Closing today -------------------------------------------------------
   The top of the urgency scale, and the one the KPI tile calls "closing
   today" -- so it wears the same red, and nothing else on the calendar does.

   Purely a matter of which cell this is, so it needs nothing from the API:
   FullCalendar already puts .fc-day-today on the cell, and cal.js already only
   emits a marker for a day that has something due. The pair is the condition.

   This is the strongest treatment in the grid on purpose. A bid closing before
   midnight is the single most decision-relevant fact the calendar holds, and
   until now it looked exactly like one closing in three weeks. */
.am-bid-calendar .fc .fc-day-today .am-marker-name {
  background: color-mix(in oklab, var(--am-red, #ED1C24) 20%, transparent);
  border-left-color: var(--am-red, #ED1C24);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--am-red, #ED1C24) 55%, transparent);
  font-weight: 700;
}

.am-bid-calendar .fc .fc-day-today .am-count {
  background-color: var(--am-red, #ED1C24);
  box-shadow:
    0 0 0 2px var(--am-surface, #fff),
    0 0 0 4px color-mix(in oklab, var(--am-red, #ED1C24) 60%, transparent);
}

/* Past days recede so the eye lands on what is still actionable. */
.am-bid-calendar .am-marker.past .am-count,
.am-bid-calendar .am-marker.past .am-marker-name,
.am-bid-calendar .am-marker.past .am-marker-more {
  opacity: .45;
  filter: saturate(.5);
}

.am-bid-calendar .fc-daygrid-day:hover .am-marker.past .am-count,
.am-bid-calendar .fc-daygrid-day:hover .am-marker.past .am-marker-name,
.am-bid-calendar .fc-daygrid-day:hover .am-marker.past .am-marker-more {
  opacity: 1;
  filter: none;
}

/* --- Narrow: names out, counts in ----------------------------------------
   A month grid on a phone gives each cell about six characters of width.
   A truncated project name at that size is worse than a number -- it looks
   like data loss -- so below this width the cells go back to count pills and
   the day modal carries the detail. */
@container (max-width: 34rem) {
  /* Set on .fc, not on .am-bid-calendar: .am-bid-calendar is itself the
     container being queried, and a container query resolves against the
     nearest *ancestor* container -- so a rule selecting the container element
     never matches its own query. .fc is the first descendant, and the day
     frames inherit from it. */
  .am-bid-calendar .fc {
    --am-cal-day-min: 3.5rem;
  }

  .am-bid-calendar .am-marker-names {
    display: none;
  }

  .am-bid-calendar .am-marker-counts {
    display: flex;
  }

  .am-bid-calendar .am-count {
    min-width: 1.05rem;
    height: 1.05rem;
    padding: 0 .25rem;
    font-size: .62rem;
  }
}

/* =========================
   List view
   =========================

   The second view behind the Month/List switch. It exists to answer the two
   questions the grid structurally cannot: what closes NEXT (a grid has no
   reading order -- you scan seven columns and five rows and assemble the
   sequence yourself), and at what TIME (a name chip in a 40px cell has no room
   for one, so the due time sat in the REST payload unrendered).

   Everything below is the theme's tokens rather than FullCalendar's stock list
   styling, which is a light-mode table with hairline borders and would have
   been a white slab in the middle of a dark card. */

.am-bid-calendar .fc .fc-list {
  border: 1px solid var(--fc-border-color);
  border-radius: var(--am-radius-sm, 6px);
  overflow: hidden;      /* clips the day-header fill to the rounded corners */
}

/* The date header above each group of rows. Sunk, like the weekday header of
   the grid, so both views separate "label" from "content" the same way. */
.am-bid-calendar .fc .fc-list-day-cushion {
  padding: .5rem .85rem;
  background: var(--am-surface-sunk, #F7F8FA);
}

.am-bid-calendar .fc .fc-list-day-text,
.am-bid-calendar .fc .fc-list-day-side-text {
  font-size: var(--am-text-sm, .875rem);
  font-weight: 700;
  color: var(--am-text, #1F2530);
  text-decoration: none;
}

/* The weekday, on the right of the header, is orientation rather than
   information -- the date beside it already says which day it is. */
.am-bid-calendar .fc .fc-list-day-side-text {
  font-weight: 550;
  color: var(--am-text-muted, #5E6673);
}

.am-bid-calendar .fc .fc-list-event td {
  padding: .55rem .85rem;
  vertical-align: top;
  transition: background-color 160ms;
}

.am-bid-calendar .fc .fc-list-event:hover td {
  background: color-mix(in oklab, var(--am-accent, #272E7E) 8%, transparent);
}

/* The due time. Tabular figures so the colons line up down the column, which
   is the whole reason to give the time its own column rather than trailing it
   after the project name. */
.am-bid-calendar .fc .fc-list-event-time {
  width: 1%;             /* shrink-to-fit: the names get the rest */
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--am-text-muted, #5E6673);
}

/* FullCalendar's colour dot, removed. It encodes one bit in a 10px circle with
   no legend anywhere on the page; the Public/Private badge below says the same
   thing in a word, and a badge and a dot saying it twice is just noise. */
.am-bid-calendar .fc .fc-list-event-graphic {
  display: none;
}

.am-bid-calendar .fc .fc-list-event-title > a {
  display: block;        /* puts .am-list-meta on its own line underneath */
  font-weight: 600;
  color: var(--am-text, #1F2530);
  text-decoration: none;
}

.am-bid-calendar .fc .fc-list-event:hover .fc-list-event-title > a {
  text-decoration: underline;
}

/* Badge and jurisdiction, as one quiet second line. Subordinate to the name on
   purpose: it is what you read once the name has caught your eye, not
   something competing with it down the column. */
.am-bid-calendar .am-list-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .3rem .5rem;
  margin-top: .2rem;
}

.am-bid-calendar .am-list-badge {
  padding: .05rem .4rem;
  border-radius: var(--am-radius-sm, .3rem);
  font-size: var(--am-text-xs, .7rem);
  font-weight: 700;
  color: var(--am-text, #1F2530);
}

/* Same two colours as the grid chips, from the same tokens, so a bid does not
   change colour when you change view. */
.am-bid-calendar .am-list-badge.am-public {
  background: color-mix(in oklab, var(--am-cal-public) var(--am-cal-tint), var(--am-surface-sunk, #F7F8FA));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--am-cal-public) 45%, transparent);
}

.am-bid-calendar .am-list-badge.am-private {
  background: color-mix(in oklab, var(--am-cal-private) var(--am-cal-tint), var(--am-surface-sunk, #F7F8FA));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--am-cal-private) 45%, transparent);
}

.am-bid-calendar .am-list-loc {
  font-size: var(--am-text-xs, .78rem);
  color: var(--am-text-muted, #5E6673);
}

/* --- Urgency, matching the grid ------------------------------------------
   cal.js writes am-ev-soon / am-ev-past onto the row from the same status the
   day markers use. Carried as an edge rather than a fill: a full-width amber
   row in a list reads as an error state, and these are ordinary bids that
   happen to be close. */
.am-bid-calendar .fc .fc-list-event.am-ev-soon > td:first-child {
  box-shadow: inset 3px 0 0 0 var(--am-amber, #F59E0B);
}

.am-bid-calendar .fc .fc-list-event.am-ev-soon .fc-list-event-time {
  color: var(--am-text, #1F2530);
  font-weight: 700;
}

/* Past bids recede but stay listed and stay clickable -- "did I miss it" is a
   real question and the answer has to be visible to be given. Restored on
   hover, exactly as the grid does it. */
.am-bid-calendar .fc .fc-list-event.am-ev-past td {
  opacity: .5;
}

.am-bid-calendar .fc .fc-list-event.am-ev-past:hover td {
  opacity: 1;
}

/* --- The empty month ----------------------------------------------------- */

.am-bid-calendar .fc .fc-list-empty {
  background: transparent;   /* stock is --fc-neutral-bg-color, a grey slab */
}

.am-bid-calendar .am-list-empty {
  display: flex;
  flex-direction: column;
  gap: .25rem;
  padding: 2.5rem 1rem;
  color: var(--am-text-muted, #5E6673);
}

.am-bid-calendar .am-list-empty strong {
  color: var(--am-text, #1F2530);
}

/* =========================
   Day modal
   =========================

   The hover popover that used to occupy ~75 lines here is gone along with its
   markup and its JavaScript. It duplicated this modal exactly -- same
   projects, same links -- while being keyboard-inaccessible, inert on touch,
   and positioned by hand over the grid it was describing.
   ========================= */

.am-email-preview img {
  max-width: 100%;
  height: auto;
}
