/* sprintplan app styles. Extends instrument-core.css; does not fork tokens.
   The plum accent (--plum/--plumwash/--accent), the --dep-line tether stroke,
   and the epic-colour palette now live in the shared foundation under
   .ins[data-app="plan"] (Brief 10 R1 — promoted from here, names unchanged).
   Amber stays reserved for capacity (pill/banner); --red is plan-local and
   reads in TWO non-overlapping places — the capacity pill/banner AND the
   dependency violation (editor row, board card border, D badge, connector) —
   never on the same element, so the two semantics stay unambiguous (Brief 8 R5). */

.ins[data-app="plan"] {
  /* Capacity-state / dependency-violation red — plan-local, NOT promoted (the
     siblings have no equivalent). Everything else moved to the shared source. */
  --red: oklch(0.5 0.13 25);
  --redwash: oklch(0.95 0.04 25);
}

.plan-page .brand .mk {
  color: var(--plum);
}

/* App-scoped brand tint of the shared chrome (not a token fork): the band's
   scope-trace and eyebrow carry the plum identity. */
.plan-page .waves {
  color: var(--plum);
}

.plan-page .band .eyebrow {
  color: var(--plum);
}

/* --- Board file control (Screen 5, G8) -----------------------------------
   The top-bar Save / load buttons reuse the suite .btn chrome but take the plum
   accent on hover and focus (G4: plum is the app identity). No capacity colours
   here — amber/red mean capacity and nothing else. */
.tbacts #tb-export:hover,
.tbacts #tb-import:hover {
  border-color: var(--plum);
  color: var(--plum);
}

.tbacts #tb-export:focus-visible,
.tbacts #tb-import:focus-visible {
  outline: none;
  border-color: var(--plum);
  box-shadow: 0 0 0 3px var(--plumwash);
}

/* --- Return to Suite (Brief 10 R4) ----------------------------------------
   A plain, always-visible, account-free link back to the hub (sprintplan is
   free/ungated, so NO auth-client snippet — the link is static, not revealed
   by /auth/whoami). Same plum accent + focus ring as every plan control; the
   #glyph-suite mark carries the suite identity at rest. */
.tbacts .suite-return .mk {
  color: var(--plum);
  display: flex;
}

.tbacts .suite-return:hover {
  border-color: var(--plum);
  color: var(--plum);
}

.tbacts .suite-return:focus-visible {
  outline: none;
  border-color: var(--plum);
  box-shadow: 0 0 0 3px var(--plumwash);
}

/* --- Report export menu (Screen 5, G8) -----------------------------------
   The plan-summary export (Brief 9, P0 #6) is its OWN control, distinct from
   the board .json Save/Import above (a thin divider separates the two groups).
   A native <details> dropdown — no JS for open/close — styled with the same
   plum accent and focus ring as every plan control. */
.export-menu {
  position: relative;
  display: inline-block;
}
.export-menu > summary {
  list-style: none;
  cursor: pointer;
}
.export-menu > summary::-webkit-details-marker {
  display: none;
}
.export-menu > summary:hover,
.export-menu-list .btn:hover {
  border-color: var(--plum);
  color: var(--plum);
}
.export-menu > summary:focus-visible,
.export-menu-list .btn:focus-visible {
  outline: none;
  border-color: var(--plum);
  box-shadow: 0 0 0 3px var(--plumwash);
}
.export-menu-list {
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  left: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: max-content;
  padding: 6px;
  background: #fff;
  border: 1px solid var(--plumwash);
  border-radius: 8px;
  box-shadow: 0 6px 20px rgb(0 0 0 / 12%);
}
.export-menu-list .btn {
  justify-content: flex-start;
}
.tbacts-sep {
  width: 1px;
  align-self: stretch;
  margin: 0 2px;
  background: var(--plumwash);
}

/* --- Settings strip (Screen 4) ------------------------------------------- */

.settings-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  max-width: 1120px;
  margin: 0 auto;
  padding: 14px 40px;
  border-bottom: 1px solid var(--line2);
  background: var(--panel);
  font-size: 14px;
}

.settings-strip.is-fresh {
  box-shadow: inset 0 0 0 2px var(--plumwash);
  transition: box-shadow 0.6s ease;
}

.ss-seg {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.ss-key {
  color: var(--faint);
}

.ss-dot {
  color: var(--line2);
  padding: 0 2px;
}

.ss-arrow {
  color: var(--plum);
  font-weight: 700;
  padding: 0 4px;
}

.ss-control {
  font-family: "IBM Plex Mono", monospace;
  font-size: 13.5px;
  color: var(--ink);
  background: var(--bone);
  border: 1px solid var(--line2);
  border-radius: 6px;
  padding: 6px 9px;
  cursor: pointer;
}

.ss-control:focus {
  outline: none;
  border-color: var(--plum);
  box-shadow: 0 0 0 3px var(--plumwash);
}

.ss-num {
  width: 56px;
  text-align: right;
}

.ss-date {
  width: 150px;
}

.ss-derived #ss-capacity {
  font-weight: 600;
  font-size: 15px;
  color: var(--plum);
}

/* --- Board: month rail + sprint stack as one aligned grid ----------------- */

.workspace {
  display: flex;
  gap: 24px;
  align-items: flex-start;
  max-width: 1240px;
  margin: 0 auto;
  padding: 26px 40px 48px;
}

.board {
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: 48px 1fr;
  column-gap: 16px;
  row-gap: 14px;
  align-items: stretch;
  /* Positioning context for the dependency overlay (Brief 8): the <svg> is the
     board's last child, absolutely placed over the grid in board-local coords. */
  position: relative;
}

.rail-seg {
  grid-column: 1;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  border-left: 2px solid var(--plumwash);
  border-radius: 2px;
  padding-top: 6px;
}

.rail-seg span {
  writing-mode: vertical-rl;
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.18em;
  font-weight: 600;
  color: var(--faint);
}

.sprint {
  grid-column: 2;
  background: var(--panel);
  border: 1px solid var(--line2);
  border-radius: 10px;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.sprint.is-partial {
  border-style: dashed;
}

.sprint-head {
  display: flex;
  align-items: center;
  gap: 12px;
}

.sprint-name {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 17px;
}

.sprint-dates {
  font-family: "IBM Plex Mono", monospace;
  font-size: 12px;
  color: var(--soft);
}

.partial-tag {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--soft);
  border: 1px solid var(--line2);
  border-radius: 4px;
  padding: 2px 6px;
}

.cap-pill {
  margin-left: auto;
  font-family: "IBM Plex Mono", monospace;
  font-size: 12.5px;
  font-weight: 600;
  padding: 5px 11px;
  border-radius: 6px;
}

.cap-pill.is-neutral {
  background: var(--bone);
  color: var(--soft);
  border: 1px solid var(--line2);
}

.cap-pill.is-amber {
  background: var(--amberwash);
  color: oklch(0.5 0.12 60);
}

.cap-pill.is-red {
  background: var(--redwash);
  color: var(--red);
}

/* --- Capacity honesty banner (Brief 4) -----------------------------------
   Slim nudge inside an over-capacity sprint, between head and body. Severity
   wash matched to the pill (amber/red), never plum. Non-blocking. */

.sprint-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border-radius: 7px;
  font-size: 13px;
  line-height: 1.35;
}

.sprint-banner-msg {
  flex: 1;
}

.sprint-banner.is-amber {
  background: var(--amberwash);
  color: oklch(0.5 0.12 60);
}

.sprint-banner.is-red {
  background: var(--redwash);
  color: var(--red);
}

/* The mono N inside the message inherits the banner's severity colour. */
.sprint-banner .mono {
  font-family: "IBM Plex Mono", monospace;
  font-size: 12.5px;
  font-weight: 600;
}

.banner-dismiss {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 5px;
  background: transparent;
  color: inherit;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  opacity: 0.7;
}

.banner-dismiss:hover {
  opacity: 1;
  background: oklch(0 0 0 / 0.06);
}

.banner-dismiss:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--plumwash);
}

/* Populated sprint body: a vertical stack of placed cards. */
.sprint-body {
  min-height: 40px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 6px;
  border-radius: 7px;
}

/* Empty sprint keeps the muted dashed "Drop stories here" drop affordance. */
.sprint-body.is-empty {
  flex-direction: row;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px dashed var(--line);
  color: var(--faint);
  font-size: 13px;
}

/* --- Drag affordances (Brief 3) ------------------------------------------ */

/* Cards are draggable; the grabbed source dims while its mirror follows. */
.sprint-body .bl-story,
.bl-stories .bl-story {
  cursor: grab;
}

.gu-transit {
  opacity: 0.4;
}

/* dragula's flying clone: plum focus ring, matches the drag accent (G4). */
.gu-mirror.bl-story {
  cursor: grabbing;
  border-color: var(--plum);
  box-shadow: 0 0 0 3px var(--plumwash);
  list-style: none;
}

/* --- Editable plan title -------------------------------------------------- */

#plan-title:empty::before {
  content: attr(data-placeholder);
  color: var(--faint);
}

/* Discoverability: the title is an inline-editable single-line field, not a
   static heading. A text caret + a faint plum underline on hover signal that
   it's clickable; white-space:nowrap keeps it one line (Enter commits, it never
   wraps to a second row). */
#plan-title {
  cursor: text;
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  border-radius: 4px;
  transition: box-shadow 0.12s ease;
}

#plan-title:hover {
  box-shadow: 0 2px 0 color-mix(in oklab, var(--plum) 38%, transparent);
}

#plan-title:focus {
  outline: none;
  text-overflow: clip;
  box-shadow: 0 2px 0 var(--plum);
}

/* --- Epic colour palette (G4) --------------------------------------------
   The [data-epic-colour] → --epic key map now lives in the shared foundation
   (instrument-core.css, .ins[data-app="plan"] [data-epic-colour]; Brief 10 R1).
   .epic-dot consumes --epic and stays here. */

.epic-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--epic, var(--faint));
  flex-shrink: 0;
  display: inline-block;
}

/* --- Backlog panel -------------------------------------------------------- */

.backlog {
  width: 280px;
  flex-shrink: 0;
  background: var(--panel);
  border: 1px solid var(--line2);
  border-radius: 10px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* The backlog can hold a whole project's worth of stories (see the demo
     sample), so it scrolls on its own and stays in view while you drag cards
     into the sprints, instead of stretching the page. */
  position: sticky;
  top: 16px;
  max-height: calc(100vh - 32px);
  overflow-y: auto;
}

.bl-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Keep the title + "Epic" button visible while the story list scrolls under
     it. The negative margin/padding pulls the sticky strip to the panel edges
     so scrolled rows don't peek above it through the panel's own padding. */
  position: sticky;
  top: -16px;
  z-index: 2;
  background: var(--panel);
  margin: -16px -16px 0;
  padding: 16px 16px 8px;
}

.bl-title {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 18px;
}

.bl-empty {
  text-align: center;
  padding: 28px 12px;
  color: var(--faint);
}

.bl-empty-msg {
  font-weight: 600;
  color: var(--soft);
}

.bl-empty-sub {
  font-size: 13px;
  margin-top: 4px;
}

.bl-group {
  border-top: 1px solid var(--line);
  padding-top: 8px;
}

.bl-group-head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.bl-chevron {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--soft);
  font-size: 12px;
  padding: 2px;
  line-height: 1;
}

.epic-title {
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
}

.epic-title-none {
  color: var(--soft);
  font-style: italic;
  cursor: default;
}

.bl-meta {
  margin-left: auto;
  font-size: 11px;
  color: var(--faint);
}

.bl-stories {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 0 2px 22px;
}

.bl-story {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--bone);
  cursor: pointer;
}

.bl-story:hover {
  border-color: var(--plum);
}

.bl-story-title {
  font-size: 13px;
}

.bl-story-pts {
  margin-left: auto;
  font-size: 12px;
  color: var(--soft);
}

.bl-add-story {
  align-self: flex-start;
  background: none;
  border: 1px dashed var(--line2);
  border-radius: 6px;
  color: var(--soft);
  font-size: 12px;
  padding: 5px 10px;
  cursor: pointer;
  margin-top: 2px;
}

.bl-add-story:hover {
  border-color: var(--plum);
  color: var(--plum);
}

/* --- Modal (card + epic editors) ------------------------------------------ */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: oklch(0.3 0.02 250 / 0.42);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
  padding: 24px;
}

.modal-card {
  background: var(--panel);
  border: 1px solid var(--line2);
  border-radius: 14px;
  width: 100%;
  max-width: 460px;
  max-height: 90vh;
  overflow-y: auto;
  padding: 24px 26px;
  box-shadow: 0 30px 70px -50px oklch(0.3 0.05 240 / 0.8);
}

.modal-heading {
  font-size: 22px;
  margin-bottom: 16px;
}

.modal-body {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.field-err {
  font-size: 12px;
  color: var(--red);
}

.epic-select-row {
  display: flex;
  gap: 8px;
}

.epic-select-row .input {
  flex: 1;
}

.new-epic-wrap {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

/* A class with display:flex would otherwise beat the [hidden] UA rule. */
.new-epic-wrap[hidden] {
  display: none;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.chip {
  font-family: "IBM Plex Mono", monospace;
  font-size: 13px;
  min-width: 34px;
  padding: 6px 0;
  text-align: center;
  border: 1px solid var(--line2);
  border-radius: 6px;
  background: var(--bone);
  color: var(--ink);
  cursor: pointer;
}

.chip.is-selected {
  background: var(--plumwash);
  border-color: var(--plum);
  color: var(--plum);
}

.points-input {
  margin-top: 8px;
  width: 80px;
  text-align: right;
}

.colour-picker {
  display: flex;
  gap: 8px;
}

.colour-choice {
  width: 22px;
  height: 22px;
  border: 2px solid transparent;
  cursor: pointer;
  padding: 0;
}

.colour-choice.is-selected {
  border-color: var(--ink);
}

.modal-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 22px;
}

.modal-footer-right {
  display: flex;
  gap: 8px;
  margin-left: auto;
}

.modal-guard {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  padding: 12px 14px;
  background: var(--bone);
  border: 1px solid var(--line2);
  border-radius: 8px;
}

.modal-guard-msg {
  font-size: 13px;
  margin-right: auto;
}

/* --- Toast (returned-to-backlog notice) ----------------------------------- */

.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--panel);
  font-size: 13px;
  padding: 10px 16px;
  border-radius: 8px;
  box-shadow: 0 10px 30px -16px oklch(0.3 0.05 240 / 0.9);
  z-index: 20;
}

/* --- Resume / New-plan prompt (Screen 3, Brief 6) -------------------------- */
/* Reuses the .modal-overlay / .modal-card chrome. Plum accent for the primary
   action and focus rings; danger-ghost for the destructive Start-new; mono for
   every number, the relative time, and the summary. NO capacity colours here —
   amber/red mean capacity and nothing else (so the invalid reason is neutral). */

.rp-card {
  max-width: 440px;
}

.rp-eyebrow {
  color: var(--plum);
  margin-bottom: 8px;
}

.rp-card .modal-heading {
  margin-bottom: 4px;
}

.rp-meta {
  font-size: 13px;
  color: var(--soft);
  margin-bottom: 14px;
}

.rp-summary {
  font-size: 12.5px;
  color: var(--ink);
  background: var(--bone);
  border: 1px solid var(--line2);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 18px;
}

.rp-actions {
  display: flex;
  gap: 10px;
}

/* A class with display:flex would otherwise beat the [hidden] UA rule. */
.rp-actions[hidden] {
  display: none;
}

.rp-resume {
  background: var(--plum);
  color: #fff;
  border-color: var(--plum);
}

.rp-resume:hover {
  filter: brightness(1.08);
}

.rp-resume:focus-visible,
.rp-import:focus-visible {
  outline: 2px solid var(--plum);
  outline-offset: 2px;
}

.rp-startnew {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 14px;
  padding: 14px;
  background: var(--bone);
  border: 1px solid var(--line2);
  border-radius: 8px;
}

.rp-startnew[hidden] {
  display: none;
}

.rp-warn {
  font-size: 13px;
  color: var(--ink);
  margin: 0;
}

.rp-confirm-row {
  display: flex;
  gap: 8px;
}

.rp-reason {
  font-size: 13.5px;
  color: var(--ink);
  margin-bottom: 10px;
}

.rp-import {
  display: inline-block;
  margin-top: 18px;
  padding: 0;
  background: none;
  border: none;
  font: inherit;
  font-size: 13px;
  color: var(--plum);
  text-decoration: underline;
  cursor: pointer;
}

/* --- Dependencies (Brief 7) -------------------------------------------------
   The shared D badge (plum/ink, neutral this slice — the board-side red is
   slice 2). The card-editor section: existing links as rows (a violating row
   takes the red treatment), then the inline picker grouped by location. No
   capacity colours here; amber/red mean capacity only. */

/* Shared D badge on the card (board + backlog), after the points chip. */
.dep-badge {
  font-size: 12px;
  line-height: 1;
  padding: 2px 5px;
  border-radius: 5px;
  background: var(--plumwash);
  color: var(--plum);
  border: 1px solid var(--plum);
}

/* Board-side violation (Brief 8 R5/R8): the neutral D badge turns red when its
   pair is a violation. Backlog badges never qualify (G7 needs both scheduled). */
.dep-badge--violation {
  background: var(--redwash);
  color: var(--red);
  border-color: var(--red);
}

/* A card that is an endpoint of a violating pair (Brief 8 R5). Distinct element
   from the capacity pill/banner, so a violating card in an over-capacity sprint
   reads unambiguously: the pill is capacity-red, the card is violation-red. */
.bl-story--dep-violation {
  border-color: var(--red);
  background: var(--redwash);
}

/* The dependency drawing layer (Brief 8): one <svg> over the board grid, sized
   to its content box, scrolls with the page. Non-interactive — hover is detected
   on the cards, so the overlay never intercepts a click or a drag. */
.dep-layer {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  overflow: visible;
}

/* Tethers and connectors. Neutral --dep-line at rest; --red on a violation. The
   arrowhead marker inherits the stroke (fill: context-stroke) so it follows. */
.dep-line {
  fill: none;
  stroke: var(--dep-line);
  stroke-width: 1.5;
  stroke-linecap: round;
}

.dep-line--violation {
  stroke: var(--red);
  stroke-width: 2;
}

.deps-section {
  border-top: 1px solid var(--line);
  padding-top: 14px;
}

.deps-rows {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.deps-empty {
  font-size: 12.5px;
  color: var(--soft);
}

.dep-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--bone);
}

.dep-dir {
  font-size: 12.5px;
  color: var(--soft);
}

.dep-other {
  font-size: 13px;
}

.dep-loc {
  margin-left: auto;
  font-size: 12px;
  color: var(--soft);
}

.dep-remove {
  padding: 2px 8px;
}

/* Violation visible at creation time (R6, Screen 2). The only red this slice. */
.dep-row--violation {
  border-color: var(--red);
  background: var(--redwash);
}

.dep-row--violation .dep-loc {
  color: var(--red);
}

.deps-actions {
  display: flex;
  gap: 8px;
  margin-top: 10px;
}

.dep-picker {
  margin-top: 10px;
  border: 1px solid var(--line2);
  border-radius: 8px;
  padding: 10px;
  background: var(--bone);
}

.dep-picker[hidden] {
  display: none;
}

.dep-search {
  width: 100%;
}

.dep-picker-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 8px;
  max-height: 220px;
  overflow-y: auto;
}

.dep-group-head {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--soft);
  margin-top: 6px;
}

.dep-option {
  justify-content: flex-start;
  text-align: left;
}

.dep-option:focus-visible,
.dep-remove:focus-visible {
  outline: none;
  border-color: var(--plum);
  box-shadow: 0 0 0 3px var(--plumwash);
}
