/* ════════════════════════════════════════════════════════════════════════
   FAMILY CALENDAR — DAY VIEW stylesheet

   Owned by the Day lane. Loaded AFTER css/calendar.css (index.html, frozen),
   so a rule here wins at equal specificity. Class prefix `fc-day-*`
   throughout — `fc-sheet__*` is the mobile day SHEET (js/views/day-sheet.js +
   calendar.css SECTION 8) and is a different component.

   Nothing in this file edits css/calendar.css. (That file was "frozen at 12
   sections" when this one was written; it grew a SECTION 13 on 2026-08-07 for
   Year's and Month's data states, which is that file's own lane, not this
   one's — Day's are in SECTION 9 below.) This
   file declares its own tier in SECTION 1 below. Every name in it begins
   `--fc-day-`, which no name in calendar.css does — verified mechanically
   with contract §4's `comm -12` command, and the check is quoted in the build
   report. A redeclaration would silently re-theme Month and Year; there is no
   build step and no scoping to stop it.

   COLOUR SOURCE: DESIGN-DECISIONS.md §1, and the pixels of
   design-export-2026-08-04/exports/desktop-day.png + mobile-day.png sampled at
   2× with a stdlib PNG reader. UI-RULES.md §2's colour table is known-wrong
   and is consulted nowhere. Every value added below is quoted with the sample
   that justifies it. Everything that already has a token in calendar.css
   SECTION 1 references that token instead.

   MOTION: `160ms ease-out`, hardcoded, per contract §5 — motion is genuinely
   undesigned in this product (`token-architecture.md` names the estate-wide
   gap) and inventing a duration scale to fill it was explicitly ruled out.
   Every line carries TODO(motion-tokens). SECTION 8 degrades all of it.

   FOCUS: never suppressed. calendar.css's global
   `:where(a, button, [tabindex]):focus-visible` rule already paints
   `2px solid var(--fc-today)` at `outline-offset: 2px`, and this file
   inherits it everywhere. The only adjustment is `outline-offset: -2px` on
   controls that sit flush inside the clipped lane grid, so the ring is drawn
   fully INSIDE rather than half-clipped by the grid's rounded corners. An
   inset ring is still a visible ring; `outline: none` appears nowhere in this
   file.

   Sections:
     1  tokens (this view's own tier)
     2  view shell + the toolbar
     3  the person lane grid
     4  trip bars in a lane
     5  the week list
     6  cards, times, empty state
     7  mobile (≤ 430px)
     8  reduced motion
     9  data states — loading skeletons + the empty/error card host
   ════════════════════════════════════════════════════════════════════════ */


/* ════════════════════════════════════════════════════════════════════════
   SECTION 1 — DAY TOKENS, SCOPED TO THE COMPONENT

   Declared on `.fc-day`, NOT on `:root`. The estate ruling (2026-08-06,
   across all four view lanes): component tokens live on the component root
   and only genuinely brand-level values reach `:root`, where the skin mirrors
   them. `scripts/token-mirror.check.mjs` enforces it — every name declared in
   a `:root` block has to exist in
   projects/studio-tool-kit/brand-foundation/calendar.tokens.json, which is
   outside this lane's write envelope, so a `:root` block here fails the gate
   by construction. The Inspector lane's 18 constants set the precedent.

   Consequence for the JS, and it is the whole reason this is one change and
   not two: `js/views/day.js` can no longer read any of these off
   `document.documentElement`. It doesn't — see the note in that file's
   `tokens()`. The three values it used to read are now consumed in this file,
   where they are declared, and nowhere else.

   Inheritance: every rule below matches a descendant of `.fc-day`, so all 50
   inherit. The one exception is `.fc-day-title-sub`, which lives inside the
   shell's own `#fc-title` and therefore OUTSIDE this scope — it deliberately
   uses only calendar.css tokens.

   Promotion candidates — the handful that are arguably brand-level rather
   than component geometry — are named in the build report for the integrator
   to mirror. Nothing is promoted here.
   ════════════════════════════════════════════════════════════════════════ */
.fc-day {
  /* ── lane grid geometry. `104px repeat(7, minmax(0,1fr))` and lane height
     46px come from DESIGN-DECISIONS §3 "Where lanes", which spec 10 §2
     extends to Day as the same shared component. The 104px is confirmed to
     the pixel off desktop-day.png (grid content starts x=62, the gutter
     divider sits at x=270, at 2× → 104.0 CSS). The 46px is NOT: the mock
     measures 42–43 CSS per lane row. Spec 10's Anatomy pins 46, so 46 ships
     and the 3px discrepancy is reported rather than silently split. */
  --fc-day-gutter:      104px;
  --fc-day-lane-h:      46px;
  --fc-day-head-h:      44px;   /* measured: grid y=250→337 at 2× = 44 CSS */
  --fc-day-avatar:      22px;   /* measured: x=90→131 at 2× = 21 CSS */

  /* ── trip bars. 22px tall, radius 11 (DESIGN-DECISIONS §3), verified: the
     Madrid bar measures y=360→403 at 2× = 22 CSS exactly. The mid-day insets
     are unitless FRACTIONS OF A COLUMN, read by js/views/day.js rather than
     re-typed there, so the token block and the placement maths cannot
     disagree. Verified: Madrid starts 138/328 = 0.4207 into 12 Oct and ends
     0.5793 through 15 Oct; Bristol and Granny's measure the same. */
  --fc-day-bar-h:            22px;
  --fc-day-radius-bar:       11px;
  --fc-day-bar-inset-start:  0.42;
  --fc-day-bar-inset-end:    0.58;
  /* The soft coloured halo under a bar. Measured off desktop-day.png as a
     ~15 CSS px falloff either side of the bar (the gradient runs x=435→464 at
     2× against a bar starting at x=410); the alpha is fitted, not sampled —
     a flat PNG cannot be inverted to a shadow spec. Approximate, and reported
     as such. A PERCENTAGE, not the estate's two-hex-digit alpha suffix,
     because it is consumed by color-mix in SECTION 4 rather than composed
     onto a hex in JS — see the note on that rule. */
  --fc-day-bar-glow-alpha:   35%;

  /* ── lane cell grounds. DESIGN-DECISIONS §1's "home lane (Where)" and its
     "Weekend … Where lane"; both sampled exact off desktop-day.png (Laura's
     12 Oct cell, Laura's 18 Oct cell). PROMOTED 2026-08-06 — this lane and the
     Where lane each proposed them, and both are now brand tokens in
     calendar.css SECTION 1. The two names below are kept as the local aliases
     the 50-odd rules in this file already read, so the promotion is one edit
     here rather than fifty. */
  --fc-day-lane-home:    var(--fc-home-lane);
  --fc-day-lane-weekend: var(--fc-weekend-lane);
  /* `--fc-day-focus-head` (the focus column's header ground, --fc-glyph-tile-
     empty) was DELETED 2026-08-06 in the convergence pass, with the lane wash
     and the numeral tint that went with it. See SECTION 3's focus-column rule:
     the whole today-blue triplet was being spent on a NON-today day. */

  /* ── the week list. DESIGN-DECISIONS §3 "Day rows": padding 14/0, gap 18,
     date gutter 74px, location column 210px, radius 12. The time gutter and
     card widths are not in any numbered source — measured off desktop-day.png
     (row content runs x=96→1903 at 2×; the location dot lands at 140 CSS,
     "nothing scheduled" at 368 CSS, the card's colour edge at 434 CSS, the
     card's right edge at 952 CSS) and reported as measured. */
  --fc-day-date-col:    74px;
  --fc-day-loc-col:     210px;
  --fc-day-when-col:    48px;
  --fc-day-card-col:    518px;
  --fc-day-row-gap:     18px;
  --fc-day-row-pad-y:   14px;
  --fc-day-radius-row:  12px;
  --fc-day-list-inset:  18px;
  --fc-day-card-gap:    8px;   /* measured: 16 at 2× between stacked cards */
  --fc-day-card-min-h:  48px;  /* measured: 96 at 2× */
  --fc-day-dot:         9px;   /* measured: 18 at 2×; NOT calendar.css's 6px --fc-dot */

  /* ── type. FONTS.md §3 "Day" and "Where is everyone", confirmed by glyph
     measurement off desktop-day.png: the date numeral's digits run 39px at 2×
     ≈ 19.5 CSS cap height ≈ 26px at Plus Jakarta Sans's 0.73 cap ratio, and
     the "O" of "Oli's week" runs 30px at 2× ≈ 20px type — i.e. FONTS.md's
     26/800 numeral and its 19/800 section heading, both confirmed. */
  --fc-day-size-num:       26px;
  --fc-day-size-dow:       10px;
  --fc-day-size-when:      12px;
  --fc-day-size-title:     12.5px;
  --fc-day-size-sub:       11px;
  --fc-day-size-loc:       13px;
  --fc-day-size-home:      11px;
  --fc-day-size-person:    12px;
  --fc-day-size-avatar:    11px;
  --fc-day-size-head-num:  15px;
  --fc-day-size-head-dow:  9px;
  --fc-day-size-list-head: 19px;
  --fc-day-size-range:     12.5px;
  --fc-day-size-bar:       11px;

  /* ── mobile tier (≤430px) ─────────────────────────────────────────────── */
  --fc-day-m-chip-gap:     5px;
  --fc-day-m-chip-h:       44px;   /* BUILD-ANSWERS D3, above the 24px AA floor */
  --fc-day-m-chip-r:       12px;
  /* Sampled off mobile-day.png: the normal chip #F5F7FB is already a token in
     calendar.css (the weekday-chip one); the focused chip is ink; the holiday
     chip is DESIGN-DECISIONS' inspector-holiday pair — that ground was
     promoted to a brand token 2026-08-06 and is referenced below rather than
     restated. The weekend chip #EDF1F8 has no token — the weekend-chip one is
     #E7EDF9, a different and stronger value — and it was deliberately NOT
     promoted with the other four at integration: it appears nowhere in
     DESIGN-DECISIONS and this is its only consumer. So it stays here.
     (Token names are deliberately not written at the start of a line in this
     file's comments: contract §4's collision command is a plain grep for
     `^\s*--fc-` and cannot tell prose from a declaration.) */
  --fc-day-m-chip-weekend: #EDF1F8;
  --fc-day-m-chip-holiday: var(--fc-holiday-chip-inspector);
  /* 46px fits `21:05` (measured 39 CSS in mobile-day.png) but NOT `2h 30m`,
     which wrapped to two lines and spilled left of the column on the first
     headless render. 54px, plus nowrap on the gutter lines. */
  --fc-day-m-when-col:     54px;
  --fc-day-m-rail-col:     32px;
  --fc-day-m-mark:         13px;
  --fc-day-m-band-r:       12px;
  --fc-day-m-size-chip-num: 13px;
  --fc-day-m-size-chip-dow: 9.5px;
  --fc-day-m-size-band:     12.5px;
  --fc-day-m-size-title:    12.5px;
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 2 — VIEW SHELL + TOOLBAR
   ════════════════════════════════════════════════════════════════════════ */
.fc-day {
  display: block;
}

/* The muted `October 2026` beside `Thu 15` in the screen-title slot on
   mobile. Sampled #9AA3B4 — calendar.css's --fc-text-muted-3, the same token
   the title qualifier uses. NOT --fc-title-year's --fc-text-faint (#C3CAD8),
   which is two steps lighter and fails contrast at this size. */
.fc-day-title-sub {
  color: var(--fc-text-muted-3);
  font-weight: var(--fc-weight-medium);
}

.fc-day-toolbar {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 16px;
}

.fc-day-people {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Person tabs. Active = filled person colour with a white label; inactive =
   the quiet neutral pill track. Type is Where's person-name pair (12/700,
   800 when selected — FONTS.md §3 "Where is everyone"). Inactive label
   sampled #5C6679; active label white on the person's own hue. */
.fc-day-person {
  appearance: none;
  border: 0;
  cursor: pointer;
  font-family: inherit;
  font-size: var(--fc-day-size-person);
  font-weight: var(--fc-weight-semibold);
  color: var(--fc-text-secondary);
  background: var(--fc-pill-track);
  border-radius: var(--fc-radius-pill);
  padding: 9px 18px;
  transition: background-color 160ms ease-out, color 160ms ease-out; /* TODO(motion-tokens) */
}
.fc-day-person:hover { background: var(--fc-neutral-chip); }
.fc-day-person--on {
  background: var(--person-c);
  color: var(--fc-text-on-fill);
  font-weight: var(--fc-weight-bold);
}
.fc-day-person--on:hover { background: var(--person-c); }

/* The selected person's trip, right-aligned. Blank when they have none
   covering the focused date — js/views/day.js does not render the node at
   all rather than leaving an empty slot. Sampled #8A94A6. */
.fc-day-context {
  margin-left: auto;
  font-size: var(--fc-day-size-range);
  font-weight: var(--fc-weight-medium);
  color: var(--fc-text-muted);
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 3 — THE PERSON LANE GRID
   ════════════════════════════════════════════════════════════════════════ */
.fc-day-grid {
  position: relative;
  border: 1px solid var(--fc-hairline-card);
  border-radius: var(--fc-radius-grid);
  background: var(--fc-surface-card);
  /* Clips the cell grounds to the rounded corners, which is what the render
     shows. The cost is that an OUTSET focus ring on an edge cell would be
     half-eaten — so those controls take an inset ring instead (see below).
     The bar layer is inside this box and is unaffected. */
  overflow: hidden;
}

.fc-day-head,
.fc-day-lane {
  display: grid;
  grid-template-columns: var(--fc-day-gutter) repeat(7, minmax(0, 1fr));
}
.fc-day-head { min-height: var(--fc-day-head-h); }
.fc-day-lane {
  position: relative;
  min-height: calc(var(--fc-day-lane-h) * var(--lane-rows, 1));
  /* Sampled #F0F2F7 at the header/lane and lane/lane boundaries. */
  border-top: 1px solid var(--fc-hairline-row);
}

/* Every vertical divider in the grid samples #E4E9F2 — the gutter/columns one
   at x=270 and the inter-column ones at 600 / 930 / 1260 / 1588.
   `border: 0` FIRST, because .fc-day-cell is a <button> and the UA's own
   border is not covered by `appearance: none` — the first headless render of
   this file drew a black box round all 21 cells. */
.fc-day-head-cell,
.fc-day-cell {
  border: 0;
  border-left: 1px solid var(--fc-divider);
}

.fc-day-head-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  background: var(--fc-surface-card);
}
.fc-day-head-num {
  font-size: var(--fc-day-size-head-num);
  font-weight: var(--fc-weight-bold);
  letter-spacing: var(--fc-track-tight);
  color: var(--fc-text-ink);
}
.fc-day-head-dow {
  font-size: var(--fc-day-size-head-dow);
  font-weight: var(--fc-weight-semibold);
  letter-spacing: var(--fc-track-caps);
  color: var(--fc-text-dow);
}
.fc-day-head-cell--weekend { background: var(--fc-day-lane-weekend); }
.fc-day-head-cell--weekend .fc-day-head-num { color: var(--fc-text-weekend-num); }
/* The focus column's header carries NO GROUND AND NO TINT of its own — the
   column outline below is the whole mark. It used to take #EEF3FE with #2F5BD0
   numerals, sampled from desktop-day.png; both are today values, and the
   focused day is not today. See the focus-column rule in this section. */
/* Past day, whole date block: a uniform wash dims ground and type together,
   which is the case BUILD-ANSWERS C7 explicitly allows. Untested against any
   render — the reference week is entirely in the future. */
.fc-day-head-cell--past { opacity: 0.55; }

/* ── TODAY. THE NAMED RESIDUAL, CLOSED — 2026-08-07 ────────────────────────
   The focus-column rule below records it verbatim: "Day has no real today
   treatment at all — it never had one, and freeing the today tokens does not
   create one. If today falls inside the rendered week it is currently
   unmarked on this screen."

   It was measured, not assumed: `[class*=today]` returned 0 nodes on
   `#/day/2026-10-15` at both 1440 and 390, and js/views/day.js contained no
   `today` reference of any kind. A calendar's Day view could not locate the
   present.

   It is NOT invented here — that was the right call in the convergence pass
   and it is still the right call. The treatment is LIFTED from the two
   surfaces that already carry one and agree with each other, Year
   (`.fc-year__cell--today`) and mobile Month (`.fc-m-cell--today`): the
   --fc-m-today-cell ground, a 1.5px inset ring in --fc-m-today-ring, and the
   numeral in --fc-today-numeral at 800. Three surfaces, one mark, no fourth
   dialect.

   It lands on the HEADER cell, not on the three lane cells beneath it. The
   numeral lives here, so this is where a reader looks for a date; and the
   lane cells already carry the home/away wash, which is the answer this screen
   exists to give — a blue column over all three would compete with it and with
   the ink focus outline that spans the same column. One mark, at the top of
   the column, on the element that names the day.

   The ink focus outline still wins its own perimeter: it is drawn at z-index 4
   over the whole column, so a day that is both today and focused reads as
   focused-and-today rather than as either alone. That is correct — they are
   different facts.

   CONTRAST, stated rather than implied. The numeral is the accessible carrier:
   #2F5BD0 over the composited ground (#E3EAFD) is 4.95:1, AA, against
   #7E8CA3 on #F1F5FB for the weekend sibling. The 1.5px ring composites to
   #A3BCF9 and is 1.81:1 against the ground — below the 3:1 non-text floor, and
   left exactly as Year and mobile Month ship it rather than strengthened on
   this one surface. It is a fourth channel on top of colour, weight and the
   accessible name, never the sole carrier. Named in the build report as an
   estate-wide residual. */
.fc-day-head-cell--today {
  background: var(--fc-m-today-cell);
  box-shadow: inset 0 0 0 1.5px var(--fc-m-today-ring);
}
.fc-day-head-cell--today .fc-day-head-num {
  color: var(--fc-today-numeral);
  font-weight: var(--fc-weight-bold);
}

/* ── one person's lane ─────────────────────────────────────────────────── */
.fc-day-lane-gutter {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  position: relative;
  z-index: 2;
  background: var(--fc-surface-card);
}
.fc-day-avatar {
  flex: 0 0 auto;
  width: var(--fc-day-avatar);
  height: var(--fc-day-avatar);
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--avatar-ground);
  color: var(--lane-c);
  font-size: var(--fc-day-size-avatar);
  font-weight: var(--fc-weight-bold);
  line-height: var(--fc-leading-flat);
}
/* Required, always visible: two people look identical in a quiet week and the
   NAME is what tells them apart (spec 10 §2, spec 08 §2). */
.fc-day-lane-name {
  font-size: var(--fc-day-size-person);
  font-weight: var(--fc-weight-semibold);
  color: var(--fc-text-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fc-day-cell {
  appearance: none;
  cursor: pointer;
  padding: 0;
  background: var(--fc-surface-card);
  /* Inside the grid's `overflow:hidden`, so the ring is drawn INSIDE the
     cell. Still 2px of --fc-today, still never suppressed. */
  outline-offset: -2px;
}
.fc-day-cell--home    { background: var(--fc-day-lane-home); }
.fc-day-cell--weekend { background: var(--fc-day-lane-weekend); }
/* `.fc-day-cell--focus` no longer paints a ground. It took --fc-today-cell
   (#F7FAFF) — today's wash, on a day that is not today. The class stays as the
   state hook the keyboard and the tests read; the column outline is the mark. */
.fc-day-cell--past    { opacity: 0.55; }

/* Selected person row: wash `<colour>0d` over the cell grounds, a 3px left
   edge in `<colour>`, and the gutter name in `<colour>`
   (DESIGN-DECISIONS §1 "Selected person row (Day/Where)"). Drawn as an
   overlay rather than a background so the cells' own grounds still show
   through underneath — which is what the pixels do: Oli's cell samples
   #FAF4F3, i.e. #FB6A2E at 0d over the #FAFBFE home ground, exact.
   The wash covers the 104px gutter too — his avatar tint samples #FFE6DD,
   which is 0d and 1f composited over white. */
.fc-day-lane--on::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--lane-wash);
  box-shadow: inset 3px 0 0 var(--lane-c);
  pointer-events: none;
  z-index: 3;
}
.fc-day-lane--on .fc-day-lane-name {
  color: var(--lane-c);
  font-weight: var(--fc-weight-bold);   /* FONTS.md: 800 when the row is selected */
}

/* ── the focus-day column: ONE continuous outline down the whole grid,
   sampled 2px running from the grid's top edge (y=250) to its bottom (y=595).

   INK, NOT BLUE. Reversed 2026-08-06 in the convergence pass. The render
   (`exports/desktop-day.png`) unambiguously shows the today-blue triplet here
   — 2px #4F7DF3 border, #EEF3FE header ground, #F7FAFF lane wash — and spec 10
   §5 pinned blue on source-precedence rank 3. DESIGN-DECISIONS §1 is rank 1
   and says the opposite in the same breath as the value: "Selected day cell —
   inset 0 0 0 2px #1A2233 (ink outline, NOT blue, so it doesn't read as
   'today')". Rank 1 wins, and the estate agrees with it: desktop Month, mobile
   Month and mobile Day all mark a selected day in ink, so this was the one
   surface out of four using the today accent for a state that is not today.
   spec 10 §5's line and its Test case step 1 are corrected to match.

   The header ground and the lane wash went with the border, for the same
   reason — they are `--fc-glyph-tile-empty` and `--fc-today-cell`, both today
   values. The outline is now the whole mark, exactly as §1 models a selected
   day on every other screen.

   NAMED RESIDUAL: Day has no real today treatment at all — it never had one,
   and freeing the today tokens does not create one. If today falls inside the
   rendered week it is currently unmarked on this screen. That is a design
   question for Oli / Claude Design, not something to invent here. */
.fc-day-focus-col {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--fc-day-gutter) + (100% - var(--fc-day-gutter)) * var(--focus-col) / 7);
  width: calc((100% - var(--fc-day-gutter)) / 7);
  border: 2px solid var(--fc-text-ink);
  border-radius: 3px;
  pointer-events: none;
  z-index: 4;
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 4 — TRIP BARS IN A LANE

   Placement comes off FamCalEngine's own segments. The only arithmetic in
   js/views/day.js turns startCol/span into the two percentages below; the
   lane index, the span and the continuation flags are all the engine's.
   ════════════════════════════════════════════════════════════════════════ */
.fc-day-bars {
  position: absolute;
  left: var(--fc-day-gutter);
  right: 0;
  top: 0;
  bottom: 0;
  pointer-events: none;
  z-index: 5;
}
/* Horizontal placement is done HERE, not in the view, and that is deliberate:
   the two mid-day insets are component tokens declared in SECTION 1, so the
   arithmetic that consumes them belongs in the same file. js/views/day.js
   passes only what the ENGINE gave it — `--seg-col` (startCol) and
   `--seg-span` — plus the two continuation flags as classes. It reads no
   token of its own off the document root, which is what the estate ruling
   requires and what makes a silent `''` impossible.

   The insets: a bar starts 0.42 into its first day and ends 0.58 through its
   last (DESIGN-DECISIONS §3; measured 138/328 = 0.4207 on Madrid). A segment
   that CONTINUES past a week edge runs flush to that edge instead — hence the
   two overrides below. */
.fc-day-bar {
  --ins-l: var(--fc-day-bar-inset-start);
  --ins-r: var(--fc-day-bar-inset-end);
  position: absolute;
  pointer-events: auto;
  appearance: none;
  border: 0;
  cursor: pointer;
  left: calc((var(--seg-col) + var(--ins-l)) / 7 * 100%);
  width: calc((var(--seg-span) - 1 + var(--ins-r) - var(--ins-l)) / 7 * 100%);
  top: calc(
    var(--lane) * var(--fc-day-lane-h)
    + (var(--fc-day-lane-h) - var(--fc-day-bar-h)) / 2
  );
  height: var(--fc-day-bar-h);
  border-radius: var(--fc-day-radius-bar);
  background: var(--bar-c);
  /* The soft coloured halo. Composed here with color-mix rather than by
     appending a hex alpha suffix in JS (the estate's usual trick, which
     month.js and year.js both use) for one reason: the alpha is a component
     token now, so composing it in JS would mean reading a `.fc-day` value
     from the document root — the coupling this re-scope exists to remove.
     color-mix is Chrome 111+; this product is a local tool rendered in
     Chrome. Named as the one modern-CSS feature this file introduces. */
  box-shadow: 0 4px 16px
    color-mix(in srgb, var(--bar-c) var(--fc-day-bar-glow-alpha), transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
  transition: transform 160ms ease-out, box-shadow 160ms ease-out; /* TODO(motion-tokens) */
}
.fc-day-bar:hover { transform: translateY(var(--fc-hover-lift)); }
.fc-day-bar-label {
  font-family: inherit;
  font-size: var(--fc-day-size-bar);
  /* FONTS.md §2: the coloured fill is the emphasis, not the weight — a label
     inside a saturated bar never goes above 700. */
  font-weight: var(--fc-weight-medium);
  /* Per-bar AA-correct ink, set by day.js from schema.inkFor — same rule as
     calendar.css's .fc-bar. White alone failed on the light hues and the
     fills are Oli's design decision, so the label moves, not the palette. */
  color: var(--bar-ink, var(--fc-text-on-fill));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Continuation: square off the edge the trip runs past, exactly as the
   engine's flags report it. NEITHER REFERENCE RENDER EXERCISES THIS —
   Madrid's whole span fits inside the displayed week — so it is built to the
   rule and flagged pixel-unverified in the build report. */
.fc-day-bar--cont-left {
  --ins-l: 0;
  border-top-left-radius: var(--fc-radius-barcut);
  border-bottom-left-radius: var(--fc-radius-barcut);
}
.fc-day-bar--cont-right {
  --ins-r: 1;
  border-top-right-radius: var(--fc-radius-barcut);
  border-bottom-right-radius: var(--fc-radius-barcut);
}

/* Tentative: three simultaneous signals, no separate icon (DESIGN-DECISIONS
   §4) — tinted fill, dashed border, label in the colour instead of white,
   plus the trailing ' ?' the view appends to the text. */
.fc-day-bar--tentative {
  background: var(--bar-tentative-fill);
  border: 1.5px dashed var(--bar-dashed);
  box-shadow: none;
}
.fc-day-bar--tentative .fc-day-bar-label { color: var(--bar-c); }

/* Past: NEVER blanket opacity on a bar — it destroys the label stroke at
   these sizes (BUILD-ANSWERS C7, FONTS.md §4). Muted fill, dark label.
   Hover restores full colour so faded history stays inspectable
   (DESIGN-DECISIONS §5). */
.fc-day-bar--past {
  background: var(--bar-past-fill);
  box-shadow: none;
}
.fc-day-bar--past .fc-day-bar-label { color: var(--fc-text-past-label); }
.fc-day-bar--past:hover { background: var(--bar-c); }
.fc-day-bar--past:hover .fc-day-bar-label { color: var(--fc-text-on-fill); }


/* ════════════════════════════════════════════════════════════════════════
   SECTION 5 — THE WEEK LIST
   ════════════════════════════════════════════════════════════════════════ */
.fc-day-list {
  padding: 0 var(--fc-day-list-inset);
  margin-top: 26px;
}

/* `Oli's week 12 Oct – 18 Oct` — no middot. Section heading 19/800
   (FONTS.md §3), confirmed by glyph measurement; the range sampled #9AA3B4. */
.fc-day-list-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 6px;
}
.fc-day-list-title {
  font-size: var(--fc-day-size-list-head);
  font-weight: var(--fc-weight-bold);
  letter-spacing: var(--fc-track-tight);
  color: var(--fc-text-ink);
}
.fc-day-list-range {
  font-size: var(--fc-day-size-range);
  font-weight: var(--fc-weight-medium);
  color: var(--fc-text-muted-3);
}

.fc-day-row {
  display: grid;
  grid-template-columns:
    var(--fc-day-date-col)
    var(--fc-day-loc-col)
    minmax(0, calc(var(--fc-day-when-col) + var(--fc-day-row-gap) + var(--fc-day-card-col)));
  gap: var(--fc-day-row-gap);
  align-items: start;
  padding: var(--fc-day-row-pad-y) 0;
  border-top: 1px solid var(--fc-hairline-card);
  border-radius: var(--fc-day-radius-row);
  /* The wash on a holiday / weekend row runs the full width of the row grid
     and no further — measured x=96→1903 at 2× = 904 CSS. */
  max-width: calc(
    var(--fc-day-date-col) + var(--fc-day-loc-col) + var(--fc-day-when-col)
    + var(--fc-day-card-col) + 3 * var(--fc-day-row-gap)
  );
}
/* Holiday beats weekend — the product's standing precedence. Both sampled
   exact: holiday #EEF9F2 (--fc-holiday-cell), weekend #F2F5FA
   (--fc-rail-row-weekend, DESIGN-DECISIONS §1's "day row" weekend value). */
.fc-day-row--holiday { background: var(--fc-holiday-cell); }
.fc-day-row--weekend { background: var(--fc-rail-row-weekend); }
/* Past: a uniform wash over the whole row, ground and type together
   (BUILD-ANSWERS C7). Untested against any render — flagged. */
.fc-day-row--past { opacity: 0.55; }

/* ── the date gutter ─────────────────────────────────────────────────────
   Numeral 26/800/-0.03em with the weekday word BENEATH it at 10/700/.06em.
   FONTS.md §3 Day says "weekday above it"; desktop-day.png puts it beneath
   and the render wins on appearance. Weekend numerals sampled #7E8CA3. */
.fc-day-date {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.fc-day-date-num {
  font-size: var(--fc-day-size-num);
  font-weight: var(--fc-weight-bold);
  letter-spacing: var(--fc-track-title);
  line-height: var(--fc-leading-flat);
  color: var(--fc-text-ink);
}
.fc-day-date-dow {
  font-size: var(--fc-day-size-dow);
  font-weight: var(--fc-weight-semibold);
  letter-spacing: var(--fc-track-micro);
  color: var(--fc-text-dow);
}
.fc-day-row--weekend .fc-day-date-num { color: var(--fc-text-weekend-num); }

/* ── the directional location line ───────────────────────────────────────
   THE HAND-CORRECTED CELL, AND THE RENDER AGREES WITH IT. An AWAY day is
   13/700 in the person's colour with a dot in that colour; a `Home` day is
   11/700/.04em in #98A1AE with the dot in #AEB6C4 — never the person's.
   Sampled on desktop-day.png: 12/14/15 Oct text and dot both #FB6A2E;
   16/17/18 Oct text #98A1AE and dot #AEB6C4, to the byte.
   The dot is a CIRCLE, confirmed by crop — a square would collide with
   DESIGN-DECISIONS §5's kid-logistics shape rule.

   ⚠ CONTRAST, computed not estimated: Oli's #FB6A2E on white is 2.92:1 and
   Laura's #EC4899 is 3.53:1; `Home` at #98A1AE on white is 2.61:1. All three
   fail AA for body text, all three are specified by three concordant numbered
   sources (spec 10 §2, FONTS.md §3 Where, DESIGN-DECISIONS §5/§6), and none
   is on spec 10 §7's accepted-exception list, which covers white bar labels
   only. Built as specified; escalated in the build report rather than
   silently overridden — it is a design decision, not a build one. */
.fc-day-loc { min-width: 0; }
.fc-day-loc-line {
  display: flex;
  align-items: center;
  gap: 9px;
}
.fc-day-loc-dot {
  flex: 0 0 auto;
  width: var(--fc-day-dot);
  height: var(--fc-day-dot);
  border-radius: 50%;
  background: var(--person-c);
}
.fc-day-loc-text {
  font-size: var(--fc-day-size-loc);
  font-weight: var(--fc-weight-semibold);
  color: var(--person-c);
}
.fc-day-loc--home .fc-day-loc-dot  { background: var(--fc-text-dow); }
.fc-day-loc--home .fc-day-loc-text {
  font-size: var(--fc-day-size-home);
  letter-spacing: var(--fc-track-micro);
  color: var(--fc-text-muted-2);
}
/* The generated sub-note, `day N of M · Schengen` — derived by derive.js R7,
   never typed. 11/500 #98A1AE (FONTS.md §3 Where, sampled and matching).
   Same inherited contrast problem as the line above it — 2.61:1 on white,
   2.35:1 where it sits on a card ground. Specified, so shipped, so flagged. */
.fc-day-loc-note {
  margin-top: 3px;
  padding-left: calc(var(--fc-day-dot) + 9px);
  font-size: var(--fc-day-size-sub);
  font-weight: var(--fc-weight-regular);
  color: var(--fc-text-muted-2);
}
/* ── two trips on one person on one day (spec 10 §6a, added 2026-08-06) ──────
   On an OVERLAP day the sub-note is not a day count — it is the other PLACE
   the person is (`+ Travels to London`), and the only place that trip is named
   in words on this row. So it takes the secondary ink and the medium weight
   rather than the muted regular: it is a location line in its own right, one
   step down from the primary, not throwaway metadata. It also lifts the
   flagged 2.35:1 of `--fc-text-muted-2` to `--fc-text-secondary`'s 5.78:1 for
   the one line where a whole trip depends on being read. */
.fc-day-loc--overlap .fc-day-loc-note {
  font-weight: var(--fc-weight-medium);
  color: var(--fc-text-secondary);
}
/* Holiday chip #E3F4EA / #3E8C6C (DESIGN-DECISIONS §1); the text colour is
   sampled exact off the 13 Oct row. */
.fc-day-holiday {
  display: inline-block;
  margin-top: 8px;
  margin-left: calc(var(--fc-day-dot) + 9px);
  padding: 4px 9px;
  border-radius: var(--fc-radius-tag);
  background: var(--fc-holiday-chip);
  color: var(--fc-holiday-chip-text);
  font-size: var(--fc-day-size-sub);
  font-weight: var(--fc-weight-medium);
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 6 — TIMES, CARDS, EMPTY STATE
   ════════════════════════════════════════════════════════════════════════ */
.fc-day-items {
  display: grid;
  grid-template-columns: var(--fc-day-when-col) minmax(0, var(--fc-day-card-col));
  gap: var(--fc-day-card-gap) var(--fc-day-row-gap);
  align-content: start;
  min-width: 0;
}

/* Times sit in a right-aligned gutter BEFORE the card, ascending down the
   day; a flight shows departure over arrival (DESIGN-DECISIONS §3). Sampled
   #5C6679 for the primary and #AEB6C4 for the arrival beneath it. */
.fc-day-when {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  padding-top: 9px;
  font-size: var(--fc-day-size-when);
  font-weight: var(--fc-weight-semibold);
  line-height: var(--fc-leading-chip);
}
.fc-day-when-1,
.fc-day-when-2,
.fc-day-when-3 { white-space: nowrap; }
.fc-day-when-1 { color: var(--fc-text-secondary); }
.fc-day-when-2,
.fc-day-when-3 { color: var(--fc-text-dow); }

/* One event / flight / hotel card. Ground is `<colour>` at the chip-fill
   alpha, with a 3px colour edge bled to the left corner: sampled #F2F3F4 for
   an appointment (graphite at 14 over white, exact) and #F5F0FE for kid
   logistics (#7C3AED at 14, exact), with a 6px-at-2× #5C6679 edge. */
.fc-day-card {
  appearance: none;
  border: 0;
  border-left: 3px solid var(--bar-c);
  cursor: pointer;
  text-align: left;
  min-width: 0;
  min-height: var(--fc-day-card-min-h);
  padding: 9px 14px;
  border-radius: var(--fc-day-radius-row);
  background: var(--bar-fill);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  font-family: inherit;
  transition: background-color 160ms ease-out, transform 160ms ease-out; /* TODO(motion-tokens) */
}
.fc-day-card:hover { transform: translateY(var(--fc-hover-lift)); }
/* Painted only when opts.onSelect actually RETURNED true — i.e. only when a
   panel is really on screen. It does NOT fire when a re-click toggles the
   Inspector shut, which is the point of reading the return value rather than
   the click (contract §3).
   CORRECTED 2026-08-10 (_promotions/lane-3-hygiene.md P1.2). This comment used
   to say "The Inspector stub returns false, so today this never fires". The
   Inspector is not a stub — it is 1035 lines, four variants, both breakpoints —
   and open() returns true on the ordinary path, so this rule DOES fire. A
   reader trusting the old comment would have read a working selected state as a
   regression, or deleted this rule as dead. */
.fc-day-card.is-selected {
  box-shadow: 0 0 0 2px var(--fc-surface-card), 0 0 0 3.5px var(--bar-c);
}
.fc-day-card-top {
  display: flex;
  align-items: baseline;
  gap: 7px;
  min-width: 0;
}
.fc-day-card-glyph {
  flex: 0 0 auto;
  color: var(--fc-text-secondary);
  font-size: var(--fc-day-size-sub);
}
.fc-day-card-title {
  font-size: var(--fc-day-size-title);
  font-weight: var(--fc-weight-semibold);
  color: var(--fc-text-ink-2);
  min-width: 0;
  overflow-wrap: anywhere;
}
.fc-day-card-number {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: var(--fc-day-size-sub);
  font-weight: var(--fc-weight-semibold);
  letter-spacing: 0.02em;
  color: var(--fc-text-secondary);
}
.fc-day-card-sub,
.fc-day-card-book {
  font-size: var(--fc-day-size-sub);
  font-weight: var(--fc-weight-regular);
  color: var(--fc-text-muted-2);
  overflow-wrap: anywhere;
}
/* The booking record — `ref …` / `seat …`. Both mocks omit it; PRD §4.4 names
   the flight reference as part of the complete stored record and spec 10 §8
   forbids dropping stored detail for width. Deliberate, and reported. */
.fc-day-card-book { color: var(--fc-text-dow); }

/* ── the shared flight leg inside Day's item list ──────────────────────────
   The component is calendar.css SECTION 5b / js/views/leg.js, and everything
   about its ANATOMY — field order, tile, number chip, right-aligned duration,
   3-column detail panel — belongs to it and is not touched here. This is
   PLACEMENT ONLY, and the distinction is the point: an override that reaches
   past layout is how the second copy grows back.

   Two things to place. The leg's 14px top margin and top hairline are how legs
   separate from each other inside the Inspector's single stack; Day's rows are
   already separated by --fc-day-card-gap on the item grid, so the hairline
   would read as a stray rule above one item. And the leg sits in the card
   column, so it takes the card's own left inset rather than the Inspector's.

   A flight therefore reads as STRUCTURE where an appointment reads as a card,
   which is deliberate: a flight is the only item here that carries a from/to,
   two times, two airports and two terminals. That is more information, and it
   is allowed to look like more information. */
.fc-day-leg {
  margin-top: 0;
  border-top: 0;
  padding: 2px 0 4px;
}
.fc-day-leg .fc-leg__detail { margin-left: 0; }

/* The empty day. Layout only now — the chip itself is `.fc-empty-chip` in
   calendar.css SECTION 5, shared with the Month rail. This rule used to carry
   the words "nothing scheduled" as plain muted text; both the words and the
   treatment were converged on DESIGN-DECISIONS §5 (`Nothing on`, a neutral
   chip) on 2026-08-06. The AA argument that used to live here — the render's
   #C3CAD8 is 1.65:1 and §6 rejects that very value on the Where lane — is now
   carried by the chip, which is --fc-text-secondary on --fc-neutral-chip.
   `justify-self: start` so the chip is a chip and not a full-width band. */
.fc-day-empty {
  grid-column: 1 / -1;
  justify-self: start;
  margin: 0;
  margin-top: 9px;
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 7 — MOBILE (≤ 430px)

   The day scroller REPLACES the lane grid and the single-day timeline
   REPLACES the week list — a branch in js/views/day.js, not a squeezed
   desktop DOM, which is the mistake the 2026-08-04 pack was issued to
   correct. 430px is the widest current iPhone logical width; the number is
   duplicated in five places and commented on all of them.
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 430px) {
  .fc-day-mobile { display: block; }

  /* ── the seven-chip day scroller ── */
  .fc-day-scroller {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: var(--fc-day-m-chip-gap);
    margin-bottom: 12px;
  }
  .fc-day-chip {
    appearance: none;
    border: 0;
    cursor: pointer;
    font-family: inherit;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    /* BUILD-ANSWERS D3: 44px on mobile, deliberately above the 24×24 AA
       floor. The plain tap token in calendar.css is the DESKTOP view-pill one
       at 24px and is a trap here — the mobile variant is the right one. */
    min-height: var(--fc-day-m-chip-h);
    padding: 6px 0;
    border-radius: var(--fc-day-m-chip-r);
    background: var(--fc-weekday-chip);
    outline-offset: 2px;
  }
  .fc-day-chip-num {
    font-size: var(--fc-day-m-size-chip-num);
    font-weight: var(--fc-weight-bold);
    letter-spacing: var(--fc-track-tight);
    color: var(--fc-text-ink);
  }
  .fc-day-chip-dow {
    font-size: var(--fc-day-m-size-chip-dow);
    font-weight: var(--fc-weight-semibold);
    letter-spacing: var(--fc-track-badge);
    color: var(--fc-text-dow);
  }
  .fc-day-chip--weekend { background: var(--fc-day-m-chip-weekend); }
  .fc-day-chip--weekend .fc-day-chip-num { color: var(--fc-text-weekend-num); }
  .fc-day-chip--holiday { background: var(--fc-day-m-chip-holiday); }
  .fc-day-chip--holiday .fc-day-chip-num,
  .fc-day-chip--holiday .fc-day-chip-dow { color: var(--fc-holiday-chip-text); }
  /* Today, same three-channel mark as the desktop header cell and as Year and
     mobile Month — ground, 1.5px inset ring, blue numeral. `:not(--on)`
     because the focused chip is a solid ink fill with white type: a translucent
     blue over it would muddy both. Today-and-focused reads as the ink chip,
     and today is still announced in the chip's accessible name, which
     H.describeDay() writes. Declared BEFORE `--on` so the ink fill also wins
     on source order, not only on the :not(). */
  .fc-day-chip--today:not(.fc-day-chip--on) {
    background: var(--fc-m-today-cell);
    box-shadow: inset 0 0 0 1.5px var(--fc-m-today-ring);
  }
  .fc-day-chip--today:not(.fc-day-chip--on) .fc-day-chip-num { color: var(--fc-today-numeral); }
  /* The focused chip is filled INK, not blue — sampled #1A2233 with white
     type. On mobile there is no column outline to carry the focused day, so
     the chip itself is the whole indicator. */
  .fc-day-chip--on { background: var(--fc-text-ink); }
  .fc-day-chip--on .fc-day-chip-num,
  .fc-day-chip--on .fc-day-chip-dow { color: var(--fc-text-on-fill); }
  .fc-day-chip--past { opacity: 0.55; }

  /* Person tabs keep the 44px floor too (BUILD-ANSWERS D3). mobile-day.png
     draws them ~29px tall; the accessibility ruling is a numbered source and
     wins over the mock's height. Reported. */
  .fc-day-people { gap: 8px; margin-bottom: 12px; }
  .fc-day-person {
    min-height: var(--fc-tap);
    padding: 0 20px;
  }

  /* ── the trip / location band. NOT IN ANY NUMBERED SOURCE — measured off
     mobile-day.png and flagged. Ground is the person's colour at the
     chip-fill alpha (sampled #FFF3EC ≈ #FB6A2E at 14 over white); the dot
     and the left text take the person's colour, matching the desktop
     directional location line rather than the mock's untokened #C2521C. */
  .fc-day-band {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    margin-bottom: 16px;
    border-radius: var(--fc-day-m-band-r);
    background: var(--band-fill);
  }
  .fc-day-band-left {
    display: flex;
    align-items: center;
    gap: 9px;
    min-width: 0;
  }
  .fc-day-band-dot {
    flex: 0 0 auto;
    width: var(--fc-day-dot);
    height: var(--fc-day-dot);
    border-radius: 50%;
    background: var(--person-c);
  }
  .fc-day-band-text {
    font-size: var(--fc-day-m-size-band);
    font-weight: var(--fc-weight-semibold);
    color: var(--person-c);
  }
  /* Schengen is a fact carried by the category flag, never a count — there is
     no counting authority (PRD §6.1). Secondary ink, which clears AA on the
     wash where the mock's #B4795B (3.32:1) does not. */
  .fc-day-band-right {
    margin-left: auto;
    flex: 0 0 auto;
    font-size: var(--fc-day-m-size-band);
    font-weight: var(--fc-weight-medium);
    color: var(--fc-text-secondary);
  }
  /* A home day: the muted `Home` treatment on the neutral chip ground. The
     render never shows this state — my extension, so the band answers the
     calendar's core question on quiet days too. Reported. */
  .fc-day-band--home { background: var(--fc-neutral-chip); }
  .fc-day-band--home .fc-day-band-dot  { background: var(--fc-text-dow); }
  .fc-day-band--home .fc-day-band-text {
    font-size: var(--fc-day-size-home);
    letter-spacing: var(--fc-track-micro);
    color: var(--fc-text-muted-2);
  }

  /* ── the single-day timeline ── */
  .fc-day-timeline { display: block; }
  .fc-day-entry {
    display: grid;
    grid-template-columns: var(--fc-day-m-when-col) var(--fc-day-m-rail-col) minmax(0, 1fr);
    gap: 0 10px;
    align-items: stretch;
  }
  .fc-day-entry .fc-day-when {
    padding-top: 14px;
    font-size: var(--fc-day-size-when);
  }
  .fc-day-entry .fc-day-when-1 { color: var(--fc-text-muted); }
  /* The connecting hairline, sampled #E4E9F2. Drawn on the rail so it runs
     continuously between entries rather than stopping at each marker. */
  .fc-day-rail {
    position: relative;
    display: flex;
    justify-content: center;
  }
  .fc-day-rail::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--fc-divider);
  }
  .fc-day-mark {
    position: relative;
    margin-top: 16px;
    width: var(--fc-day-m-mark);
    height: var(--fc-day-m-mark);
    border-radius: 50%;
    border: 2px solid var(--bar-c);
    background: var(--fc-surface-card);
    align-self: flex-start;
  }
  /* A flight's marker is the same graphite but FILLED — pixel-checked. */
  .fc-day-mark--solid { background: var(--bar-c); }
  /* Kid logistics take a CIRCLE on the timeline rail, and the argument has to
     be made carefully, because an earlier version of this comment misquoted
     the ruling at both ends. What BUILD-ANSWERS C5 (lines 102-103) actually
     says, verbatim: the canonical square-dot contexts are "Month cell chip /
     Year strip / **mobile dot**", and the Inspector gets "the literal `◻`
     character" as a 22px icon tile — not a dot at all. So mobile is IN scope,
     not excluded, and the Inspector is the glyph case, not a dot case. The
     old comment had both backwards.

     The real argument for a circle is narrower: C5's "mobile dot" is the 5px
     dot in a mobile MONTH CELL (calendar.css SECTION 9, --fc-m-dot), a
     component that existed when C5 was written. The Day timeline rail marker
     is a 13px ringed node on a hairline, a component C5 never contemplated,
     and mobile-day.png — the only render of it that exists — draws it round.
     Nothing is lost: C5's square exists solely to separate Cosmo's LOGISTICS
     from Cosmo's TRIPS, which share #7C3AED, and a trip never appears in the
     timeline at all, so there is nothing here to be confused with. The
     category is still carried in words by the card's title and its
     `Kid logistics (Cosmo)` sub-line (spec 10 §7).

     Flagged for Claude Design: if C5 is meant to extend to any new mobile
     marker, this is one rule change and one line here. */
  .fc-day-mark--kid { border-radius: 50%; }

  .fc-day-entry .fc-day-card {
    margin: 8px 0;
    border-left: 0;
    padding: 12px 14px;
  }
  /* mobile-day.png draws a flight as a SOLID graphite card with white type —
     5.78:1, comfortably AA — rather than the desktop's tinted card with a
     colour edge. */
  .fc-day-card--solid { background: var(--bar-c); }
  .fc-day-card--solid .fc-day-card-title,
  .fc-day-card--solid .fc-day-card-glyph,
  .fc-day-card--solid .fc-day-card-number { color: var(--fc-text-on-fill); }
  .fc-day-card--solid .fc-day-card-sub,
  .fc-day-card--solid .fc-day-card-book { color: var(--fc-neutral-chip); }

  .fc-day-timeline .fc-day-empty { margin: 16px 0; }
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 8 — REDUCED MOTION

   calendar.css SECTION 6 carries the estate's block, but it cannot know
   about selectors that did not exist when it was written (contract §5), so
   every effect this file adds degrades here too — to instant-legible, with
   no travel. Nothing in this view hijacks scroll, so there is nothing to
   disable beyond transitions and the hover lift.
   ════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  .fc-day-person,
  .fc-day-bar,
  .fc-day-card {
    transition: none;
  }
  /* No travel — the colour and shadow changes still read. */
  .fc-day-bar:hover,
  .fc-day-card:hover {
    transform: none;
  }
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 9 — DATA STATES: loading skeletons + the card host
   Added 2026-08-07. js/app.js has passed `opts.loading` / `opts.empty` /
   `opts.error` to this view since 2026-08-06 and it ignored all three, so
   `?state=loading#/day/2026-10-15` rendered a finished week under no
   indication at all, at both widths.

   Declared last so it wins the tie on source order against SECTION 7's mobile
   chip rules, which a media query does not out-specify. Same rule the estate
   follows in calendar.css SECTION 13 and css/where.css SECTION 6: anything
   DERIVED FROM THE DATA is masked; the chrome §6 keeps in every state —
   weekday caps, the person tabs, the list heading — is not. Geometry never
   changes, so nothing moves when the data lands.
   ════════════════════════════════════════════════════════════════════════ */

/* The empty / error card is `position:absolute; inset:0`, so this is what it
   is centred over. Only in those two states — a blanket `position: relative`
   on `.fc-day` would re-parent every absolutely-positioned descendant in the
   default render, the focus column and the lane bars among them. */
.fc-day[data-state='empty'],
.fc-day[data-state='error'] { position: relative; }
/* This screen is TALL — the lane grid plus a seven-row week list runs past
   1200px at 1440 — so a card centred in it lands near the bottom of the
   viewport and, on a shorter window, below the fold. Measured at 1440×900
   before this rule: the error card sat at y=629–882, 18px of clearance.
   Anchored under the lane grid instead, which is the part of the screen the
   card is actually about. Same fix, same reason, as the mobile year ribbon in
   calendar.css SECTION 13. */
.fc-day[data-state='empty'] .fc-state-layer--overlay,
.fc-day[data-state='error'] .fc-state-layer--overlay {
  align-items: start;
  padding-top: 96px;
}

/* ── the lane grid ───────────────────────────────────────────────────────── */
.fc-day[data-state='loading'] .fc-day-cell {
  background: var(--fc-skeleton-cell);
  box-shadow: none;
}
/* The today mark goes with the grounds; today is redrawn when the data lands,
   and a blue ring over a skeleton reads as content. */
.fc-day[data-state='loading'] .fc-day-head-cell {
  background: var(--fc-skeleton-cell);
  box-shadow: none;
}
.fc-day[data-state='loading'] .fc-day-head-num,
.fc-day[data-state='loading'] .fc-day-lane-name,
.fc-day[data-state='loading'] .fc-day-context,
.fc-day[data-state='loading'] .fc-day-loc-text,
.fc-day[data-state='loading'] .fc-day-loc-note,
.fc-day[data-state='loading'] .fc-day-date-num,
.fc-day[data-state='loading'] .fc-day-card-title,
.fc-day[data-state='loading'] .fc-day-card-sub,
.fc-day[data-state='loading'] .fc-day-card-number,
.fc-day[data-state='loading'] .fc-day-when,
.fc-day[data-state='loading'] .fc-day-mark,
.fc-day[data-state='loading'] .fc-day-band-text,
.fc-day[data-state='loading'] .fc-day-band-right {
  /* §6: "text placeholders #EDF0F6 at 8px tall, radius 4" */
  color: transparent;
  background: var(--fc-skeleton-text);
  border-radius: 4px;
  min-height: 8px;
}
/* …and the timeline marker's RING with it. `.fc-day-mark` is a 13px node with
   `border: 2px solid var(--bar-c)`, so masking its fill left a ring in the
   category colour — rgb(124,58,237), Cosmo's, on the kid-logistics marker — a
   who-signal surviving the mask on a product whose first rule is that colour
   says who. Found by the chroma sweep on 2026-08-08; the text sweep returned
   clean here, because a coloured ring carries no text. */
.fc-day[data-state='loading'] .fc-day-mark { border-color: var(--fc-skeleton-bar); }
/* The weekday caps stay: `MON` is true in every state (§6 chrome). */
.fc-day[data-state='loading'] .fc-day-avatar {
  background: var(--fc-skeleton-bar);
  color: transparent;
}
.fc-day[data-state='loading'] .fc-day-bar {
  background: var(--fc-skeleton-bar);
  box-shadow: none;
}
.fc-day[data-state='loading'] .fc-day-bar-label { color: transparent; }
/* The selected-person wash is derived from nothing, but it tints a skeleton
   with a live person colour and reads as loaded content. It comes back with
   the data. */
.fc-day[data-state='loading'] .fc-day-lane--on::before { background: transparent; }
.fc-day[data-state='loading'] .fc-day-loc-dot { background: var(--fc-skeleton-bar); }
.fc-day[data-state='loading'] .fc-day-card {
  background: var(--fc-skeleton-cell);
  box-shadow: none;
  border-color: transparent;
}
.fc-day[data-state='loading'] .fc-day-card-glyph {
  color: transparent;
  background: var(--fc-skeleton-bar);
}
/* `Nothing on` is an ANSWER about the day, and during loading the answer is
   not known yet — a screen that says nothing is on while it is still fetching
   is stating a fact it does not have. Masked like any other derived text. */
.fc-day[data-state='loading'] .fc-day-holiday,
.fc-day[data-state='loading'] .fc-empty-chip {
  background: var(--fc-skeleton-text);
  color: transparent;
}
/* ── the leg row (calendar.css SECTION 5b / js/views/leg.js) ───────────────
   The single biggest leak in the first pass: under a LOADING… pill the week
   list rendered `STN → MAD · FR 8102 · ref QJ41MB · 2h 25m · London Stansted
   · Madrid Barajas · T1`, fully legible, at 1440. The leg is a SHARED
   component — the Inspector uses the same one — so it is masked here, inside
   this screen's loading scope, and not by touching the component. */
.fc-day[data-state='loading'] .fc-leg {
  background: var(--fc-skeleton-cell);
  box-shadow: none;
  border-color: transparent;
}
.fc-day[data-state='loading'] .fc-leg__code,
.fc-day[data-state='loading'] .fc-leg__time,
.fc-day[data-state='loading'] .fc-leg__airport,
.fc-day[data-state='loading'] .fc-leg__term,
.fc-day[data-state='loading'] .fc-leg__title,
.fc-day[data-state='loading'] .fc-leg__sub,
.fc-day[data-state='loading'] .fc-leg__name,
.fc-day[data-state='loading'] .fc-leg__num,
.fc-day[data-state='loading'] .fc-leg__meta,
.fc-day[data-state='loading'] .fc-leg__side,
.fc-day[data-state='loading'] .fc-leg__arrow,
.fc-day[data-state='loading'] .fc-day-card-book {
  color: transparent;
  background: var(--fc-skeleton-text);
  border-radius: 4px;
  min-height: 8px;
}
.fc-day[data-state='loading'] .fc-leg__tile {
  background: var(--fc-skeleton-bar);
  color: transparent;
}
/* The times in the left gutter of a week-list row — `07:10`, `10:35`, `19:00`
   — are three separate spans, and masking only their wrapper left all three
   readable. */
.fc-day[data-state='loading'] .fc-day-when-1,
.fc-day[data-state='loading'] .fc-day-when-2,
.fc-day[data-state='loading'] .fc-day-when-3 { color: transparent; }

/* ── mobile ──────────────────────────────────────────────────────────────── */
@media (max-width: 430px) {
  .fc-day[data-state='loading'] .fc-day-chip {
    background: var(--fc-skeleton-cell);
    box-shadow: none;
  }
  .fc-day[data-state='loading'] .fc-day-chip-num { color: transparent; }
  /* the `MON` cap stays — chrome, in every state.
     …AND THE SELECTED ONE HAS TO STAY WITH IT. `.fc-day-chip--on` fills the
     focused chip with ink and paints both its lines in --fc-text-on-fill
     (white). The mask above repaints the chip's GROUND to the skeleton cell at
     (0,3,0) but `.fc-day-chip--on .fc-day-chip-dow` is (0,2,0) and untouched,
     so the white cap survived onto a near-white ground: six weekday letters
     legible at 1.99–3.95:1 and `THU` — the day being looked at — under 1.35:1
     and gone. The one chip that must not vanish was the one that did. Measured
     2026-08-08. Put back on the sibling colour, so all seven read alike. */
  .fc-day[data-state='loading'] .fc-day-chip--on .fc-day-chip-dow { color: var(--fc-text-dow); }
  .fc-day[data-state='loading'] .fc-day-band {
    background: var(--fc-skeleton-cell);
    box-shadow: none;
  }
  .fc-day[data-state='loading'] .fc-day-band-dot { background: var(--fc-skeleton-bar); }
}
