.roadmap { display: flex; flex-direction: column; gap: 12px; }
.roadmap-toolbar { display: flex; gap: 8px; align-items: center; }

.roadmap-viewport {
    position: relative;
    height: calc(100vh - 220px);
    min-height: 420px;
    overflow: hidden;
    background: var(--bp-muted);
    border: 1px solid var(--bp-border-soft);
    border-radius: var(--radius-lg);
    background-image: radial-gradient(var(--bp-border-soft) 1px, transparent 1px);
    background-size: 24px 24px;
    touch-action: none;
    cursor: grab;
}
.roadmap-viewport:active { cursor: grabbing; }

.roadmap-world, .roadmap-edges { position: absolute; top: 0; left: 0; transform-origin: 0 0; }
.roadmap-edges { width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.roadmap-world { width: 0; height: 0; }

.roadmap-edge { fill: none; stroke: var(--bp-border); stroke-width: 2; }
.roadmap-edge:hover { stroke: var(--accent); }
.roadmap-arrowhead { fill: var(--bp-border); }

.roadmap-card {
    position: absolute;
    width: 210px;
    background: var(--bp-surface);
    border: 1px solid var(--bp-border);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-1);
    padding: 10px 12px;
    cursor: pointer;
    transition: box-shadow var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
    user-select: none;
}
.roadmap-card:hover { box-shadow: var(--shadow-2); transform: translateY(-1px); }
/* "This feature is being worked on" is a resting fact about the data, not a
   focus position. It used to borrow --shadow-focus, which made one green glow
   mean two different things; it now takes the accent rail that .nav-item.active
   already uses for "you are marked here". */
.roadmap-card.is-active { border-color: var(--accent); box-shadow: inset 3px 0 0 0 var(--accent), var(--shadow-1); }

/* Keyboard focus has to read louder than hover here: cards sit on a busy canvas
   and the focused one may be the only cue to where you are. */
.roadmap-card:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    box-shadow: var(--shadow-2);
}
/* The card a keyboard dependency is being drawn FROM, and the candidates it can
   be drawn to, while that mode is active. */
/* Also not focus: while connecting, the keyboard has moved on to the candidate
   card, so a focus ring left behind here would point at the wrong element. The
   dashed accent border carries it, lifted so it reads as the anchor. */
.roadmap-card.is-connect-source {
    border-color: var(--accent);
    border-style: dashed;
    box-shadow: var(--shadow-2);
}
.roadmap.is-connecting .roadmap-card:not(.is-connect-source) { border-style: dashed; }

.roadmap-card-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.roadmap-card-status { font-size: 11px; padding: 2px 8px; border-radius: var(--radius-pill); background: var(--bp-muted-2); color: var(--fg-muted); }
.roadmap-card-status.status-active { background: var(--status-progress-bg); color: var(--status-progress-fg); }
.roadmap-card-status.status-completed { background: var(--status-done-bg); color: var(--status-done-fg); }
.roadmap-card-live { color: var(--accent); animation: roadmap-pulse 1.6s ease-in-out infinite; }
.roadmap-card-name { font-weight: 600; color: var(--fg-1); font-size: 14px; margin-bottom: 8px; line-height: 1.3; }

.roadmap-progress { height: 6px; background: var(--bp-muted-2); border-radius: 3px; overflow: hidden; }
.roadmap-progress-bar { height: 100%; background: var(--accent); border-radius: 3px; transition: width var(--dur-med) var(--ease-out); }
.roadmap-progress-label { font-size: 11px; color: var(--fg-muted); margin-top: 3px; }

.roadmap-card-window { font-size: 11px; color: var(--fg-muted); margin-top: 4px; white-space: nowrap; }
.roadmap-card-window.is-delayed { color: var(--status-blocked-fg); font-weight: 600; }

/* Ink on green, never white — white measured 1.87:1 here. 28px is the system's
   target floor; the circle straddles the card's right edge, so half of it also
   sits in the empty canvas beside the card and nothing is covered. */
.roadmap-connect {
    position: absolute; right: -14px; top: 50%; transform: translateY(-50%);
    width: 28px; height: 28px; border-radius: 50%; background: var(--accent); color: #0E2A1C;
    display: flex; align-items: center; justify-content: center; font-size: 14px; cursor: crosshair;
    opacity: 0; transition: opacity var(--dur-fast) var(--ease-out);
}
/* Keyboard reaches the card too, and a handle that only answers the mouse is
   invisible to everyone else on the same path. */
.roadmap-card:hover .roadmap-connect,
.roadmap-card:focus-visible .roadmap-connect,
.roadmap-card:focus-within .roadmap-connect { opacity: 1; }
/* Without hover there is no way to reveal the handle, so drawing a dependency
   would be impossible on a touch screen. It stays visible there instead. */
@media (hover: none) {
    .roadmap-connect { opacity: 1; }
}

@keyframes roadmap-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* ── Reduced motion ────────────────────────────────────────────
   See the block at the end of app.css for the rule this follows. */
@media (prefers-reduced-motion: reduce) {
    /* "Právě se dělá" was a dot fading to 35% and back, forever — text
       whose contrast never settles. Frozen at full strength it still says
       the same thing: it is the only Signal Green mark on the card. */
    .roadmap-card-live { animation: none; opacity: 1; }

    /* The 1px hover lift goes. The shadow that came with it stays, and it
       is what actually reads as "this one". */
    .roadmap-card { transition: box-shadow var(--dur-fast) var(--ease-out); }
    .roadmap-card:hover { transform: none; }

    /* A share of finished work, same as the dashboard bars. */
    .roadmap-progress-bar { transition: none; }

    /* The connect handle's fade stays: opacity is not travel, and without
       it the handle would appear with no acknowledgement at all. */
}
