/* ============================================================================
   StoryBoard — application stylesheet
   ----------------------------------------------------------------------------
   Bootstrap 5.3 (wwwroot/lib/bootstrap) provides every component and utility.
   This file does two things:

     1. retunes Bootstrap's own CSS variables into the visual language of PLANKA
        (planka.app) — dark chrome, a saturated board surface, white list panels,
        solid label pills — without recompiling Sass
     2. adds the handful of things a narrative board needs and Bootstrap has no
        notion of: the horizontal column scroller, the drag placeholder, the
        drawer, a sticky table header, the timeline lanes, the game picker and
        two density steps

   The palette is not invented. It was sampled from PLANKA's own demo capture:
   board surface #33526F, chrome #22252A, list header #D7DEE0, white panels, and
   the teal accent family #3E888C / #41ADCC.

   Bootstrap 5.3 drives its components through custom properties, so overriding
   `--bs-btn-bg` or `--bs-card-*` is the supported way to re-theme without a
   Sass build step. No component is re-implemented here.
   ========================================================================== */

/* ============================================================================
   1. Theme
   ========================================================================== */

:root,
[data-bs-theme="light"] {
  /* --- chrome: the dark frame the workspace sits in ---------------------- */
  --sb-chrome: #22252a;
  --sb-chrome-hover: #2d3138;
  --sb-chrome-active: #383e46;
  --sb-chrome-text: #e7e9eb;
  --sb-chrome-muted: #98a0a8;
  --sb-chrome-border: #33383f;

  /* --- board surface: the saturated field the columns float on ----------- */
  --sb-board-surface: #33526f;

  /* --- panels: columns, cards, tiles ------------------------------------- */
  --sb-panel: #ffffff;
  --sb-panel-header: #dfe5e8;
  --sb-panel-border: #e6eaec;

  /* --- accent: PLANKA's teal --------------------------------------------- */
  --sb-accent: #3e888c;
  --sb-accent-strong: #2f6e72;
  --sb-accent-rgb: 62, 136, 140;

  --bs-body-bg: #f5f6f7;
  --bs-body-color: #2a2e33;
  --bs-secondary-color: #6c747c;
  --bs-tertiary-bg: #f0f2f4;
  --bs-secondary-bg: #eceff1;
  --bs-border-color: #e2e6e9;
  --bs-border-color-translucent: rgba(34, 37, 42, 0.12);
  --bs-emphasis-color: #1d2126;
  --bs-heading-color: #1d2126;
  --bs-link-color: #2f6e72;
  --bs-link-hover-color: #26595c;

  /* Bootstrap's default code colour is a bright pink (#d63384). It is the one
     colour in the framework that belongs to no palette, and it showed up on the
     sign-in screen, where the demo addresses are <code>. A muted violet keeps
     identifiers distinct from prose without shouting. */
  --bs-code-color: #6a4fb8;

  --bs-primary: var(--sb-accent);
  --bs-primary-rgb: var(--sb-accent-rgb);
  --bs-primary-bg-subtle: #e4f0f0;
  --bs-primary-border-subtle: #c2dedf;
  --bs-primary-text-emphasis: #26595c;

  /* PLANKA's geometry is tight: small radii, flat panels, soft shadows. */
  --bs-border-radius: 0.5rem;
  --bs-border-radius-sm: 0.375rem;
  --bs-border-radius-lg: 0.625rem;
  --bs-border-radius-xl: 1rem;

  --sb-shadow-card: 0 1px 2px rgba(34, 37, 42, 0.08);
  --sb-shadow-lift: 0 4px 14px rgba(34, 37, 42, 0.18);
}

[data-bs-theme="dark"] {
  --sb-chrome: #1a1d21;
  --sb-chrome-hover: #24282d;
  --sb-chrome-active: #2e343a;
  --sb-chrome-text: #e7e9eb;
  --sb-chrome-muted: #8b939b;
  --sb-chrome-border: #2c3137;

  --sb-board-surface: #23272c;

  --sb-panel: #292e34;
  --sb-panel-header: #333a41;
  --sb-panel-border: #383f47;

  --sb-accent: #4fa3a7;
  --sb-accent-strong: #62b3b7;
  --sb-accent-rgb: 79, 163, 167;

  --bs-body-bg: #1e2126;
  --bs-body-color: #dfe3e6;
  --bs-secondary-color: #a3abb2;
  --bs-tertiary-bg: #24282d;
  --bs-secondary-bg: #282d33;
  --bs-border-color: #33383f;
  --bs-border-color-translucent: rgba(255, 255, 255, 0.12);
  --bs-emphasis-color: #ffffff;
  --bs-heading-color: #ffffff;
  --bs-link-color: #6bb7bb;
  --bs-link-hover-color: #86c8cb;
  --bs-code-color: #b9a6e8;

  --bs-primary: var(--sb-accent);
  --bs-primary-rgb: var(--sb-accent-rgb);
  --bs-primary-bg-subtle: #22383a;
  --bs-primary-border-subtle: #2f4f52;
  --bs-primary-text-emphasis: #8fd0d3;

  --sb-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.3);
  --sb-shadow-lift: 0 6px 18px rgba(0, 0, 0, 0.45);
}

/* Bootstrap compiles .btn-primary and .text-bg-primary with fixed values, but
   both are driven by custom properties, so re-pointing them is enough. */
.btn-primary {
  --bs-btn-bg: var(--sb-accent);
  --bs-btn-border-color: var(--sb-accent);
  --bs-btn-color: #ffffff;
  --bs-btn-hover-bg: var(--sb-accent-strong);
  --bs-btn-hover-border-color: var(--sb-accent-strong);
  --bs-btn-hover-color: #ffffff;
  --bs-btn-active-bg: var(--sb-accent-strong);
  --bs-btn-active-border-color: var(--sb-accent-strong);
  --bs-btn-active-color: #ffffff;
  --bs-btn-disabled-bg: var(--sb-accent);
  --bs-btn-disabled-border-color: var(--sb-accent);
  --bs-btn-disabled-color: #ffffff;
  --bs-btn-focus-shadow-rgb: var(--sb-accent-rgb);
}

.btn-outline-primary {
  --bs-btn-color: var(--sb-accent);
  --bs-btn-border-color: var(--sb-accent);
  --bs-btn-hover-bg: var(--sb-accent);
  --bs-btn-hover-border-color: var(--sb-accent);
  --bs-btn-hover-color: #ffffff;
  --bs-btn-active-bg: var(--sb-accent-strong);
  --bs-btn-active-border-color: var(--sb-accent-strong);
  --bs-btn-active-color: #ffffff;
  --bs-btn-focus-shadow-rgb: var(--sb-accent-rgb);
}

.text-bg-primary {
  color: #ffffff !important;
  background-color: var(--sb-accent) !important;
}

.card {
  --bs-card-border-radius: var(--bs-border-radius-lg);
  --bs-card-border-color: var(--sb-panel-border);
  --bs-card-cap-bg: var(--sb-panel-header);
  --bs-card-bg: var(--sb-panel);
  box-shadow: var(--sb-shadow-card);
}

/* ---- Element type as a solid label pill ---------------------------------- */

/* PLANKA marks a card with a small number of solid, saturated pills. The type
   is the one label a narrative card always carries, so it gets that treatment;
   the act, region and tag chips stay light, or four solid pills per card would
   read as noise.

   One hue per element type, everything else derived from it, which keeps this
   to two rule blocks instead of twenty. */
.sb-type {
  background-color: hsl(var(--sb-hue), 40%, 40%);
  color: #ffffff;
  border: 0;
  border-radius: 0.25rem;
  font-size: 0.6875rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

[data-bs-theme="dark"] .sb-type {
  background-color: hsl(var(--sb-hue), 32%, 42%);
  color: #ffffff;
}

.sb-type-character { --sb-hue: 214; }
.sb-type-location { --sb-hue: 158; }
.sb-type-faction { --sb-hue: 355; }
.sb-type-quest { --sb-hue: 32; }
.sb-type-item { --sb-hue: 272; }
.sb-type-creature { --sb-hue: 92; }
.sb-type-event { --sb-hue: 322; }
.sb-type-dialogue { --sb-hue: 246; }
.sb-type-encounter { --sb-hue: 16; }
.sb-type-codex { --sb-hue: 196; }

/* ---- Application shell ---------------------------------------------------- */

.sb-sidebar {
  flex: 0 0 15rem;
  width: 15rem;
  overflow-y: auto;
  /* The markup also carries a Bootstrap `bg-body-tertiary` utility, which is
     important, so this needs to be important as well to win. */
  background-color: var(--sb-chrome) !important;
  color: var(--sb-chrome-text);
  border-color: var(--sb-chrome-border) !important;
}

.sb-sidebar .sb-brand {
  color: #ffffff;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* Shown only in the collapsed rail, where the wordmark would be clipped. */
.sb-brand-mark {
  display: none;
}

.sb-sidebar .sb-sidebar-label {
  color: var(--sb-chrome-muted);
}

.sb-sidebar .list-group-item {
  background-color: transparent;
  color: var(--sb-chrome-muted);
  border-left: 0;
  border-right: 0;
  border-color: var(--sb-chrome-border);
  border-radius: 0;
}

.sb-sidebar .list-group-item:first-child {
  border-top: 0;
}

.sb-sidebar .list-group-item:hover,
.sb-sidebar .list-group-item:focus {
  background-color: var(--sb-chrome-hover);
  color: var(--sb-chrome-text);
}

.sb-sidebar .list-group-item.active {
  background-color: var(--sb-chrome-active);
  border-color: transparent;
  color: #ffffff;
}

/* The presence footer sits at the bottom of the rail. */
.sb-sidebar .text-body-secondary {
  color: var(--sb-chrome-muted) !important;
}

/* The top bar is dark chrome. The markup carries data-bs-theme="dark", so every
   Bootstrap control inside it — search field, buttons, the game dropdown —
   already renders for a dark surface; only the surface itself is set here. */
.sb-topbar {
  background-color: var(--sb-chrome);
  color: var(--sb-chrome-text);
  border-bottom-color: var(--sb-chrome-border) !important;
}

.sb-topbar .text-body-secondary {
  color: var(--sb-chrome-muted) !important;
}

@media (max-width: 991.98px) {
  .sb-sidebar {
    flex-basis: 4.25rem;
    width: 4.25rem;
  }

  .sb-sidebar .sb-sidebar-label,
  .sb-sidebar .sb-sidebar-text,
  .sb-sidebar .sb-brand {
    display: none;
  }

  .sb-sidebar .sb-brand-block {
    padding: 0.75rem 0.25rem !important;
    text-align: center;
  }

  .sb-sidebar .sb-brand-mark {
    display: inline;
    font-size: 1.05rem;
    letter-spacing: 0.02em;
  }
}

/* ---- Board ---------------------------------------------------------------- */

/* The saturated PLANKA board surface. Columns are the white panels on it. */
.sb-board {
  --sb-column-width: 19.5rem;
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 0.75rem 1rem 2rem;
  flex: 1 1 auto;
  min-height: 0;
  background-color: var(--sb-board-surface);
}

.sb-column {
  flex: 0 0 var(--sb-column-width);
  width: var(--sb-column-width);
  max-height: 100%;
  display: flex;
  flex-direction: column;
  border: 0;
}

/* The list header is the grey band; the card list below it is white. */
.sb-column > .card-header {
  background-color: var(--sb-panel-header);
  border-bottom: 0;
  font-weight: 600;
}

/* The card list is the only scrolling part of a column, so the header stays put. */
.sb-column > .card-body {
  overflow-y: auto;
  min-height: 3.5rem;
  padding: 0.375rem;
  background-color: var(--sb-panel);
}

/* PLANKA adds cards through a quiet text button, not a loud primary one. */
.sb-column > .card-footer {
  background-color: var(--sb-panel);
  border-top: 0;
  padding: 0.25rem;
}

.sb-column > .card-footer .btn-primary {
  --bs-btn-bg: transparent;
  --bs-btn-border-color: transparent;
  --bs-btn-color: var(--bs-secondary-color);
  --bs-btn-hover-bg: rgba(34, 37, 42, 0.06);
  --bs-btn-hover-border-color: transparent;
  --bs-btn-hover-color: var(--bs-body-color);
  --bs-btn-active-bg: rgba(34, 37, 42, 0.1);
  --bs-btn-active-border-color: transparent;
  --bs-btn-active-color: var(--bs-body-color);
  --bs-btn-disabled-bg: transparent;
  --bs-btn-disabled-border-color: transparent;
  --bs-btn-disabled-color: var(--bs-secondary-color);
  --bs-btn-focus-shadow-rgb: var(--sb-accent-rgb);
  justify-content: flex-start;
  font-weight: 500;
}

[data-bs-theme="dark"] .sb-column > .card-footer .btn-primary {
  --bs-btn-hover-bg: rgba(255, 255, 255, 0.07);
  --bs-btn-active-bg: rgba(255, 255, 255, 0.11);
}

/* ---- Drag and drop -------------------------------------------------------- */

.sb-card-tile {
  cursor: pointer;
  background-color: var(--sb-panel);
  border: 1px solid var(--sb-panel-border);
  transition: box-shadow 120ms ease-out, border-color 120ms ease-out;
}

.sb-card-tile:hover {
  border-color: var(--sb-accent);
  box-shadow: var(--sb-shadow-lift);
}

.sb-card-tile--dragging {
  opacity: 0.45;
}

.sb-drop-placeholder {
  height: 3px;
  margin: 0.125rem 0;
  border-radius: 2px;
  background-color: var(--sb-accent);
  opacity: 0.9;
}

.sb-column--drop {
  outline: 2px solid var(--sb-accent);
  outline-offset: -2px;
}

/* ---- Card details -------------------------------------------------------- */

.sb-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}

.sb-card-meta {
  font-size: 0.75rem;
  color: var(--bs-secondary-color);
}

/* Bootstrap 5.3 has no line-clamp utility, and single-line truncation is the wrong
   trade for a card title: it is the one field a writer scans the board for, and
   "Nebenhandlung: Di…" is not a title. Two lines is where a title stops being
   readable at a glance. */
.sb-clamp-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---- Card dialog --------------------------------------------------------- */

/* The card opens as a centred dialog rather than a side panel. The editor is a form with several
   sections, and a window keeps the board visible around it instead of covering a third of the screen.
   Width and scrolling come from Bootstrap's `modal-xl modal-dialog-scrollable`, which the modal
   component applies for `Wide` - a rule here would be a second place to keep the same number. */

/* ---- Codex table --------------------------------------------------------- */

/* Bootstrap tables scroll with the page; the codex has its own scroll container
   and needs the header to stay visible inside it. */
.sb-table-sticky thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background-color: var(--sb-panel);
  box-shadow: inset 0 -1px 0 var(--bs-border-color);
}

.sb-table-sticky tbody tr {
  cursor: pointer;
}

/* ---- Timeline ------------------------------------------------------------ */

.sb-lanes {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  overflow-x: auto;
  padding: 0.75rem 1rem 2rem;
  flex: 1 1 auto;
  min-height: 0;
  background-color: var(--sb-board-surface);
}

.sb-lane {
  flex: 0 0 19.5rem;
  width: 19.5rem;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  border: 0;
}

.sb-lane > .card-header {
  background-color: var(--sb-panel-header);
  border-bottom: 0;
  font-weight: 600;
}

.sb-lane > .card-body {
  overflow-y: auto;
  min-height: 3.5rem;
  padding: 0.375rem;
  background-color: var(--sb-panel);
}

/* ---- Game picker --------------------------------------------------------- */

.sb-game-card {
  height: 100%;
  cursor: pointer;
  background-color: var(--sb-panel);
  transition: box-shadow 140ms ease-out, border-color 140ms ease-out;
}

.sb-game-card:hover {
  border-color: var(--sb-accent);
  box-shadow: var(--sb-shadow-lift);
}

/* The game's own colour, so several games stay distinguishable at a glance. */
.sb-game-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--bs-border-radius);
  font-weight: 600;
  font-size: 1.125rem;
  background-color: hsl(var(--sb-hue), 40%, 40%);
  color: #ffffff;
}

[data-bs-theme="dark"] .sb-game-mark {
  background-color: hsl(var(--sb-hue), 32%, 42%);
}

/* ---- Boot shell --------------------------------------------------------- */

/* Shown by index.html until WebAssembly has started. Laid out with Bootstrap
   utilities in the markup; only the spinner spacing lives here. */
.sb-boot {
  min-height: 100vh;
  background-color: var(--sb-chrome);
  color: var(--sb-chrome-text);
}

.sb-boot .spinner-border {
  width: 2rem;
  height: 2rem;
}

/* ---- Login -------------------------------------------------------------- */

/* The sign-in screen sits on the same saturated surface as a board does, so the first thing
   somebody sees is the product rather than a grey form. The surface is the full viewport and the
   cards keep their measure inside it; a direct-child rule covers both the sign-in card and the
   demo-accounts card without touching the markup. */
.sb-auth {
  background-color: var(--sb-board-surface);
}

.sb-auth > .card {
  max-width: 26rem;
  width: 100%;
}

/* Anything that is not inside a card stands directly on the surface, so the stock outline button
   would be a grey edge on dark blue. It gets the light-on-dark treatment here, and only here. */
.sb-auth > .btn {
  --bs-btn-color: var(--bs-white);
  --bs-btn-border-color: rgba(var(--bs-white-rgb), 0.5);
  --bs-btn-hover-color: var(--bs-white);
  --bs-btn-hover-bg: rgba(var(--bs-white-rgb), 0.12);
  --bs-btn-hover-border-color: var(--bs-white);
  --bs-btn-active-color: var(--bs-white);
  --bs-btn-active-bg: rgba(var(--bs-white-rgb), 0.18);
  --bs-btn-active-border-color: var(--bs-white);
}

/* ---- Tutorial ----------------------------------------------------------- */

/* A two-pane dialog: the topic list on the left, the selected topic on the
   right. Bootstrap has no such layout, and driving `nav-pills` + a pane with
   Blazor state avoids needing Bootstrap's JavaScript for the tabs. */
.sb-guide-topics {
  flex: 0 0 15rem;
  overflow-y: auto;
}

.sb-guide-body {
  overflow-y: auto;
}

.sb-guide-body h6 {
  margin-top: 1.25rem;
}

.sb-guide-body h6:first-child {
  margin-top: 0;
}

/* ---- Density ------------------------------------------------------------- */

/* Bootstrap has no density concept, so the two settings are spelled out. They
   only touch padding and the card's base font size — nothing structural. */
[data-sb-density="compact"] .sb-column > .card-body,
[data-sb-density="compact"] .sb-lane > .card-body {
  padding: 0.25rem;
}

[data-sb-density="compact"] .sb-card-tile .card-body {
  padding: 0.5rem 0.625rem;
}

[data-sb-density="compact"] .sb-card-tile {
  font-size: 0.8125rem;
}

/* ============================================================================
   Story flow (/handlung) — APPENDED section.

   The vertical timeline. Everything here is built from the theme variables above
   (--sb-panel, --sb-panel-header, --sb-border-radius, --sb-shadow-card,
   --sb-accent) and adds no literal colour of its own, so the dark theme needs no
   second rule set.

   The spine is one absolutely positioned line per strand, not a border on each
   row: the line then runs unbroken through the dots instead of restarting at
   every row. Indentation is carried by --sb-story-depth, one number per beat,
   so depth is an inline value rather than a class per level.
   ============================================================================ */

.sb-story {
  background-color: var(--sb-board-surface);
}

.sb-story-timeline {
  max-width: 72rem;
  margin: 0 auto;
}

.sb-story-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin-bottom: 0.75rem;
}

.sb-story-act > .card-header {
  background-color: var(--sb-panel-header);
  border-bottom: 0;
}

.sb-story-act-title {
  letter-spacing: 0.05em;
  font-size: 0.8125rem;
}

/* ---- Strands and the spine ----------------------------------------------- */

.sb-story-strand {
  position: relative;
  padding-left: 1.625rem;
  margin-bottom: 0.75rem;
}

.sb-story-strand:last-child {
  margin-bottom: 0;
}

/* The spine: a hairline from the strand label to the last dot of the chain. */
.sb-story-strand::before {
  content: "";
  position: absolute;
  top: 0.55rem;
  bottom: 0.35rem;
  left: 0.3125rem;
  width: 1px;
  background-color: var(--sb-accent);
  opacity: 0.5;
}

.sb-story-strand-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  font-weight: 600;
  margin-bottom: 0.375rem;
}

/* The strand's own marker, drawn over the spine so the line starts at it. */
.sb-story-strand-dot {
  position: absolute;
  left: 0;
  width: 0.6875rem;
  height: 0.6875rem;
  border-radius: 50%;
  background-color: var(--sb-accent);
}

/* ---- Beats --------------------------------------------------------------- */

.sb-story-row {
  position: relative;
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  /* Indentation by dependency depth: the strip between two depths is one step of
     the chain, so a prerequisite always sits above and to the left of what it
     enables. */
  margin-left: calc(var(--sb-story-depth, 0) * 0.5rem);
  padding: 0.25rem 0 0.25rem 0.25rem;
  border-bottom: 1px solid var(--sb-panel-border);
}

.sb-story-row:last-child {
  border-bottom: 0;
}

.sb-story-row:hover {
  background-color: var(--sb-panel-header);
  border-radius: var(--sb-border-radius);
}

.sb-story-dot {
  position: absolute;
  left: -1.3125rem;
  top: 0.625rem;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background-color: var(--sb-accent);
  z-index: 1;
}

.sb-story-dot--warning {
  background-color: var(--bs-warning);
}

.sb-story-dot--danger {
  background-color: var(--bs-danger);
}

.sb-story-dot--small {
  position: static;
  width: 0.375rem;
  height: 0.375rem;
}

.sb-story-row-body {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 0;
  flex: 1 1 auto;
}

.sb-story-row-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.75rem;
}

.sb-story-cast {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

/* ---- Clickable chips ----------------------------------------------------- */

/* A card key is the handle a writer quotes, so it is a button everywhere it
   appears: on a beat, in a dependency chip and in a character's chain. */
.sb-story-key {
  cursor: pointer;
  text-align: left;
}

.sb-story-key:hover,
.sb-story-key:focus-visible {
  background-color: var(--sb-accent) !important;
  color: var(--bs-white);
}

.sb-story-title {
  text-decoration: none;
  min-width: 0;
  overflow-wrap: anywhere;
}

.sb-story-title:hover,
.sb-story-title:focus-visible {
  text-decoration: underline;
  color: var(--sb-accent) !important;
}

.sb-story-requires {
  cursor: pointer;
}

.sb-story-requires:hover,
.sb-story-requires:focus-visible {
  background-color: var(--bs-warning-subtle) !important;
  color: var(--bs-warning-text-emphasis) !important;
}

.sb-story-cast-member {
  line-height: 1;
}

/* ---- Character threads --------------------------------------------------- */

.sb-story-thread {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0;
  border-bottom: 1px solid var(--sb-panel-border);
}

.sb-story-thread:last-of-type {
  border-bottom: 0;
}

.sb-story-thread-chain {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
}

/* One step of a character's chain: a dot and a key, joined by a short rule so the
   sequence reads left to right rather than as a cloud of chips. */
.sb-story-step {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

.sb-story-step + .sb-story-step::before {
  content: "";
  width: 0.75rem;
  height: 1px;
  background-color: var(--bs-border-color);
}

.sb-story-once {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--bs-border-color);
}

/* ---- Concept: the one-page brief ----------------------------------------- */

/* The concept is a document, not a dashboard: one column, capped for reading,
   and the same white PLANKA panels every other screen uses. Nothing here invents
   a colour; the few rules below only lay out what Bootstrap's utilities and the
   `.sb-type` pills already carry. */
.sb-concept-page {
  max-width: 64rem;
  margin-inline: auto;
  padding: 1rem;
}

.sb-concept-section-title {
  letter-spacing: 0.06em;
}

/* The fact sheet reads as a header block, not as a form: labelled values in as
   many columns as fit. */
.sb-concept-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 0.5rem 1rem;
}

.sb-concept-fact {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.sb-concept-label {
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--bs-secondary-color);
}

.sb-concept-value {
  overflow-wrap: anywhere;
}

.sb-concept-counters,
.sb-concept-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
}

.sb-concept-distributions {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.sb-concept-distribution,
.sb-concept-field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.sb-concept-share .progress {
  height: 0.5rem;
}

/* The authored part: the pitch leads, the lists follow. */
.sb-concept-authored,
.sb-concept-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.sb-concept-pitch {
  margin: 0;
  font-size: 1.0625rem;
  line-height: 1.5;
}

.sb-concept-pillars {
  margin: 0;
  padding-left: 1.1rem;
}

.sb-concept-group + .sb-concept-group,
.sb-concept-field + .sb-concept-field {
  margin-top: 0.75rem;
}

.sb-concept-group-head {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  margin-bottom: 0.25rem;
}

/* A listed card. The whole row is a button because the whole row opens the
   drawer, so it has to look like a row and behave like one. */
.sb-concept-entry {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.375rem 0.5rem;
  text-align: left;
  color: var(--bs-body-color);
  background-color: transparent;
  border: 1px solid transparent;
  border-radius: var(--bs-border-radius);
}

.sb-concept-entry:hover,
.sb-concept-entry:focus-visible {
  background-color: var(--sb-panel-header);
  border-color: var(--sb-panel-border);
}

.sb-concept-entry-title {
  min-width: 0;
  overflow-wrap: anywhere;
}

.sb-concept-entry-logline {
  min-width: 0;
  overflow: hidden;
  font-size: 0.8125rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sb-concept-entry-meta {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
  margin-left: auto;
}

/* The plot: one row per act, its length drawn relative to the busiest act, so
   the shape of the story is readable at a glance without a gauge per act. */
.sb-concept-act + .sb-concept-act {
  margin-top: 0.5rem;
}

.sb-concept-act-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
}

.sb-concept-act-bar {
  height: 0.375rem;
  margin-top: 0.25rem;
  overflow: hidden;
  background-color: var(--bs-tertiary-bg);
  border-radius: var(--bs-border-radius-pill);
}

.sb-concept-act-fill {
  display: block;
  height: 100%;
  background-color: var(--sb-accent);
}

/* Maturity: the four gaps side by side, the findings as a list underneath. */
.sb-concept-gaps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0.75rem;
}

.sb-concept-gap {
  min-width: 0;
}

.sb-concept-finding-list {
  border-top: 1px solid var(--sb-panel-border);
}

.sb-concept-finding {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0;
  font-size: 0.8125rem;
  border-bottom: 1px solid var(--sb-panel-border);
}

.sb-concept-finding-text {
  flex: 1 1 12rem;
  min-width: 0;
}

/* ============================================================================
   Live cursors - APPENDED section.

   The layer is a sibling of the columns inside the scrolling board, so it travels with
   the content instead of being repositioned on every scroll event. It never takes
   pointer events: a cursor layer you can click by accident is worse than none, and the
   whole thing is decoration, so assistive technology is told to ignore it.
   ============================================================================ */

/* The containing block for the layer. The board already scrolls; all it needs is a
   positioning context so that content coordinates mean the same thing to both sides. */
.sb-board {
  position: relative;
}

/* Every surface the cursor layer can sit on needs to be its own positioning context. The
   coordinates are measured against that element, so if it were not positioned they would be
   resolved against some ancestor instead and every cursor would land somewhere else. */
.sb-concept,
.sb-story,
#sb-codex {
  position: relative;
}

.sb-cursors {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
}

.sb-cursor {
  position: absolute;
  left: var(--sb-cursor-x);
  top: var(--sb-cursor-y);
  display: flex;
  align-items: flex-start;
  gap: 0.125rem;
  transform: translate(-1px, -1px);
}

.sb-cursor__arrow {
  fill: var(--sb-cursor-color);
  filter: drop-shadow(0 1px 1px rgba(var(--bs-black-rgb), 0.35));
}

.sb-cursor__name {
  margin-top: 0.7rem;
  padding: 0.05rem 0.35rem;
  border-radius: 0.35rem;
  background-color: var(--sb-cursor-color);
  color: var(--bs-white);
  font-size: 0.6875rem;
  font-weight: 600;
  white-space: nowrap;
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
}
