/* The Friday file, visual pass (9 October 2026). Astra v2, docs/working-papers/friday-visual-pass-2026-10-09/.
   Loaded after participant.css on the Friday play page only; every rule is scoped to the mission. */
/* Friday: local light, spacing and shadow values without changing brand tokens. */
body[data-mission="the-friday-file"] {
  --fv-pad: clamp(22px, 4vw, 36px);
  --fv-glow: color-mix(in srgb, var(--accent) 18%, transparent);
  --fv-grid: color-mix(in srgb, var(--on-dark) 7%, transparent);
  background:
    radial-gradient(ellipse 850px 500px at 90% 0,
      var(--accent-soft), transparent 75%),
    var(--bg-page);
  background-repeat: no-repeat;
}
/* The hero glow reaches 64px past the copy; on phones that made the page scroll sideways. */
body[data-mission="the-friday-file"] #app { overflow-x: clip; }

/* Friday: replace only inherited entry effects that conflict with this pass. */
body[data-mission="the-friday-file"] #app[data-stage] :is(
  .fx-notice, .fx-resume, .fx-done,
  .gd-hero-copy, .gd-scene-you, .gd-scene-dash,
  .gd-scene .gd-bubble, .gd-scene-files > li,
  .gd-scene-clock, .gd-pulse,
  .gd-typing, .gd-typing i, .gd-said,
  .gd-faces > li, .gd-journey > li,
  .fx-pane, .fx-arrive, .fx-unlocked,
  .fx-later, .fx-later > *, .fx-note-seq > li,
  .fx-lines .fx-pathway > li, .fx-tick
) {
  animation: none;
}
body[data-mission="the-friday-file"] #app .gd-journey::before,
body[data-mission="the-friday-file"] #app .gd-cta::before,
body[data-mission="the-friday-file"] #app[data-drawer="open"] {
  animation: none;
}
body[data-mission="the-friday-file"] #app
.gd-debrief details[open] > :not(summary) {
  animation: none;
}
body[data-mission="the-friday-file"] #app[data-drawer="open"]
.gd-drawer-body {
  opacity: 1;
  transform: none;
}

/* Friday: place replaced transitions inside the motion preference query. */
body[data-mission="the-friday-file"] #app :is(
  button, a, summary, input,
  .gd-choice, .gd-check, .gd-arrow, .gd-setup,
  .gd-faces > li, .gd-scene-files > li, .gd-stop, .fx-saved
),
body[data-mission="the-friday-file"] #app .gd-setup::after {
  transition: none;
}

/* Brief: remove inert hover lifts and the delayed CTA shine. */
body[data-mission="the-friday-file"] .gd-faces li:hover,
body[data-mission="the-friday-file"] .gd-scene-files li:hover,
body[data-mission="the-friday-file"] .gd-journey li:hover .gd-stop,
body[data-mission="the-friday-file"] .gd-setup:hover,
body[data-mission="the-friday-file"] .gd-cta:hover .gd-arrow,
body[data-mission="the-friday-file"] .gd-btn:active:not(:disabled) {
  transform: none;
}
body[data-mission="the-friday-file"] .gd-cta::before {
  content: none;
}

/* Brief: keep complete dialogue as the default and reserve its full height. */
body[data-mission="the-friday-file"] #app[data-stage]
.gd-scene .gd-typing {
  display: none;
  padding: 0;
  visibility: hidden;
}
body[data-mission="the-friday-file"] #app[data-stage]
.gd-scene .gd-said {
  opacity: 1;
  transform: none;
}

/* Frame: simulate frost with opaque pearl gradients instead of backdrop blur. */
body[data-mission="the-friday-file"] .fx-header {
  background: linear-gradient(110deg, var(--card), var(--card-soft));
  border-bottom-color: var(--accent-line);
  box-shadow: var(--shadow-nav);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
body[data-mission="the-friday-file"] .fx-stages [aria-current="step"] {
  color: var(--accent-deep);
  background: var(--accent-soft);
  border-radius: var(--r-sm);
  text-decoration-color: var(--accent);
}
body[data-mission="the-friday-file"] .fx-clock:not(:empty) {
  color: var(--ink);
  background: var(--amber-pill);
}
body[data-mission="the-friday-file"] .skip-link {
  z-index: 100;
}

/* Controls: add a solid violet body, inner highlight and restrained glow. */
body[data-mission="the-friday-file"] .gd-btn.gd-primary {
  color: var(--on-dark);
  border-color: var(--accent-press);
  background: linear-gradient(125deg,
    var(--accent-hover), var(--accent), var(--accent-deep));
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--on-dark) 30%, transparent),
    0 8px 22px var(--fv-glow);
}
body[data-mission="the-friday-file"] .gd-btn.gd-primary:disabled,
body[data-mission="the-friday-file"] .gd-btn:disabled {
  opacity: 1;
  color: var(--muted);
  border-color: var(--line-strong);
  background: var(--bg-page);
  box-shadow: none;
}
body[data-mission="the-friday-file"] .gd-btn.gd-primary:disabled:hover {
  color: var(--muted);
  border-color: var(--line-strong);
  background: var(--bg-page);
}

/* Controls: keep focus visible inside clipped lists and on dark actions. */
body[data-mission="the-friday-file"] :is(
  button, a, summary, input, select, textarea
):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -3px;
}
body[data-mission="the-friday-file"] .gd-primary:focus-visible,
body[data-mission="the-friday-file"] .skip-link:focus-visible {
  outline-color: var(--on-dark);
  outline-offset: -4px;
  box-shadow: 0 0 0 2px var(--accent-deep);
}
body[data-mission="the-friday-file"] :is(
  .gd-choice, .gd-check
):has(input:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Notice and lean: frame the existing sheet without moving its body copy. */
body[data-mission="the-friday-file"] :is(
  .fx-notice, .fx-lean, .fx-done
) {
  position: relative;
  isolation: isolate;
  border-color: var(--line-strong);
  background: var(--card);
  box-shadow: var(--shadow-card-lg);
}
body[data-mission="the-friday-file"] :is(
  .fx-notice, .fx-lean, .fx-done
)::before {
  content: "";
  position: absolute;
  inset: 14px;
  background:
    linear-gradient(var(--brand), var(--brand))
      left top / 22px 2px no-repeat,
    linear-gradient(var(--brand), var(--brand))
      left top / 2px 22px no-repeat,
    linear-gradient(var(--brand), var(--brand))
      right bottom / 22px 2px no-repeat,
    linear-gradient(var(--brand), var(--brand))
      right bottom / 2px 22px no-repeat;
  pointer-events: none;
  z-index: -1;
}

/* Brief: make typography the defining gesture on both laptop and phone. */
body[data-mission="the-friday-file"] .gd-hero-copy {
  position: relative;
  isolation: isolate;
}
body[data-mission="the-friday-file"] .gd-display {
  font-size: clamp(36px, 4.6vw, 58px);
  line-height: 1.04;
  letter-spacing: -.045em;
  color: var(--accent-deep);
}
@supports (background-clip: text) {
  body[data-mission="the-friday-file"] .gd-display {
    background: linear-gradient(115deg,
      var(--accent-deep), var(--accent-press) 55%, var(--accent));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}
body[data-mission="the-friday-file"] .gd-hero-copy::before {
  content: "";
  position: absolute;
  inset: -48px -64px;
  background:
    radial-gradient(closest-side, var(--accent-soft), transparent);
  border-radius: var(--r-2xl);
  z-index: -1;
  pointer-events: none;
}

/* Brief: give the story a dimensional violet backing and architectural grid. */
body[data-mission="the-friday-file"] .gd-scene {
  isolation: isolate;
  background: var(--accent-deep);
  box-shadow:
    var(--shadow-scene),
    0 0 64px var(--fv-glow);
}
body[data-mission="the-friday-file"] .gd-scene::before {
  content: "";
  position: absolute;
  inset: 0;
  width: auto;
  height: auto;
  border-radius: inherit;
  background:
    linear-gradient(90deg, var(--fv-grid) 1px, transparent 1px)
      0 0 / 36px 36px,
    linear-gradient(var(--fv-grid) 1px, transparent 1px)
      0 0 / 36px 36px,
    linear-gradient(135deg,
      var(--accent), var(--accent-press) 45%, var(--accent-deep));
  transform-origin: right center;
  pointer-events: none;
  z-index: -1;
}
body[data-mission="the-friday-file"] .gd-scene::after {
  content: "";
  position: absolute;
  inset: 7px;
  border: 1px solid var(--on-dark-faint);
  border-radius: calc(var(--r-2xl) - 7px);
  pointer-events: none;
  z-index: -1;
}
body[data-mission="the-friday-file"] .gd-scene-you,
body[data-mission="the-friday-file"] .gd-scene-you p {
  color: var(--on-dark);
}
body[data-mission="the-friday-file"] .gd-scene-files li,
body[data-mission="the-friday-file"] .gd-scene-files li:hover {
  color: var(--on-dark);
  background: var(--accent-deep);
  border: 1px solid var(--accent-line);
  box-shadow: inset 0 1px 0 var(--on-dark-faint);
}
body[data-mission="the-friday-file"] .gd-scene .gd-bubble-body {
  box-shadow: var(--shadow-float);
}

/* Brief: retain the corrected currency width and sharpen the starting cards. */
body[data-mission="the-friday-file"] .fx-start > li {
  border-color: var(--line-strong);
  background: var(--card);
  box-shadow: var(--shadow-card);
}
body[data-mission="the-friday-file"] .fx-start-note {
  background: linear-gradient(120deg, var(--bg-sunken), var(--card-soft));
  box-shadow: inset 0 0 0 1px var(--card-line);
}
body[data-mission="the-friday-file"] .fx-start-currency {
  grid-column: 1 / -1;
  min-width: 0;
  width: 100%;
}

/* Choices: retain equal emphasis until the participant selects a row. */
body[data-mission="the-friday-file"] .gd-choice,
body[data-mission="the-friday-file"] .gd-conds .gd-check {
  border-color: var(--line-strong);
  background: var(--card);
}
body[data-mission="the-friday-file"] .gd-choice.is-on,
body[data-mission="the-friday-file"] .gd-conds .gd-check.is-on {
  color: var(--ink);
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: inset 3px 0 0 var(--accent);
}

/* Desk: animate bounded backings rather than panes containing readings. */
body[data-mission="the-friday-file"] .fx-pane {
  position: relative;
  isolation: isolate;
}
body[data-mission="the-friday-file"] .fx-pane::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 300px;
  max-height: 100%;
  background: linear-gradient(var(--bg-sunken), transparent);
  box-shadow: inset 0 2px 0 var(--accent-line);
  pointer-events: none;
  z-index: -1;
}
body[data-mission="the-friday-file"] .fx-juno {
  background: var(--tool-soft);
}
body[data-mission="the-friday-file"] .fx-juno::before {
  background: linear-gradient(var(--card), transparent);
  box-shadow: inset 0 2px 0 var(--tool-line);
}
body[data-mission="the-friday-file"] .fx-people {
  background: var(--card-soft);
}
body[data-mission="the-friday-file"] :is(
  .fx-tiles, .fx-files, .fx-person-list
) {
  border-color: var(--line-strong);
  background: var(--card);
  box-shadow: var(--shadow-card);
}

/* Desk: put the one-time dashboard light in its border, above the values. */
body[data-mission="the-friday-file"] .fx-tiles {
  position: relative;
}
body[data-mission="the-friday-file"] .fx-tiles::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 3px;
  background: linear-gradient(90deg,
    transparent, var(--accent-line), var(--accent), transparent);
  opacity: 0;
  pointer-events: none;
}

/* Advice: preserve slate identity and animate only the existing arrival chip. */
body[data-mission="the-friday-file"] .fx-msg:not(.is-replied) {
  border-color: var(--tool-line);
  background: var(--card);
  box-shadow: var(--shadow-card);
}
body[data-mission="the-friday-file"] .fx-juno .fx-new,
body[data-mission="the-friday-file"] .fx-call-juno .fx-new {
  color: var(--tool);
  background: var(--tool-soft);
  box-shadow: inset 0 0 0 1px var(--tool-line);
}

/* Files: give the reader a separately animated document backing. */
body[data-mission="the-friday-file"] .fx-reader .gd-mail {
  position: relative;
  isolation: isolate;
  border-color: var(--accent-line);
  background: transparent;
  box-shadow: var(--shadow-card-lg);
}
body[data-mission="the-friday-file"] .fx-reader .gd-mail::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--card);
  box-shadow: inset 4px 0 0 var(--accent-line);
  pointer-events: none;
  z-index: -1;
}
body[data-mission="the-friday-file"] .fx-reader .gd-mail > header {
  background: linear-gradient(120deg, var(--bg-sunken), var(--card-soft));
  border-bottom-color: var(--line-strong);
}

/* People: distinguish the open contact and received reply without invented hooks. */
body[data-mission="the-friday-file"] .fx-person.is-open > .fx-contact {
  background: var(--accent-soft);
}
body[data-mission="the-friday-file"] .fx-person .fx-qa {
  padding-left: 10px;
  box-shadow: inset 2px 0 0 var(--accent-line);
}

/* Limits: let the notification surface arrive behind stationary wording. */
body[data-mission="the-friday-file"] .fx-unlocked {
  position: relative;
  isolation: isolate;
  color: var(--ink-2);
  border: 1px solid var(--accent-line);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  background: transparent;
}
body[data-mission="the-friday-file"] .fx-unlocked::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--accent-soft);
  pointer-events: none;
  z-index: -1;
}

/* Decision: retain the violet anchor bar and its original sticky positioning. */
body[data-mission="the-friday-file"] #app[data-stage="desk"]
.gd-drawer .gd-drawer-bar {
  position: relative;
  background: linear-gradient(110deg, var(--accent-deep), var(--accent-press));
  border-color: var(--accent-deep);
}
body[data-mission="the-friday-file"] #app[data-stage="desk"]
.gd-drawer .gd-drawer-bar :is(p, .gd-drawer-t, .gd-drawer-s) {
  color: var(--on-dark);
}
body[data-mission="the-friday-file"] #app[data-stage="desk"]
.gd-drawer .gd-drawer-bar .gd-primary {
  color: var(--accent-deep);
  border-color: var(--card);
  background: var(--card);
  box-shadow: 0 6px 18px rgb(17 18 23 / 28%);
}
body[data-mission="the-friday-file"] #app[data-stage="desk"]
.gd-drawer .gd-drawer-bar .gd-primary:hover:not(:disabled) {
  color: var(--accent-deep);
  border-color: var(--accent-soft);
  background: var(--accent-soft);
}
body[data-mission="the-friday-file"] #app[data-stage="desk"]
.gd-drawer .gd-drawer-bar .gd-primary:focus-visible {
  outline-color: var(--accent-deep);
  box-shadow: 0 0 0 2px var(--card);
}
body[data-mission="the-friday-file"] #app[data-drawer="open"]
.gd-drawer .gd-drawer-bar {
  position: sticky;
  top: 52px;
}
body[data-mission="the-friday-file"] .gd-drawer-bar::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 2px;
  background: var(--gradient-rail);
  transform-origin: left;
  pointer-events: none;
}

/* Decision: use static gutter rules because checked rows do not prove completion. */
body[data-mission="the-friday-file"] .gd-drawer-body > .gd-dstep {
  position: relative;
}
body[data-mission="the-friday-file"] .gd-drawer-body > .gd-dstep::before {
  content: "";
  position: absolute;
  top: 8px;
  bottom: 0;
  left: -12px;
  width: 2px;
  background: linear-gradient(var(--accent-line), var(--card-line-soft));
  pointer-events: none;
}
body[data-mission="the-friday-file"] .gd-dstep .gd-n {
  color: var(--on-dark);
  background: var(--accent-deep);
}
body[data-mission="the-friday-file"] .fx-preview {
  color: var(--ink);
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-line);
}
body[data-mission="the-friday-file"] #app .gd-send .gd-btn[data-do="send"] {
  min-height: 52px;
  padding-inline: 28px;
  font-size: 16px;
  box-shadow:
    inset 0 1px 0 var(--on-dark-faint),
    0 12px 28px var(--fv-glow);
}

/* Phone navigation: strengthen the current tab without adding motion to counts. */
body[data-mission="the-friday-file"] .fx-tabs {
  border-bottom-color: var(--accent-line);
  background: var(--card);
}
body[data-mission="the-friday-file"] .fx-tab[aria-pressed="true"] {
  color: var(--accent-deep);
  border-color: var(--accent-line);
  background: var(--accent-soft);
  box-shadow: inset 0 -2px 0 var(--accent);
}
body[data-mission="the-friday-file"] .fx-call-foot {
  background: var(--card);
  border-top-color: var(--accent-line);
  box-shadow: var(--shadow-card);
}

/* Later: turn the title into a full-width chapter header within the existing card. */
body[data-mission="the-friday-file"] .fx-later {
  padding: var(--fv-pad);
  border-color: var(--line-strong);
  background: var(--card);
  box-shadow: var(--shadow-card-lg);
}
body[data-mission="the-friday-file"] .fx-later > h1 {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin:
    calc(-1 * var(--fv-pad))
    calc(-1 * var(--fv-pad))
    28px;
  padding: clamp(36px, 5vw, 56px) var(--fv-pad);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  color: var(--on-dark);
  background: linear-gradient(115deg, var(--accent-press), var(--accent-deep));
  font-size: clamp(30px, 3.6vw, 46px);
  line-height: 1.12;
  letter-spacing: -.035em;
}
body[data-mission="the-friday-file"] .fx-later > h1::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, var(--fv-grid) 1px, transparent 1px)
      0 0 / 32px 32px,
    linear-gradient(var(--fv-grid) 1px, transparent 1px)
      0 0 / 32px 32px;
  pointer-events: none;
  z-index: -2;
}
body[data-mission="the-friday-file"] .fx-later > h1::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 45%;
  background: linear-gradient(105deg,
    transparent,
    color-mix(in srgb, var(--on-dark) 8%, transparent),
    transparent);
  opacity: 0;
  pointer-events: none;
  z-index: -1;
}
body[data-mission="the-friday-file"] .fx-receipt {
  color: var(--ink);
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-line);
}

/* Later: connect the existing event rows without implying chronological sorting. */
body[data-mission="the-friday-file"] .fx-note-seq {
  position: relative;
  padding: 4px 22px;
  border-color: var(--line-strong);
  background: var(--card-soft);
}
body[data-mission="the-friday-file"] .fx-note-seq::before {
  content: "";
  position: absolute;
  top: 26px;
  bottom: 26px;
  left: 26px;
  width: 1px;
  background: var(--accent-line);
  transform-origin: top;
  pointer-events: none;
}
body[data-mission="the-friday-file"] .fx-note-seq > li {
  position: relative;
  padding-left: 20px;
}
body[data-mission="the-friday-file"] .fx-note-seq > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 22px;
  width: 9px;
  height: 9px;
  border: 2px solid var(--accent);
  border-radius: var(--r-pill);
  background: var(--card);
  pointer-events: none;
}
body[data-mission="the-friday-file"] .fx-later :is(.gd-reply, .fx-forward) {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-card);
}

/* Record: introduce a report header with a strong but quiet top rule. */
body[data-mission="the-friday-file"] .gd-debrief-head {
  padding: 24px;
  border: 1px solid var(--line-strong);
  border-top: 3px solid var(--accent);
  border-radius: var(--r-lg);
  background: linear-gradient(120deg, var(--card), var(--bg-sunken));
}
body[data-mission="the-friday-file"] .gd-debrief-head h1 {
  color: var(--accent-deep);
  font-size: clamp(30px, 3.4vw, 42px);
}

/* Record: stagger card backings while numbers and findings remain stationary. */
body[data-mission="the-friday-file"] .fx-lines .fx-pathway > li {
  isolation: isolate;
  border-color: transparent;
  background: transparent;
  box-shadow: none;
}
body[data-mission="the-friday-file"] .fx-lines .fx-pathway > li::after {
  content: "";
  position: absolute;
  inset: -1px -1px -1px -3px;
  border: 1px solid transparent;
  border-left-width: 3px;
  border-radius: inherit;
  background:
    linear-gradient(var(--card), var(--card)) padding-box,
    linear-gradient(var(--accent), var(--accent-line)) border-box;
  box-shadow: var(--shadow-card);
  pointer-events: none;
  z-index: -1;
}
body[data-mission="the-friday-file"] .fx-fold-card {
  border-color: var(--line-strong);
}
body[data-mission="the-friday-file"] .fx-fold-card > summary {
  border-radius: inherit;
  background: var(--card-soft);
}
body[data-mission="the-friday-file"] .fx-tick {
  stroke-dashoffset: 0;
}

/* Phone: retain the working currency layout and comfortable control widths. */
@media (max-width: 760px) {
  body[data-mission="the-friday-file"] .gd-display {
    font-size: 38px;
  }
  body[data-mission="the-friday-file"] .gd-debrief-head {
    padding: 18px;
  }
  body[data-mission="the-friday-file"] .fx-src {
    min-width: 0;
    white-space: normal;
  }
  body[data-mission="the-friday-file"] .gd-conds .gd-check {
    flex-wrap: wrap;
  }
  body[data-mission="the-friday-file"] #app .gd-send .gd-btn[data-do="send"] {
    width: 100%;
  }
}

/* Phone timeline: maintain alignment between the rail and the event nodes. */
@media (max-width: 640px) {
  body[data-mission="the-friday-file"] .fx-note-seq {
    padding-inline: 16px;
  }
  body[data-mission="the-friday-file"] .fx-note-seq::before {
    left: 20px;
  }
}

/* Motion: finite entry and arrival keyframes using only opacity and transform. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes fv-rise {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: none; }
  }
  @keyframes fv-depth {
    from { transform: perspective(900px) rotateY(-7deg) rotateX(3deg) scale(.96); }
    to { transform: none; }
  }
  @keyframes fv-turn {
    from { opacity: 0; transform: perspective(600px) rotateY(-45deg) translateY(8px); }
    to { opacity: 1; transform: none; }
  }
  @keyframes fv-panel {
    from { opacity: 0; transform: translateY(14px); }
    to { opacity: 1; transform: none; }
  }
  @keyframes fv-document {
    from { opacity: 0; transform: translateX(-16px); }
    to { opacity: 1; transform: none; }
  }
  @keyframes fv-title {
    from { transform: perspective(1000px) rotateX(5deg) scale(.975); }
    to { transform: none; }
  }
  @keyframes fv-sweep {
    0% { opacity: 0; transform: translateX(-140%); }
    15% { opacity: 1; }
    80% { opacity: 1; }
    100% { opacity: 0; transform: translateX(340%); }
  }
  @keyframes fv-draw-x {
    from { transform: scaleX(0); }
    to { transform: none; }
  }
  @keyframes fv-draw-y {
    from { transform: scaleY(0); }
    to { transform: none; }
  }
  @keyframes fv-node {
    from { opacity: 0; transform: scale(.6); }
    to { opacity: 1; transform: none; }
  }
  @keyframes fv-dot {
    0%, 100% { opacity: .35; transform: none; }
    50% { opacity: 1; transform: translateY(-2px); }
  }
  @keyframes fv-type-out {
    from { opacity: 1; }
    to { opacity: 0; }
  }
  @keyframes fv-line {
    from { opacity: 0; }
    to { opacity: 1; }
  }

  /* Notice and lean: animate titles and frames independently of body copy. */
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="notice"] .fx-notice > h1 {
    animation: fv-rise 360ms var(--ease-out) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="notice"] .fx-notice::before {
    animation: fv-depth 500ms var(--ease-out) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="lean"] .fx-lean > h1 {
    animation: fv-rise 320ms var(--ease-out) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="lean"] .fx-lean::before {
    animation: fv-depth 440ms var(--ease-out) both;
  }

  /* Brief: establish the headline and frame before the dialogue sequence. */
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-display {
    animation: fv-rise 460ms var(--ease-out) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-scene::before {
    animation: fv-depth 560ms var(--ease-out) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-scene-you {
    animation: fv-rise 300ms var(--ease-out) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-scene-dash {
    animation: fv-rise 300ms var(--ease-out) 100ms both;
  }

  /* Brief dialogue: use short finite dot sequences and finish by 1500 ms. */
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-scene .gd-bubble-ai {
    --fv-bubble: 260ms;
    --fv-type: 360ms;
    --fv-line: 680ms;
    animation: fv-rise 300ms var(--ease-out) var(--fv-bubble) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-scene .gd-bubble-right {
    --fv-bubble: 900ms;
    --fv-type: 1000ms;
    --fv-line: 1320ms;
    animation: fv-rise 300ms var(--ease-out) var(--fv-bubble) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-scene .gd-typing {
    display: inline-flex;
    visibility: visible;
    padding: 0;
    animation: fv-type-out 1ms linear var(--fv-line) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-scene .gd-typing i {
    animation: fv-dot 160ms ease-in-out var(--fv-type) 1 both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-scene .gd-typing i:nth-child(2) {
    animation-delay: calc(var(--fv-type) + 60ms);
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-scene .gd-typing i:nth-child(3) {
    animation-delay: calc(var(--fv-type) + 120ms);
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-scene .gd-said {
    animation: fv-line 180ms ease var(--fv-line) both;
  }

  /* Brief files: turn the existing tiles while leaving the hours pill still. */
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-scene-files > li {
    animation: fv-turn 340ms var(--ease-out)
      calc(620ms + var(--i, 0) * 60ms) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-scene-clock .gd-pulse {
    animation: fv-node 150ms var(--ease-out) 1450ms both;
  }

  /* Brief route: finish all four instructional entries inside 700 ms. */
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-journey > li {
    animation: fv-rise 360ms var(--ease-out)
      calc(60ms + var(--i, 0) * 60ms) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="brief"] .gd-journey::before {
    animation: fv-draw-x 600ms var(--ease-out) both;
  }

  /* Desk: stagger bounded decorative backings without translating readings. */
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="desk"][data-drawer="closed"] .fx-pane::before {
    animation: fv-panel 420ms var(--ease-out) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="desk"][data-drawer="closed"] .fx-centre::before {
    animation-delay: 70ms;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="desk"][data-drawer="closed"] .fx-people::before {
    animation-delay: 140ms;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="desk"][data-drawer="closed"] .fx-tiles::before {
    animation: fv-sweep 650ms var(--ease-out) 100ms both;
  }

  /* Arrivals: use the renderer's existing markers, not general redraw selectors. */
  body[data-mission="the-friday-file"] #app .fx-arrive .gd-mail::before {
    animation: fv-document 300ms var(--ease-out) both;
  }
  body[data-mission="the-friday-file"] #app .fx-unlocked::before {
    animation: fv-panel 360ms var(--ease-out) both;
  }
  body[data-mission="the-friday-file"] #app .fx-new {
    animation: fv-rise 300ms var(--ease-out) both;
  }

  /* Decision: acknowledge first entry without transforming the sticky drawer. */
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="desk"][data-drawer="open"] .gd-drawer-bar::before {
    animation: fv-draw-x 400ms var(--ease-out) both;
  }

  /* Later: settle the chapter title and pass light behind its lettering once. */
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="later"] .fx-later > h1 {
    animation: fv-title 500ms var(--ease-out) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="later"] .fx-later > h1::after {
    animation: fv-sweep 850ms var(--ease-out) 80ms both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="later"] .fx-note-seq::before {
    animation: fv-draw-y 500ms var(--ease-out) 100ms both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="later"] .fx-note-seq > li::before {
    animation: fv-node 260ms var(--ease-out)
      calc(120ms + min(var(--i, 0) * 50ms, 250ms)) both;
  }

  /* Record: assemble the report surfaces without animating facts or numbers. */
  body[data-mission="the-friday-file"]
  #app[data-enter]:is([data-stage="debrief"], [data-stage="compare"])
  .gd-debrief-head h1 {
    animation: fv-rise 360ms var(--ease-out) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter]:is([data-stage="debrief"], [data-stage="compare"])
  .fx-lines .fx-pathway > li::after {
    animation: fv-panel 440ms var(--ease-out) both;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter]:is([data-stage="debrief"], [data-stage="compare"])
  .fx-lines .fx-pathway > li:nth-child(2)::after {
    animation-delay: 80ms;
  }
  body[data-mission="the-friday-file"]
  #app[data-enter]:is([data-stage="debrief"], [data-stage="compare"])
  .fx-lines .fx-pathway > li:nth-child(n + 3)::after {
    animation-delay: 160ms;
  }

  /* Done: reveal the complete tick without drawing or counting anything. */
  body[data-mission="the-friday-file"]
  #app[data-enter][data-stage="done"] .fx-tick {
    animation: fv-node 320ms var(--ease-out) both;
  }

  /* Controls: permit short colour, border and shadow responses to interaction. */
  body[data-mission="the-friday-file"] #app :is(
    .gd-btn, .fx-file, .fx-contact, .fx-note-g,
    .gd-choice, .gd-check, .gd-seg-b
  ) {
    transition:
      background-color 160ms ease,
      border-color 160ms ease,
      box-shadow 160ms ease;
  }
  body[data-mission="the-friday-file"] #app .gd-btn.gd-primary {
    transition:
      transform 120ms var(--ease-out),
      box-shadow 160ms ease,
      border-color 160ms ease;
  }
  body[data-mission="the-friday-file"] #app
  .gd-btn.gd-primary:active:not(:disabled) {
    transform: translateY(1px);
    box-shadow:
      inset 0 2px 4px var(--accent-deep),
      0 2px 6px var(--fv-glow);
  }

  /* Phone route: draw the existing vertical connector on its correct axis. */
  @media (max-width: 760px) {
    body[data-mission="the-friday-file"]
    #app[data-enter][data-stage="brief"] .gd-journey::before {
      animation-name: fv-draw-y;
    }
  }
}

/* Pointer interaction: tactile surfaces without moving figures or inert cards. */
@media (hover: hover) and (pointer: fine) {
  body[data-mission="the-friday-file"] .gd-btn.gd-primary:hover:not(:disabled) {
    border-color: var(--accent-line);
    box-shadow:
      inset 0 1px 0 var(--on-dark-faint),
      0 10px 28px var(--fv-glow);
  }
  body[data-mission="the-friday-file"] #app :is(
    .fx-file, .fx-contact, .fx-note-g
  ):hover:not(:disabled) {
    background: var(--bg-sunken);
    box-shadow: inset 3px 0 0 var(--accent-line);
  }
  body[data-mission="the-friday-file"] #app :is(
    .gd-choice, .gd-conds .gd-check
  ):hover {
    border-color: var(--accent);
  }
}

/* Forced colours: preserve real heading text when gradient fills are suppressed. */
@media (forced-colors: active) {
  body[data-mission="the-friday-file"] .gd-display {
    background: none;
    color: CanvasText;
  }
}
