:root {
  /*
    These custom properties define the board's geometry and visual style.

    Geometry:
    - --rows: how many background grid rows to draw initially
    - --cell-h: the height of one logical row
    - --gap: the vertical spacing between rows
    - --time-tile-w: the fallback width of the measured time column

    Theme:
    - colors, radius, and shadow used by the board and tiles
  */
  --rows: 1000;
  --cell-h: 30px;
  --gap: 5px;
  --time-tile-w: 170px;

  --board-bg: #ffffff;
  --grid-fill: #f8fafc;
  --grid-line: #d6dbe4;
  --tile-bg: #2563eb;
  --tile-text: #ffffff;
  --radius: 12px;
  --shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}

* {
  /*
    Use border-box sizing everywhere.

    Why:
    - width and height become easier to reason about
    - padding and borders stay inside the declared size
    - prevents subtle layout drift in grid and dragged elements
  */
  box-sizing: border-box;
}

body {
  /*
    Basic page styling for demo/use:
    - remove default browser margin
    - set a readable system font stack
    - give the page a light background so the board stands out
  */
  margin: 24px;
  font-family: Inter, ui-sans-serif, system-ui, sans-serif;
  background: #f3f4f6;
}

.stack-board {
  /*
    This is the outer board.

    It is itself a CSS grid with:
    - exactly one column
    - a fixed set of row tracks
    - a gap between rows

    Important idea:
    Both the visual background layer and the interactive content layer
    will be placed on top of this same footprint.
  */
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: repeat(var(--rows), var(--cell-h));
  gap: var(--gap);
  width: 100%;
  background: var(--board-bg);
}

.stack-board__grid,
.stack-board__content {
  /*
    These two layers share the exact same grid geometry.

    grid-area: 1 / 1 / -1 / -1 means:
    - start at row 1 / column 1
    - span the whole parent grid

    So they occupy the same space, one over the other.

    Each layer is also its own 1-column grid with the same row sizing.
    That lets:
    - the background draw row cells
    - the content place tiles on matching row lines
  */
  grid-area: 1 / 1 / -1 / -1;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: repeat(var(--rows), var(--cell-h));
  gap: var(--gap);
}

.stack-board__grid {
  /*
    This is the visual-only background layer.

    z-index: 1 puts it behind the content layer.
    pointer-events: none ensures it never intercepts clicks, drags, or taps.
  */
  z-index: 1;
  pointer-events: none;
}

.stack-board__grid > .grid-cell {
  /*
    Style for each background slot.

    This gives users a visible row structure without making the cells interactive.
    The dashed border helps communicate "grid guide" rather than "card."
  */
  background: var(--grid-fill);
  border: 1px dashed var(--grid-line);
  border-radius: 10px;
}

.stack-board__content {
  /*
    This is the interactive layer that holds the tiles.

    z-index: 2 puts it above the background layer.
    position: relative establishes the containing block for absolutely
    positioned tiles while they are being dragged.
  */
  position: relative;
  z-index: 2;
}

.stack-tile {
  /*
    Base appearance of each tile.

    These tiles are normally positioned by CSS Grid using grid-row.

    Layout:
    - display: flex centers content vertically
    - padding gives text room to breathe

    Interaction:
    - cursor: grab suggests draggability
    - user-select: none avoids accidental text selection while dragging
    - touch-action: none gives pointer events better control on touch devices

    Visuals:
    - background/text colors
    - rounded corners
    - shadow for depth

    Transition:
    - smooths opacity/shadow changes while dragging states change
  */
  display: flex;
  margin-left: auto;
  align-items: center;
  width: calc(100% - var(--time-tile-w));
  padding: 0 16px;
  background: var(--tile-bg);
  color: var(--tile-text);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  font-weight: 600;
  cursor: grab;
  user-select: none;
  touch-action: none;
  transition:
    transform 120ms ease,
    box-shadow 120ms ease,
    opacity 120ms ease;
}
.stack-tile.is-dragging {
  /*
    Applied while a tile is actively being dragged.

    cursor: grabbing gives immediate feedback that the item is "picked up."
    Slight opacity change helps distinguish the dragged state.
  */
  cursor: grabbing;
  opacity: 0.95;
}

.stack-tile.is-floating {
  /*
    Applied only during drag.

    Key idea:
    - normally, tiles are grid-positioned
    - during drag, the active tile leaves grid flow and follows the pointer

    position: absolute lets JavaScript move the tile using left/top.
    z-index: 50 keeps it above the preview and other tiles.
    transition: none removes animation lag while the pointer is moving.
  */
  position: absolute;
  z-index: 50;
  transition: none;
}

.drop-preview {
  /*
    This is the translucent "ghost" showing where the dragged tile
    would land if released right now.

    It is grid-positioned like a tile, but:
    - purely visual
    - non-interactive
    - lighter so it reads as a preview rather than a real item
  */
  border-radius: var(--radius);
  background: rgba(37, 99, 235, 0.12);
  border: 2px solid rgba(37, 99, 235, 0.55);
  pointer-events: none;
}
