/* Family Workspace ---------------------------------------------------------
   A calm two-pane surface layered over the existing kin graph and design
   tokens. All relationship semantics still come from the renderer/kernel. */

.adv-cast-tree {
    --kc-rail-w: 244px;
    --kc-blue: #6da8ff;
    --kc-blue-strong: #3f87f5;
    --kc-green: #43d18b;
    --kc-warn: #f2b84b;

    /* [NE:kin] CONNECTOR COLOUR IS ITS OWN THING, not the theme accent.
       `.kc-link.is-bio` used to be color-mix(var(--adv-accent) 72%, muted), and
       --adv-accent resolves to #d23b45 in this skin — so every healthy blood
       line rendered SALMON RED, one shade off `.is-refused`'s #e5484d, which is
       the actual "this relationship was rejected" state. A reader could not
       tell a working family tree from a broken one by colour, and the whole
       chart read as an error.
       Lineage is structure, so it is drawn in structural colours: a calm steel
       that recedes behind the cards, and red reserved for genuine problems. */
    --kc-line: #7d93b8;
    --kc-line-care: #6b7a92;
    --kc-line-strong: #a9c2e8;
    --kc-refused: #e5484d;
    display: block;
    min-width: 0;
}

.kc-workspace {
    position: relative;
    display: grid;
    grid-template-columns: var(--kc-rail-w) minmax(0, 1fr);
    width: 100%;
    height: clamp(620px, calc(100vh - 238px), 900px);
    min-height: 620px;
    overflow: hidden;
    border: 1px solid color-mix(in srgb, var(--adv-border) 82%, transparent);
    border-radius: 18px;
    background: color-mix(in srgb, var(--adv-surface) 92%, #07101f);
    box-shadow: 0 24px 70px color-mix(in srgb, #020712 35%, transparent);
    color: var(--adv-ink);
}

.kc-family-rail {
    position: relative;
    z-index: 12;
    display: flex;
    min-width: 0;
    flex-direction: column;
    overflow: hidden;
    border-right: 1px solid color-mix(in srgb, var(--adv-border) 76%, transparent);
    background: color-mix(in srgb, var(--adv-raised) 94%, #0a1423);
    transition: width 180ms ease, transform 180ms ease;
}

.kc-rail-head {
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr) 32px;
    align-items: center;
    gap: 10px;
    min-height: 72px;
    padding: 14px 12px 12px 14px;
}

.kc-rail-mark,
.kc-family-swatch {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border: 1px solid color-mix(in srgb, var(--kc-blue) 28%, var(--adv-border));
    border-radius: 11px;
    background: color-mix(in srgb, var(--kc-blue) 12%, var(--adv-inset));
    color: color-mix(in srgb, var(--kc-blue) 88%, var(--adv-ink));
    font-size: 0.76rem;
    font-weight: 800;
}
.kc-rail-mark { padding: 0; font: inherit; cursor: pointer; }

.kc-rail-mark svg,
.kc-family-swatch svg { width: 17px; height: 17px; }
.kc-rail-title { min-width: 0; display: flex; flex-direction: column; }
.kc-rail-title strong { font-size: 0.91rem; line-height: 1.2; }
.kc-rail-title span { margin-top: 3px; color: var(--adv-muted); font-size: 0.69rem; }

.kc-icon-btn,
.kc-tool-btn,
.kc-canvas-controls button,
.kc-context-actions button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    border: 1px solid color-mix(in srgb, var(--adv-border) 85%, transparent);
    background: color-mix(in srgb, var(--adv-surface) 92%, transparent);
    color: var(--adv-ink);
    font: inherit;
    cursor: pointer;
}

.kc-icon-btn {
    width: 32px;
    height: 32px;
    padding: 0;
    border-radius: 9px;
    color: var(--adv-muted);
}
.kc-icon-btn:hover,
.kc-tool-btn:hover { border-color: color-mix(in srgb, var(--kc-blue) 60%, var(--adv-border)); color: var(--adv-ink); }
.kc-icon-btn svg,
.kc-tool-btn svg { width: 15px; height: 15px; }

.kc-family-search,
.kc-person-search {
    display: flex;
    align-items: center;
    gap: 8px;
    border: 1px solid transparent;
    background: color-mix(in srgb, var(--adv-inset) 76%, transparent);
    color: var(--adv-muted);
}

.kc-family-search {
    margin: 0 12px 13px;
    padding: 0 10px;
    min-height: 38px;
    border-radius: 10px;
}

.kc-family-search:focus-within,
.kc-person-search:focus-within {
    border-color: color-mix(in srgb, var(--kc-blue) 55%, transparent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--kc-blue) 10%, transparent);
}

.kc-family-search svg,
.kc-person-search svg { width: 15px; height: 15px; flex: 0 0 auto; }
.kc-family-search input,
.kc-person-search input {
    width: 100%;
    min-width: 0;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--adv-ink);
    font: inherit;
    font-size: 0.75rem;
}
.kc-family-search input::placeholder,
.kc-person-search input::placeholder { color: color-mix(in srgb, var(--adv-muted) 75%, transparent); }

.kc-family-nav {
    min-height: 0;
    padding: 0 8px 16px;
    overflow: auto;
    scrollbar-width: thin;
}

.kc-rail-label {
    margin: 18px 9px 7px;
    color: color-mix(in srgb, var(--adv-muted) 78%, transparent);
    font-size: 0.62rem;
    font-weight: 750;
    letter-spacing: 0.11em;
    text-transform: uppercase;
}

.kc-family-list { display: grid; gap: 3px; }
.kc-family-row {
    position: relative;
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 56px;
    padding: 8px 8px;
    border: 1px solid transparent;
    border-radius: 12px;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background 120ms ease, border-color 120ms ease, transform 120ms ease;
}
.kc-family-row:hover { background: color-mix(in srgb, var(--adv-muted) 7%, transparent); }
.kc-family-row:active { transform: scale(0.99); }
.kc-family-row.is-active {
    border-color: color-mix(in srgb, var(--kc-blue) 25%, var(--adv-border));
    background: linear-gradient(100deg, color-mix(in srgb, var(--kc-blue) 14%, transparent), color-mix(in srgb, var(--kc-blue) 5%, transparent));
}
.kc-family-row.is-active::before {
    position: absolute;
    inset: 10px auto 10px -1px;
    width: 3px;
    border-radius: 0 4px 4px 0;
    background: var(--kc-blue);
    content: "";
}
.kc-family-row.is-all { margin-bottom: 3px; }
.kc-family-copy { min-width: 0; display: flex; flex-direction: column; }
.kc-family-copy strong { overflow: hidden; font-size: 0.78rem; line-height: 1.35; text-overflow: ellipsis; white-space: nowrap; }
.kc-family-copy small { overflow: hidden; margin-top: 3px; color: var(--adv-muted); font-size: 0.64rem; text-overflow: ellipsis; white-space: nowrap; }
.kc-avatar-stack { display: flex; padding-right: 2px; }
.kc-avatar-stack span {
    display: grid;
    place-items: center;
    width: 21px;
    height: 21px;
    margin-left: -7px;
    border: 2px solid color-mix(in srgb, var(--adv-raised) 94%, #0a1423);
    border-radius: 50%;
    background: var(--adv-inset);
    color: var(--adv-muted);
    font-size: 0.55rem;
    font-weight: 750;
}
.kc-family-alert {
    position: absolute;
    top: 5px;
    right: 5px;
    min-width: 16px;
    padding: 1px 4px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--kc-warn) 17%, var(--adv-inset));
    color: color-mix(in srgb, var(--kc-warn) 80%, var(--adv-ink));
    font-size: 0.58rem;
    font-weight: 800;
    text-align: center;
}
.kc-rail-no-results { margin: 14px 10px; color: var(--adv-muted); font-size: 0.72rem; }

.kc-unlinked { margin: 18px 5px 0; border-top: 1px solid color-mix(in srgb, var(--adv-border) 70%, transparent); padding-top: 12px; }
.kc-unlinked summary {
    display: flex;
    justify-content: space-between;
    padding: 5px;
    color: var(--adv-muted);
    font-size: 0.69rem;
    font-weight: 700;
    cursor: pointer;
}
.kc-unlinked summary span { color: var(--adv-ink); }
.kc-unlinked-list { display: grid; gap: 3px; margin-top: 5px; }
.kc-unlinked-person { display: grid; grid-template-columns: minmax(0, 1fr) 28px; align-items: center; gap: 4px; }
.kc-unlinked-person > button {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    min-height: 34px;
    padding: 4px 6px;
    overflow: hidden;
    border: 0;
    border-radius: 9px;
    background: transparent;
    color: var(--adv-muted);
    font: inherit;
    font-size: 0.7rem;
    text-align: left;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: pointer;
}
.kc-unlinked-person > button:hover { background: var(--adv-inset); color: var(--adv-ink); }
.kc-unlinked-person > button span {
    display: grid;
    place-items: center;
    width: 24px;
    height: 24px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--adv-inset);
    font-size: 0.58rem;
    font-weight: 800;
}

.kc-rail-add {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 40px;
    margin: auto 12px 12px;
    border: 1px solid color-mix(in srgb, var(--kc-blue) 36%, var(--adv-border));
    border-radius: 11px;
    background: color-mix(in srgb, var(--kc-blue) 11%, var(--adv-surface));
    color: var(--adv-ink);
    font: inherit;
    font-size: 0.72rem;
    font-weight: 720;
    cursor: pointer;
}
.kc-rail-add svg { width: 15px; height: 15px; color: var(--kc-blue); }

.kc-main { display: flex; min-width: 0; min-height: 0; flex-direction: column; }
.kc-canvas-toolbar {
    position: relative;
    z-index: 8;
    display: flex;
    align-items: center;
    gap: 14px;
    min-height: 76px;
    padding: 11px 14px 11px 20px;
    border-bottom: 1px solid color-mix(in srgb, var(--adv-border) 70%, transparent);
    background: color-mix(in srgb, var(--adv-raised) 90%, transparent);
}
.kc-mobile-families { display: none; }
.kc-canvas-title { min-width: 170px; margin-right: auto; }
.kc-eyebrow {
    display: block;
    margin-bottom: 3px;
    color: color-mix(in srgb, var(--kc-blue) 82%, var(--adv-muted));
    font-size: 0.58rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
.kc-canvas-title h2 { margin: 0; overflow: hidden; font-size: 0.96rem; line-height: 1.25; text-overflow: ellipsis; white-space: nowrap; }
.kc-canvas-title p { margin: 3px 0 0; color: var(--adv-muted); font-size: 0.66rem; }
.kc-toolbar-actions { display: flex; align-items: center; gap: 7px; }
.kc-layout-switch { display: inline-flex; padding: 3px; border: 1px solid var(--adv-border); border-radius: 10px; background: var(--adv-inset); }
.kc-layout-switch button {
    min-height: 28px;
    padding: 0 10px;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: var(--adv-muted);
    font: inherit;
    font-size: 0.66rem;
    font-weight: 700;
    cursor: pointer;
}
.kc-layout-switch button.is-active { background: var(--adv-surface); color: var(--adv-ink); box-shadow: var(--adv-shadow-1); }
.kc-layout-switch button:disabled { opacity: 0.42; cursor: not-allowed; }
.kc-person-search { width: 142px; min-height: 34px; padding: 0 9px; border-radius: 9px; }
.kc-tool-btn { min-height: 34px; padding: 0 11px; border-radius: 9px; font-size: 0.68rem; font-weight: 720; }
.kc-tool-btn.is-primary { border-color: color-mix(in srgb, var(--kc-blue) 54%, transparent); background: var(--kc-blue-strong); color: #fff; }
.kc-tool-btn.is-primary:hover { background: color-mix(in srgb, var(--kc-blue-strong) 88%, #fff); }
.kc-tool-btn.is-active { border-color: var(--kc-blue); background: color-mix(in srgb, var(--kc-blue) 13%, var(--adv-surface)); }

.kc-connect-banner,
.kc-conflict {
    position: relative;
    z-index: 7;
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 10px 12px 0;
    padding: 9px 12px;
    border-radius: 11px;
    font-size: 0.7rem;
}
.kc-connect-banner {
    border: 1px solid color-mix(in srgb, var(--kc-blue) 34%, var(--adv-border));
    background: color-mix(in srgb, var(--kc-blue) 10%, var(--adv-surface));
}
.kc-connect-banner > svg { width: 16px; height: 16px; color: var(--kc-blue); }
.kc-connect-banner strong { font-size: 0.72rem; }
.kc-connect-banner > span { color: var(--adv-muted); }
.kc-connect-banner button { margin-left: auto; border: 0; background: transparent; color: var(--adv-muted); font: inherit; cursor: pointer; }
.kc-connect-banner kbd { margin-left: 5px; padding: 1px 4px; border: 1px solid var(--adv-border); border-radius: 4px; background: var(--adv-inset); }
.kc-conflict { display: block; border-color: color-mix(in srgb, #e5484d 55%, var(--adv-border)); }

.kc-canvas-shell { position: relative; min-width: 0; min-height: 0; flex: 1 1 auto; overflow: hidden; }
.kc-live-region {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    border: 0;
    white-space: nowrap;
}
.kc-viewport {
    position: relative;
    min-width: 0;
    min-height: 0;
    overflow: auto;
    overscroll-behavior: contain;
    background-color: color-mix(in srgb, var(--adv-surface) 94%, #06101e);
    background-image: radial-gradient(circle, color-mix(in srgb, var(--adv-muted) 18%, transparent) 1px, transparent 1px);
    background-size: 22px 22px;
    cursor: grab;
    scrollbar-width: thin;
}
.kc-viewport[data-layout="lineage"] {
    background-image:
        radial-gradient(circle at 50% 42%, color-mix(in srgb, var(--kc-blue) 5%, transparent), transparent 46%),
        radial-gradient(circle, color-mix(in srgb, var(--adv-muted) 10%, transparent) 1px, transparent 1px);
    background-size: auto, 28px 28px;
}
.kc-canvas-shell > .kc-viewport { position: absolute; inset: 0; }
.kc-viewport.is-panning { cursor: grabbing; user-select: none; }
.kc-viewport:focus-visible { outline: 2px solid var(--kc-blue); outline-offset: -2px; }
.kc-stage { position: relative; min-width: 100%; min-height: 100%; margin: auto; }
.kc-canvas {
    position: absolute;
    margin: 0;
    padding: 0;
    transform-origin: 0 0;
}
.kc-links { position: absolute; inset: 0; z-index: 1; overflow: visible; pointer-events: auto; }

/* Opacity 1, not 0.72. Each child's branch is now ONE path that redraws the
   shared trunk, so a translucent stroke would double-darken the trunk once per
   sibling — four children would have made it four times as dark as its own
   stubs. Fully opaque strokes overlap invisibly, which is what lets the
   per-child paths exist at all. Recession comes from the COLOUR now. */
.kc-link {
    pointer-events: none;
    opacity: 1;
    stroke: var(--kc-line);
    stroke-width: 1.75;
    stroke-linecap: butt;
    stroke-linejoin: round;
    transition: stroke 140ms ease, stroke-width 140ms ease;
}
/* linecap: butt, deliberately. The inherited `round` put a half-round nub past
   the end of every segment; harmless on a single curve, but on a bracket whose
   segments meet at corners it showed as small bumps at each turn. */
.kc-link.is-bio { stroke: var(--kc-line); stroke-dasharray: none; }
.kc-link.is-care { stroke: var(--kc-line-care); stroke-dasharray: 4 5; }
/* is-union and is-partner also resolved to --adv-accent upstream, so a RECORDED
   marriage bar was red too. Every stroke that means "related" now comes from
   the --kc-line family; red survives only where it means refused. */
.kc-link.is-union { stroke: var(--kc-line-strong); stroke-width: 2.5; }
.kc-link.is-partner { stroke: var(--kc-line-care); stroke-dasharray: 2 4; }
.kc-link.is-refused { stroke: var(--kc-refused); stroke-width: 2.5; stroke-dasharray: none; }
.kc-link.is-related { stroke: var(--kc-line-strong); stroke-width: 2.5; }
.kc-link.is-selected { stroke: var(--kc-blue); stroke-width: 3; }
.kc-link-hit { pointer-events: stroke; stroke: transparent; stroke-width: 16; cursor: pointer; }

/* The junction. A reader's eye lands here and learns "this pair, together, is
   where the branch starts" — the thing a bare line descending from the gap
   between two cards completely failed to say. */
.kc-union-dot {
    fill: color-mix(in srgb, var(--kc-line) 88%, #0b1726);
    stroke: color-mix(in srgb, #0b1726 70%, transparent);
    stroke-width: 1.5;
    transition: fill 140ms ease;
}
.kc-union-dot.is-care { fill: color-mix(in srgb, var(--kc-line-care) 80%, #0b1726); }
.kc-union-dot.is-related { fill: var(--kc-line-strong); }

.kc-ruler { z-index: 0; }
.kc-band { width: 116px; color: color-mix(in srgb, var(--adv-muted) 82%, transparent); font-size: 0.59rem; }
.kc-band-stripe { border-radius: 15px; background: color-mix(in srgb, var(--adv-muted) 4%, transparent); }
.kc-generation-guides { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.kc-generation-guide {
    position: absolute;
    right: 0;
    left: 0;
    border-top: 1px dashed color-mix(in srgb, var(--adv-muted) 14%, transparent);
}
.kc-generation-guide span {
    position: absolute;
    top: -9px;
    left: 8px;
    max-width: 86px;
    padding: 2px 7px;
    border: 1px solid color-mix(in srgb, var(--adv-border) 68%, transparent);
    border-radius: 999px;
    background: color-mix(in srgb, var(--adv-surface) 96%, #07101f);
    color: color-mix(in srgb, var(--adv-muted) 76%, transparent);
    font-size: 0.52rem;
    font-weight: 760;
    letter-spacing: 0.055em;
    line-height: 1.35;
    text-align: center;
    text-transform: uppercase;
    white-space: nowrap;
}
.kc-lane-heads { z-index: 4; }
.kc-lane-head {
    top: -36px;
    min-height: 30px;
    padding: 4px 9px;
    border-bottom-width: 2px;
    border-bottom-color: color-mix(in srgb, var(--kc-blue) 48%, transparent);
    border-radius: 8px 8px 0 0;
}
.kc-lane-head:hover { background: color-mix(in srgb, var(--kc-blue) 10%, transparent); }

.kc-nodes { z-index: 3; }
.kc-node {
    display: flex;
    gap: 8px;
    padding: 9px 9px 9px 7px;
    border: 1px solid color-mix(in srgb, var(--adv-border) 88%, transparent);
    border-left: 3px solid color-mix(in srgb, var(--kc-blue) 64%, var(--adv-border));
    border-radius: 13px;
    background: color-mix(in srgb, var(--adv-surface) 96%, #0b1726);
    box-shadow: 0 9px 24px color-mix(in srgb, #020813 20%, transparent), inset 0 1px color-mix(in srgb, #fff 4%, transparent);
    cursor: pointer;
    transition: opacity 140ms ease, transform 140ms ease, box-shadow 140ms ease, border-color 140ms ease;
}
.kc-node:hover { z-index: 6; transform: translateY(-2px); border-color: color-mix(in srgb, var(--kc-blue) 44%, var(--adv-border)); box-shadow: 0 13px 32px color-mix(in srgb, #020813 28%, transparent); }
.kc-node:focus-visible { z-index: 7; outline: 2px solid var(--kc-blue); outline-offset: 3px; }
.kc-node.is-focus {
    z-index: 7;
    border-color: var(--kc-blue);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--kc-blue) 15%, transparent), 0 14px 36px color-mix(in srgb, #020813 30%, transparent);
}
.kc-node.is-dim { opacity: 0.24; }
.kc-node.is-search-miss { opacity: 0.12; filter: saturate(0.35); }
.kc-node.is-search-hit { z-index: 5; border-color: color-mix(in srgb, var(--kc-blue) 76%, var(--adv-border)); }
.kc-node.is-connect-source { border-color: var(--kc-blue); box-shadow: 0 0 0 4px color-mix(in srgb, var(--kc-blue) 17%, transparent); }
.kc-node.is-connect-target { animation: kc-target-pulse 1.8s ease-in-out infinite; }
.kc-node.is-blocked { border-style: dashed; background: color-mix(in srgb, var(--adv-surface) 82%, transparent); }
.kc-node.is-ghost { border-style: dotted; border-left-style: solid; }
.kc-node-open { padding: 0; pointer-events: none; }
.kc-avatar-wrap { width: 40px; height: 40px; }
.kc-avatar-wrap .kc-avatar { width: 32px; height: 32px; background: color-mix(in srgb, var(--kc-blue) 15%, var(--adv-inset)); }
.kc-node-name { font-size: 0.76rem; }
.kc-node-house,
.kc-node-meta { font-size: 0.63rem; }
.kc-node-tail { margin-left: auto; }
.kc-node .kc-add { opacity: 0; pointer-events: auto; }
.kc-node:hover .kc-add,
.kc-node:focus-within .kc-add,
.kc-node.is-focus .kc-add { opacity: 1; }
.kc-add { flex: 0 0 auto; }

/* Lineage is deliberately a family tree, not a second timeline. Portrait
   tiles keep names central, generations read left-to-right, and every branch
   lands on a visible union instead of disappearing into a dossier card. */
/* =========================================================================
   [NE:kin] THE BIRTH CHART — the Timeline view
   =========================================================================
   A dot plot: one row per character, one dot at the year they were born.
   Nothing else — no death, no alive state, no bar.

   The bars this replaced had to end somewhere, and for a living character the
   only available end was the world clock. A cast born around PY 812 against a
   present of PY 1123 became a single 311-year bar. A point cannot lie about
   duration, because it does not claim any.

   THE CHART IS THE PANE. Every top/left/width/height on a .kc-bc-* element
   arrives INLINE, from the kernel, which is built against a one-time viewport
   read. CSS may set anything here EXCEPT those four properties — the moment a
   stylesheet decides a position, the arithmetic and the picture disagree and
   the only way back is to measure the DOM, which is the class of bug this whole
   engine exists to remove. Pseudo-elements have their own boxes and are free.

   Colour comes ONLY from the --kc-* tokens. Never --adv-accent or --accent:
   they resolve to red in this skin, and a healthy chart then reads as a refused
   one. That bug already shipped on this exact surface. #e8a33d stays reserved
   for "unfinished / not drawable". */

/* MANDATORY, not cosmetic. The inline transform:scale() was the only thing
   giving .kc-canvas a stacking context, and a fitted birth chart has no
   transform — without this the chart's z-0..6 layers escape into the same
   context as the context card (z-20), the zoom cluster (z-15) and the legend. */
.kc-canvas[data-layout="births"] { isolation: isolate; }

.kc-viewport[data-layout="births"] {
    /* clientWidth must equal the width the chart was built for; a scrollbar
       appearing mid-render must not shave the measurement it was sized from. */
    scrollbar-gutter: stable;
    cursor: default;
    background-image:
        radial-gradient(120% 60% at 50% 0%, color-mix(in srgb, var(--kc-blue) 4%, transparent), transparent 62%),
        linear-gradient(180deg, color-mix(in srgb, #06101e 45%, transparent) 0%, transparent 20%,
            transparent 80%, color-mix(in srgb, #06101e 45%, transparent) 100%),
        radial-gradient(circle, color-mix(in srgb, var(--adv-muted) 12%, transparent) 1px, transparent 1px);
    background-size: auto, auto, 26px 26px;
}
/* The grab cursor promised a pan even when the chart fitted exactly. */
.kc-viewport[data-layout="births"].is-scrollable { cursor: grab; }
.kc-viewport[data-layout="births"].is-scrollable.is-panning { cursor: grabbing; }

/* The frame. An INSET RING, never a border: box-sizing is border-box globally
   and this element carries an inline height from the kernel, so a real 1px
   border would shrink the padding box and shift every child a pixel off the
   year it marks. */
.kc-births {
    position: relative;
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    border-radius: var(--adv-r-lg);
    background:
        linear-gradient(180deg, color-mix(in srgb, #ffffff 3%, transparent) 0%, transparent 34%),
        color-mix(in srgb, var(--adv-inset) 62%, transparent);
    box-shadow:
        inset 0 1px 0 color-mix(in srgb, #ffffff 5%, transparent),
        inset 0 0 0 1px color-mix(in srgb, var(--adv-border) 52%, transparent),
        0 1px 2px color-mix(in srgb, #020813 40%, transparent),
        0 26px 60px -18px color-mix(in srgb, #020813 62%, transparent);
}

/* The year band stays put while a long cast scrolls under it. Only possible
   now that the chart is a flex column rather than one scaled, absolutely
   layered box — losing the axis off the top of a forty-person chart was the
   worst part of scrolling instead of scaling. */
.kc-bc-axis {
    position: sticky;
    top: 0;
    z-index: 6;
    flex: 0 0 auto;
    overflow: hidden;
    border-radius: var(--adv-r-lg) var(--adv-r-lg) 0 0;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--adv-raised) 88%, transparent),
        color-mix(in srgb, var(--adv-raised) 62%, transparent));
    box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--adv-border) 46%, transparent);
}
.kc-bc-tick-label {
    position: absolute;
    bottom: 8px;
    transform: translateX(-50%);
    color: color-mix(in srgb, var(--adv-muted) 62%, transparent);
    font-size: 0.66rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.kc-bc-tick-label.is-major {
    color: color-mix(in srgb, var(--adv-muted) 88%, transparent);
    font-size: var(--adv-fs-eyebrow);
}
/* The pill flips sides; the LINE never moves. It also stops colliding with the
   tick years, which used to sit on the same 1px row. */
.kc-bc-chapter {
    position: absolute;
    top: 9px;
    padding: 3px 9px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--kc-green) 20%, var(--adv-surface));
    color: var(--kc-green);
    font-size: 0.62rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
}
.kc-bc-chapter.is-right { transform: translateX(6px); }
.kc-bc-chapter.is-left { transform: translateX(calc(-100% - 6px)); }

.kc-bc-plot { position: relative; flex: 0 0 auto; }

/* The horizontal axis line this chart never had. It reaches full strength at
   the first and last tick and softens only outside them, so unused axis reads
   as scale rather than as the chart running out. */
.kc-bc-foot {
    position: relative;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    padding: 0 var(--adv-4);
    color: color-mix(in srgb, var(--adv-muted) 62%, transparent);
    font-size: var(--adv-fs-eyebrow);
}
.kc-bc-foot::before {
    position: absolute;
    top: 0;
    left: var(--kc-bc-plot-left);
    width: var(--kc-bc-plot-w);
    height: 1px;
    content: "";
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--kc-line) 10%, transparent) 0,
        color-mix(in srgb, var(--kc-line) 36%, transparent) 4%,
        color-mix(in srgb, var(--kc-line) 36%, transparent) 96%,
        color-mix(in srgb, var(--kc-line) 10%, transparent) 100%);
}

/* Generation bands, behind everything. Births are a 1-D distribution and the
   structure worth seeing is CLUSTERING — a band is "these were born within a
   generation of each other", derived from gaps rather than asserted. */
.kc-bc-gens { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.kc-bc-gen {
    position: absolute;
    left: 0;
    right: 0;
    border-radius: 12px;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--kc-line) 10%, transparent),
        color-mix(in srgb, var(--kc-line) 4%, transparent));
    box-shadow: inset 0 1px 0 color-mix(in srgb, var(--kc-line) 14%, transparent);
}
/* A shelf that says nothing is just a stripe. The chip lives in the gutter the
   kernel reserves (metrics.gutterR) — do not reclaim that space to widen the
   plot or the chips and the last tick label clip. */
.kc-bc-gen-chip {
    position: absolute;
    right: 10px;
    top: 6px;
    display: grid;
    gap: 1px;
    max-width: 96px;
    padding: 2px 7px;
    border: 1px solid color-mix(in srgb, var(--adv-border) 68%, transparent);
    border-radius: 999px;
    background: color-mix(in srgb, var(--adv-surface) 96%, #07101f);
    font-size: 0.52rem;
    font-weight: 760;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.kc-bc-gen-chip i {
    color: color-mix(in srgb, var(--adv-muted) 52%, transparent);
    font-size: 0.86em;
    font-weight: 640;
    font-style: normal;
}

/* Gridlines recede over a FIXED 120px, then hold. A percentage ramp is
   calibrated for a short sparse plot and fades the line to nothing across the
   top half of a forty-person one, taking the axis reference away from most of
   the data. */
.kc-bc-grid { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
.kc-bc-tick {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--adv-border) 16%, transparent) 0,
        color-mix(in srgb, var(--adv-border) 40%, transparent) 120px,
        color-mix(in srgb, var(--adv-border) 40%, transparent) 100%);
}
.kc-bc-tick.is-major {
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--adv-border) 26%, transparent) 0,
        color-mix(in srgb, var(--adv-border) 64%, transparent) 120px,
        color-mix(in srgb, var(--adv-border) 64%, transparent) 100%);
}
/* Only drawn in the fallback, where there is no axis band to hold the years. */
.kc-bc-tick span {
    position: absolute;
    top: 3px;
    left: 50%;
    transform: translateX(-50%);
    color: color-mix(in srgb, var(--adv-muted) 68%, transparent);
    font-size: 0.62rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Descent arcs. The horizontal distance one covers IS the parent's age at that
   birth, so an impossible gap reads as a shape before it reads as a number. */
.kc-bc-links { position: absolute; inset: 0; pointer-events: none; z-index: 2; overflow: visible; }
.kc-bc-descent { fill: none; stroke: color-mix(in srgb, var(--kc-line) 34%, transparent); stroke-width: 1.4; }
.kc-bc-descent.is-care { stroke: var(--kc-line-care); stroke-dasharray: 4 5; }
.kc-bc-descent.is-problem { stroke: var(--kc-refused); stroke-width: 2; stroke-dasharray: none; }
.kc-bc-descent.is-focus { stroke: color-mix(in srgb, var(--kc-line-strong) 70%, transparent); stroke-width: 2; }
.kc-bc-descent-age {
    fill: color-mix(in srgb, var(--adv-muted) 70%, transparent);
    font-size: 0.6rem;
    font-weight: 700;
    text-anchor: middle;
}

/* The only vertical line allowed to be bright: the moment being written. The
   world clock is deliberately absent — it is what made the old axis useless.
   Under the rows, so it can never swallow a click. */
.kc-bc-marker {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 2px;
    z-index: 3;
    pointer-events: none;
    background: color-mix(in srgb, var(--kc-green) 60%, transparent);
}
/* The one glow in the chart, and it stays under the dots' contrast: the marker
   is a reference, the dots are the observations. */
.kc-bc-marker.is-focus { box-shadow: 0 0 12px color-mix(in srgb, var(--kc-green) 26%, transparent); }
.kc-bc-marker.is-focus::before {
    position: absolute;
    inset-block: 0;
    left: -38px;
    right: -38px;
    content: "";
    pointer-events: none;
    background: radial-gradient(38px 100% at 50% 46%,
        color-mix(in srgb, var(--kc-green) 10%, transparent), transparent 70%);
}
.kc-bc-marker span {
    position: absolute;
    top: 4px;
    left: 6px;
    padding: 2px 7px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--kc-green) 20%, var(--adv-surface));
    color: var(--kc-green);
    font-size: 0.56rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
}

.kc-bc-rows { position: absolute; inset: 0; z-index: 4; }
.kc-bc-row {
    position: absolute;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    transition: background-color 140ms ease;
}
.kc-bc-row:nth-child(even) {
    border-radius: 10px;
    background: color-mix(in srgb, var(--kc-line) 3.5%, transparent);
}
/* A leader from the name to a dot that can be 600px away. The dot sits ON it,
   so the eye never has to guess which row a mark belongs to. --kc-bc-x is
   written inline per row from the kernel's x; no geometry is decided here. */
.kc-bc-row::before {
    position: absolute;
    top: 50%;
    left: var(--kc-bc-plot-left);
    width: max(0px, calc(var(--kc-bc-x) - var(--kc-bc-plot-left)));
    height: 1px;
    content: "";
    background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--kc-line) 22%, transparent));
}
.kc-bc-row:hover { background: color-mix(in srgb, var(--kc-blue) 5%, transparent); }
.kc-bc-row:hover .kc-bc-dot { transform: translate(-50%, -50%) scale(1.18); }

/* DIM BY COOLING, NOT BY ERASURE. 0.22 opacity on a 13px ring destroys the one
   comparison a dot plot exists for — where these people sit relative to each
   other — and takes the click target with it. The unrelated rows step back in
   weight and colour instead, and stay readable and clickable. */
.kc-bc-row.is-dim { opacity: 1; }
.kc-bc-row.is-dim .kc-bc-name,
.kc-bc-row.is-dim .kc-bc-derived { color: color-mix(in srgb, var(--adv-muted) 38%, transparent); }
.kc-bc-row.is-dim .kc-bc-year { color: color-mix(in srgb, var(--adv-muted) 26%, transparent); }
.kc-bc-row.is-dim .kc-bc-dot {
    border-color: color-mix(in srgb, var(--kc-line) 34%, transparent);
    transform: translate(-50%, -50%) scale(0.82);
}
.kc-bc-row.is-dim::before { background: none; }
/* A search is a filter, and vanishing is the correct answer there. */
.kc-bc-row.is-search-miss { opacity: 0.1; }

.kc-bc-label {
    position: absolute;
    left: 0;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
    height: 100%;
    /* The dossier carries two or three lines now; ragging them against a 300px
       column reads as an accident. Width still arrives inline. */
    padding: 0 12px;
    border: 0;
    background: transparent;
    color: var(--adv-ink);
    font: inherit;
    text-align: left;
    cursor: pointer;
    overflow: hidden;
}
.kc-bc-dossier { display: grid; gap: 1px; min-width: 0; }
.kc-bc-face { flex: 0 0 auto; }
/* Ink scales off ONE inline custom property, so a taller row is a bigger row
   rather than a taller row with the same small type in it. */
.kc-bc-name {
    display: flex;
    align-items: baseline;
    gap: 6px;
    font-size: clamp(0.78rem, calc(var(--kc-bc-row-h, 30px) * 0.16), 1rem);
    font-weight: 620;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.kc-bc-derived {
    color: color-mix(in srgb, var(--adv-muted) 76%, transparent);
    font-size: clamp(0.64rem, calc(var(--kc-bc-row-h, 30px) * 0.115), 0.8rem);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.kc-bc-house {
    flex: 0 0 auto;
    color: color-mix(in srgb, var(--adv-muted) 60%, transparent);
    font-size: 0.66rem;
    font-weight: 560;
}
.kc-canvas[data-row-tier="card"] .kc-bc-face { width: 44px; height: 44px; }
.kc-canvas[data-row-tier="full"] .kc-bc-face { width: 32px; height: 32px; }
.kc-canvas[data-row-tier="compact"] .kc-bc-face,
.kc-canvas[data-row-tier="dense"] .kc-bc-face { display: none; }
.kc-canvas[data-row-tier="dense"] .kc-bc-house { display: none; }
.kc-bc-label:hover .kc-bc-name { color: var(--kc-blue); }
.kc-bc-label:focus-visible { outline: 2px solid var(--kc-blue); outline-offset: 2px; border-radius: 6px; }

/* The mark. A ring rather than a filled disc: it sits over a gridline without
   hiding it, and it reads as a precise position rather than a blob. */
/* EVERY state that touches `transform` here must re-state translate(-50%,-50%),
   or the dot snaps half its width off the year it marks. */
.kc-bc-dot {
    position: absolute;
    top: 50%;
    width: var(--kc-bc-dot, 13px);
    height: var(--kc-bc-dot, 13px);
    padding: 0;
    transform: translate(-50%, -50%);
    border: clamp(2.5px, calc(var(--kc-bc-row-h, 30px) * 0.032), 4px) solid var(--kc-blue);
    border-radius: 50%;
    background: color-mix(in srgb, var(--adv-surface) 90%, #0b1726);
    cursor: pointer;
    transition: transform 130ms ease, border-color 130ms ease;
}
.kc-bc-dot:hover { transform: translate(-50%, -50%) scale(1.35); }
.kc-bc-dot:focus-visible { outline: 2px solid var(--kc-blue); outline-offset: 3px; }
/* Unfinished carries the ring's amber, so "needs work" is one colour sitewide. */
.kc-bc-dot.is-blocked { border-color: #e8a33d; }
/* At the row floor the mark is 13px. A fingertip is not, so the hit area is
   grown past the ink rather than the ink past legibility. */
.kc-canvas[data-row-tier="dense"] .kc-bc-dot::after { position: absolute; inset: -8px; content: ""; }
.kc-bc-year {
    position: absolute;
    top: 50%;
    left: calc(var(--kc-bc-dot, 13px) + 6px);
    transform: translateY(-50%);
    color: color-mix(in srgb, var(--adv-muted) 82%, transparent);
    font-size: clamp(0.62rem, calc(var(--kc-bc-row-h, 30px) * 0.115), 0.78rem);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    pointer-events: none;
}
/* Focus is a halo, not a recolour — the old rule set border-color to the colour
   the dot already was, so selecting a row changed nothing you could see. */
.kc-bc-row.is-focus { background: color-mix(in srgb, var(--kc-blue) 8%, transparent); }
.kc-bc-row.is-focus::before {
    background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--kc-line) 45%, transparent));
}
.kc-bc-row.is-focus .kc-bc-dot {
    transform: translate(-50%, -50%) scale(1.3);
    box-shadow: 0 0 0 5px color-mix(in srgb, var(--kc-blue) 12%, transparent);
}
.kc-bc-row.is-focus .kc-bc-year { color: var(--adv-ink); }

/* Off-scale and undated people are NAMED, never squeezed onto the axis edge and
   never silently dropped — a dot pinned to the end would read as a birth year
   the character does not have. */
/* The side padding keeps the rails clear of the legend and the zoom / minimap
   cluster, which float over the canvas's bottom corners. */
.kc-bc-trays { display: flex; flex-direction: column; gap: 8px; padding: 14px 200px 0 160px; }
/* flex-wrap: nowrap and the fixed 44px are LOAD-BEARING. metrics.trayH is exact
   arithmetic — one rail, one line — and that is what lets the trays sit inside
   the canvas's height budget instead of hanging off the bottom of it. Let a
   tray wrap and the kernel's height silently becomes a lie. */
.kc-bc-tray {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 7px;
    box-sizing: border-box;
    height: 44px;
    padding: 0 13px;
    overflow-x: auto;
    overflow-y: hidden;
    border: 1px solid color-mix(in srgb, var(--adv-border) 70%, transparent);
    border-radius: 12px;
    background: var(--adv-raised);
    box-shadow: var(--adv-shadow-1);
    scrollbar-width: thin;
}
.kc-bc-tray-head { flex: 0 0 auto; }
.kc-bc-tray-head {
    color: color-mix(in srgb, var(--adv-muted) 84%, transparent);
    font-size: 0.6rem;
    font-weight: 800;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}
.kc-bc-chip {
    flex: 0 0 auto;
    padding: 4px 10px;
    border: 1px solid color-mix(in srgb, var(--adv-border) 84%, transparent);
    border-radius: 999px;
    background: color-mix(in srgb, var(--adv-surface) 96%, transparent);
    color: var(--adv-ink);
    font: inherit;
    font-size: 0.72rem;
    cursor: pointer;
}
.kc-bc-chip:hover { border-color: var(--kc-blue); color: var(--kc-blue); }
/* The only one of this block's four buttons that had no focus ring. */
.kc-bc-chip:focus-visible { outline: 2px solid var(--kc-blue); outline-offset: 2px; }
.kc-bc-tray-note {
    /* Was flex: 1 1 100%, which forced a second line and broke the arithmetic
       the tray height is computed from. */
    flex: 0 0 auto;
    color: color-mix(in srgb, var(--adv-muted) 62%, transparent);
    font-size: 0.63rem;
}

/* [NE:kin] The incomplete count, as a control. Amber because it is the same
   signal the completeness ring uses for "not finished" — a creator should not
   have to learn two colours for one idea. Underlined so it reads as clickable
   inside a line of plain summary text, where a bare colour change would not. */
.kc-incomplete-chip {
    padding: 1px 5px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: #e8a33d;
    font: inherit;
    font-weight: 700;
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, #e8a33d 45%, transparent);
    text-underline-offset: 2px;
    cursor: pointer;
    transition: background 130ms ease, color 130ms ease;
}
.kc-incomplete-chip:hover { background: color-mix(in srgb, #e8a33d 14%, transparent); }
.kc-incomplete-chip:focus-visible { outline: 2px solid var(--kc-blue); outline-offset: 2px; }
.kc-incomplete-chip.is-on {
    background: color-mix(in srgb, #e8a33d 20%, transparent);
    color: #f5c173;
    text-decoration: none;
}

/* [NE:kin] The band chip carries two lines: the years it holds, and the
   generation ordinal underneath in a quieter tone. Years are what a creator can
   act on; the ordinal is what explains a shared shelf. */
.kc-generation-guide span {
    display: grid;
    gap: 1px;
    max-width: 128px;
    line-height: 1.25;
}
.kc-generation-guide span i {
    font-style: normal;
    font-size: 0.86em;
    font-weight: 640;
    letter-spacing: 0.03em;
    color: color-mix(in srgb, var(--adv-muted) 52%, transparent);
}

.kc-canvas[data-layout="lineage"] .kc-links { z-index: 2; }
.kc-canvas[data-layout="lineage"] .kc-link {
    stroke-width: 2;
    /* MUST stay 1. This selector is more specific than `.kc-link`, so an
       opacity here silently defeats the opaque-stroke rule above — and each
       child's branch redraws the shared trunk, so a translucent stroke makes
       the trunk darker once per sibling. Four children, four times as dark as
       their own stubs. Recede with colour, never with alpha. */
    opacity: 1;
}
.kc-canvas[data-layout="lineage"] .kc-link.is-related { stroke-width: 2.75; }
.kc-canvas[data-layout="lineage"] .kc-link.is-union,
.kc-canvas[data-layout="lineage"] .kc-link.is-partner:not(.is-sibling) {
    stroke-width: 3;
    stroke-dasharray: none;
}
.kc-canvas[data-layout="lineage"] .kc-link.is-betrothed { stroke-dasharray: 7 4; }
/* Co-parents: they share a child, but no marriage is recorded. The bar exists
   so the children have something real to descend from; it is quieter than a
   stated marriage so the chart does not assert a couple nobody typed. */
.kc-link.is-union.is-coparent,
.kc-canvas[data-layout="lineage"] .kc-link.is-union.is-coparent {
    stroke: color-mix(in srgb, var(--kc-line) 62%, transparent);
    stroke-width: 2;
    stroke-dasharray: 3 4;
}
/* [NE:kin] THE PORTRAIT TILE.
   Reworked 2026-08-12. Three things changed and each has a reason:

   1. The flat 3px accent stripe across the top is gone. It painted the same
      blue on every card regardless of state, so it carried no information —
      and the completeness ring right beneath it is the element that DOES.
      Two competing accents on a 130px card is one too many.
   2. A top-lit surface gradient instead of a flat fill. A card lit from above
      reads as a physical object at a glance; a flat rectangle reads as a div.
   3. Layered shadow — a wide ambient one for depth plus a tight contact one
      directly under the card. A single large blur is the thing that makes
      cheap UI look like it is floating in soup. */
.kc-canvas[data-layout="lineage"] .kc-node {
    align-items: center;
    justify-content: flex-start;
    flex-direction: column;
    gap: 7px;
    padding: 14px 11px 12px;
    border: 1px solid color-mix(in srgb, var(--adv-border) 88%, transparent);
    border-radius: 16px;
    background:
        linear-gradient(180deg,
            color-mix(in srgb, #ffffff 6%, transparent) 0%,
            transparent 42%),
        color-mix(in srgb, var(--adv-surface) 96%, #0b1726);
    box-shadow:
        0 1px 2px color-mix(in srgb, #020813 40%, transparent),
        0 12px 28px -8px color-mix(in srgb, #020813 45%, transparent),
        inset 0 1px color-mix(in srgb, #fff 7%, transparent);
    text-align: center;
}
.kc-canvas[data-layout="lineage"] .kc-node:hover {
    transform: translateY(-3px);
    border-color: color-mix(in srgb, var(--kc-blue) 40%, var(--adv-border));
    box-shadow:
        0 1px 2px color-mix(in srgb, #020813 40%, transparent),
        0 20px 40px -10px color-mix(in srgb, #020813 55%, transparent),
        inset 0 1px color-mix(in srgb, #fff 9%, transparent);
}
/* The focus ring reads as a halo around the card rather than a recolour of its
   border, so a focused card still shows its own completeness state. */
.kc-canvas[data-layout="lineage"] .kc-node.is-focus {
    border-color: color-mix(in srgb, var(--kc-blue) 70%, var(--adv-border));
    box-shadow:
        0 0 0 3px color-mix(in srgb, var(--kc-blue) 18%, transparent),
        0 1px 2px color-mix(in srgb, #020813 40%, transparent),
        0 22px 44px -10px color-mix(in srgb, #020813 55%, transparent);
}
/* A ghost is INFERRED — placed by family, no year of its own. Rendering it at
   the same weight as a stated person would let a guess pass for a fact. */
.kc-canvas[data-layout="lineage"] .kc-node.is-ghost {
    border-style: dashed;
    border-color: color-mix(in srgb, var(--adv-border) 70%, transparent);
    background: color-mix(in srgb, var(--adv-surface) 82%, #0b1726);
    box-shadow: 0 1px 2px color-mix(in srgb, #020813 30%, transparent);
}
.kc-canvas[data-layout="lineage"] .kc-node:hover {
    transform: translateY(-3px) scale(1.015);
    box-shadow: 0 16px 38px color-mix(in srgb, #020813 34%, transparent), 0 0 0 1px color-mix(in srgb, var(--kc-blue) 15%, transparent);
}
.kc-canvas[data-layout="lineage"] .kc-node[data-house="0"] { border-top-color: #4c7dfd; }
.kc-canvas[data-layout="lineage"] .kc-node[data-house="1"] { border-top-color: #16a34a; }
.kc-canvas[data-layout="lineage"] .kc-node[data-house="2"] { border-top-color: #d97706; }
.kc-canvas[data-layout="lineage"] .kc-node[data-house="3"] { border-top-color: #9333ea; }
.kc-canvas[data-layout="lineage"] .kc-node[data-house="4"] { border-top-color: #0891b2; }
.kc-canvas[data-layout="lineage"] .kc-node[data-house="5"] { border-top-color: #db2777; }
.kc-canvas[data-layout="lineage"] .kc-node[data-house="6"] { border-top-color: #65a30d; }
.kc-canvas[data-layout="lineage"] .kc-node[data-house="7"] { border-top-color: #b45309; }
.kc-canvas[data-layout="lineage"] .kc-node-open {
    width: 100%;
    flex: 0 0 auto;
    flex-direction: column;
    justify-content: center;
    gap: 7px;
}
.kc-canvas[data-layout="lineage"] .kc-avatar-wrap { width: 50px; height: 50px; }
.kc-canvas[data-layout="lineage"] .kc-avatar-wrap .kc-avatar {
    width: 41px;
    height: 41px;
    font-size: 0.73rem;
    box-shadow: inset 0 0 0 1px color-mix(in srgb, #fff 6%, transparent);
}
.kc-canvas[data-layout="lineage"] .kc-node-body { width: 100%; align-items: center; }
.kc-canvas[data-layout="lineage"] .kc-node-name {
    width: 100%;
    font-size: 0.78rem;
    line-height: 1.2;
    text-align: center;
}
.kc-canvas[data-layout="lineage"] .kc-node-house { display: none; }
.kc-canvas[data-layout="lineage"] .kc-node-meta {
    max-width: 100%;
    margin-top: 2px;
    font-size: 0.59rem;
    line-height: 1.25;
    text-align: center;
}
.kc-canvas[data-layout="lineage"] .kc-node-tail {
    position: absolute;
    top: 7px;
    right: 7px;
    margin: 0;
}
.kc-canvas[data-layout="lineage"] .kc-degree,
.kc-canvas[data-layout="lineage"] .kc-ring,
.kc-canvas[data-layout="lineage"] .kc-seam { display: none; }
.kc-canvas[data-layout="lineage"] .kc-add {
    width: 23px;
    height: 23px;
    border-color: color-mix(in srgb, var(--kc-blue) 34%, var(--adv-border));
    background: color-mix(in srgb, var(--adv-raised) 96%, transparent);
    color: var(--kc-blue);
    box-shadow: 0 4px 12px color-mix(in srgb, #020813 28%, transparent);
}
.kc-canvas[data-layout="lineage"][data-tier="min"] .kc-node { gap: 4px; padding: 8px 7px 7px; }
.kc-canvas[data-layout="lineage"][data-tier="min"] .kc-avatar-wrap { width: 38px; height: 38px; }
.kc-canvas[data-layout="lineage"][data-tier="min"] .kc-avatar-wrap .kc-avatar { width: 31px; height: 31px; font-size: 0.61rem; }
.kc-canvas[data-layout="lineage"][data-tier="min"] .kc-node-name { font-size: 0.67rem; }
.kc-canvas[data-layout="lineage"][data-tier="min"] .kc-node-meta { display: none; }
.kc-canvas[data-layout="lineage"][data-tier="max"] .kc-avatar-wrap { width: 56px; height: 56px; }
.kc-canvas[data-layout="lineage"][data-tier="max"] .kc-avatar-wrap .kc-avatar { width: 46px; height: 46px; font-size: 0.78rem; }
.kc-canvas[data-layout="lineage"][data-tier="max"] .kc-node-name { font-size: 0.86rem; }

.kc-context-card {
    position: absolute;
    z-index: 20;
    top: 18px;
    right: 18px;
    width: min(294px, calc(100% - 32px));
    margin: 0;
    padding: 15px;
    border: 1px solid color-mix(in srgb, var(--kc-blue) 25%, var(--adv-border));
    border-radius: 15px;
    background: color-mix(in srgb, var(--adv-raised) 96%, #0a1423);
    box-shadow: 0 22px 55px color-mix(in srgb, #010713 38%, transparent);
    cursor: default;
    animation: kc-card-in 170ms ease-out;
}
.kc-context-close { position: absolute; top: 10px; right: 10px; display: grid; place-items: center; width: 27px; height: 27px; border: 0; border-radius: 8px; background: transparent; color: var(--adv-muted); cursor: pointer; }
.kc-context-close:hover { background: var(--adv-inset); color: var(--adv-ink); }
.kc-context-close svg { width: 14px; height: 14px; }
.kc-context-person { display: flex; align-items: center; gap: 10px; padding-right: 28px; }
.kc-context-person > span,
.kc-command-avatar { display: grid; place-items: center; width: 42px; height: 42px; flex: 0 0 auto; border-radius: 13px; background: color-mix(in srgb, var(--kc-blue) 15%, var(--adv-inset)); color: var(--kc-blue); font-size: 0.72rem; font-weight: 850; }
.kc-context-person > div { min-width: 0; display: flex; flex-direction: column; }
.kc-context-person strong { overflow: hidden; font-size: 0.82rem; text-overflow: ellipsis; white-space: nowrap; }
.kc-context-person small { margin-top: 4px; color: var(--adv-muted); font-size: 0.64rem; }
.kc-context-actions { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; margin-top: 13px; }
.kc-context-actions button { min-width: 0; min-height: 43px; flex-direction: column; padding: 5px 3px; border-radius: 9px; color: var(--adv-muted); font-size: 0.58rem; }
.kc-context-actions button:hover { border-color: color-mix(in srgb, var(--kc-blue) 45%, var(--adv-border)); color: var(--adv-ink); }
.kc-context-actions button svg { width: 14px; height: 14px; }
.kc-context-actions button.is-danger:hover { border-color: color-mix(in srgb, #e5484d 55%, var(--adv-border)); color: #e86a6e; }
.kc-context-relatives { display: grid; gap: 8px; margin-top: 13px; padding-top: 11px; border-top: 1px solid var(--adv-border); }
.kc-context-relatives > div { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.kc-context-relatives > div > span { width: 58px; color: var(--adv-muted); font-size: 0.58rem; font-weight: 750; text-transform: uppercase; }
.kc-context-relatives button { padding: 3px 7px; border: 1px solid var(--adv-border); border-radius: 999px; background: var(--adv-inset); color: var(--adv-ink); font: inherit; font-size: 0.61rem; cursor: pointer; }
.kc-context-relatives p { margin: 0; color: var(--adv-muted); font-size: 0.68rem; }
.kc-edge-card h3 { margin: 5px 28px 6px 0; font-size: 0.8rem; line-height: 1.45; }
.kc-edge-card h3 span { color: var(--adv-muted); font-weight: 500; }
.kc-edge-card > p { margin: 0; color: var(--adv-muted); font-size: 0.66rem; line-height: 1.5; }
.kc-edge-card .kc-context-actions { grid-template-columns: 1fr 1fr 1fr; }

.kc-canvas-controls {
    position: absolute;
    z-index: 15;
    right: 16px;
    bottom: 16px;
    display: inline-flex;
    gap: 3px;
    margin: 0;
    padding: 4px;
    border: 1px solid color-mix(in srgb, var(--adv-border) 85%, transparent);
    border-radius: 11px;
    background: color-mix(in srgb, var(--adv-raised) 94%, transparent);
    box-shadow: 0 12px 32px color-mix(in srgb, #010713 28%, transparent);
    cursor: default;
}
.kc-canvas-controls button { min-width: 30px; height: 30px; padding: 0 7px; border: 0; border-radius: 7px; background: transparent; color: var(--adv-muted); font-size: 0.62rem; }
.kc-canvas-controls button:hover { background: var(--adv-inset); color: var(--adv-ink); }
.kc-canvas-controls button svg { width: 13px; height: 13px; }
.kc-canvas-controls > span { width: 1px; margin: 5px 2px; background: var(--adv-border); }

.kc-legend {
    position: absolute;
    z-index: 14;
    left: 16px;
    bottom: 16px;
    margin: 0;
    padding: 0;
    border: 1px solid color-mix(in srgb, var(--adv-border) 82%, transparent);
    border-radius: 10px;
    background: color-mix(in srgb, var(--adv-raised) 94%, transparent);
    box-shadow: 0 10px 28px color-mix(in srgb, #010713 22%, transparent);
    color: var(--adv-muted);
    cursor: default;
    display: block;
}
.kc-legend summary { display: flex; align-items: center; gap: 6px; padding: 8px 10px; list-style: none; font-size: 0.62rem; font-weight: 720; cursor: pointer; }
.kc-legend summary::-webkit-details-marker { display: none; }
.kc-legend summary svg { width: 13px; height: 13px; }
.kc-legend > div { display: grid; gap: 7px; min-width: 220px; padding: 0 11px 10px; font-size: 0.61rem; }
.kc-legend-count { margin: 2px 0 0; padding-top: 7px; border-top: 1px solid var(--adv-border); }

.kc-minimap {
    position: absolute;
    z-index: 14;
    right: 16px;
    bottom: 64px;
    width: 154px;
    height: 94px;
    margin: 0;
    padding: 7px;
    border: 1px solid color-mix(in srgb, var(--adv-border) 82%, transparent);
    border-radius: 11px;
    background: color-mix(in srgb, var(--adv-raised) 92%, transparent);
    box-shadow: 0 10px 28px color-mix(in srgb, #010713 24%, transparent);
    cursor: crosshair;
}
.kc-minimap-map { position: relative; display: block; width: 100%; height: 100%; overflow: hidden; border-radius: 7px; background: color-mix(in srgb, var(--adv-inset) 75%, transparent); }
.kc-minimap-map i { position: absolute; min-width: 3px; min-height: 3px; border-radius: 2px; background: color-mix(in srgb, var(--kc-blue) 55%, var(--adv-muted)); opacity: 0.7; }
.kc-minimap-map b { position: absolute; min-width: 10px; min-height: 8px; border: 1px solid var(--kc-blue); border-radius: 3px; background: color-mix(in srgb, var(--kc-blue) 10%, transparent); pointer-events: none; }

.kc-canvas-empty {
    position: absolute;
    z-index: 10;
    left: 50%;
    top: 50%;
    width: min(370px, calc(100% - 40px));
    padding: 28px;
    border: 1px solid color-mix(in srgb, var(--adv-border) 75%, transparent);
    border-radius: 18px;
    background: color-mix(in srgb, var(--adv-raised) 88%, transparent);
    text-align: center;
    transform: translate(-50%, -50%);
    cursor: default;
}
.kc-canvas-empty > svg { width: 30px; height: 30px; color: var(--kc-blue); }
.kc-canvas-empty h3 { margin: 12px 0 5px; font-size: 0.94rem; }
.kc-canvas-empty p { margin: 0 auto 16px; color: var(--adv-muted); font-size: 0.7rem; line-height: 1.6; }

.kc-command-panel { display: grid; gap: 14px; }
.kc-command-guided { display: flex; align-items: center; gap: 11px; width: 100%; padding: 11px; border: 1px solid color-mix(in srgb, var(--kc-blue) 25%, var(--adv-border)); border-radius: 12px; background: color-mix(in srgb, var(--kc-blue) 7%, var(--adv-surface)); color: inherit; font: inherit; text-align: left; cursor: pointer; }
.kc-command-guided > span:nth-child(2) { min-width: 0; display: flex; flex: 1; flex-direction: column; }
.kc-command-guided strong { font-size: 0.78rem; }
.kc-command-guided small { margin-top: 3px; color: var(--adv-muted); font-size: 0.66rem; }
.kc-command-guided > svg { width: 16px; height: 16px; color: var(--adv-muted); }
.kc-command-divider { display: flex; align-items: center; gap: 9px; color: var(--adv-muted); font-size: 0.63rem; }
.kc-command-divider::before,
.kc-command-divider::after { height: 1px; flex: 1; background: var(--adv-border); content: ""; }
.kc-command-form { display: grid; gap: 7px; }
.kc-command-form > label { font-size: 0.7rem; font-weight: 720; }
.kc-command-form > div { display: flex; gap: 7px; }
.kc-command-form input { min-width: 0; flex: 1; padding: 10px 11px; border: 1px solid var(--adv-border); border-radius: 9px; background: var(--adv-surface); color: var(--adv-ink); font: inherit; }
.kc-command-form p { margin: 0; color: var(--adv-muted); font-size: 0.63rem; line-height: 1.5; }

.kc-workspace.is-rail-collapsed { --kc-rail-w: 70px; }
.kc-workspace.is-rail-collapsed .kc-family-rail { align-items: center; }
.kc-workspace.is-rail-collapsed .kc-rail-head { grid-template-columns: 34px; justify-content: center; padding-inline: 0; }
.kc-workspace.is-rail-collapsed .kc-rail-title,
.kc-workspace.is-rail-collapsed .kc-family-search,
.kc-workspace.is-rail-collapsed .kc-family-copy,
.kc-workspace.is-rail-collapsed .kc-avatar-stack,
.kc-workspace.is-rail-collapsed .kc-family-alert,
.kc-workspace.is-rail-collapsed .kc-rail-label,
.kc-workspace.is-rail-collapsed .kc-unlinked,
.kc-workspace.is-rail-collapsed .kc-rail-add span,
.kc-workspace.is-rail-collapsed .kc-rail-close { display: none; }
.kc-workspace.is-rail-collapsed .kc-family-nav { width: 100%; padding-inline: 8px; }
.kc-workspace.is-rail-collapsed .kc-family-row { grid-template-columns: 34px; justify-content: center; padding-inline: 8px; }
.kc-workspace.is-rail-collapsed .kc-rail-add { width: 40px; padding: 0; margin-inline: auto; }
.kc-workspace.is-rail-collapsed .kc-rail-head::after { position: absolute; inset: 12px 8px auto auto; width: 24px; height: 24px; content: ""; }

@keyframes kc-card-in { from { opacity: 0; transform: translateY(-5px) scale(0.98); } to { opacity: 1; transform: none; } }
@keyframes kc-target-pulse { 0%, 100% { border-color: var(--adv-border); } 50% { border-color: color-mix(in srgb, var(--kc-blue) 68%, var(--adv-border)); } }

@media (max-width: 1180px) {
    .kc-workspace { --kc-rail-w: 210px; }
    .kc-person-search { width: 112px; }
    .kc-tool-btn span { display: none; }
    .kc-tool-btn { width: 35px; padding: 0; }
    .kc-canvas-title { min-width: 145px; }
    .kc-avatar-stack { display: none; }
}

@media (max-width: 900px) {
    .kc-workspace { grid-template-columns: minmax(0, 1fr); height: calc(100vh - 190px); min-height: 570px; }
    .kc-family-rail {
        position: absolute;
        inset: 0 auto 0 0;
        width: min(280px, calc(100% - 48px));
        box-shadow: 24px 0 60px color-mix(in srgb, #010713 42%, transparent);
        transform: translateX(-105%);
    }
    .kc-workspace.is-mobile-rail-open .kc-family-rail { transform: translateX(0); }
    .kc-workspace.is-mobile-rail-open::after { position: absolute; z-index: 11; inset: 0; background: color-mix(in srgb, #020814 44%, transparent); content: ""; }
    .kc-mobile-families { display: inline-flex; }
    .kc-canvas-toolbar { padding-left: 12px; }
    .kc-person-search { display: none; }
    .kc-workspace.is-rail-collapsed .kc-family-rail { align-items: stretch; }
    .kc-workspace.is-rail-collapsed .kc-rail-title,
    .kc-workspace.is-rail-collapsed .kc-family-search,
    .kc-workspace.is-rail-collapsed .kc-family-copy,
    .kc-workspace.is-rail-collapsed .kc-avatar-stack,
    .kc-workspace.is-rail-collapsed .kc-family-alert,
    .kc-workspace.is-rail-collapsed .kc-rail-label,
    .kc-workspace.is-rail-collapsed .kc-unlinked,
    .kc-workspace.is-rail-collapsed .kc-rail-add span,
    .kc-workspace.is-rail-collapsed .kc-rail-close { display: initial; }
}

@media (max-width: 620px) {
    /* Below this the minimap is already hidden and the context card is a fixed
       bottom sheet, so the medallion is the first thing that has to go. */
    .kc-bc-trays { padding: 10px 9px 0; }
    .kc-canvas[data-row-tier="card"] .kc-bc-face,
    .kc-canvas[data-row-tier="full"] .kc-bc-face { display: none; }
    .kc-workspace { height: calc(100vh - 150px); min-height: 520px; border-radius: 13px; }
    .kc-canvas-toolbar { min-height: 68px; gap: 8px; padding: 8px; }
    .kc-canvas-title { min-width: 0; }
    .kc-canvas-title h2 { max-width: 135px; font-size: 0.85rem; }
    .kc-canvas-title p { max-width: 145px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .kc-layout-switch button { padding: 0 7px; }
    .kc-toolbar-actions > .kc-icon-btn { display: none; }
    .kc-minimap { display: none; }
    .kc-context-card { position: fixed; inset: auto 10px 10px; float: none; width: auto; margin: 0; border-radius: 16px; }
    .kc-canvas-controls { right: 9px; bottom: 9px; margin-right: 9px; margin-bottom: 9px; }
    .kc-legend { left: 9px; bottom: 9px; margin-left: 9px; margin-bottom: 9px; }
    .kc-connect-banner { align-items: flex-start; flex-wrap: wrap; }
    .kc-connect-banner button { margin-left: 24px; }
    .kc-command-form > div { flex-direction: column; }
    .kc-generation-guide span { left: 3px; max-width: 60px; overflow: hidden; text-overflow: ellipsis; }
}

@media (pointer: coarse) {
    .kc-canvas[data-layout="lineage"] .kc-node .kc-add { opacity: 0.82; }
}

@media (prefers-reduced-motion: reduce) {
    .kc-family-rail,
    .kc-family-row,
    .kc-node,
    /* The birth chart's row and dot transitions leaked through this block from
       the day it shipped; the new hover and focus states would widen the gap. */
    .kc-bc-row,
    .kc-bc-dot,
    .kc-bc-label,
    .kc-bc-chip,
    .kc-link { transition: none; }
    .kc-node.is-connect-target { animation: none; }
    .kc-context-card { animation: none; }
}
