:root {
    --bg: #faf9f7;
    --surface: #ffffff;
    --ink: #24211d;
    --ink-muted: #6b645c;
    --line: #e2ddd6;
    --accent: #7a5c3e;
    --accent-soft: #f2ebe2;
    --danger: #a33a2a;
    --radius: 10px;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #1b1916;
        --surface: #24211d;
        --ink: #ece7e0;
        --ink-muted: #a39a8f;
        --line: #3a352f;
        --accent: #c9a37a;
        --accent-soft: #332c24;
        --danger: #e08a7a;
    }
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

.site-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.875rem 1.25rem;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
}

.site-title { font-weight: 600; color: var(--ink); text-decoration: none; }
.site-nav { display: flex; align-items: center; gap: 1rem; }
.site-user { color: var(--ink-muted); font-size: 0.9rem; }

.role-badge {
    display: inline-block;
    margin-left: 0.35rem;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.site-main { padding: 1.5rem 1.25rem 4rem; }

.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1.5rem;
}

.card--narrow { max-width: 26rem; margin: 3rem auto; }

.stack { display: grid; gap: 1rem; }
.stack label { display: grid; gap: 0.35rem; font-size: 0.9rem; color: var(--ink-muted); }

input[type="email"], input[type="password"], input[type="text"] {
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--bg);
    color: var(--ink);
    font: inherit;
}

.button {
    padding: 0.6rem 1rem;
    border: 0;
    border-radius: 6px;
    background: var(--accent);
    color: #fff;
    font: inherit;
    font-weight: 500;
    cursor: pointer;
}

.link-button {
    border: 0;
    background: none;
    color: var(--accent);
    font: inherit;
    cursor: pointer;
    padding: 0;
}

.alert { padding: 0.65rem 0.8rem; border-radius: 6px; font-size: 0.9rem; }
.alert--error { background: var(--accent-soft); color: var(--danger); }
.muted { color: var(--ink-muted); font-size: 0.875rem; }

/* ---- Tree ------------------------------------------------------------- */

.tree-header { margin-bottom: 1.5rem; }
.tree-header h1 { margin: 0 0 0.25rem; font-size: 1.5rem; }

/* The tree scrolls as ONE unit. Previously each generation row scrolled
   independently, which was fine for bare cards but makes connectors impossible:
   a line drawn between two rows would be wrong the moment either one scrolled. */
.tree-scroll { overflow-x: auto; padding-bottom: 0.5rem; }

.tree {
    display: grid;
    gap: 2.25rem;
    position: relative;
    min-width: min-content;
}

/* The connector layer sits behind the cards, so a line never crosses a name. */
.tree-lines {
    position: absolute;
    top: 0;
    left: 0;
    pointer-events: none;
    z-index: 0;
    overflow: visible;
}

.tree-line {
    fill: none;
    stroke: var(--line);
    stroke-width: 1.5;
    stroke-linecap: round;
}

/* Only a biological link is drawn solid. Adoptive, step and foster are real
   relationships but not descent, and the tree should not claim otherwise. */
.tree-line--adoptive,
.tree-line--step,
.tree-line--foster,
.tree-line--unknown { stroke-dasharray: 4 4; }

.tree-line--partnership { stroke: var(--accent); stroke-width: 2; }
.tree-line--ended,
.tree-line--divorced,
.tree-line--widowed { stroke: var(--line); stroke-dasharray: 3 3; }

.generation-label {
    margin: 0 0 0.6rem;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ink-muted);
}

/* Generations are centred on each other so a junction's descent is roughly
   vertical rather than raking across the whole width. */
.generation-row {
    display: flex;
    justify-content: center;
    gap: 1.25rem;
    position: relative;
    z-index: 1;
}

/* A couple reads as one unit, joined by a short rule. */
.couple {
    display: flex;
    align-items: stretch;
    gap: 0.75rem;
    position: relative;
}

.person {
    position: relative;
    z-index: 1;
    background: var(--surface);
    display: grid;
    gap: 0.2rem;
    align-content: start;
    min-width: 11rem;
    padding: 0.7rem 0.85rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    color: var(--ink);
    text-decoration: none;
}

.person:hover { border-color: var(--accent); }

.person--focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px var(--accent-soft);
}

.person-name { font-weight: 500; }
.person-dates, .person-note { font-size: 0.8rem; color: var(--ink-muted); }
.person-note { font-style: italic; }

/* ---- Navigation and flash --------------------------------------------- */

.site-brand { display: flex; align-items: baseline; gap: 1.5rem; }
.site-links { display: flex; gap: 1rem; font-size: 0.9rem; }
.site-links a { color: var(--ink-muted); text-decoration: none; }
.site-links a:hover { color: var(--accent); }

.flash-area { padding: 0.75rem 1.25rem 0; display: grid; gap: 0.5rem; }
.alert--success { background: var(--accent-soft); color: var(--accent); }

.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* ---- Page furniture ---------------------------------------------------- */

.page-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.page-header h1 { margin: 0; font-size: 1.5rem; }

.search-form { display: flex; align-items: center; gap: 0.5rem; }

input[type="search"] {
    padding: 0.5rem 0.7rem;
    min-width: 18rem;
    max-width: 100%;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--surface);
    color: var(--ink);
    font: inherit;
}

.button--quiet { background: var(--surface); color: var(--ink); border: 1px solid var(--line); }
.button--quiet:hover { border-color: var(--accent); }
.button--danger { background: var(--danger); }
.link-button--danger { color: var(--danger); }

.card + .card { margin-top: 1.25rem; }
.card--form { max-width: 44rem; }
.card--danger { border-color: var(--danger); }
.card h2 { margin: 0 0 0.75rem; font-size: 1.05rem; }

/* ---- Tables ------------------------------------------------------------ */

/* position: relative is load-bearing. Without it, an absolutely positioned
   child (a .visually-hidden column label) resolves against the viewport rather
   than this wrapper -- overflow does not create a containing block -- and its
   static position inside the scrolled table gives the whole page a horizontal
   scrollbar. */
.table-scroll { overflow-x: auto; position: relative; }

.data-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

.data-table th, .data-table td {
    padding: 0.55rem 0.8rem;
    text-align: left;
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}

.data-table tr:last-child td { border-bottom: 0; }
.data-table th { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-muted); }
.data-table a { color: var(--ink); text-decoration: none; font-weight: 500; }
.data-table a:hover { color: var(--accent); }
.row-actions { display: flex; gap: 0.75rem; font-size: 0.85rem; }
.row-actions a { color: var(--accent); font-weight: 400; }

/* ---- Forms ------------------------------------------------------------- */

.field-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.field-narrow { max-width: 20rem; }
.field-label { font-size: 0.8rem; font-weight: 500; color: var(--ink-muted); }
.field-hint { font-size: 0.8rem; color: var(--ink-muted); margin: 0.25rem 0 0; }

select, textarea {
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--bg);
    color: var(--ink);
    font: inherit;
    width: 100%;
}

textarea { resize: vertical; }

.date-fields {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.85rem 1rem 1rem;
    margin: 0;
}

.date-fields legend { padding: 0 0.4rem; font-size: 0.8rem; font-weight: 500; color: var(--ink-muted); }
.date-row { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.date-row label { display: grid; gap: 0.3rem; }

.form-actions { display: flex; align-items: center; gap: 1rem; }

.add-form { margin-top: 1rem; border-top: 1px solid var(--line); padding-top: 0.75rem; }
.add-form summary { cursor: pointer; color: var(--accent); font-size: 0.9rem; }
.add-form .stack { margin-top: 0.85rem; }
.inline-form { display: inline; }

/* ---- Person page ------------------------------------------------------- */

.person-header {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.person-header h1 { margin: 0 0 0.25rem; font-size: 1.6rem; }
.person-summary { margin: 0; color: var(--ink-muted); font-size: 0.9rem; }
.person-actions { display: flex; gap: 0.6rem; }
.person-actions .button { text-decoration: none; display: inline-block; }

/* Timeline beside relations on wide screens, stacked on narrow ones. */
.person-columns { display: grid; gap: 1.25rem; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
.person-relations { display: grid; gap: 1.25rem; align-content: start; }
.person-relations .card + .card { margin-top: 0; }

@media (max-width: 60rem) {
    .person-columns { grid-template-columns: 1fr; }
}

.timeline { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; }

.timeline-entry {
    display: grid;
    gap: 0.15rem;
    padding-left: 0.85rem;
    border-left: 2px solid var(--line);
}

.timeline-entry--birth, .timeline-entry--death { border-left-color: var(--accent); }
.timeline-date { font-size: 0.78rem; color: var(--ink-muted); }
.timeline-title { font-weight: 500; }
.timeline-place, .timeline-detail { font-size: 0.85rem; color: var(--ink-muted); }

.relation-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.relation-list li { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.relation-list a { color: var(--ink); font-weight: 500; }

.tag {
    padding: 0.08rem 0.4rem;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--ink-muted);
    font-size: 0.72rem;
}

.tag--living { color: var(--accent); }
.tag--current { color: var(--accent); }
.tag--divorced, .tag--ended, .tag--widowed { color: var(--ink-muted); }

.history-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; font-size: 0.85rem; }

/* Quick-add: create a person and link them in one step. Set back from the
   select above it so the "either/or" reads at a glance. */
.new-person {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.85rem 1rem 1rem;
    margin: 0;
    background: var(--bg);
    display: grid;
    gap: 0.85rem;
}

.new-person legend {
    padding: 0 0.4rem;
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--ink-muted);
}

.new-person .date-fields { border: 0; padding: 0; }
.new-person .date-fields legend { padding-left: 0; }

.checkbox-row { display: flex; align-items: flex-start; gap: 0.6rem; }
.checkbox-row input { margin-top: 0.25rem; }
.checkbox-row span { display: grid; gap: 0.2rem; }

/* ---- Photos ------------------------------------------------------------ */

.add-form--card { padding: 1rem 1.25rem; }
.add-form--card > summary { font-size: 1rem; }

.photo-grid {
    list-style: none;
    margin: 1.25rem 0 0;
    padding: 0;
    display: grid;
    gap: 1rem;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
}

.photo-card {
    display: grid;
    gap: 0.5rem;
    color: var(--ink);
    text-decoration: none;
}

.photo-card img {
    width: 100%;
    height: 9rem;
    object-fit: cover;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    background: var(--surface);
}

.photo-card:hover img { border-color: var(--accent); }
.photo-meta { display: grid; gap: 0.1rem; font-size: 0.85rem; }
.photo-caption { font-weight: 500; }

.photo-layout { display: grid; gap: 1.25rem; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
.photo-side { display: grid; gap: 1.25rem; align-content: start; }
.photo-side .card + .card { margin-top: 0; }

@media (max-width: 60rem) {
    .photo-layout { grid-template-columns: 1fr; }
}

/* The stage carries the image's aspect ratio, so percentage-positioned tags
   are correct before the file loads and at every display size. */
.photo-stage {
    position: relative;
    margin: 0;
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid var(--line);
    background: var(--surface);
}

.photo-stage img { display: block; width: 100%; height: 100%; object-fit: contain; }
.photo-stage--taggable { cursor: crosshair; }
.photo-hint { margin-top: 0.5rem; }

.face-tag {
    position: absolute;
    transform: translate(-50%, -50%);
    display: grid;
    justify-items: center;
    gap: 0.25rem;
    text-decoration: none;
    color: #fff;
}

.face-tag-dot {
    width: 1.6rem;
    height: 1.6rem;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.9);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45), inset 0 0 0 1px rgba(0, 0, 0, 0.25);
}

.face-tag-label {
    font-size: 0.75rem;
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    background: rgba(0, 0, 0, 0.72);
    white-space: nowrap;
    opacity: 0;
    transition: opacity 0.12s ease;
}

/* Labels stay out of the way until wanted; on a touch screen there is no hover,
   so they are always shown there. */
.face-tag:hover .face-tag-label,
.face-tag:focus-visible .face-tag-label,
.face-tag--pending .face-tag-label { opacity: 1; }

@media (hover: none) {
    .face-tag-label { opacity: 1; }
}

.face-tag--pending .face-tag-dot { border-color: var(--accent); border-style: dashed; }
.photo-delete { margin-top: 1rem; border-top: 1px solid var(--line); padding-top: 0.85rem; }

.person-identity { display: flex; align-items: center; gap: 0.9rem; }

.person-avatar {
    width: 4.5rem;
    height: 4.5rem;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid var(--line);
    background: var(--surface);
}

/* ---- Citations --------------------------------------------------------- */

.citations { margin-top: 0.35rem; }
.citation-empty { font-size: 0.78rem; color: var(--ink-muted); }

.citation-summary {
    cursor: pointer;
    font-size: 0.78rem;
    color: var(--accent);
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

.citation-summary::before { content: "\201C\201D"; letter-spacing: -0.1em; opacity: 0.7; }
.citation-summary--empty { color: var(--ink-muted); }
.citation-details[open] .citation-summary { margin-bottom: 0.5rem; }

.citation-list {
    list-style: none;
    margin: 0 0 0.6rem;
    padding: 0 0 0 0.9rem;
    border-left: 2px solid var(--line);
    display: grid;
    gap: 0.4rem;
    font-size: 0.85rem;
}

.citation-list li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.4rem; }
.citation-detail { flex-basis: 100%; color: var(--ink-muted); font-style: italic; }

.citation-form {
    display: grid;
    gap: 0.6rem;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    align-items: end;
    padding: 0.75rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--bg);
}

.citation-form label { display: grid; gap: 0.25rem; }
.citation-form .citation-detail-field { grid-column: 1 / -1; }
.citation-form button { justify-self: start; }

.tag--high { color: var(--accent); }
.tag--low { opacity: 0.75; }

.source-usage { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; }
.source-usage li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; }

.detail-list { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 0.35rem 0.85rem; font-size: 0.9rem; }
.detail-list dt { color: var(--ink-muted); }
.detail-list dd { margin: 0; }
.detail-heading { margin: 1rem 0 0.4rem; font-size: 0.9rem; }
