/* ════════════════════════════════════════════════════════════════════════
   INSPECTOR — the one detail surface for every object on every screen.

   Sources, in the order set by specs/11-view-module-contract.md §0.
   This file reads: specs/11 §3 (the singleton), §4 (this file's boundary), §5
   (focus ring, motion, colour-never-alone); specs/09-inspector.md §2 anatomy,
   §3 variants, §5 states, §7 a11y; design-export-2026-08-04/DESIGN-DECISIONS.md
   §1 (colour), §3 (geometry), §5, §6 (per-object-type anatomy);
   design-export-2026-08-04/FONTS.md §3 "Inspector / ClarifyCard", §4 floors;
   and the reference renders exports/inspector-{trip,flight,event}.png
   (desktop), exports/mobile-trip-sheet.png (the ≤430px presentation).

   The order itself lives in §0, and a copy of it here would be a divergence on
   a delay fuse.

   ⚠ UI-RULES.md §2's colour table is known-wrong in this pack. Nothing here
   is taken from it; DESIGN-DECISIONS §1 is the only colour source.

   TWO PRESENTATIONS, ONE COMPONENT. Above 430px the Inspector is a floating
   panel anchored to the top-right of the card (DESIGN §3). At ≤430px it is a
   bottom sheet — that is what exports/mobile-trip-sheet.png shows, and it is
   why the Inspector and the mobile day sheet can never both be on screen:
   they occupy the same slot. That mutual exclusion is enforced in JS
   (js/views/inspector.js + js/views/month.js) and named in the build report.

   ── WHY THE CUSTOM PROPERTIES BELOW ARE ON `.fc-insp` AND NOT IN `:root` ──
   scripts/token-mirror.check.mjs treats every `:root` custom property as part
   of the brand-skin contract and fails the run until the property is mirrored
   by hand into brand-foundation/calendar.tokens.json — a file outside this
   lane's write envelope. Component GEOMETRY (a 320px panel, a 31px indent) is
   not brand skin and does not belong in that file, so it is declared on the
   component root instead, which the gate explicitly holds out of scope.

   Five of the values below were reported as brand-level promotion candidates
   for the integrator. One was promoted at integration, 2026-08-06:
     confirmed-ground  #EAF6EF  → PROMOTED, now var(--fc-holiday-chip-inspector)
   The other four were deliberately left alone in that pass — it was scoped to
   values with a verbatim DESIGN-DECISIONS §1/§6 line AND more than one
   independent consumer, and these have neither yet:
     tentative-ground  #FFF3DB   tentative-ink  #B77400
     legs-hairline     #F2F4F9   terminal-chip  #E7ECF6
   Nothing here REDECLARES a name from calendar.css (all 227 checked).
   ════════════════════════════════════════════════════════════════════════ */


/* ════════════════════════════════════════════════════════════════════════
   SECTION 1 — COMPONENT CONSTANTS
   ════════════════════════════════════════════════════════════════════════ */
.fc-insp {
  /* geometry — DESIGN-DECISIONS §3 "Inspector: 320px, radius 18, 6px colour
     bar bled to the card edge, anchored top:74px; right:30px" */
  --fc-insp-width:  320px;
  --fc-insp-bar-h:  6px;
  --fc-insp-top:    74px;
  --fc-insp-right:  30px;
  --fc-insp-pad-x:  18px;
  --fc-insp-pad-y:  20px;

  /* The flight-leg anatomy's five numbers (tile, detail indent, detail arrow,
     code size, airport size) MOVED with the component to calendar.css SECTION
     5b on 2026-08-06 and are component-scoped on `.fc-leg` there. Its two
     surfaces became brand tokens in the same move: --fc-insp-legs-hairline is
     --fc-hairline-leg, --fc-insp-terminal-chip is --fc-terminal-chip;
     DESIGN-DECISIONS §1 names both verbatim. Nothing about them is redeclared
     here — a local alias for a component this file no longer owns is exactly
     how a second copy comes back. */
  /* PROMOTED 2026-08-06 at integration. DESIGN-DECISIONS §1 gives this one
     value two names — "inspector holiday chip" and the "Confirmed chip" — so
     it is brand-level, and css/day.css had a second private copy of it for the
     mobile holiday chip. Now one token, referenced twice. */
  --fc-insp-confirmed-ground:  var(--fc-holiday-chip-inspector);   /* --fc-eu-ink on it measures 4.81:1 */
  --fc-insp-tentative-ground:  #FFF3DB;
  /* design value: #B77400 (3.46:1 on the ground above). Substituted for AA —
     same amber family, 5.26:1. Every other muted value in this file follows
     the same convention as calendar.css, which substitutes in 16 places. */
  --fc-insp-tentative-ink:     #8F5A00;

  /* type — FONTS.md §3 "Inspector / ClarifyCard". Only the levels with no
     equivalent already in calendar.css SECTION 1 are named here; the rest
     reference the shared tokens directly. */
  --fc-insp-size-title:   17px;

  /* motion. TODO(motion-tokens) — motion is undesigned in this product and
     token-architecture.md names the estate-wide gap; one hardcoded value,
     flagged, is the agreed placeholder (contract §5). Do NOT grow this into
     an easing system. */
  --fc-insp-motion: 160ms ease-out;
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 2 — THE PANEL (> 430px: floating, anchored to the card)

   `left` and `top` are written by JS at open time from the card's own rect,
   so the panel sits 30px in from the card edge rather than the window edge
   (DESIGN §3 anchors to the card). The values here are the fallback for the
   frame before that measurement lands, and for a page with no card.
   ════════════════════════════════════════════════════════════════════════ */
.fc-insp {
  position: fixed;
  top: var(--fc-insp-top);
  right: var(--fc-insp-right);
  z-index: 60;                      /* over the card, under nothing else */
  width: var(--fc-insp-width);
  max-width: calc(100vw - 2 * var(--fc-insp-right));
  /* dvh, never vh — a mobile URL bar must not clip the panel */
  max-height: calc(100dvh - var(--fc-insp-top) - 24px);
  display: flex;
  flex-direction: column;
  overflow: hidden;                 /* this is what bleeds the bar to the edge */
  background: var(--fc-surface-card);
  border-radius: var(--fc-radius-panel);
  box-shadow: var(--fc-shadow-inspector);
  font-family: var(--fc-font);
  color: var(--fc-text-ink);
  /* opacity + transform only */
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity var(--fc-insp-motion), transform var(--fc-insp-motion); /* TODO(motion-tokens) */
}
.fc-insp[hidden] { display: none; }
.fc-insp--open { opacity: 1; transform: none; }

/* The 6px colour bar. Decorative — the object's colour is always restated in
   words (the person chip, the category chip), because colour is never the
   sole carrier of meaning (contract §5). */
.fc-insp__bar {
  flex: 0 0 auto;
  height: var(--fc-insp-bar-h);
  background: var(--fc-insp-c, var(--fc-cat-appointment));
}

/* The scroller. Only this scrolls, so the colour bar stays pinned. */
.fc-insp__body {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--fc-insp-pad-y) var(--fc-insp-pad-x) 18px;
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 3 — HEAD: title · when-line · ✕
   ════════════════════════════════════════════════════════════════════════ */
.fc-insp__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  column-gap: 8px;
}
.fc-insp__title {
  grid-column: 1;
  margin: 0;
  font-size: var(--fc-insp-size-title);
  font-weight: var(--fc-weight-bold);
  letter-spacing: var(--fc-track-tight);
  line-height: 1.2;
  color: var(--fc-text-ink);
  overflow-wrap: anywhere;
}
/* REQUIRED and always visible — two trips share the title `FM: Mallorca` in
   the fixture year, so the title alone never identifies an object
   (spec 09 §2, "the two-bone-broths problem"). */
.fc-insp__when {
  grid-column: 1;
  margin: 4px 0 0;
  font-size: var(--fc-size-qualifier);        /* 12px */
  font-weight: var(--fc-weight-medium);
  /* design value: --fc-text-muted #8A94A6 (3.06:1). Substituted for AA. */
  color: var(--fc-text-secondary);
  line-height: 1.35;
  text-wrap: pretty;
}
.fc-insp__close {
  grid-column: 2;
  grid-row: 1 / span 2;
  /* 44×44 — spec 09 §7 asks for the AAA/HIG target on the ✕ and there is room.
     The glyph is centred in the box; the box is bigger than it looks. */
  inline-size: var(--fc-tap);
  block-size: var(--fc-tap);
  margin: -12px -10px 0 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--fc-radius-chip);
  background: transparent;
  /* design value: --fc-text-faint #C3CAD8 (1.65:1 — unreadable, and this is
     one of only two ways to close the panel). Substituted for AA, exactly as
     the shipped .fc-sheet__close already does. */
  color: var(--fc-text-secondary);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: color var(--fc-insp-motion), background var(--fc-insp-motion); /* TODO(motion-tokens) */
}
.fc-insp__close:hover { color: var(--fc-text-ink); background: var(--fc-neutral-chip); }


/* ════════════════════════════════════════════════════════════════════════
   SECTION 4 — CHIP ROW (person · Confirmed/Tentative · Ref · Seat · category)

   Every chip carries a text label. There is no colour-only chip anywhere in
   this component (contract §5).
   ════════════════════════════════════════════════════════════════════════ */
.fc-insp__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 14px;
}
.fc-insp__chip {
  display: inline-flex;
  align-items: center;
  min-height: 24px;                       /* AA 2.5.8's floor; --fc-tap-desktop's value */
  padding: 4px 11px;
  border-radius: 999px;
  font-size: var(--fc-size-chip);         /* 10.5px */
  font-weight: var(--fc-weight-semibold);
  line-height: var(--fc-leading-flat);
  white-space: nowrap;
  background: var(--fc-neutral-chip);
  color: var(--fc-text-secondary);
}
/* Person / category chip — the ground is the object's own colour at the
   design's `1a` alpha, composed in JS from the token and never typed here.
   design value for the INK: the same colour at full strength, which measures
   2.62:1 (Oli), 3.11:1 (Laura) and 1.99:1 (birthday amber) on its own tint.
   Substituted for AA. Nothing is lost: the chip's WORD carries who it is —
   colour was never the sole carrier (contract §5) — and the tinted ground
   still shows the hue. */
.fc-insp__chip--person { background: var(--fc-insp-chip-ground); color: var(--fc-text-ink-2); }
.fc-insp__chip--confirmed { background: var(--fc-insp-confirmed-ground); color: var(--fc-eu-ink); }
.fc-insp__chip--tentative { background: var(--fc-insp-tentative-ground); color: var(--fc-insp-tentative-ink); }


/* ════════════════════════════════════════════════════════════════════════
   SECTION 5 — THE SCHENGEN STRIP, IN ITS UNAVAILABLE STATE

   The reference render draws a filled EU bar reading "4 days · 50 of 90 by
   15 Oct". There is no counting authority in this build (PRD §6.1; contract
   §2: `schengen` is never passed, and absent ≡ unavailable, never a zero), so
   that number cannot be produced honestly and is NOT drawn.

   The slot is not left empty either — it states the unavailable state in the
   same shape the header chip already uses (index.html `.fc-eu-chip`, ruling
   C8): the neutral ground rather than the green one, an em-dash rather than a
   figure, and the whole fact in prose for a screen reader.
   ════════════════════════════════════════════════════════════════════════ */
.fc-insp__eu {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  padding: 8px 12px;
  border-radius: var(--fc-radius-tag);
  background: var(--fc-neutral-chip);     /* NOT the green --fc-eu-panel */
}
.fc-insp__eu-label {
  font-size: var(--fc-size-badge);        /* 9px */
  font-weight: var(--fc-weight-semibold);
  letter-spacing: var(--fc-track-caps);
  /* design value: --fc-text-muted-2 #98A1AE (2.37:1 on this ground).
     Substituted for AA. */
  color: var(--fc-text-secondary);
}
.fc-insp__eu-text {
  font-size: var(--fc-size-meta);         /* 11px */
  font-weight: var(--fc-weight-medium);
  color: var(--fc-text-secondary);
  text-wrap: pretty;
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 6 — LEG ROWS (flight · accommodation · trip · item · who-is-home)
   ════════════════════════════════════════════════════════════════════════ */
.fc-insp__legs { margin-top: 4px; }

.fc-insp__group-label {
  margin: 16px 0 0;
  font-size: var(--fc-size-badge);        /* 9px */
  font-weight: var(--fc-weight-semibold);
  letter-spacing: var(--fc-track-caps);
  text-transform: uppercase;
  /* design value: --fc-text-dow #AEB6C4 (2.04:1). Substituted for AA, exactly
     as the mobile month and the year ribbon already do. */
  color: var(--fc-text-secondary);
}

/* ── THE LEG ROW LIVES IN calendar.css SECTION 5b NOW ──────────────────────
   Everything that used to be here — `.fc-insp__leg` and its top row, tile,
   title, name, number chip, meta, sub-line, and the whole flight detail panel
   (detail, side, code-row, code, time, airport, terminal chip, arrow) — moved
   VERBATIM into css/calendar.css SECTION 5b as `.fc-leg*` on 2026-08-06, and
   js/views/leg.js builds it.

   Why it left a file it was correct in: DESIGN-DECISIONS §3's heading is
   "Day-view / inspector flight-leg field order" and the Day view was
   rendering the same flight two other ways — one run-together line on desktop,
   a solid graphite block on mobile. This build was the one §3 describes, so it
   was promoted rather than reconciled. Nothing about it changed in the move;
   only the prefix did, because an `fc-insp` class on a Day row would be the
   same fragmentation with a tidier diff.

   Four values went with it as component-scoped properties on `.fc-leg`
   (--fc-leg-tile, --fc-leg-detail-indent, --fc-leg-detail-arrow, and the two
   type sizes), and two became brand tokens: --fc-insp-legs-hairline is now
   --fc-hairline-leg, --fc-insp-terminal-chip is now --fc-terminal-chip.
   DESIGN-DECISIONS §1 names both verbatim, which is what made them brand-level.

   THIS FILE ADDS NO OVERRIDES TO IT. A `.fc-insp .fc-leg` rule here would be
   the second copy growing back one declaration at a time. If the Inspector
   ever genuinely needs a leg to differ from Day's, that is a design decision
   to take and record, not a specificity bump to reach for. */

/* ── the who-is-home read-out (DESIGN §6, plain events) ───────────────── */
.fc-insp__home {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 14px;
  padding: 10px 12px;
  border-radius: var(--fc-radius-row);
  background: var(--fc-surface-rail);
  font-size: var(--fc-size-body);
  font-weight: var(--fc-weight-semibold);
  color: var(--fc-text-ink);
  text-wrap: pretty;
}
.fc-insp__home-dot {
  flex: 0 0 auto;
  inline-size: var(--fc-dot);
  block-size: var(--fc-dot);
  border-radius: 50%;
  background: var(--fc-insp-home-c, var(--fc-cat-appointment));
}

/* ── the empty day (spec 09 §5 `empty`) ───────────────────────────────── */
.fc-insp__empty { margin-top: 16px; }
.fc-insp__empty-title {
  margin: 0;
  font-size: var(--fc-size-body);
  font-weight: var(--fc-weight-bold);
  color: var(--fc-text-ink);
}
.fc-insp__empty-body {
  margin: 5px 0 0;
  font-size: var(--fc-size-meta);
  font-weight: var(--fc-weight-medium);
  /* design value: --fc-text-muted #8A94A6 (3.06:1). Substituted for AA. */
  color: var(--fc-text-secondary);
  line-height: 1.5;
  text-wrap: pretty;
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 7 — FOCUS

   #4F7DF3, never suppressed (contract §5 / spec 09 §5). It is the
   existing `--fc-today` token; the hex is not retyped. Every interactive
   element in the component is covered by the one rule below, including the
   panel itself when it takes programmatic focus — where focus went should be
   visible.

   (Token names are kept off the start of a comment line throughout this file:
   contract §4's collision check is a line-anchored grep, and a name in prose
   at column 0 reads to it as a redeclaration.)
   ════════════════════════════════════════════════════════════════════════ */
.fc-insp :focus-visible,
.fc-insp:focus-visible {
  outline: 2px solid var(--fc-today);
  outline-offset: 2px;
  border-radius: var(--fc-radius-badge);
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 8 — MOBILE (≤ 430px): the bottom sheet

   exports/mobile-trip-sheet.png. Same content, sheet chrome. It occupies the
   same slot as js/views/day-sheet.js, which is why only one of the two is
   ever on screen — see the module header and the JS.
   ════════════════════════════════════════════════════════════════════════ */
.fc-insp-scrim {
  position: fixed;
  inset: 0;
  z-index: 59;
  display: none;                    /* desktop: aria-modal=false, nothing to dim */
  appearance: none;
  padding: 0;
  border: 0;
  background: var(--fc-scrim);
  opacity: 0;
  cursor: pointer;
  transition: opacity var(--fc-insp-motion); /* TODO(motion-tokens) */
}
.fc-insp-scrim--on { opacity: 1; }
.fc-insp-scrim[hidden] { display: none; }

@media (max-width: 430px) {
  .fc-insp-scrim { display: block; }
  .fc-insp-scrim[hidden] { display: none; }

  .fc-insp {
    top: auto;
    right: 0;
    left: 0;
    bottom: 0;
    width: auto;
    max-width: none;
    max-height: var(--fc-m-sheet-max-h);    /* 78% */
    border-radius: var(--fc-radius-sheet) var(--fc-radius-sheet) 0 0;
    /* the sheet arrives from below, not from above */
    transform: translateY(100%);
  }
  .fc-insp--open { transform: translateY(0); }
  /* while a finger is on the handle the sheet must track it exactly */
  .fc-insp--dragging { transition: none; }

  /* the grab handle sits ABOVE the colour bar, as the render shows */
  .fc-insp__grab {
    display: flex;
    justify-content: center;
    padding: 9px 0 8px;
    touch-action: none;                     /* the LIST keeps its scrolling */
    cursor: grab;
  }
  .fc-insp__handle {
    inline-size: var(--fc-m-grab-w);
    block-size: var(--fc-m-grab-h);
    border-radius: 999px;
    background: var(--fc-grab-handle);
  }

  .fc-insp__body { padding: 18px 20px calc(18px + env(safe-area-inset-bottom)); }

  /* FONTS.md §4 / ruling D3: 44px on mobile regardless of the label inside.
     `--fc-tap` IS 44 since the 2026-08-09 rename — the canonical name now
     carries the canonical value, and `--fc-tap-desktop` (24) is the named
     exception for fine-pointer controls that never render at this width. */
  .fc-insp__chip { min-height: var(--fc-tap); }
  /* `button.fc-insp__leg` used to be here. The leg's 44px mobile floor moved
     with the component into calendar.css SECTION 5b, where it applies to Day's
     legs too — which is the point of the move. */
}

/* Above the mobile breakpoint the handle is not rendered at all (JS keeps it
   in the DOM so the node is built once); belt and braces. */
@media (min-width: 431px) {
  .fc-insp__grab { display: none; }
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 8b — THE DAY SHEET'S OPENABLE ROWS

   ⚠ These selectors are NOT `fc-insp-*`. Read the boundary carefully before
   deciding this file has overstepped contract §4.

   `.fc-sheet__*` is js/views/day-sheet.js + calendar.css SECTION 8, and
   calendar.css is FROZEN. Until 2026-08-06 every sheet row was an inert
   <div>; the Inspector lane made a row that opens something a real <button>
   (day-sheet.js renderRow(), authorised for that one purpose), because on a
   390px viewport the sheet row is the ONLY accessible route to the Inspector
   for a trip — the mobile trip bar is aria-hidden and pointer-only.

   A <button> does not inherit font, alignment or box from its class the way
   the <div> did, and it arrives with a UA border. The reset below is what
   makes the button look identical to the div it replaced. Both selectors are
   qualified with [type="button"], so they can match ONLY the rows this change
   creates — a shipped inert <div> row cannot be touched by them, at any
   specificity. Nothing here sets a colour: the row's ground and ink still come
   from calendar.css SECTION 8 and the caller's own custom properties.

   If day-sheet.js ever gets its own stylesheet, this section moves there
   wholesale. Flagged for the integrator.
   ════════════════════════════════════════════════════════════════════════ */
.fc-sheet__trip[type="button"],
.fc-sheet__item[type="button"] {
  width: 100%;
  border: 0;
  margin: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
  /* the mobile tap floor, ruling D3 — these rows exist only on mobile */
  min-height: var(--fc-tap);
  -webkit-appearance: none;
  appearance: none;
}
/* The estate's ring, on a row that had none because it was not focusable
   before (contract §5 — every interactive row gets one, never suppressed). */
.fc-sheet__trip[type="button"]:focus-visible,
.fc-sheet__item[type="button"]:focus-visible {
  outline: 2px solid var(--fc-today);
  outline-offset: 2px;
}


/* ════════════════════════════════════════════════════════════════════════
   SECTION 9 — 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 to instant here. Instant-legible, no travel —
   the panel still appears and disappears, it just does not move.
   ════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  .fc-insp,
  .fc-insp-scrim,
  .fc-insp__close {
    transition: none !important;
  }
  .fc-insp { transform: none; }
  .fc-insp--open { transform: none; }
  /* The leg's own reduced-motion rules moved with the component into
     calendar.css SECTION 5b — `.fc-leg` transition:none and no hover travel —
     so they now cover Day's legs as well as these. */

  @media (max-width: 430px) {
    /* no slide-up: the sheet is simply there, or simply not */
    .fc-insp { transform: none; }
    .fc-insp--open { transform: none; }
  }
}
