/* Exception Desk: desk.css
   Token values copied in from design-system/tokens.css (never imported at runtime).
   This demo is self-contained under site/demos/exception-desk/ per hard constraint #2. */

:root {
  /* ---- Core palette ---- */
  --bg: rgb(0, 0, 0);
  /* Cards and panels sit on --surface, the page sits on --bg. In dark they are the
     same black, so nothing changes. In light the page goes grey and the cards go
     white, which is what gives the three columns visible edges in daylight. */
  --surface: rgb(0, 0, 0);
  --fg: rgb(255, 255, 255);
  --accent: #6aa8ff;
  --accent-cyan: rgb(51, 194, 255);
  --shadow-card: 0 8px 24px rgba(0, 0, 0, 0.35);
  --shadow-header: 0 1px 0 rgba(255, 255, 255, 0.04), 0 8px 24px rgba(0, 0, 0, 0.45);
  --shadow-pop: 0 20px 50px rgba(0, 0, 0, 0.65);
  --scrim: rgba(0, 0, 0, 0.86);
  --scrim-soft: rgba(0, 0, 0, 0.6);
  --scrim-strong: rgba(0, 0, 0, 0.92);
  --hover-wash: rgba(255, 255, 255, 0.02);

  /* ---- White-with-alpha ladder ---- */
  --muted-93: rgba(255, 255, 255, 0.93);
  --muted-75: rgba(255, 255, 255, 0.75);
  --muted-70: rgba(255, 255, 255, 0.7);
  --hairline-20: rgba(255, 255, 255, 0.2);
  --border-10: rgba(255, 255, 255, 0.1);
  --border-06: rgba(255, 255, 255, 0.06);
  --border-05: rgba(255, 255, 255, 0.05);
  --muted: var(--muted-93);
  --hairline: var(--hairline-20);
  --border: var(--border-10);

  /* ---- Accent tint ---- */
  --accent-tint: rgba(106, 168, 255, 0.10);
  --accent-tint-strong: rgba(106, 168, 255, 0.18);

  /* ---- State palette ----
     The desk used to be black, white and one blue, so a resolved case, an escalated
     case and one still being worked all looked identical: you had to read every card
     to know what had happened. These three colours are the whole legend.
     Blue = the agent is working it. Green = it closed it. Amber = it stopped and
     handed the call to a human. */
  --state-working: #6aa8ff;
  --state-working-tint: rgba(106, 168, 255, 0.12);
  --state-resolved: #4ade80;
  --state-resolved-tint: rgba(74, 222, 128, 0.12);
  --state-escalated: #ffa53c;
  --state-escalated-tint: rgba(255, 165, 60, 0.12);

  /* ---- Typography ---- */
  --font-display: "Clash Grotesk", "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-sans: "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Bumped from 11/13. 50 of the 57 type-token uses in this file were xs or sm, so
     the whole desk was an 11-13px interface and read as unreadably small.

     The clamps below cap at 16-35px and the xs/sm steps are fixed, so every one of
     them saturates well before a 2560 or 3840 wide viewport. The three columns are
     percentages (26/44/30) and keep stretching, so on a 4K display the desk grew and
     the type did not: the same "unreadably small" complaint the bump above answered,
     one viewport class up. --ui-scale is the multiplier that makes the type follow the
     shell. At 1.0 (anything under 1680px) these resolve to exactly the values the
     laptop-width rendering was verified at, so nothing below 1680 moves. */
  --text-xs: calc(12px * var(--ui-scale));
  --text-sm: calc(15px * var(--ui-scale));
  --text-base: calc(clamp(15px, 0.09vw + 14.65px, 16px) * var(--ui-scale));
  --text-md: calc(clamp(16px, 0.19vw + 15.3px, 18px) * var(--ui-scale));
  --text-lg: calc(clamp(18px, 0.28vw + 16.9px, 21px) * var(--ui-scale));
  --text-xl: calc(clamp(20px, 0.38vw + 18.6px, 24px) * var(--ui-scale));
  --text-2xl: calc(clamp(24px, 0.47vw + 22.2px, 29px) * var(--ui-scale));
  --text-3xl: calc(clamp(28px, 0.66vw + 25.5px, 35px) * var(--ui-scale));

  /* ---- Spacing scale (4/8 base) ----
     Scaled by the same factor as the type. Bigger text inside chrome that stayed put
     would read as cramped, which is the failure mode the Factory OS correction calls
     out: the shell has to grow with the words it frames. Every padding, gap and inset
     in this file goes through these tokens, so scaling here scales the chrome. */
  --space-1: calc(4px * var(--ui-scale));
  --space-2: calc(8px * var(--ui-scale));
  --space-3: calc(12px * var(--ui-scale));
  --space-4: calc(16px * var(--ui-scale));
  --space-5: calc(20px * var(--ui-scale));
  --space-6: calc(24px * var(--ui-scale));
  --space-7: calc(32px * var(--ui-scale));
  --space-8: calc(40px * var(--ui-scale));

  /* ---- Border radii ---- */
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-pill: 100px;

  /* ---- Motion ---- */
  --ease-out-expo: cubic-bezier(0.165, 0.84, 0.44, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --dur-fast: 200ms;
  --dur-base: 500ms;

  /* ---- Viewport scale ----
     The multiplier behind every type and spacing token above, and the panel widths
     further down. Declared here at its 1.0 identity so the tokens resolve on any
     viewport; the steps below raise it. Unitless on purpose: it multiplies px values
     rather than being one, so a single variable moves type and chrome together. */
  --ui-scale: 1;

  /* The desk stops growing past this and centers. This is the real 4K fix: the three
     columns are percentages, so without a cap they balloon to ~1600px each on a 3840
     screen and the text looks tiny beside them. Capping the shell keeps the columns a
     reading width, which is why the scale ceiling above can stay gentle. Below this
     width the cap does nothing, so the reviewed laptop rendering is untouched. */
  --desk-max: 1900px;
}

/* Gentle ceiling of 1.15, not the 2.0 the Factory OS shell uses. That spec is for a
   full-bleed app; this desk is width-capped (--desk-max below) and centered, so the
   columns no longer balloon on a wide screen and the text no longer has to chase them.
   All the scale does now is a small bump for viewing distance on a physically large
   display. A 2.0 here read as a 2x zoom (a case card at 1603px with 32px body text),
   which is the "looks zoomed in" the founder caught. Below 1680 the scale stays 1.0,
   so the laptop rendering this desk was reviewed at is untouched. Stepped, not fluid,
   so the verification viewports are what actually ship. */
@media (min-width: 1680px) { :root { --ui-scale: 1.07; } }
@media (min-width: 2240px) { :root { --ui-scale: 1.15; } }

/* ---- Light theme ----
   This is a content-dense dashboard, and read in daylight the all-black surface made
   the three columns bleed into one another. In light the page is grey and the cards
   are white, so every panel and every case has a real edge.

   The state colours cannot carry over as-is: #6aa8ff / #4ade80 / #ffa53c are tuned
   for a black background and fall below readable contrast on white. Each gets a
   darker twin here, same meaning, same legend.

   Written once and applied from two places: the OS preference (for anyone who has not
   touched the toggle) and an explicit data-theme, which always wins. */
:root[data-theme="light"],
:root[data-theme="light"] body {
  color-scheme: light;
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) { color-scheme: light; }
}

:root[data-theme="light"] {
  --bg: #eceff3;
  --surface: #ffffff;
  --fg: #0e1420;
  --accent: #1a63c9;
  --accent-cyan: #0e7490;

  --muted-93: rgba(14, 20, 32, 0.93);
  --muted-75: rgba(14, 20, 32, 0.70);
  --muted-70: rgba(14, 20, 32, 0.62);
  --hairline-20: rgba(14, 20, 32, 0.20);
  --border-10: rgba(14, 20, 32, 0.14);
  --border-06: rgba(14, 20, 32, 0.10);
  --border-05: rgba(14, 20, 32, 0.07);

  --accent-tint: rgba(26, 99, 201, 0.08);
  --accent-tint-strong: rgba(26, 99, 201, 0.15);

  --state-working: #1a63c9;
  --state-working-tint: rgba(26, 99, 201, 0.10);
  --state-resolved: #15803d;
  --state-resolved-tint: rgba(21, 128, 61, 0.10);
  --state-escalated: #b45309;
  --state-escalated-tint: rgba(180, 83, 9, 0.10);

  --shadow-card: 0 1px 2px rgba(14, 20, 32, 0.06), 0 8px 24px rgba(14, 20, 32, 0.08);
  --shadow-header: 0 1px 0 rgba(14, 20, 32, 0.06), 0 8px 24px rgba(14, 20, 32, 0.06);
  --shadow-pop: 0 20px 50px rgba(14, 20, 32, 0.18);
  --scrim: rgba(14, 20, 32, 0.55);
  --scrim-soft: rgba(14, 20, 32, 0.40);
  --scrim-strong: rgba(14, 20, 32, 0.65);
  --hover-wash: rgba(14, 20, 32, 0.03);
}

/* Same values again for visitors on a light OS who have never touched the toggle.
   `:not([data-theme="dark"])` means an explicit dark choice still beats the OS. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]):not([data-theme="light"]) {
    --bg: #eceff3;
    --surface: #ffffff;
    --fg: #0e1420;
    --accent: #1a63c9;
    --accent-cyan: #0e7490;

    --muted-93: rgba(14, 20, 32, 0.93);
    --muted-75: rgba(14, 20, 32, 0.70);
    --muted-70: rgba(14, 20, 32, 0.62);
    --hairline-20: rgba(14, 20, 32, 0.20);
    --border-10: rgba(14, 20, 32, 0.14);
    --border-06: rgba(14, 20, 32, 0.10);
    --border-05: rgba(14, 20, 32, 0.07);

    --accent-tint: rgba(26, 99, 201, 0.08);
    --accent-tint-strong: rgba(26, 99, 201, 0.15);

    --state-working: #1a63c9;
    --state-working-tint: rgba(26, 99, 201, 0.10);
    --state-resolved: #15803d;
    --state-resolved-tint: rgba(21, 128, 61, 0.10);
    --state-escalated: #b45309;
    --state-escalated-tint: rgba(180, 83, 9, 0.10);

    --shadow-card: 0 1px 2px rgba(14, 20, 32, 0.06), 0 8px 24px rgba(14, 20, 32, 0.08);
    --shadow-header: 0 1px 0 rgba(14, 20, 32, 0.06), 0 8px 24px rgba(14, 20, 32, 0.06);
    --shadow-pop: 0 20px 50px rgba(14, 20, 32, 0.18);
    --scrim: rgba(14, 20, 32, 0.55);
    --scrim-soft: rgba(14, 20, 32, 0.40);
    --scrim-strong: rgba(14, 20, 32, 0.65);
    --hover-wash: rgba(14, 20, 32, 0.03);
  }
}

* { box-sizing: border-box; }

/* Author rules on overlay containers below set their own `display`, which beats
   the user-agent [hidden] rule at equal specificity. This restores `hidden`. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: var(--text-base);
}

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  /* The page background shows in the side margins once the desk hits --desk-max and
     centers, so the desk reads as one island on a wide screen instead of stretching
     edge to edge. */
  align-items: center;
}

/* The four top-level strips (header, tabs, main, footer) are direct flex children of
   body with no wrapper, so each carries the cap itself and they stay aligned. width
   100% keeps them full-bleed below the cap (align-items: center would otherwise shrink
   them to content); max-width centers them above it. */
.desk-header,
.narration-strip,
.desk-tabs,
.desk-main,
.desk-footer {
  width: 100%;
  max-width: var(--desk-max);
}
/* The intro / drawer / manual overlays are position: fixed full-screen modals and are
   deliberately NOT in the list above: they cover the whole viewport, not the capped
   desk. */

/* ---- Header strip ---- */

.desk-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border-bottom: 1px solid var(--hairline);
  position: sticky;
  top: 0;
  background: var(--surface);
  box-shadow: var(--shadow-header);
  z-index: 10;
}

.desk-header__left {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.desk-header__title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.desk-badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-75);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
}

.desk-header__controls {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.desk-btn {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  /* The end card's primary CTA is an <a>, not a <button>, so without this it
     carries the browser's default underline and reads as a text link sitting in
     a box next to the un-underlined Replay button. */
  text-decoration: none;
  transition: border-color var(--dur-base) var(--ease-out-expo), background var(--dur-base) var(--ease-out-expo);
}

.desk-btn:hover { border-color: var(--hairline); }
.desk-btn:disabled { opacity: 0.35; cursor: not-allowed; }

.desk-btn--danger { border-color: rgba(255, 90, 90, 0.3); color: rgb(255, 140, 140); }

.desk-btn--primary {
  background: var(--accent-tint);
  border-color: var(--accent);
  color: var(--accent);
}
.desk-btn--primary:hover { background: var(--accent-tint-strong); }

.desk-speed-group { display: flex; align-items: center; gap: var(--space-1); }

/* Names the control group, so "1x / 2x / 4x" is not left to the visitor to decode. */
.desk-ctrl-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-70);
  margin-right: var(--space-1);
}

/* Icon + word, so the theme button says what pressing it does. */
.desk-btn--icon { display: inline-flex; align-items: center; gap: var(--space-2); }
.desk-btn__icon { display: inline-flex; }

.desk-btn--speed.is-active {
  background: var(--accent-tint);
  border-color: var(--accent);
  color: var(--accent);
}

/* Tertiary link under the two intro buttons. */
.intro-card__tourlink {
  display: inline-block;
  margin-top: var(--space-4);
  background: none;
  border: 0;
  padding: 0;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--muted-70);
  text-decoration: underline;
  cursor: pointer;
}
.intro-card__tourlink:hover { color: var(--fg); }

/* ---- Guided tour panel ----
   Lives in the left column, in the layout. It used to be a popup docked across the
   bottom of the viewport, which meant it sat on top of the cards it was describing and
   had to chase them as they grew (artifact text types out, actions reveal on timers),
   so the page jumped up and down and you could not follow what was happening. A column
   cannot be covered and never has to scroll anything, which deleted a whole class of
   bug along with it. */
.guide {
  border: 1px solid var(--state-working);
  border-radius: var(--radius-lg);
  background: var(--surface);
  padding: var(--space-5);
  margin-bottom: var(--space-6);
  /* Sticks as the page scrolls, so the step you are reading stays with you when the
     worklog scrolls down to a decision. align-self:start gives it a tall grid area to
     travel inside; without that its area is exactly its own height and sticky has
     nowhere to go. */
  position: sticky;
  top: var(--space-4);
  align-self: start;
  /* The 120px is the header-plus-gutter allowance this has to clear, and the header
     scales with --ui-scale, so the allowance does too. */
  max-height: calc(100vh - (120px * var(--ui-scale)));
  /* Only the case list scrolls. The step and the run button are pinned, so with fourteen
     cases in the list they can never be pushed out of sight. */
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* ---- The spotlight ----
   Until the visitor has picked a case there is nothing to see in the worklog and nothing
   in the ledger, so both are frosted back and made untouchable. That leaves exactly one
   live thing on the screen, and no question about where to start. The frost lifts the
   moment they pick, and never comes back. */
body.awaiting-pick .desk-panel--worklog,
body.awaiting-pick .desk-panel--ledger,
body.awaiting-pick .desk-panel--inbound,
body.awaiting-pick .narration-strip {
  filter: blur(4px) saturate(0.5);
  opacity: 0.35;
  pointer-events: none;
  user-select: none;
}

.desk-panel--worklog,
.desk-panel--ledger,
.desk-panel--inbound,
.narration-strip {
  transition: filter var(--dur-base) var(--ease-out-expo),
              opacity var(--dur-base) var(--ease-out-expo);
}

/* And the one thing they CAN touch says so. */
body.awaiting-pick #guide {
  border-color: var(--state-working);
  box-shadow: 0 0 0 1px var(--state-working), 0 0 44px var(--state-working-tint);
  animation: guideBeacon 2.4s ease-in-out infinite;
}
@keyframes guideBeacon {
  0%, 100% { box-shadow: 0 0 0 1px var(--state-working), 0 0 24px var(--state-working-tint); }
  50%      { box-shadow: 0 0 0 1px var(--state-working), 0 0 56px var(--state-working-tint); }
}

.guide-prompt {
  margin: var(--space-4) 0 0;
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--state-working-tint);
  color: var(--state-working);
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.45;
}

@media (prefers-reduced-motion: reduce) {
  body.awaiting-pick #guide { animation: none; }
  .desk-panel--worklog,
  .desk-panel--ledger,
  .desk-panel--inbound,
  .narration-strip { transition: none; }
}

.guide-list {
  list-style: none;
  margin: var(--space-4) 0;
  padding: 0 2px 0 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.guide-case {
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: left;
  width: 100%;
  padding: var(--space-3);
  background: transparent;
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out-expo), border-color var(--dur-fast) var(--ease-out-expo);
}
.guide-case:hover:not([disabled]) { background: var(--state-working-tint); border-color: var(--state-working); }
.guide-case:focus-visible { outline: 2px solid var(--state-working); outline-offset: 2px; }

.guide-case__label {
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--fg);
}
.guide-case__blurb {
  font-size: var(--text-xs);
  line-height: 1.45;
  color: var(--muted-70);
}

/* Group headers. Fourteen flat rows is a wall; grouped, the list answers "which one
   should I click?" without the visitor having to read every row. */
.guide-group {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: var(--space-5) 0 var(--space-2);
}
.guide-group:first-child { margin-top: 0; }
.guide-group__title {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg);
  font-weight: 600;
}
.guide-group__count {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  padding: 1px 6px;
  border-radius: var(--radius-pill);
  background: var(--border-10);
  color: var(--muted-70);
}
.guide-group__note {
  flex: 1 1 100%;
  font-size: var(--text-xs);
  line-height: 1.4;
  color: var(--muted-70);
}
.guide-group__cases {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* The group already says what these cases are, so the per-row tags are gone. */
.guide-group__cases .guide-case[data-group="race"] { border-left-color: var(--state-working); }
.guide-group__cases .guide-case[data-group="decide"] { border-left-color: var(--state-escalated); }

.guide-case__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
}
.guide-case__time {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted-70);
  flex: 0 0 auto;
}
/* .guide-case__tags / __tag / __tag--decide lived here and were deleted 2026-07-17.
   Nothing in desk.js or index.html ever rendered them: the case list carries its
   grouping in the group headings, which is where the 2026-07-15 pass put it. They
   surfaced during the --ui-scale work as one of two rules declaring a raw 10px, and
   the only reason to keep them would have been to scale text nobody can see. */

/* The case the visitor is in right now. */
.guide-case[data-state="current"] {
  border-left-color: var(--state-working);
  background: var(--state-working-tint);
}
/* Watched already. A tick, not a lock: this is a demo, and a visitor who has seen a case
   should be able to see it again. Locking the row behind the tick just told them they
   had used it up. */
.guide-case[data-state="done"] { border-left-color: var(--state-resolved); }
.guide-case[data-state="done"] .guide-case__label::after {
  content: " \2713";
  color: var(--state-resolved);
}

/* Both choices, on the card, next to each other, so the comparison reads as a comparison.
   .desk-btn--manual is full-width on its own, which shoved the by-hand button onto its
   own line and broke the pairing, so inside the pair they share the row instead. */
.case-card__choose { display: flex; gap: var(--space-2); align-items: stretch; }
.case-card__choose .desk-btn { width: auto; flex: 1 1 0; margin: 0; }
@media (max-width: 900px) {
  .case-card__choose { flex-direction: column; }
}

/* The tour's controls on the card. Separated from the case content by a rule, so it
   reads as "what do I do now" rather than as more of the agent's output. */
.case-card__guided:not(:empty) {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
}

/* The step commentary now sits in the worklog column, directly above the card it is
   describing, so it reads as the voice explaining the agent rather than a note pinned to
   the menu on the other side of the screen. */
.guide-step {
  flex: 0 0 auto;
  border: 1px solid var(--state-working);
  border-left: 3px solid var(--state-working);
  border-radius: var(--radius-md);
  background: var(--state-working-tint);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-4);
}
.guide__run { flex: 0 0 auto; }
.guide-step__n {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--state-working);
  margin: 0 0 var(--space-2);
}
.guide-step__title {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 600;
  margin: 0 0 var(--space-2);
  color: var(--fg);
}
.guide-step__body {
  font-size: var(--text-sm);
  line-height: 1.55;
  color: var(--muted-75);
  margin: 0 0 var(--space-4);
}
.guide-step__next { width: 100%; }
.guide__run { width: 100%; }


/* ---- Three-panel layout ---- */

.desk-main {
  flex: 1;
  display: grid;
  grid-template-columns: 26% 44% 30%;
  /* Two rows so the guide can sit on top of the left column with Inbound beneath it,
     while the worklog and the ledger run the full height alongside. */
  grid-template-rows: auto 1fr;
  gap: 1px;
  background: var(--border-06);
  min-height: 0;
}

/* When the visitor picks "just run the shift" the guide is [hidden], so row 1 has no
   item in it and the `auto` track collapses to zero on its own. Inbound then fills the
   column and the layout is byte-for-byte the old three-panel desk. */
.desk-main > #guide { grid-column: 1; grid-row: 1; }
.desk-panel--inbound { grid-column: 1; grid-row: 2; }
.desk-panel--worklog { grid-column: 2; grid-row: 1 / -1; }
.desk-panel--ledger  { grid-column: 3; grid-row: 1 / -1; }

/* During the tour the guide owns the left column and Inbound steps aside. Sharing the
   column just squeezed Inbound down to a sliver, and the whole complaint being answered
   here is that too much was happening at once: while we are teaching one case, three
   panels is one fewer thing to track than four. Inbound comes straight back the moment
   the shift runs. */
@media (min-width: 900px) {
  body.guided .desk-main { grid-template-rows: 1fr; }
  body.guided .desk-main > #guide { grid-row: 1; }
  body.guided .desk-panel--inbound { display: none; }
}

/* ---- One case at a time ----
   The worklog is an append-only feed, which is right while the night is playing: the
   cases pile up and that IS the point. But the tour is the opposite job. You are
   studying one case, and appending it below the ones already handled meant the page had
   to scroll down to find it and it was unclear which card you had just clicked on.
   During the tour the worklog shows the case you picked and nothing else. The others
   are not lost: they carry a green check in the guide and they are counted in the
   ledger. The full feed comes back the moment the shift runs. */
body.guided .case-card { display: none; }
body.guided .case-card.is-focus { display: block; }

.desk-panel {
  background: var(--surface);
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: var(--space-5);
  overflow-y: auto;
}

.desk-panel__title {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-70);
  margin: 0 0 var(--space-4);
}

.desk-panel__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  flex: 1;
}

.desk-panel__live {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--hairline);
}

.desk-panel__caption {
  font-size: var(--text-sm);
  color: var(--muted-70);
  margin: calc(var(--space-4) * -1 + 2px) 0 var(--space-4);
}

/* ---- Orientation layer: intro card ---- */

.intro-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  background: var(--scrim);
  backdrop-filter: blur(6px);
}

.intro-card {
  /* Measure scales with the type it holds. A fixed 560px box around 2x text would set
     a much narrower line and undo the legibility the scale just bought. */
  max-width: calc(560px * var(--ui-scale));
  width: 100%;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-8) var(--space-7);
  background: var(--surface);
  text-align: center;
}

.intro-card__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.16em;
  color: var(--accent-cyan);
  margin: 0 0 var(--space-4);
}

.intro-card__title {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 600;
  margin: 0 0 var(--space-4);
}

.intro-card__body {
  font-size: var(--text-md);
  color: var(--muted-75);
  margin: 0 0 var(--space-6);
  line-height: 1.5;
}

.intro-card__note {
  font-size: var(--text-sm);
  color: var(--muted-70);
  margin: var(--space-5) 0 var(--space-2);
}

.intro-card__countdown {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted-70);
  margin: 0;
}

/* ---- Narration strip ---- */

/* The narration is the only plain-English account of what the agent just did, and it
   was 13px mono at 75% white: the one line that explains the demo was the easiest
   thing on screen to miss. Give it a left accent rule, real size, and full contrast. */
.narration-strip {
  border-bottom: 1px solid var(--hairline);
  border-left: 3px solid var(--state-working);
  padding: var(--space-3) var(--space-6);
  background: linear-gradient(90deg, var(--state-working-tint), transparent 55%);
}

.narration-strip__text {
  font-family: var(--font-sans);
  font-size: var(--text-md);
  line-height: 1.5;
  color: var(--fg);
}

/* ---- Mobile tabs (hidden on desktop, shown under 900px) ---- */

.desk-tabs {
  display: none;
}

.desk-tab {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted-70);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
}

.desk-tab.is-active {
  color: var(--fg);
  border-bottom-color: var(--accent);
}

.tab-badge {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: transparent;
  margin-left: var(--space-1);
  vertical-align: middle;
}

.tab-badge.is-pulsing {
  background: rgb(255, 160, 60);
  animation: badge-pulse 1.1s var(--ease-in-out) infinite;
}

@keyframes badge-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.4; transform: scale(1.4); }
}

/* ---- Channel identity ---- */

.ch-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: var(--space-1);
  background: var(--muted-70);
}
.ch-dot[data-channel="email"] { background: var(--accent-cyan); }
.ch-dot[data-channel="sms"] { background: rgb(140, 220, 140); }
.ch-dot[data-channel="edi"] { background: var(--accent); }
.ch-dot[data-channel="tms"] { background: rgb(255, 190, 90); }

/* ---- Inbound feed items ---- */

.inbound-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  width: 100%;
  text-align: left;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  background: var(--surface);
  color: var(--fg);
  cursor: pointer;
  transition: border-color var(--dur-base) var(--ease-out-expo);
}
.inbound-item:hover { border-color: var(--hairline); background: var(--hover-wash); }
.inbound-item.is-hidden { display: none; }

.inbound-item__head {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted-70);
  display: flex;
  align-items: center;
}

.inbound-item__subject {
  font-size: var(--text-sm);
  font-weight: 600;
}

.inbound-item__preview {
  font-size: var(--text-sm);
  color: var(--muted-75);
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.desk-earlier-btn {
  align-self: center;
  margin-top: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted-75);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: var(--space-2) var(--space-4);
  cursor: pointer;
}
.desk-earlier-btn:hover { border-color: var(--hairline); }

/* ---- Case cards (worklog) ---- */

.case-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  background: var(--surface);
  transition: border-color var(--dur-base) var(--ease-out-expo), box-shadow var(--dur-base) var(--ease-out-expo),
    transform var(--dur-base) var(--ease-out-expo);
  cursor: pointer;
}

.case-card:hover {
  border-color: var(--hairline);
  box-shadow: var(--shadow-card);
  transform: translateY(-1px);
}

.case-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---- State colour on the card itself ----
   A 3px left stripe carries the state, so you can parse the whole worklog without
   reading a word: blue is being worked, green closed itself, amber needs a human. */
.case-card {
  border-left: 3px solid var(--border);
}
.case-card[data-phase="detected"],
.case-card[data-phase="classified"],
.case-card[data-phase="acting"] {
  border-left-color: var(--state-working);
  background: linear-gradient(90deg, var(--state-working-tint), transparent 40%);
}
.case-card[data-phase="resolved"] { border-left-color: var(--state-resolved); }
.case-card[data-phase="escalated"] {
  border-color: rgba(255, 165, 60, 0.35);
  border-left-color: var(--state-escalated);
  background: linear-gradient(90deg, var(--state-escalated-tint), transparent 40%);
}

/* Settled cases recede so the eye lands on the one the agent is working now. They
   come back to full strength on hover, since they are still worth opening. */
.case-card[data-collapsed="1"] { opacity: 0.62; }
.case-card[data-collapsed="1"]:hover,
.case-card[data-collapsed="1"]:focus-visible { opacity: 1; }

.case-card--live {
  border-color: var(--accent-cyan);
}

.case-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.02em;
  color: var(--muted-70);
  margin-bottom: var(--space-2);
}

.case-card__channel { display: flex; align-items: center; }

/* Filled, not a faint outline. The old badge was a 1px 10%-alpha border, which read
   as grey at every phase, so resolved and escalated looked the same. */
.case-card__phase-badge {
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 600;
  padding: 3px var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
}
.case-card[data-phase="detected"] .case-card__phase-badge,
.case-card[data-phase="classified"] .case-card__phase-badge,
.case-card[data-phase="acting"] .case-card__phase-badge {
  border-color: var(--state-working);
  background: var(--state-working-tint);
  color: var(--state-working);
}
.case-card[data-phase="resolved"] .case-card__phase-badge {
  border-color: var(--state-resolved);
  background: var(--state-resolved-tint);
  color: var(--state-resolved);
}
.case-card[data-phase="escalated"] .case-card__phase-badge {
  border-color: var(--state-escalated);
  background: var(--state-escalated-tint);
  color: var(--state-escalated);
}

/* ---- Agent progress tracker ----
   The four steps the agent actually moves through. Previously this existed only as a
   pill whose text swapped, so the reasoning sequence was invisible. */
.case-track {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0;
  margin: 0 0 var(--space-3);
  padding: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.case-track__step {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: 1;
  min-width: 0;
  color: var(--muted-70);
  opacity: 0.4;
  transition: opacity var(--dur-base) var(--ease-out-expo), color var(--dur-base) var(--ease-out-expo);
}
/* The connecting rail between steps. */
.case-track__step:not(:last-child)::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
  margin: 0 var(--space-2);
}
.case-track__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: 0 0 auto;
  border: 1px solid var(--hairline);
  background: transparent;
  transition: background var(--dur-base) var(--ease-out-expo), border-color var(--dur-base) var(--ease-out-expo);
}
.case-track__label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Steps the agent has already passed. */
.case-track__step[data-state="done"] { opacity: 1; color: var(--muted-75); }
.case-track__step[data-state="done"] .case-track__dot {
  background: var(--state-working);
  border-color: var(--state-working);
}
/* The step it is in right now: full strength, and it pulses so the eye finds it. */
.case-track__step[data-state="current"] { opacity: 1; color: var(--state-working); font-weight: 600; }
.case-track__step[data-state="current"] .case-track__dot {
  background: var(--state-working);
  border-color: var(--state-working);
  box-shadow: 0 0 0 3px var(--state-working-tint);
  animation: trackPulse 1.4s ease-in-out infinite;
}
@keyframes trackPulse {
  0%, 100% { box-shadow: 0 0 0 3px var(--state-working-tint); }
  50%      { box-shadow: 0 0 0 6px var(--state-working-tint); }
}

/* Once the case lands, the whole rail takes the outcome colour so a closed case and
   an escalated one are distinguishable across the room. */
.case-track[data-outcome="resolved"] .case-track__step[data-state="done"] .case-track__dot,
.case-track[data-outcome="resolved"] .case-track__step[data-state="current"] .case-track__dot {
  background: var(--state-resolved);
  border-color: var(--state-resolved);
}
.case-track[data-outcome="resolved"] .case-track__step[data-state="current"] { color: var(--state-resolved); }
.case-track[data-outcome="escalated"] .case-track__step[data-state="done"] .case-track__dot,
.case-track[data-outcome="escalated"] .case-track__step[data-state="current"] .case-track__dot {
  background: var(--state-escalated);
  border-color: var(--state-escalated);
}
.case-track[data-outcome="escalated"] .case-track__step[data-state="current"] { color: var(--state-escalated); }
/* A landed case is not "in progress": stop the pulse. */
.case-track[data-outcome] .case-track__step[data-state="current"] .case-track__dot { animation: none; }

/* On a phone the four labels squeeze to ~33px each and ellipsis into "Det…", "Cla…".
   Drop them and let the dots carry the progress: the phase badge in the card header
   is already colour-coded and names the phase, so nothing is lost. */
@media (max-width: 900px) {
  .case-track__label { display: none; }
  .case-track__step { flex: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .case-track__step[data-state="current"] .case-track__dot { animation: none; }
}

.case-card__title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 var(--space-2);
}

.case-card__reasoning {
  font-size: var(--text-sm);
  color: var(--muted-70);
  margin: 0 0 var(--space-2);
}

.case-card__policy {
  font-size: var(--text-sm);
  color: var(--muted-75);
  margin: 0 0 var(--space-2);
}

.case-card__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0 0 var(--space-2);
}

.case-card__action {
  min-height: 2.4em;
  padding: var(--space-2) var(--space-3);
  border-left: 2px solid var(--border);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out-expo);
}
.case-card__action.is-revealed { opacity: 1; border-left-color: var(--accent); }

.case-card__action-label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--accent-cyan);
  margin-bottom: 2px;
}

.case-card__action-artifact {
  display: block;
  font-size: var(--text-sm);
  color: var(--muted-75);
}

.case-card__decision { margin: 0 0 var(--space-2); }

.case-card__consequence {
  font-size: var(--text-sm);
  color: var(--muted-75);
  border-top: 1px solid var(--border-06);
  padding-top: var(--space-2);
}

.case-card__cost-delta {
  font-family: var(--font-mono);
  color: var(--accent-cyan);
}

.case-card__choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: var(--space-2) 0;
}

.desk-btn--choice {
  background: var(--accent-tint);
  border-color: var(--accent);
  color: var(--accent);
}

.case-card__keep-watching {
  display: inline-block;
  font-size: var(--text-xs);
  color: var(--muted-70);
  text-decoration: underline;
}

.case-card__waiting {
  font-size: var(--text-sm);
  color: rgb(255, 180, 100);
  margin: 0 0 var(--space-1);
}

.case-card__scored-note {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted-70);
  margin: var(--space-1) 0 0;
}

.case-card__manual-cta:empty { display: none; }

.desk-btn--manual {
  width: 100%;
  border-color: var(--accent-cyan);
  color: var(--accent-cyan);
  margin: var(--space-1) 0 var(--space-2);
}

.case-card__meta {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted-70);
  margin: 0;
}

.case-card__live-badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  color: var(--accent-cyan);
  border: 1px solid var(--accent-cyan);
  border-radius: var(--radius-pill);
  padding: 2px var(--space-2);
  margin-bottom: var(--space-2);
}

/* ---- Collapsed worklog cards (passive path, after 8 sim-minutes) ---- */

.case-card__collapsed { display: none; }

.case-card[data-collapsed="1"]:not(.is-expanded) .case-card__full { display: none; }
.case-card[data-collapsed="1"]:not(.is-expanded) .case-card__collapsed {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--text-sm);
  cursor: pointer;
}
.case-card[data-collapsed="1"].is-expanded .case-card__collapsed { display: none; }

.case-card__collapsed-type { font-weight: 600; }
/* This chip only ever coloured the escalated case, so every RESOLVED row in the
   worklog rendered plain grey and a closed case looked the same as anything else. */
.case-card__collapsed-chip {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  color: var(--muted-70);
}
.case-card__collapsed-chip[data-outcome="resolved"] {
  color: var(--state-resolved);
  background: var(--state-resolved-tint);
}
.case-card__collapsed-chip[data-outcome="escalated"] {
  color: var(--state-escalated);
  background: var(--state-escalated-tint);
}
.case-card__collapsed-minutes {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--accent-cyan);
  margin-left: auto;
}

/* ---- Ledger ---- */

.ledger-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border-06);
  font-size: var(--text-sm);
}

.ledger-row span { color: var(--muted-70); }
.ledger-row strong { font-family: var(--font-mono); font-size: var(--text-xl); font-weight: 600; color: var(--fg); }
/* The ledger totals carry the same legend as the cards, so "Resolved 12 / Escalated 2"
   is readable at a glance instead of two identical white numbers. */
#ledger-resolved { color: var(--state-resolved); }
#ledger-escalated { color: var(--state-escalated); }

/* ---- Escalation queue ---- */

.escalation-queue {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--hairline);
}

.escalation-queue__title {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-70);
  margin: 0 0 var(--space-3);
}

.escalation-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-2);
  cursor: pointer;
  font-size: var(--text-sm);
}
.escalation-row:hover { border-color: var(--hairline); }

.escalation-row__status {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
}
.escalation-row__status--pending { color: rgb(255, 180, 100); }
.escalation-row__status--decided { color: rgb(140, 230, 160); }
.escalation-row__status--waiting { color: var(--muted-70); }

/* ---- Detail drawer ---- */

.drawer-overlay {
  position: fixed;
  inset: 0;
  z-index: 150;
  display: flex;
  justify-content: flex-end;
  background: var(--scrim-soft);
}

.drawer {
  position: relative;
  width: min(calc(480px * var(--ui-scale)), 100%);
  height: 100%;
  background: var(--surface);
  border-left: 1px solid var(--hairline);
  padding: var(--space-7) var(--space-6);
  overflow-y: auto;
}

.drawer__close {
  position: sticky;
  top: 0;
  float: right;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--fg);
  font-size: var(--text-lg);
  line-height: 1;
  padding: var(--space-1) var(--space-3);
  cursor: pointer;
}

.drawer__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted-70);
  margin: 0 0 var(--space-2);
}

.drawer__title {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  margin: 0 0 var(--space-3);
}

.drawer__narration {
  font-size: var(--text-sm);
  color: var(--accent-cyan);
  margin: 0 0 var(--space-5);
}

.drawer__section {
  border-top: 1px solid var(--border-06);
  padding: var(--space-4) 0;
}
.drawer__section h3 {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-70);
  margin: 0 0 var(--space-2);
}

.drawer__mono {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted-75);
  margin: 0 0 var(--space-1);
}

.drawer__body-text {
  font-size: var(--text-sm);
  color: var(--muted-93);
  line-height: 1.55;
  white-space: pre-line;
  margin: 0;
}

.drawer__artifact {
  border: 1px solid var(--border-06);
  border-radius: var(--radius-sm);
  padding: var(--space-3);
  margin-bottom: var(--space-2);
}

/* ---- Manual-comparison overlay ---- */

.manual-overlay {
  position: fixed;
  inset: 0;
  z-index: 180;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  background: var(--scrim);
}

.manual-overlay__panel {
  position: relative;
  width: min(calc(520px * var(--ui-scale)), 100%);
  max-height: 88vh;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-7) var(--space-6);
}

.manual-overlay__title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  margin: 0 0 var(--space-2);
}

.manual-overlay__note {
  font-size: var(--text-sm);
  color: var(--muted-70);
  margin: 0 0 var(--space-4);
}

.manual-overlay__steps {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.manual-step {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  text-align: left;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-3);
  background: var(--surface);
  color: var(--fg);
  cursor: pointer;
}
.manual-step[data-state="done"] { border-color: rgba(120, 220, 150, 0.4); color: var(--muted-70); }
.manual-step[data-state="done"] .manual-step__label::before { content: "✓ "; color: rgb(140, 230, 160); }
.manual-step[data-state="locked"] { opacity: 0.4; cursor: not-allowed; }
.manual-step[data-state="next"] { border-color: var(--accent); }
.manual-step__minutes {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted-70);
  flex-shrink: 0;
}

.manual-overlay__timer {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--muted-75);
  margin: 0 0 var(--space-3);
}

.manual-overlay__finish {
  font-size: var(--text-sm);
  color: var(--muted-93);
  border-top: 1px solid var(--hairline);
  padding-top: var(--space-4);
  line-height: 1.6;
}
.manual-overlay__finish .desk-btn { margin-left: var(--space-2); }

/* ---- End card ---- */

.end-card {
  position: absolute;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  background: var(--scrim-strong);
}

.desk-panel--worklog { position: relative; }

.end-card__panel {
  max-width: calc(480px * var(--ui-scale));
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-7);
  background: var(--surface);
  text-align: center;
}

.end-card__title {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  margin: 0 0 var(--space-3);
}

/* White-label mode: partner firm name on the end card (plan section 5). */
.end-card__brand-note {
  font-size: var(--text-sm);
  color: var(--accent);
  margin: 0 0 var(--space-3);
}

.end-card__body {
  font-size: var(--text-md);
  color: var(--muted-75);
  margin: 0 0 var(--space-4);
  line-height: 1.5;
}

.end-card__replay-copy {
  font-size: var(--text-sm);
  color: var(--muted-70);
  margin: 0 0 var(--space-5);
}

.end-card__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.end-card__secondary {
  font-size: var(--text-sm);
  color: var(--muted-75);
  text-decoration: underline;
}

/* ---- Footer skeleton ---- */

.desk-footer {
  border-top: 1px solid var(--hairline);
  padding: var(--space-5) var(--space-6);
  font-size: var(--text-sm);
  color: var(--muted-70);
}

.desk-footer__selftest {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted-75);
  margin: 0 0 var(--space-2);
}

.desk-footer__note { margin: 0; }

/* White-label mode: the one quiet disclosure line in branded mode (plan section 5). */
.desk-footer__white-label-note { margin: var(--space-2) 0 0; }

/* Default view: the product signature. Same slot and same treatment as the white-label
   note above, and never rendered at the same time as it. */
.desk-footer__signature { margin: var(--space-2) 0 0; }

/* ---- Guided tour (spotlight walkthrough) ---- */

.tour-spotlight {
  position: fixed;
  z-index: 300;
  border-radius: var(--radius-md);
  border: 1px solid var(--accent-cyan);
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.8), 0 0 0 3px var(--accent-tint-strong);
  pointer-events: none;
  transition: top var(--dur-base) var(--ease-out-expo), left var(--dur-base) var(--ease-out-expo),
    width var(--dur-base) var(--ease-out-expo), height var(--dur-base) var(--ease-out-expo);
}

.tour-bubble {
  position: fixed;
  z-index: 301;
  width: min(calc(320px * var(--ui-scale)), calc(100vw - 24px));
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-pop);
}

.tour-bubble__title {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 600;
  margin: 0 0 var(--space-2);
}

.tour-bubble__text {
  font-size: var(--text-sm);
  color: var(--muted-75);
  line-height: 1.5;
  margin: 0 0 var(--space-4);
}

.tour-bubble__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.tour-dots {
  display: flex;
  gap: 6px;
}

.tour-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--border);
}
.tour-dot.is-active { background: var(--accent-cyan); }

.tour-bubble__actions {
  display: flex;
  gap: var(--space-2);
}

/* Mobile: tour bubble becomes a bottom sheet (plan section 3). */
.tour-bubble--sheet {
  top: auto !important;
  left: 0 !important;
  right: 0;
  bottom: 0;
  width: 100%;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  border-bottom: none;
}

/* ---- Contextual first-time tooltips ---- */

.contextual-tooltip {
  position: fixed;
  z-index: 250;
  max-width: calc(260px * var(--ui-scale));
  font-size: var(--text-sm);
  color: var(--muted-93);
  background: var(--surface);
  border: 1px solid var(--accent-cyan);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  box-shadow: var(--shadow-pop);
  line-height: 1.4;
}

/* ---- Header tour link ---- */

.desk-header__tour-link {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-70);
  background: transparent;
  border: none;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  padding: 0;
}
.desk-header__tour-link:hover { color: var(--muted-93); }

/* ---- Intro card: dual actions ---- */

.intro-card__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  margin: 0 0 var(--space-2);
}

/* ---- Footer: how this maps to a real deployment ---- */

/* Collapsed by default. Three paragraphs of prose under the desk looked like part of the
   app, so visitors sat waiting for something to happen in it. Now the desk ends where the
   desk ends, and the answer is one click away. */
.desk-footer__deployment {
  margin: 0 var(--space-6) var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--hairline);
}

.desk-footer__deployment-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-70);
  margin: 0;
  cursor: pointer;
  list-style: none;
  transition: color var(--dur-fast) var(--ease-out-expo);
}
.desk-footer__deployment-title::-webkit-details-marker { display: none; }
.desk-footer__deployment-title:hover { color: var(--fg); }
/* A disclosure caret, so it reads as expandable rather than as a dead heading. */
.desk-footer__deployment-title::before {
  content: "";
  width: 0;
  height: 0;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform var(--dur-fast) var(--ease-out-expo);
}
.desk-footer__deployment[open] .desk-footer__deployment-title::before { transform: rotate(90deg); }

/* Three columns across the full width, echoing the desk's own three panels, so the copy
   uses the space instead of floating in a narrow strip with dead gutters on both sides.
   The three paragraphs are three distinct ideas (what swaps, what does not, how you buy
   it), so each becomes a headed column. */
.desk-footer__deployment-body {
  margin-top: var(--space-5);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-7);
}

.deploy-col__head {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--state-working);
  margin: 0 0 var(--space-3);
}
.deploy-col p {
  font-size: var(--text-sm);
  color: var(--muted-75);
  line-height: 1.6;
  margin: 0 0 var(--space-3);
}
.deploy-col p:last-child { margin-bottom: 0; }

.deploy-col__links { display: flex; flex-direction: column; gap: var(--space-2); }
.desk-footer__deployment a {
  color: var(--accent-cyan);
  text-decoration: none;
  font-weight: 600;
}
.desk-footer__deployment a:hover { color: var(--fg); }

@media (max-width: 900px) {
  .desk-footer__deployment-body { grid-template-columns: 1fr; gap: var(--space-5); }
}

/* ---- Responsive (<900px): tabs, full-screen sheets, stacked choices ---- */

@media (max-width: 899.98px) {
  .desk-main {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
  }
  /* Stack: the guide sits above whichever tab is showing, so it stays with you when you
     switch to the worklog to watch the case it just told you to watch. */
  .desk-main > #guide,
  .desk-panel--inbound,
  .desk-panel--worklog,
  .desk-panel--ledger { grid-column: 1; grid-row: auto; }
  .guide { margin: 0; border-radius: 0; border-left: 0; border-right: 0; border-top: 0; }
  .desk-panel {
    display: none;
    border-bottom: 1px solid var(--border-06);
  }
  .desk-panel.is-active-panel {
    display: flex;
  }
  .desk-header {
    padding: var(--space-3) var(--space-4);
    position: sticky;
    top: 0;
  }
  .desk-tabs {
    display: flex;
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--surface);
    border-bottom: 1px solid var(--hairline);
  }
  .drawer {
    width: 100%;
  }
  .manual-overlay__panel {
    width: 100%;
    max-height: 100vh;
    height: 100%;
    border-radius: 0;
  }
  .case-card__choices {
    flex-direction: column;
  }
  .desk-btn--choice {
    width: 100%;
    text-align: center;
  }
  .end-card {
    position: fixed;
  }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.001ms !important; animation-duration: 0.001ms !important; }
}
