/* Owner-approved V3 foundation; application finishing pass,15October2026.
   Exact Owner V3 font bytes. Every visual rule is scoped to body.v3-app.
   No shared tokens, geometry, semantic status colours or behaviour are changed. */
@font-face{font-family:'Big Shoulders Display';font-style:normal;font-weight:600 800;font-display:swap;src:url("../vendor/marketing-v3/v3-font-01.woff2") format('woff2')}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:400;font-display:swap;src:url("../vendor/marketing-v3/v3-font-02.woff2") format('woff2')}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:500;font-display:swap;src:url("../vendor/marketing-v3/v3-font-03.woff2") format('woff2')}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:600;font-display:swap;src:url("../vendor/marketing-v3/v3-font-04.woff2") format('woff2')}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:700;font-display:swap;src:url("../vendor/marketing-v3/v3-font-05.woff2") format('woff2')}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:800;font-display:swap;src:url("../vendor/marketing-v3/v3-font-06.woff2") format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url("../vendor/marketing-v3/v3-font-07.woff2") format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:500;font-display:swap;src:url("../vendor/marketing-v3/v3-font-08.woff2") format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:600;font-display:swap;src:url("../vendor/marketing-v3/v3-font-09.woff2") format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:700;font-display:swap;src:url("../vendor/marketing-v3/v3-font-10.woff2") format('woff2')}

/* Adapt the supplied V3 palette to the existing component vocabulary. */
body.v3-app {
  --fc-paper: #F7F9FB;
  --fc-well: #EDF1F5;
  --fc-calc: #EEF2F6;
  --fc-ink: #0E1B2C;
  --fc-marine: #06244A;
  --fc-marine-hover: #0A2F5C;
  --fc-marine-deep: #06244A;
  --fc-sky: #19B8EC;
  --fc-sky-soft: #8EDCF7;
  --fc-steel: #4A5A6C;
  --fc-mute: #4A5A6C;
  --fc-faint: #9FB3C8;
  --fc-line: #D9E1E9;
  --fc-line-soft: #EEF2F6;
  --fc-line-strong: #B9C7D5;
  --font-body: 'Plus Jakarta Sans', system-ui, sans-serif;
  --font-display: 'Plus Jakarta Sans', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;
  --h1: 800 38px/1.05 'Big Shoulders Display', sans-serif;
  --h2: 700 19px/1.3 'Plus Jakarta Sans', sans-serif;
  --h3: 700 16px/1.35 'Plus Jakarta Sans', sans-serif;
  --shadow-rest: 0 2px 8px rgba(6,36,74,.045);
  --shadow-float: 0 8px 24px rgba(6,36,74,.09);
  --chrome-surface: #06244A;
  --chrome-border: #0A2F5C;
  --chrome-ink: #C9D6E3;
  --chrome-ink-strong: #FFFFFF;
  --chrome-mute: #9FB3C8;
  --chrome-accent: #19B8EC;
  --chrome-num-dim: #9FB3C8;
  --chrome-active-bg: rgba(25,184,236,.15);
  --chrome-panel-label: #8EDCF7;
  --chrome-panel-sub: #C9D6E3;
  --chrome-bar: rgba(255,255,255,.98);
  /* Application-wide pass (Acer, 15 Oct): the DERIVED tokens. tokens-v2.css defines these on
     :root as var() references, which resolve at :root — so re-mapping --fc-* on the body never
     reached them, and every field border, label font and calc well kept the old warm palette.
     Re-stated here against the V3 values. Semantic override/attention values are untouched. */
  --fc-mute: #5B6B7D;
  --fc-mist: #9FB3C8;
  --fc-mist-strong: #C9D6E3;
  --fc-info: #0B6E99;
  --fc-green: #0E6B45;
  --fc-green-tint: #E5F4EC;
  --field-input-bg: #FFFFFF;
  --field-input-border: #C3CFDB;
  --field-calc-bg: #EEF2F6;
  --text-body: var(--fc-ink);
  --text-secondary: var(--fc-steel);
  --text-muted: var(--fc-mute);
  --text-heading: var(--fc-ink);
  --surface-app: var(--fc-paper);
  --surface-card: #FFFFFF;
  --surface-dark: var(--fc-marine);
  --action-primary: var(--fc-marine);
  --action-primary-hover: var(--fc-marine-hover);
  --accent: var(--fc-sky);
  --focus-ring: var(--fc-marine);
  --focus-ring-dark: var(--fc-sky);
  --selection: var(--fc-sky-soft);
  --label: 600 12px/1.3 'Plus Jakarta Sans', system-ui, sans-serif;
  --overline: 700 11px/1.3 'Plus Jakarta Sans', system-ui, sans-serif;
  --numeric: 'JetBrains Mono', ui-monospace, monospace;
  --radius-card: 10px;
  --radius-control: 8px;
  --radius-chip: 8px;
  --radius-badge: 6px;
  --v3-ring: 0 0 0 3px rgba(25,184,236,.28);
  --v3-hover-wash: #EDF1F5;
  scrollbar-color: #B9C7D5 transparent;
  background: var(--fc-paper);
  color: var(--fc-ink);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
}
body.v3-app ::selection { background: #8EDCF7; color: #0E1B2C; }

body.v3-app .iq-title {
  color: var(--fc-marine);
  text-transform: uppercase;
  letter-spacing: .012em;
}
body.v3-app .iq-lead { line-height: 1.65; }
body.v3-app .iq-head {
  padding-bottom: 18px;
  border-bottom: 1px solid var(--fc-line);
}
body.v3-app .fc-card {
  background: #FFFFFF;
  border-color: var(--fc-line);
  box-shadow: var(--shadow-rest);
}
body.v3-app .iq-kicker,
body.v3-app .fc-card__head {
  color: var(--fc-marine);
  background-color: #FFFFFF;
  font-weight: 700;
}
body.v3-app .iq-src { color: var(--fc-steel); }
body.v3-app .overview-card h2 {
  color: var(--fc-marine);
  font-family: var(--font-body);
  font-weight: 800;
  letter-spacing: -.025em;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--fc-line-soft);
}
body.v3-app .rail { box-shadow: 4px 0 18px rgba(6,36,74,.04); }
body.v3-app .rail__brand-name { font-family: var(--font-body); }
body.v3-app .rail__heading {
  font-family: var(--font-mono);
  letter-spacing: .13em;
}
body.v3-app .rail__item {
  border-radius: 6px;
  transition: background-color .12s ease;
}
body.v3-app .rail__item--active { box-shadow: inset 3px 0 var(--fc-sky); }
body.v3-app .topbar { border-bottom: 1px solid var(--fc-line); }
body.v3-app .fc-btn,
body.v3-app .ct-period__btn {
  font-family: var(--font-body);
  font-weight: 700;
  box-shadow: 0 1px 2px rgba(6,36,74,.04);
}
body.v3-app .fc-btn--primary {
  background: var(--fc-marine);
  border-color: var(--fc-marine);
  color: #FFFFFF;
}
body.v3-app .fc-btn--primary:hover:not(:disabled) {
  background: var(--fc-marine-hover);
  border-color: var(--fc-marine-hover);
}
body.v3-app .fc-btn--secondary,
body.v3-app .ct-period__btn {
  background: #FFFFFF;
  color: var(--fc-marine);
  border-color: var(--fc-line-strong);
}
body.v3-app .fc-btn--secondary:hover:not(:disabled),
body.v3-app .ct-period__btn:hover {
  background: #EDF1F5;
  border-color: var(--fc-marine);
}
body.v3-app .fc-btn:focus-visible,
body.v3-app .fc-seg__opt:focus-visible,
body.v3-app .ct-period__btn:focus-visible {
  outline: 2px solid var(--fc-marine);
  outline-offset: 3px;
  box-shadow: 0 0 0 4px #8EDCF7;
}
body.v3-app .fc-seg { background: #EDF1F5; border-color: var(--fc-line); }
body.v3-app .fc-seg__opt { color: var(--fc-steel); font-family: var(--font-body); }
body.v3-app .fc-seg__opt[aria-selected="true"] {
  color: #FFFFFF;
  background: var(--fc-marine);
  box-shadow: 0 1px 3px rgba(6,36,74,.12);
}
body.v3-app .ct-tile { background: #FFFFFF; }
body.v3-app .ct-tile:hover { background: #F7F9FB; }
/* Preserve confirmed/estimated/overdue meaning, independent of the new brand. */
body.v3-app .ct-confirmed,
body.v3-app .ct-confirmed:hover { background: var(--fc-green-tint); }
body.v3-app .ct-assumption,
body.v3-app .ct-assumption:hover { background: var(--fc-amber-tint); }
body.v3-app .ct-overdue,
body.v3-app .ct-overdue:hover { background: var(--fc-red-tint); }
body.v3-app .ct-tile__label { letter-spacing: .08em; }
body.v3-app .ct-tile__value { color: var(--fc-marine); letter-spacing: -.03em; }
body.v3-app .ct-tile__value--none { color: var(--fc-steel); letter-spacing: 0; }
body.v3-app .ct-proftable th { color: var(--fc-marine); background: #F7F9FB; }
body.v3-app .ct-proftable tbody tr:hover { background: #F7F9FB; }
body.v3-app .ct-filter__select { font-family: var(--font-body); background: #FFFFFF; }
body.v3-app .sm-layer-chip { border-radius: 6px; }
body.v3-app .sm-mapcard { box-shadow: var(--shadow-float); }
body.v3-app .overview-page #overview_content > h2 {
  color: var(--fc-marine);
  font-family: var(--font-body);
  font-weight: 800;
  letter-spacing: -.025em;
}
body.v3-app .overview-page details > summary {
  color: var(--fc-marine);
  font-weight: 800;
  cursor: pointer;
  padding-block: 4px;
}
body.v3-app form[data-block-report] {
  display: grid;
  gap: 14px;
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--fc-line);
}
body.v3-app form[data-block-report] fieldset {
  margin: 0;
  padding: 14px;
  border: 1px solid var(--fc-line);
  border-radius: 8px;
  background: var(--fc-paper);
  min-width: 0;
}
body.v3-app form[data-block-report] fieldset:not([hidden]) { display: grid; gap: 12px; }
body.v3-app form[data-block-report] fieldset[hidden] { display: none; }
body.v3-app form[data-block-report] [role="status"] { margin: 0; overflow-wrap: anywhere; }
body.v3-app .overview-reports {
  max-height: 18rem;
  overflow-y: auto;
  overflow-wrap: anywhere;
  padding: 0 12px;
  border: 1px solid var(--fc-line-soft);
  border-radius: 8px;
  background: var(--fc-paper);
}
body.v3-app .overview-reports:empty { display: none; }
body.v3-app .overview-reports:focus-visible { outline: 2px solid var(--fc-marine); outline-offset: 3px; }
/* Keep every existing tool in order and reachable on narrow screens. No clipping. */
body.v3-app .mc-modes { min-width: 0; max-width: 100%; }
body.v3-app .sm-saved { display: flex; flex-wrap: wrap; align-items: end; gap: 8px; width: 100%; }
body.v3-app .sm-saved .fc-field { flex: 1 1 220px; min-width: 0; margin: 0; }
body.v3-app .sm-saved select { width: 100%; min-width: 0; }
body.v3-app #sm_tool,
body.v3-app #sm_plan { flex-wrap: wrap; max-width: 100%; }
body.v3-app .sm-grid > * { min-width: 0; }
@media (max-width: 980px) {
  body.v3-app .sm-grid { grid-template-columns: minmax(0,1fr); }
}

@media (prefers-reduced-motion: reduce) {
  body.v3-app .rail__item { transition: none; }
}


/* P2 integration demonstration A: retained through successive candidate installs. */
/* P2 integration demonstration B: second change preserves demonstration A. */

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   APPLICATION-WIDE V3 CONTROL LAYER — Acer Claude, Part B, 15 Oct 2026.
   Owner: "EVERY INPUT STYLED … NO UNSTYLED BROWSER-DEFAULT CONTROLS."

   Two tiers, deliberately:
   · BASE looks are wrapped in :where(), specificity 0 — they beat the browser's own stylesheet
     (a different cascade origin) but lose to every screen rule, so a sheet cell, a gate-row
     input or a designed price-list control keeps exactly the treatment its screen gives it.
   · A few MUST-HAVES carry real specificity because a screen rule must not erase them: the
     select chevron, the keyboard focus ring and the disabled state.
   Semantic meaning is never restyled: input / ƒ calc / amber override / red attention keep
   their tokens, and missing-price "pending" stays visibly not-a-number.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* ── Text-like controls: one font, one border, one radius ─────────────────────────────────── */
:where(body.v3-app) :where(input:not([type=checkbox],[type=radio],[type=range],[type=file],[type=color],[type=hidden],[type=submit],[type=button],[type=reset],[type=image]), select, textarea) {
  font: inherit;
  font-size: 13.5px;
  line-height: 1.35;
  color: var(--fc-ink);
  background-color: #FFFFFF;
  border: 1px solid var(--field-input-border);
  border-radius: var(--radius-control);
  padding: 8px 11px;
  box-sizing: border-box;
  transition: border-color .12s ease, box-shadow .12s ease, background-color .12s ease;
}
/* The shared field control never named a family, so every field select/input fell back to the
   browser's Arial while its label beside it was the brand face. Fixed once, at the component. */
body.v3-app .fc-field__control { font-family: var(--font-body); }
body.v3-app .fc-field__control--numeric,
body.v3-app input[type=number] { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
:where(body.v3-app) :where(button, input[type=submit], input[type=button], input[type=reset]) {
  font-family: inherit;
}
:where(body.v3-app) :where(input, textarea)::placeholder { color: #8796A8; opacity: 1; }
:where(body.v3-app) :where(textarea) { line-height: 1.5; resize: vertical; }
:where(body.v3-app) :where(input:not([type=checkbox],[type=radio],[type=range],[type=file]), select, textarea):hover {
  border-color: #9FB3C8;
}

/* MUST-HAVE · keyboard and pointer focus on every entry control: a navy edge and a soft cyan
   halo. The edge overrides an amber/red state border only while the field is being edited. */
body.v3-app :is(input:not([type=checkbox],[type=radio],[type=range],[type=file]), select, textarea):focus {
  outline: none;
  border-color: var(--fc-marine);
  box-shadow: var(--v3-ring);
}
/* Sheet cells and in-table editors draw no box at rest; they still show where the caret is. */
body.v3-app :is(td, th) :is(input:not([type=checkbox],[type=radio]), select, textarea):focus { box-shadow: inset 0 0 0 2px var(--fc-sky); }

/* MUST-HAVE · disabled reads as unavailable, read-only reads as a value rather than a field.
   Specificity (0,2,1): beats the shared field states, loses to a screen's own disabled design
   (the costing sheet's transparent scaffold cells, `.is-scaffold .mc-sheet input:disabled`). */
body.v3-app :is(input, select, textarea, button):disabled { cursor: not-allowed; }
body.v3-app :where(input:not([type=checkbox],[type=radio],[type=range],[type=file]), select, textarea):disabled {
  background-color: #EEF2F6;
  color: #6B7A8C;
  border-color: #D9E1E9;
  -webkit-text-fill-color: #6B7A8C;
}
:where(body.v3-app) :where(input[readonly], textarea[readonly]) {
  background-color: var(--fc-calc);
  border-color: var(--fc-line);
}
/* Validation: only after the person has interacted, never on first paint. */
body.v3-app :is(input, select, textarea):user-invalid,
body.v3-app :is(input, select, textarea)[aria-invalid="true"] {
  border-color: var(--field-attention-border);
  background-color: var(--field-attention-bg);
}

/* ── Select: one drawn chevron everywhere (MUST-HAVE — a screen background shorthand would
      otherwise erase it and leave a select with no affordance at all). ─────────────────── */
body.v3-app select:not([multiple]):not([size]) {
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%2306244A' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  background-size: 11px 7px;
  padding-right: 30px;
  cursor: pointer;
  text-overflow: ellipsis;
}
body.v3-app select:disabled { cursor: not-allowed; opacity: 1; }
:where(body.v3-app) :where(select) option { color: var(--fc-ink); background: #FFFFFF; }
:where(body.v3-app) :where(select[multiple], select[size]) { padding: 4px; }

/* ── Checkbox and radio: drawn, not native ───────────────────────────────────────────────────
   MUST-HAVE specificity, unlike the text controls: a screen rule written for text inputs
   (`.mc-sheet input { border: 0; background: none }`, `.mc-sheet input[type=radio] { width:
   auto }`) erases a drawn box completely — with `appearance: none` an auto width is ZERO, and
   the costing sheet's Rate 1/2/3 choice vanished from the page in the first preview of this
   layer. The one designed switch built on a checkbox (Security's `.se-toggle`) is excluded. */
body.v3-app :is(input[type=checkbox], input[type=radio]):not(.se-toggle input) {
  -webkit-appearance: none;
  appearance: none;
  flex: none;
  box-sizing: border-box;
  width: 18px;
  min-width: 18px;
  height: 18px;
  padding: 0;
  margin: 0 6px 0 0;
  vertical-align: -4px;
  border: 1.5px solid #9FB3C8;
  border-radius: 5px;
  background: #FFFFFF center / 12px 12px no-repeat;
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease, box-shadow .12s ease;
}
body.v3-app input[type=radio]:not(.se-toggle input) { border-radius: 50%; }
body.v3-app :is(input[type=checkbox], input[type=radio]):not(.se-toggle input):hover:not(:disabled) { border-color: var(--fc-marine); }
body.v3-app input[type=checkbox]:not(.se-toggle input):is(:checked, :indeterminate) {
  background-color: var(--fc-marine);
  border-color: var(--fc-marine);
}
body.v3-app input[type=checkbox]:not(.se-toggle input):checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 6.2 5 8.6l4.6-5' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
body.v3-app input[type=checkbox]:not(.se-toggle input):indeterminate {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 6h6' stroke='%23fff' stroke-width='1.9' stroke-linecap='round'/%3E%3C/svg%3E");
}
body.v3-app input[type=radio]:not(.se-toggle input):checked {
  border-color: var(--fc-marine);
  background-image: radial-gradient(circle, var(--fc-marine) 0 4px, transparent 4.6px);
  background-size: 100% 100%;
}
body.v3-app :is(input[type=checkbox], input[type=radio]):not(.se-toggle input):focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(25,184,236,.35);
  border-color: var(--fc-marine);
}
body.v3-app :is(input[type=checkbox], input[type=radio]):not(.se-toggle input):disabled {
  background-color: #EEF2F6;
  border-color: #D9E1E9;
}
body.v3-app input[type=checkbox]:not(.se-toggle input):checked:disabled { background-color: #9FB3C8; border-color: #9FB3C8; }
body.v3-app input[type=radio]:not(.se-toggle input):checked:disabled {
  background-image: radial-gradient(circle, #9FB3C8 0 4px, transparent 4.6px);
}
:where(body.v3-app) :where(label):has(> input[type=checkbox], > input[type=radio]) { cursor: pointer; }
/* Security's switch keeps its own drawing; it gains only the V3 focus halo. */
body.v3-app .se-toggle input:focus-visible { outline: 2px solid var(--fc-marine); outline-offset: 3px; }

/* ── Range, colour, file ─────────────────────────────────────────────────────────────────── */
:where(body.v3-app) :where(input[type=range]) { accent-color: var(--fc-marine); cursor: pointer; }
:where(body.v3-app) :where(input[type=file]) { font: inherit; font-size: 13px; color: var(--fc-steel); max-width: 100%; }
body.v3-app input[type=file]::file-selector-button {
  font: 700 12.5px/1 var(--font-body);
  color: var(--fc-marine);
  background: #FFFFFF;
  border: 1px solid var(--fc-line-strong);
  border-radius: var(--radius-control);
  padding: 9px 14px;
  margin-right: 12px;
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease;
}
body.v3-app input[type=file]::file-selector-button:hover { background: var(--v3-hover-wash); border-color: var(--fc-marine); }
body.v3-app input[type=file]:focus-visible { outline: 2px solid var(--fc-marine); outline-offset: 3px; border-radius: var(--radius-control); }
body.v3-app input:is([type=date],[type=time],[type=datetime-local],[type=month],[type=week])::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: .62;
  filter: invert(12%) sepia(41%) saturate(2390%) hue-rotate(196deg) brightness(92%);
}
body.v3-app input:is([type=date],[type=time],[type=datetime-local])::-webkit-calendar-picker-indicator:hover { opacity: 1; }

/* ── Buttons: the remaining variants the trial did not reach ─────────────────────────────── */
body.v3-app .fc-btn { transition: background-color .12s ease, border-color .12s ease, color .12s ease, box-shadow .12s ease, transform .12s ease; }
body.v3-app .fc-btn--primary:hover:not(:disabled) { box-shadow: 0 6px 16px -8px rgba(6,36,74,.55); }
body.v3-app .fc-btn:active:not(:disabled) { transform: translateY(1px); }
/* Ghost buttons get a light border: borderless they read as plain text beside bordered buttons
   ("New plan", "Show all", "← Material call-up"). Still quieter than secondary's stronger line. */
body.v3-app .fc-btn--ghost { color: var(--fc-steel); border-color: var(--fc-line); }
body.v3-app .fc-btn--ghost:disabled { border-color: transparent; }
body.v3-app .fc-btn--ghost:hover:not(:disabled) { background: var(--v3-hover-wash); color: var(--fc-marine); }
body.v3-app .fc-btn--danger { background: #FFFFFF; color: var(--fc-red); border-color: var(--field-attention-border); }
body.v3-app .fc-btn--danger:hover:not(:disabled) { background: var(--fc-red-tint); border-color: var(--fc-red); }
body.v3-app .fc-btn--success { background: var(--fc-green); border-color: var(--fc-green); color: #FFFFFF; }
body.v3-app .fc-btn--success:hover:not(:disabled) { background: #0B5636; }
body.v3-app .fc-btn--bare { text-decoration-color: rgba(6,36,74,.3); }
body.v3-app .fc-btn--bare:hover:not(:disabled) { text-decoration-color: var(--fc-marine); }
body.v3-app .fc-btn:disabled,
body.v3-app .fc-btn[aria-disabled="true"] {
  background: #EEF2F6;
  color: #8796A8;
  border-color: #E1E7EE;
  box-shadow: none;
  cursor: not-allowed;
}
body.v3-app .fc-btn[aria-busy="true"] { cursor: progress; opacity: .8; }

/* ── Chips, filters, legends, notices, money ─────────────────────────────────────────────── */
:where(body.v3-app) .fc-chip { font-family: var(--font-body); letter-spacing: .01em; }
:where(body.v3-app) .fc-chip--neutral { background: #EEF2F6; color: var(--fc-steel); border-color: var(--fc-line); }
:where(body.v3-app) .fc-filter {
  color: var(--fc-steel);
  border-color: var(--fc-line-strong);
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
:where(body.v3-app) .fc-filter:hover { border-color: var(--fc-marine); color: var(--fc-marine); }
:where(body.v3-app) .fc-filter[aria-pressed="true"] { background: var(--fc-marine); color: #FFFFFF; border-color: var(--fc-marine); }
:where(body.v3-app) .fc-filter:focus-visible { outline: 2px solid var(--fc-marine); outline-offset: 3px; }
:where(body.v3-app) .fc-legend__key { color: var(--fc-mute); font-family: var(--font-mono); font-weight: 600; letter-spacing: .12em; }
:where(body.v3-app) .fc-notice { border-radius: var(--radius-card); }
:where(body.v3-app) .fc-notice--info { border-color: #BFDDEB; }
:where(body.v3-app) .fc-notice--dark { background: var(--fc-marine); border-color: var(--fc-marine); box-shadow: inset 0 -3px 0 var(--fc-sky); }
:where(body.v3-app) .fc-money { background: #EEF2F6; color: var(--fc-marine); }
:where(body.v3-app) .fc-pending { font-weight: 600; }
:where(body.v3-app) .fc-dark { background: var(--fc-marine); box-shadow: inset 0 -3px 0 var(--fc-sky), var(--shadow-float); }
:where(body.v3-app) .fc-rule__label { font-family: var(--font-mono); font-weight: 600; letter-spacing: .14em; color: var(--fc-mute); }

/* Dark panels: the trial's white kicker band is for light cards only. */
body.v3-app .fc-dark .iq-kicker { background-color: transparent; border-bottom-color: rgba(255,255,255,.14); }

/* ── Cards and section heads ─────────────────────────────────────────────────────────────── */
:where(body.v3-app) .fc-card { border-radius: var(--radius-card); }
:where(body.v3-app) .fc-card__head { border-bottom-color: var(--fc-line); letter-spacing: -.005em; }
:where(body.v3-app) .fc-card__title { color: var(--fc-marine); }

/* ── Tables: navy overline heads on a paper band, tabular figures, a quiet row hover ─────── */
:where(body.v3-app) .fc-table th {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: .07em;
  color: var(--fc-steel);
  background: var(--fc-paper);
  border-bottom-color: var(--fc-line);
}
:where(body.v3-app) .fc-table td { border-bottom-color: #E8EDF2; }
:where(body.v3-app) .fc-table tbody tr { transition: background-color .1s ease; }
:where(body.v3-app) .fc-table tbody tr:hover { background: #F7F9FB; }
:where(body.v3-app) :where(td, th) { font-variant-numeric: tabular-nums; }

/* ── Price screens (11 Engine, 12 Everyday) wrap in `main.pg`, a class no stylesheet defines,
      so both pages had no gutter, no line height and fell to the browser serif wherever a
      component did not name a family. Page treatment only — the 13 Oct mock layouts, columns
      and controls are untouched. ──────────────────────────────────────────────────────────── */
:where(body.v3-app) main.pg {
  padding: var(--pad-screen);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  color: var(--fc-ink);
}
:where(body.v3-app) main.pg .bar #epl-search { width: min(460px, 100%); }

/* ── Form sections (Logistics, Timesheets, Job gallery, Feedback): a card holding a fieldset
      grid of labelled fields with a legend as its title. The legend rendered as body text, and
      each label stretched to its grid row so a select beside a textarea grew to 48px. ─────── */
:where(body.v3-app) :where(.fc-card) legend {
  box-sizing: border-box;
  width: 100%;
  padding: 0 0 12px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--fc-line);
  font: 700 15px/1.3 var(--font-body);
  letter-spacing: -.005em;
  color: var(--fc-marine);
}
:where(body.v3-app) :where(fieldset) > :where(label.fc-field) { align-self: start; }
:where(body.v3-app) :where(.fc-card fieldset) > :where(p) { margin: 0; color: var(--fc-steel); font-size: 13px; line-height: 1.55; }

/* ── Company docs identity: read-only values were drawn as bordered mono inputs, so a reader
      could not tell them from editable fields (Owner: "clear distinction between editable
      controls and static information"). Static value tiles in the brand face; labels align. */
:where(body.v3-app) .cd-id-grid { align-items: start; }
:where(body.v3-app) .cd-id-value {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  color: var(--fc-ink);
  background: var(--fc-paper);
  border-color: var(--fc-line-soft);
  box-shadow: inset 3px 0 0 var(--fc-line-strong);
}
:where(body.v3-app) .cd-id-value--blank { font-weight: 500; color: var(--fc-mute); font-style: italic; }

/* ── A button carrying no size modifier (Client onboarding "Add client", Accounts) had no
      padding at all — a cramped label on a navy bar. It takes the standard md geometry; any
      sized or screen-styled button is untouched (specificity 0). ─────────────────────────── */
:where(body.v3-app) :where(.fc-btn:not(.fc-btn--sm, .fc-btn--md, .fc-btn--lg, .fc-btn--bare)) {
  font-size: 13px;
  padding: 10px 18px;
  border-radius: var(--radius-control);
}
/* A button with no colour variant (Everyday's upload "Close"/"Cancel") fell to the browser's
   grey button face. It reads as the secondary action it is. One class of weight, so it beats
   the base `.fc-btn { border: 1px solid transparent }` that hid the border at specificity 0. */
:where(body.v3-app) :where(.fc-btn:not(.fc-btn--primary, .fc-btn--secondary, .fc-btn--ghost, .fc-btn--danger, .fc-btn--success, .fc-btn--dark-outline, .fc-btn--bare)).fc-btn {
  background: #FFFFFF;
  color: var(--fc-marine);
  border-color: var(--fc-line-strong);
}
:where(body.v3-app) :where(.fc-btn:not(.fc-btn--primary, .fc-btn--secondary, .fc-btn--ghost, .fc-btn--danger, .fc-btn--success, .fc-btn--dark-outline, .fc-btn--bare)).fc-btn:hover:not(:disabled) {
  background: var(--v3-hover-wash);
  border-color: var(--fc-marine);
}
/* Consecutive cards directly on a page had no space between them (Client onboarding's route
   note sat glued to the form card). Screens that space their own cards keep their rule. */
:where(body.v3-app .iq-page > .fc-card + .fc-card) { margin-top: var(--gap-card); }
:where(body.v3-app) .co-form > .iq-kicker { margin-bottom: 14px; }

/* ── Narrow screens: the page never scrolls sideways — a wide table scrolls inside its card.
      Measured at 390px before this rule: Engine Price List +578px, Rules +434px and Client
      onboarding +95px (all pre-existing), Everyday +7px. Desktop geometry is untouched. ──── */
:where(body.v3-app) .co-terms > span { min-width: 0; }
:where(body.v3-app) .co-terms .fc-pending { white-space: normal; }
/* ── Long lists (ui/v2/long_list.js): the pager under a paged table, the "Show all" preview. ── */
/* A row off the current page. `!important` because `hidden` alone loses to a screen's display rule. */
[data-ll-out] { display: none !important; }
:where(body.v3-app) .ll-pager {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 10px;
  margin: 12px 0 4px;
  padding-top: 12px;
  border-top: 1px solid var(--fc-line-soft);
  font: 500 12.5px/1.3 var(--font-body);
  color: var(--fc-steel);
}
:where(body.v3-app) .ll-pager[hidden] { display: none; }
:where(body.v3-app) .epl-pager { margin: 12px 0 16px; }
:where(body.v3-app) .epl-held { margin: 8px 0 0; padding: 8px 12px; border-radius: 8px; background: #FFF7ED; border: 1px solid #FDBA74; color: #9A3412; font-size: 13px; }
:where(body.v3-app) .epl-held[hidden] { display: none; }
:where(body.v3-app) .epl-pager__held { flex-basis: 100%; text-align: right; font-size: 12px; color: #9A3412; }
:where(body.v3-app) .ll-pager__count { margin-right: auto; font-family: var(--font-mono); font-size: 12px; color: var(--fc-mute); }
:where(body.v3-app) .ll-pager__page { font-weight: 600; color: var(--fc-ink); min-width: 92px; text-align: center; }
:where(body.v3-app) .ll-preview { margin-top: 6px; }

/* ── Headline tiles on Job tracker, Clients, Time saved and Purchase orders: the dashboard's KPI
      look (V3 pass, 16 Oct 2026) — a mono overline, the figure large in the brand face, no grey
      pill. Same markup, same figures; Clients' green/amber meaning on its values is kept. ─── */
:where(body.v3-app) :is(.jt-tile, .cl-tile) { display: flex; flex-direction: column; gap: 6px; padding: 16px 16px 14px; }
body.v3-app :is(.jt-tile, .cl-tile) .iq-kicker {
  margin: 0; padding: 0; border: 0; background: transparent;
  font: 600 11px/1.3 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--fc-steel);
}
:where(body.v3-app) :is(.jt-tile, .cl-tile) .fc-money {
  align-self: flex-start; padding: 0; background: transparent;
  font: 800 clamp(18px, 1.5vw, 24px)/1.1 var(--font-body); letter-spacing: -.02em;
}
:where(body.v3-app) .jt-tile .fc-money { color: var(--fc-marine); }
:where(body.v3-app) .jt-tile__note { margin-top: auto; font-size: 12px; color: var(--fc-mute); }
@media (max-width: 560px) {
  /* Two up on a phone instead of a column of five tall cards. */
  body.v3-app :is(.jt-tiles, .cl-tiles) { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  :where(body.v3-app) :is(.jt-tile, .cl-tile) { padding: 12px; }
}

/* ── The V3 confirmation dialog for irreversible actions (ui/v2/confirm_dialog.js). ───────── */
/* The confirm button is the design system's own `.fc-btn--danger` (outlined red), as on every
   other destructive control; the dialog adds only its frame, the red rule and the kicker. */
.fc-confirm { border: 0; padding: 0; border-radius: 12px; width: min(440px, calc(100vw - 32px)); color: var(--fc-ink);
  background: var(--fc-white); box-shadow: 0 24px 64px -20px rgba(6,36,74,.45); font: 14px/1.5 var(--font-body); }
.fc-confirm::backdrop { background: rgba(6,36,74,.5); }
.fc-confirm__form { margin: 0; padding: 24px 24px 20px; border-top: 3px solid var(--danger); border-radius: 12px; }
.fc-confirm__kicker { margin: 0 0 6px; font: 600 11px/1.3 var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: #9A3412; }
.fc-confirm__title { margin: 0 0 8px; font: 700 17px/1.35 var(--font-body); color: var(--fc-marine); overflow-wrap: anywhere; }
.fc-confirm__message { margin: 0; color: var(--fc-steel); }
.fc-confirm__actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 22px; }

/* ── Master lists (Projects, Employee profiles): a find box and their own scroll panel. ──── */
[data-ll-miss] { display: none !important; }
:where(body.v3-app) .ll-find { width: 100%; margin: 0 0 10px; border-color: var(--field-input-border); background-color: #FFFFFF; }
/* A long readiness chip wraps under the job number instead of spilling past the card. */
:where(body.v3-app) .pj-item__row, :where(body.v3-app) .ep-person__row { flex-wrap: wrap; row-gap: 4px; }
:where(body.v3-app) .ll-master { min-width: 0; align-self: start; position: sticky; top: var(--sticky-top, 78px); }
:where(body.v3-app) .ll-master > .pj-list, :where(body.v3-app) .ll-master > .ep-list { position: static; }
@media (max-width: 900px) { :where(body.v3-app) .ll-master { position: static; } }
/* Installers folder job packs: an aligned grid in a bounded scroll panel (one pack per job won). */
:where(body.v3-app) .ll-master:has(> #if_packs) { position: static; }
body.v3-app .if-packs { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  gap: 10px; margin: 0 0 16px; padding: 3px; max-height: 452px; overflow-y: auto; position: relative; overscroll-behavior: contain; }
body.v3-app .if-pack { min-width: 0; width: 100%; }
body.v3-app .if-blocktable td:nth-child(3) { white-space: nowrap; }
:where(body.v3-app) .if-packs[data-ll-empty]::after { grid-column: 1 / -1; content: "Nothing matches."; font-size: 13px; color: var(--fc-mute); padding: 8px 2px; }
:where(body.v3-app) .pj-list[data-ll-empty]::after,
:where(body.v3-app) .ep-list[data-ll-empty]::after { content: "Nothing matches."; font-size: 13px; color: var(--fc-mute); padding: 8px 2px; }
@media (min-width: 901px) {
  :where(body.v3-app) .pj-list,
  :where(body.v3-app) .ep-list { max-height: calc(100vh - 260px); overflow-y: auto; padding-right: 6px; scrollbar-gutter: stable; }
}
:where(body.v3-app) .pj-item, :where(body.v3-app) .ep-person { flex: none; }

/* ── Job folders: newest first, months that fold, a list that scrolls in its own panel. ──── */
:where(body.v3-app) .jf-order { width: auto; min-width: 170px; border-color: var(--field-input-border); background-color: #FFFFFF; }
:where(body.v3-app) .jf-month { border-bottom: 1px solid var(--fc-line-soft); }
:where(body.v3-app) .jf-month__head {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 9px 4px 9px 2px;
  background: var(--fc-paper);
  font: 700 12px/1.3 var(--font-body);
  letter-spacing: .02em;
  color: var(--fc-marine);
  cursor: pointer;
  box-sizing: border-box;
  width: 100%;
  border: 0;
  text-align: left;
}
:where(body.v3-app) .jf-month__head:hover { color: var(--fc-marine-hover); }
:where(body.v3-app) .jf-month__rows[hidden] { display: none; }
:where(body.v3-app) .jf-month__head::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  margin-right: 4px;
  border-right: 1.6px solid var(--fc-steel);
  border-bottom: 1.6px solid var(--fc-steel);
  transform: rotate(-45deg);
  transition: transform .12s ease;
}
:where(body.v3-app) .jf-month__head[aria-expanded="true"]::before { transform: rotate(45deg); }
:where(body.v3-app) .jf-month__head > span:first-child { margin-right: auto; }
:where(body.v3-app) .jf-month__n {
  font: 600 11px/1 var(--font-mono);
  color: var(--fc-steel);
  background: #EEF2F6;
  border-radius: 999px;
  padding: 3px 8px;
}
:where(body.v3-app) .jf-month__rows { display: flex; flex-direction: column; gap: 6px; padding: 2px 0 12px; }
/* Compact folder rows: number, status, client and meta in ~62px rather than ~100px. */
:where(body.v3-app) .jf-folder { padding: 8px 12px; border-radius: 8px; transition: background-color .1s ease, border-color .1s ease; }
:where(body.v3-app) .jf-folder:hover { background: #F7F9FB; border-color: var(--fc-line-strong); }
:where(body.v3-app) .jf-folder.is-open { background: #FFFFFF; box-shadow: 0 0 0 1px var(--fc-marine), inset 3px 0 0 var(--fc-sky); }
:where(body.v3-app) .jf-folder__top { align-items: center; }
:where(body.v3-app) .jf-folder .fc-chip { font-size: 11px; padding: 2px 8px; }
:where(body.v3-app) .jf-folder__client { margin-top: 2px; font-size: 13px; color: var(--fc-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:where(body.v3-app) .jf-folder__meta { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:where(body.v3-app) .jf-folder:focus-visible { outline: 2px solid var(--fc-marine); outline-offset: 2px; }
@media (min-width: 901px) {
  :where(body.v3-app) #jf_folders {
    max-height: calc(100vh - 300px);
    min-height: 260px;
    overflow-y: auto;
    padding-right: 6px;
    scrollbar-gutter: stable;
  }
}

/* ── Job tracker rows (overnight, 15 Oct 2026): a row was ~185px — three full-height contact
      inputs stacked — and the date cells cut "2024-11-28" to "2024-11-2". Tighter cell padding gives
      the dates their width back (and narrows the table, which only helps the measured 1280/1440
      fit recorded in screens.css); the contact trio goes compact; the read-only client name reads
      in the body face. Same cells, same order, same controls. ────────────────────────────────── */
:where(body.v3-app) .jt-table td { padding: 10px 10px; }
:where(body.v3-app) .jt-table th { padding-left: 10px; padding-right: 10px; }
:where(body.v3-app) .jt-table .jt-edit { padding-left: 8px; padding-right: 8px; }
:where(body.v3-app) .jt-sub .jt-edit { padding-top: 4px; padding-bottom: 4px; font-size: 12px; margin-top: 4px; }
:where(body.v3-app) .jt-client .fc-field__value { font-family: var(--font-body); font-weight: 600; font-size: 13px; }
:where(body.v3-app) .jt-actions { gap: 2px; }
/* A date never truncates: at 1280 the table already scrolls inside .jt-scroll, so a few more
   pixels there scroll rather than cutting "2024-11-28" short. */
:where(body.v3-app) .jt-table .jt-edit:is([data-field="date_entered"], [data-field="follow_up_date"]) { min-width: 104px; }
/* Job tracker rows (Owner, 23 Oct 2026 — previewed live and approved): the duplicate Workflow no. column is gone, the
   three actions read on one line each, the fence type shows whole, and the contact lines read as text until hovered
   or focused. Same controls, same order; nothing is hidden. */
:where(body.v3-app) .jt-table td.jt-actions { display: table-cell; max-width: none; white-space: nowrap; }
:where(body.v3-app) .jt-table td.jt-actions .fc-btn { display: flex; white-space: nowrap; margin-bottom: 4px; }
:where(body.v3-app) .jt-client .fc-field__value { text-align: left; }
:where(body.v3-app) .jt-sub .jt-edit { border-color: transparent; background: transparent; box-shadow: none;
                                       margin-top: 1px; padding-top: 2px; padding-bottom: 2px; }
:where(body.v3-app) .jt-sub .jt-edit:is(:hover, :focus) { border-color: var(--fc-line); background: var(--field-input-bg); }
:where(body.v3-app) .jt-table .jt-edit[data-field="fence_type"] { min-width: 180px; }
:where(body.v3-app) .jt-table .jt-status { min-width: 118px; }
:where(body.v3-app) .jt-gst { margin-bottom: 10px; }

/* Follow-up rows on a phone: four columns with a nowrap "quoted $X · overdue since …" pushed the
   Log-call button 220px past a 390px screen. Below 760px the row stacks: who, then due, then the
   actions side by side. Desktop keeps its four columns. */
@media (max-width: 760px) {
  :where(body.v3-app) .jt-followups__row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 6px; }
  :where(body.v3-app) .jt-followups__who { grid-column: 1 / -1; }
  :where(body.v3-app) .jt-followups__due { grid-column: 1 / -1; white-space: normal; }
}

/* Job tracker's add-reference form (replaces two native prompts): a small card under the chips. */
:where(body.v3-app) .jt-refform {
  flex-basis: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 8px;
  margin-top: 6px;
  padding: 10px;
  background: #FFFFFF;
  border: 1px solid var(--fc-line);
  border-radius: var(--radius-control);
  box-shadow: var(--shadow-float);
  min-width: 340px;
}
:where(body.v3-app) .jt-refform__field { display: grid; gap: 4px; font: 600 11.5px/1.3 var(--font-body); color: var(--fc-steel); }
:where(body.v3-app) .jt-refform__field select,
:where(body.v3-app) .jt-refform__field input { width: 100%; font-size: 13px; padding: 6px 9px; }
:where(body.v3-app) .jt-refform__field select { padding-right: 28px; }
:where(body.v3-app) .jt-refform__actions { grid-column: 1 / -1; display: flex; gap: 6px; justify-content: flex-end; }

/* Topbar: the job line truncated as ONE box, so with a long job name the "Close job" button
   inside it was clipped under the review chip — measured unreachable at 768px (pre-existing).
   Only the job name truncates now; the button and the screen name keep their width. */
:where(body.v3-app) .topbar__job { display: flex; align-items: center; gap: 6px; }
:where(body.v3-app) .topbar__job > #chrome_job { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
:where(body.v3-app) .topbar__job > :not(#chrome_job) { flex: none; }
/* At phone width the chip and Sign out took the whole row and the job name truncated to nothing,
   leaving only "Close job". The job line gets its own first row there instead. */
@media (max-width: 560px) {
  :where(body.v3-app) .topbar { flex-wrap: wrap; row-gap: 6px; }
  :where(body.v3-app) .topbar__job { flex: 1 1 100%; order: -1; }
}

/* Client quote: the A4 page (794px) pushed a phone 202px sideways (pre-existing). On narrow
   screens it scrolls inside its own host; print is untouched. */
@media screen and (max-width: 900px) {
  :where(body.v3-app) .cq-doc-host { max-width: 100%; overflow-x: auto; }
}

/* Phone/tablet navigation. chrome.css wraps the rail into a ~900px block of thirty links above
   every screen at 390px, so a crew member on Clock or Today scrolled past the whole nav to reach
   the page. Same links, same order, nothing removed: one compact strip that scrolls sideways,
   group headings inline, the current screen underlined in cyan and scrolled into view by
   chrome.js. "Switch to Classic" and the quote total stay in the strip. */
@media (max-width: 900px) {
  body.v3-app .rail {
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    gap: 0;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 10px 12px;
    border-right: 0;
    border-bottom: 3px solid var(--fc-sky);
    box-shadow: none;
  }
  body.v3-app .rail__brand { flex: none; margin: 0 6px 0 0; padding: 0 4px; }
  body.v3-app .rail__brand-sub { display: none; }
  body.v3-app .rail__group {
    flex: none;
    display: flex;
    align-items: center;
    margin: 0;
    padding: 0 4px 0 10px;
    border-left: 1px solid rgba(255,255,255,.12);
  }
  body.v3-app .rail__heading { padding: 0 6px 0 0; font-size: 9.5px; }
  body.v3-app .rail__items { flex-direction: row; gap: 2px; }
  body.v3-app .rail__item { width: auto; white-space: nowrap; padding: 9px 10px; }
  body.v3-app .rail__item--active { box-shadow: inset 0 -3px var(--fc-sky); }
  body.v3-app .rail__fallback { flex: none; margin: 0 0 0 10px; white-space: nowrap; }
  body.v3-app .rail__total { flex: none; margin: 0 0 0 10px; padding: 8px 12px; }
}

@media (max-width: 900px) {
  :where(body.v3-app) .fc-seg { max-width: 100%; flex-wrap: wrap; }
  :where(body.v3-app) .fc-card:has(> table),
  :where(body.v3-app) .fc-card:has(> .fc-table) { overflow-x: auto; }
}

/* ── Disclosure, links, keyboard focus on everything else ───────────────────────────────── */
:where(body.v3-app) :where(details > summary) { cursor: pointer; }
:where(body.v3-app) :where(summary):focus-visible { outline: 2px solid var(--fc-marine); outline-offset: 3px; border-radius: 4px; }
:where(body.v3-app main) :where(a:not([class])) { color: var(--fc-marine-hover); text-decoration-color: rgba(10,47,92,.35); text-underline-offset: 3px; }
:where(body.v3-app main) :where(a:not([class])):hover { text-decoration-color: currentColor; }
:where(body.v3-app) :where(a, button, [role=button], [role=tab], [tabindex]):focus-visible {
  outline: 2px solid var(--fc-marine);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  body.v3-app .fc-btn,
  body.v3-app .fc-filter,
  body.v3-app .fc-table tbody tr { transition: none; }
  body.v3-app .fc-btn:active:not(:disabled) { transform: none; }
}
